payload-notifications 0.1.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/README.md +164 -0
- package/dist/api.d.ts +11 -0
- package/dist/api.d.ts.map +1 -0
- package/dist/api.js +144 -0
- package/dist/api.js.map +1 -0
- package/dist/components/NotificationBell.d.ts +4 -0
- package/dist/components/NotificationBell.d.ts.map +1 -0
- package/dist/components/NotificationBell.js +318 -0
- package/dist/components/NotificationBell.js.map +1 -0
- package/dist/components/NotificationBell.module.css +184 -0
- package/dist/components/NotificationItem.d.ts +11 -0
- package/dist/components/NotificationItem.d.ts.map +1 -0
- package/dist/components/NotificationItem.js +97 -0
- package/dist/components/NotificationItem.js.map +1 -0
- package/dist/components/NotificationItem.module.css +136 -0
- package/dist/components/notification-reducer.d.ts +36 -0
- package/dist/components/notification-reducer.d.ts.map +1 -0
- package/dist/components/notification-reducer.js +74 -0
- package/dist/components/notification-reducer.js.map +1 -0
- package/dist/const.d.ts +2 -0
- package/dist/const.d.ts.map +1 -0
- package/dist/const.js +3 -0
- package/dist/const.js.map +1 -0
- package/dist/context.d.ts +19 -0
- package/dist/context.d.ts.map +1 -0
- package/dist/context.js +20 -0
- package/dist/context.js.map +1 -0
- package/dist/email/default-email.d.ts +10 -0
- package/dist/email/default-email.d.ts.map +1 -0
- package/dist/email/default-email.js +34 -0
- package/dist/email/default-email.js.map +1 -0
- package/dist/email/email-token.d.ts +17 -0
- package/dist/email/email-token.d.ts.map +1 -0
- package/dist/email/email-token.js +26 -0
- package/dist/email/email-token.js.map +1 -0
- package/dist/email/index.d.ts +2 -0
- package/dist/email/index.d.ts.map +1 -0
- package/dist/email/index.js +3 -0
- package/dist/email/index.js.map +1 -0
- package/dist/email/send-email.d.ts +11 -0
- package/dist/email/send-email.d.ts.map +1 -0
- package/dist/email/send-email.js +48 -0
- package/dist/email/send-email.js.map +1 -0
- package/dist/endpoints/delete-notification.d.ts +3 -0
- package/dist/endpoints/delete-notification.d.ts.map +1 -0
- package/dist/endpoints/delete-notification.js +20 -0
- package/dist/endpoints/delete-notification.js.map +1 -0
- package/dist/endpoints/email-unsubscribe.d.ts +2 -0
- package/dist/endpoints/email-unsubscribe.d.ts.map +1 -0
- package/dist/endpoints/email-unsubscribe.js +39 -0
- package/dist/endpoints/email-unsubscribe.js.map +1 -0
- package/dist/endpoints/map-notification.d.ts +5 -0
- package/dist/endpoints/map-notification.d.ts.map +1 -0
- package/dist/endpoints/map-notification.js +19 -0
- package/dist/endpoints/map-notification.js.map +1 -0
- package/dist/endpoints/mark-all-read.d.ts +3 -0
- package/dist/endpoints/mark-all-read.d.ts.map +1 -0
- package/dist/endpoints/mark-all-read.js +36 -0
- package/dist/endpoints/mark-all-read.js.map +1 -0
- package/dist/endpoints/mark-read.d.ts +3 -0
- package/dist/endpoints/mark-read.d.ts.map +1 -0
- package/dist/endpoints/mark-read.js +23 -0
- package/dist/endpoints/mark-read.js.map +1 -0
- package/dist/endpoints/open-notification.d.ts +7 -0
- package/dist/endpoints/open-notification.d.ts.map +1 -0
- package/dist/endpoints/open-notification.js +65 -0
- package/dist/endpoints/open-notification.js.map +1 -0
- package/dist/endpoints/read-notifications.d.ts +3 -0
- package/dist/endpoints/read-notifications.d.ts.map +1 -0
- package/dist/endpoints/read-notifications.js +39 -0
- package/dist/endpoints/read-notifications.js.map +1 -0
- package/dist/endpoints/unread-notifications.d.ts +3 -0
- package/dist/endpoints/unread-notifications.d.ts.map +1 -0
- package/dist/endpoints/unread-notifications.js +69 -0
- package/dist/endpoints/unread-notifications.js.map +1 -0
- package/dist/endpoints/unsubscribe.d.ts +2 -0
- package/dist/endpoints/unsubscribe.d.ts.map +1 -0
- package/dist/endpoints/unsubscribe.js +17 -0
- package/dist/endpoints/unsubscribe.js.map +1 -0
- package/dist/endpoints/update-preferences.d.ts +2 -0
- package/dist/endpoints/update-preferences.d.ts.map +1 -0
- package/dist/endpoints/update-preferences.js +33 -0
- package/dist/endpoints/update-preferences.js.map +1 -0
- package/dist/entities.d.ts +7 -0
- package/dist/entities.d.ts.map +1 -0
- package/dist/entities.js +161 -0
- package/dist/entities.js.map +1 -0
- package/dist/exports/client.d.ts +2 -0
- package/dist/exports/client.d.ts.map +1 -0
- package/dist/exports/client.js +4 -0
- package/dist/exports/client.js.map +1 -0
- package/dist/exports/rsc.d.ts +2 -0
- package/dist/exports/rsc.d.ts.map +1 -0
- package/dist/exports/rsc.js +3 -0
- package/dist/exports/rsc.js.map +1 -0
- package/dist/helpers.d.ts +14 -0
- package/dist/helpers.d.ts.map +1 -0
- package/dist/helpers.js +50 -0
- package/dist/helpers.js.map +1 -0
- package/dist/index.d.ts +19 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +75 -0
- package/dist/index.js.map +1 -0
- package/dist/internals/index.d.ts +30 -0
- package/dist/internals/index.d.ts.map +1 -0
- package/dist/internals/index.js +81 -0
- package/dist/internals/index.js.map +1 -0
- package/dist/internals/procedure.d.ts +34 -0
- package/dist/internals/procedure.d.ts.map +1 -0
- package/dist/internals/procedure.js +111 -0
- package/dist/internals/procedure.js.map +1 -0
- package/dist/internals/urls.d.ts +11 -0
- package/dist/internals/urls.d.ts.map +1 -0
- package/dist/internals/urls.js +23 -0
- package/dist/internals/urls.js.map +1 -0
- package/dist/internals/utils.d.ts +8 -0
- package/dist/internals/utils.d.ts.map +1 -0
- package/dist/internals/utils.js +57 -0
- package/dist/internals/utils.js.map +1 -0
- package/dist/message/builder.d.ts +23 -0
- package/dist/message/builder.d.ts.map +1 -0
- package/dist/message/builder.js +43 -0
- package/dist/message/builder.js.map +1 -0
- package/dist/message/index.d.ts +3 -0
- package/dist/message/index.d.ts.map +1 -0
- package/dist/message/index.js +4 -0
- package/dist/message/index.js.map +1 -0
- package/dist/message/resolve-message.d.ts +23 -0
- package/dist/message/resolve-message.d.ts.map +1 -0
- package/dist/message/resolve-message.js +72 -0
- package/dist/message/resolve-message.js.map +1 -0
- package/dist/payload-types.d.ts +317 -0
- package/dist/payload-types.d.ts.map +1 -0
- package/dist/payload-types.js +15 -0
- package/dist/payload-types.js.map +1 -0
- package/dist/procedures.d.ts +58 -0
- package/dist/procedures.d.ts.map +1 -0
- package/dist/procedures.js +62 -0
- package/dist/procedures.js.map +1 -0
- package/dist/types.d.ts +123 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +35 -0
- package/dist/types.js.map +1 -0
- package/package.json +72 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"unread-notifications.d.ts","sourceRoot":"","sources":["../../src/endpoints/unread-notifications.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAS,MAAM,SAAS,CAAC;AAIrD,eAAO,MAAM,2BAA2B,sBACnB,cAAc,+BA6C/B,CAAC"}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { ENDPOINTS } from '../procedures';
|
|
2
|
+
import { mapNotification } from './map-notification';
|
|
3
|
+
export const unreadNotificationsEndpoint = (notificationsSlug)=>ENDPOINTS.unread.endpoint(async (req, { since })=>{
|
|
4
|
+
if (!req.user) {
|
|
5
|
+
return Response.json({
|
|
6
|
+
error: 'Unauthorized'
|
|
7
|
+
}, {
|
|
8
|
+
status: 401
|
|
9
|
+
});
|
|
10
|
+
}
|
|
11
|
+
const timestamp = new Date().toISOString();
|
|
12
|
+
const where = {
|
|
13
|
+
and: [
|
|
14
|
+
{
|
|
15
|
+
recipient: {
|
|
16
|
+
equals: req.user.id
|
|
17
|
+
}
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
readAt: {
|
|
21
|
+
exists: false
|
|
22
|
+
}
|
|
23
|
+
},
|
|
24
|
+
...since ? [
|
|
25
|
+
{
|
|
26
|
+
createdAt: {
|
|
27
|
+
greater_than: since
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
] : []
|
|
31
|
+
]
|
|
32
|
+
};
|
|
33
|
+
const result = await req.payload.find({
|
|
34
|
+
collection: notificationsSlug,
|
|
35
|
+
where,
|
|
36
|
+
sort: '-createdAt',
|
|
37
|
+
limit: 0,
|
|
38
|
+
depth: 0
|
|
39
|
+
});
|
|
40
|
+
// On initial load, check if any read notifications exist so the UI
|
|
41
|
+
// can decide whether to show the "Show older" button.
|
|
42
|
+
const hasMore = since ? undefined : (await req.payload.find({
|
|
43
|
+
collection: notificationsSlug,
|
|
44
|
+
where: {
|
|
45
|
+
and: [
|
|
46
|
+
{
|
|
47
|
+
recipient: {
|
|
48
|
+
equals: req.user.id
|
|
49
|
+
}
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
readAt: {
|
|
53
|
+
exists: true
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
]
|
|
57
|
+
},
|
|
58
|
+
limit: 1,
|
|
59
|
+
depth: 0,
|
|
60
|
+
select: {}
|
|
61
|
+
})).docs.length > 0;
|
|
62
|
+
return {
|
|
63
|
+
docs: result.docs.map(mapNotification),
|
|
64
|
+
timestamp,
|
|
65
|
+
hasMore
|
|
66
|
+
};
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
//# sourceMappingURL=unread-notifications.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/endpoints/unread-notifications.ts"],"sourcesContent":["import type { CollectionSlug, Where } from 'payload';\nimport { ENDPOINTS } from '@/procedures';\nimport { mapNotification } from './map-notification';\n\nexport const unreadNotificationsEndpoint = (\n notificationsSlug: CollectionSlug,\n) =>\n ENDPOINTS.unread.endpoint(async (req, { since }) => {\n if (!req.user) {\n return Response.json({ error: 'Unauthorized' }, { status: 401 });\n }\n\n const timestamp = new Date().toISOString();\n\n const where: Where = {\n and: [\n { recipient: { equals: req.user.id } },\n { readAt: { exists: false } },\n ...(since ? [{ createdAt: { greater_than: since } }] : []),\n ],\n };\n\n const result = await req.payload.find({\n collection: notificationsSlug as 'notifications',\n where,\n sort: '-createdAt',\n limit: 0,\n depth: 0,\n });\n\n // On initial load, check if any read notifications exist so the UI\n // can decide whether to show the \"Show older\" button.\n const hasMore = since\n ? undefined\n : (\n await req.payload.find({\n collection: notificationsSlug as 'notifications',\n where: {\n and: [\n { recipient: { equals: req.user.id } },\n { readAt: { exists: true } },\n ],\n },\n limit: 1,\n depth: 0,\n select: {},\n })\n ).docs.length > 0;\n\n return { docs: result.docs.map(mapNotification), timestamp, hasMore };\n });\n"],"names":["ENDPOINTS","mapNotification","unreadNotificationsEndpoint","notificationsSlug","unread","endpoint","req","since","user","Response","json","error","status","timestamp","Date","toISOString","where","and","recipient","equals","id","readAt","exists","createdAt","greater_than","result","payload","find","collection","sort","limit","depth","hasMore","undefined","select","docs","length","map"],"mappings":"AACA,SAASA,SAAS,QAAQ,eAAe;AACzC,SAASC,eAAe,QAAQ,qBAAqB;AAErD,OAAO,MAAMC,8BAA8B,CACzCC,oBAEAH,UAAUI,MAAM,CAACC,QAAQ,CAAC,OAAOC,KAAK,EAAEC,KAAK,EAAE;QAC7C,IAAI,CAACD,IAAIE,IAAI,EAAE;YACb,OAAOC,SAASC,IAAI,CAAC;gBAAEC,OAAO;YAAe,GAAG;gBAAEC,QAAQ;YAAI;QAChE;QAEA,MAAMC,YAAY,IAAIC,OAAOC,WAAW;QAExC,MAAMC,QAAe;YACnBC,KAAK;gBACH;oBAAEC,WAAW;wBAAEC,QAAQb,IAAIE,IAAI,CAACY,EAAE;oBAAC;gBAAE;gBACrC;oBAAEC,QAAQ;wBAAEC,QAAQ;oBAAM;gBAAE;mBACxBf,QAAQ;oBAAC;wBAAEgB,WAAW;4BAAEC,cAAcjB;wBAAM;oBAAE;iBAAE,GAAG,EAAE;aAC1D;QACH;QAEA,MAAMkB,SAAS,MAAMnB,IAAIoB,OAAO,CAACC,IAAI,CAAC;YACpCC,YAAYzB;YACZa;YACAa,MAAM;YACNC,OAAO;YACPC,OAAO;QACT;QAEA,mEAAmE;QACnE,sDAAsD;QACtD,MAAMC,UAAUzB,QACZ0B,YACA,AACE,CAAA,MAAM3B,IAAIoB,OAAO,CAACC,IAAI,CAAC;YACrBC,YAAYzB;YACZa,OAAO;gBACLC,KAAK;oBACH;wBAAEC,WAAW;4BAAEC,QAAQb,IAAIE,IAAI,CAACY,EAAE;wBAAC;oBAAE;oBACrC;wBAAEC,QAAQ;4BAAEC,QAAQ;wBAAK;oBAAE;iBAC5B;YACH;YACAQ,OAAO;YACPC,OAAO;YACPG,QAAQ,CAAC;QACX,EAAC,EACDC,IAAI,CAACC,MAAM,GAAG;QAEpB,OAAO;YAAED,MAAMV,OAAOU,IAAI,CAACE,GAAG,CAACpC;YAAkBY;YAAWmB;QAAQ;IACtE,GAAG"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"unsubscribe.d.ts","sourceRoot":"","sources":["../../src/endpoints/unsubscribe.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,mBAAmB,kCAS5B,CAAC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { unsubscribe } from '../api';
|
|
2
|
+
import { ENDPOINTS } from '../procedures';
|
|
3
|
+
export const unsubscribeEndpoint = ()=>ENDPOINTS.unsubscribe.endpoint(async (req, { documentReference })=>{
|
|
4
|
+
if (!req.user) {
|
|
5
|
+
return Response.json({
|
|
6
|
+
error: 'Unauthorized'
|
|
7
|
+
}, {
|
|
8
|
+
status: 401
|
|
9
|
+
});
|
|
10
|
+
}
|
|
11
|
+
await unsubscribe(req, req.user.id, documentReference);
|
|
12
|
+
return {
|
|
13
|
+
success: true
|
|
14
|
+
};
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
//# sourceMappingURL=unsubscribe.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/endpoints/unsubscribe.ts"],"sourcesContent":["import { unsubscribe } from '@/api';\nimport { ENDPOINTS } from '@/procedures';\n\nexport const unsubscribeEndpoint = () =>\n ENDPOINTS.unsubscribe.endpoint(async (req, { documentReference }) => {\n if (!req.user) {\n return Response.json({ error: 'Unauthorized' }, { status: 401 });\n }\n\n await unsubscribe(req, req.user.id, documentReference);\n\n return { success: true as const };\n });\n"],"names":["unsubscribe","ENDPOINTS","unsubscribeEndpoint","endpoint","req","documentReference","user","Response","json","error","status","id","success"],"mappings":"AAAA,SAASA,WAAW,QAAQ,QAAQ;AACpC,SAASC,SAAS,QAAQ,eAAe;AAEzC,OAAO,MAAMC,sBAAsB,IACjCD,UAAUD,WAAW,CAACG,QAAQ,CAAC,OAAOC,KAAK,EAAEC,iBAAiB,EAAE;QAC9D,IAAI,CAACD,IAAIE,IAAI,EAAE;YACb,OAAOC,SAASC,IAAI,CAAC;gBAAEC,OAAO;YAAe,GAAG;gBAAEC,QAAQ;YAAI;QAChE;QAEA,MAAMV,YAAYI,KAAKA,IAAIE,IAAI,CAACK,EAAE,EAAEN;QAEpC,OAAO;YAAEO,SAAS;QAAc;IAClC,GAAG"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"update-preferences.d.ts","sourceRoot":"","sources":["../../src/endpoints/update-preferences.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,yBAAyB,kCAsBlC,CAAC"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { ENDPOINTS } from '../procedures';
|
|
2
|
+
export const updatePreferencesEndpoint = ()=>ENDPOINTS.updatePreferences.endpoint(async (req, { emailEnabled })=>{
|
|
3
|
+
if (!req.user) {
|
|
4
|
+
return Response.json({
|
|
5
|
+
error: 'Unauthorized'
|
|
6
|
+
}, {
|
|
7
|
+
status: 401
|
|
8
|
+
});
|
|
9
|
+
}
|
|
10
|
+
const userSlug = req.payload.config.admin?.user;
|
|
11
|
+
if (!userSlug) {
|
|
12
|
+
return Response.json({
|
|
13
|
+
error: 'User collection not configured'
|
|
14
|
+
}, {
|
|
15
|
+
status: 500
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
await req.payload.update({
|
|
19
|
+
collection: userSlug,
|
|
20
|
+
id: req.user.id,
|
|
21
|
+
data: {
|
|
22
|
+
notificationPreferences: {
|
|
23
|
+
emailEnabled
|
|
24
|
+
}
|
|
25
|
+
},
|
|
26
|
+
req
|
|
27
|
+
});
|
|
28
|
+
return {
|
|
29
|
+
success: true
|
|
30
|
+
};
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
//# sourceMappingURL=update-preferences.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/endpoints/update-preferences.ts"],"sourcesContent":["import { ENDPOINTS } from '@/procedures';\n\nexport const updatePreferencesEndpoint = () =>\n ENDPOINTS.updatePreferences.endpoint(async (req, { emailEnabled }) => {\n if (!req.user) {\n return Response.json({ error: 'Unauthorized' }, { status: 401 });\n }\n\n const userSlug = req.payload.config.admin?.user as 'users' | undefined;\n if (!userSlug) {\n return Response.json(\n { error: 'User collection not configured' },\n { status: 500 },\n );\n }\n\n await req.payload.update({\n collection: userSlug,\n id: req.user.id,\n data: { notificationPreferences: { emailEnabled } },\n req,\n });\n\n return { success: true as const };\n });\n"],"names":["ENDPOINTS","updatePreferencesEndpoint","updatePreferences","endpoint","req","emailEnabled","user","Response","json","error","status","userSlug","payload","config","admin","update","collection","id","data","notificationPreferences","success"],"mappings":"AAAA,SAASA,SAAS,QAAQ,eAAe;AAEzC,OAAO,MAAMC,4BAA4B,IACvCD,UAAUE,iBAAiB,CAACC,QAAQ,CAAC,OAAOC,KAAK,EAAEC,YAAY,EAAE;QAC/D,IAAI,CAACD,IAAIE,IAAI,EAAE;YACb,OAAOC,SAASC,IAAI,CAAC;gBAAEC,OAAO;YAAe,GAAG;gBAAEC,QAAQ;YAAI;QAChE;QAEA,MAAMC,WAAWP,IAAIQ,OAAO,CAACC,MAAM,CAACC,KAAK,EAAER;QAC3C,IAAI,CAACK,UAAU;YACb,OAAOJ,SAASC,IAAI,CAClB;gBAAEC,OAAO;YAAiC,GAC1C;gBAAEC,QAAQ;YAAI;QAElB;QAEA,MAAMN,IAAIQ,OAAO,CAACG,MAAM,CAAC;YACvBC,YAAYL;YACZM,IAAIb,IAAIE,IAAI,CAACW,EAAE;YACfC,MAAM;gBAAEC,yBAAyB;oBAAEd;gBAAa;YAAE;YAClDD;QACF;QAEA,OAAO;YAAEgB,SAAS;QAAc;IAClC,GAAG"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export declare const Notifications: (options: Record<string, unknown> & {
|
|
2
|
+
slug: string;
|
|
3
|
+
}) => import("payload").CollectionConfig;
|
|
4
|
+
export declare const Subscriptions: (options: Record<string, unknown> & {
|
|
5
|
+
slug: string;
|
|
6
|
+
}) => import("payload").CollectionConfig;
|
|
7
|
+
//# sourceMappingURL=entities.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"entities.d.ts","sourceRoot":"","sources":["../src/entities.ts"],"names":[],"mappings":"AAKA,eAAO,MAAM,aAAa;;wCAyDxB,CAAC;AAEH,eAAO,MAAM,aAAa;;wCAkCxB,CAAC"}
|
package/dist/entities.js
ADDED
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
import { createCollectionConfigFactory } from './internals/index.js';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
import { messageSchema } from './types';
|
|
4
|
+
export const Notifications = createCollectionConfigFactory({
|
|
5
|
+
admin: {
|
|
6
|
+
hidden: true
|
|
7
|
+
},
|
|
8
|
+
access: {
|
|
9
|
+
read: ({ req })=>{
|
|
10
|
+
if (!req.user) return false;
|
|
11
|
+
return {
|
|
12
|
+
recipient: {
|
|
13
|
+
equals: req.user.id
|
|
14
|
+
}
|
|
15
|
+
};
|
|
16
|
+
},
|
|
17
|
+
create: ()=>false,
|
|
18
|
+
update: ({ req })=>{
|
|
19
|
+
if (!req.user) return false;
|
|
20
|
+
return {
|
|
21
|
+
recipient: {
|
|
22
|
+
equals: req.user.id
|
|
23
|
+
}
|
|
24
|
+
};
|
|
25
|
+
},
|
|
26
|
+
delete: ({ req })=>{
|
|
27
|
+
if (!req.user) return false;
|
|
28
|
+
return {
|
|
29
|
+
recipient: {
|
|
30
|
+
equals: req.user.id
|
|
31
|
+
}
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
},
|
|
35
|
+
fields: [
|
|
36
|
+
{
|
|
37
|
+
name: 'recipient',
|
|
38
|
+
type: 'relationship',
|
|
39
|
+
relationTo: 'users',
|
|
40
|
+
required: true,
|
|
41
|
+
index: true
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
name: 'event',
|
|
45
|
+
type: 'text',
|
|
46
|
+
required: true
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
name: 'actor',
|
|
50
|
+
type: 'relationship',
|
|
51
|
+
relationTo: 'users'
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
name: 'message',
|
|
55
|
+
type: 'json',
|
|
56
|
+
required: true,
|
|
57
|
+
typescriptSchema: [
|
|
58
|
+
()=>z.toJSONSchema(messageSchema)
|
|
59
|
+
]
|
|
60
|
+
},
|
|
61
|
+
{
|
|
62
|
+
name: 'url',
|
|
63
|
+
type: 'text'
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
name: 'meta',
|
|
67
|
+
type: 'json'
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
name: 'documentReference',
|
|
71
|
+
type: 'group',
|
|
72
|
+
fields: [
|
|
73
|
+
{
|
|
74
|
+
name: 'entity',
|
|
75
|
+
type: 'select',
|
|
76
|
+
options: [
|
|
77
|
+
'collection',
|
|
78
|
+
'global'
|
|
79
|
+
]
|
|
80
|
+
},
|
|
81
|
+
{
|
|
82
|
+
name: 'slug',
|
|
83
|
+
type: 'text',
|
|
84
|
+
index: true
|
|
85
|
+
},
|
|
86
|
+
{
|
|
87
|
+
name: 'documentId',
|
|
88
|
+
type: 'text',
|
|
89
|
+
index: true
|
|
90
|
+
}
|
|
91
|
+
]
|
|
92
|
+
},
|
|
93
|
+
{
|
|
94
|
+
name: 'readAt',
|
|
95
|
+
type: 'date'
|
|
96
|
+
},
|
|
97
|
+
{
|
|
98
|
+
name: 'emailSentAt',
|
|
99
|
+
type: 'date'
|
|
100
|
+
},
|
|
101
|
+
{
|
|
102
|
+
name: 'emailError',
|
|
103
|
+
type: 'text'
|
|
104
|
+
}
|
|
105
|
+
]
|
|
106
|
+
});
|
|
107
|
+
export const Subscriptions = createCollectionConfigFactory({
|
|
108
|
+
admin: {
|
|
109
|
+
hidden: true
|
|
110
|
+
},
|
|
111
|
+
access: {
|
|
112
|
+
read: ({ req })=>{
|
|
113
|
+
if (!req.user) return false;
|
|
114
|
+
return {
|
|
115
|
+
user: {
|
|
116
|
+
equals: req.user.id
|
|
117
|
+
}
|
|
118
|
+
};
|
|
119
|
+
},
|
|
120
|
+
create: ()=>false,
|
|
121
|
+
update: ()=>false,
|
|
122
|
+
delete: ()=>false
|
|
123
|
+
},
|
|
124
|
+
fields: [
|
|
125
|
+
{
|
|
126
|
+
name: 'user',
|
|
127
|
+
type: 'relationship',
|
|
128
|
+
relationTo: 'users',
|
|
129
|
+
required: true,
|
|
130
|
+
index: true
|
|
131
|
+
},
|
|
132
|
+
{
|
|
133
|
+
name: 'documentReference',
|
|
134
|
+
type: 'group',
|
|
135
|
+
fields: [
|
|
136
|
+
{
|
|
137
|
+
name: 'entity',
|
|
138
|
+
type: 'select',
|
|
139
|
+
options: [
|
|
140
|
+
'collection',
|
|
141
|
+
'global'
|
|
142
|
+
],
|
|
143
|
+
required: true
|
|
144
|
+
},
|
|
145
|
+
{
|
|
146
|
+
name: 'slug',
|
|
147
|
+
type: 'text',
|
|
148
|
+
required: true,
|
|
149
|
+
index: true
|
|
150
|
+
},
|
|
151
|
+
{
|
|
152
|
+
name: 'documentId',
|
|
153
|
+
type: 'text',
|
|
154
|
+
index: true
|
|
155
|
+
}
|
|
156
|
+
]
|
|
157
|
+
}
|
|
158
|
+
]
|
|
159
|
+
});
|
|
160
|
+
|
|
161
|
+
//# sourceMappingURL=entities.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/entities.ts"],"sourcesContent":["import { createCollectionConfigFactory } from '@repo/common';\nimport type { JSONSchema4 } from 'json-schema';\nimport { z } from 'zod';\nimport { messageSchema } from './types';\n\nexport const Notifications = createCollectionConfigFactory({\n admin: { hidden: true },\n access: {\n read: ({ req }) => {\n if (!req.user) return false;\n return { recipient: { equals: req.user.id } };\n },\n create: () => false,\n update: ({ req }) => {\n if (!req.user) return false;\n return { recipient: { equals: req.user.id } };\n },\n delete: ({ req }) => {\n if (!req.user) return false;\n return { recipient: { equals: req.user.id } };\n },\n },\n fields: [\n {\n name: 'recipient',\n type: 'relationship',\n relationTo: 'users',\n required: true,\n index: true,\n },\n { name: 'event', type: 'text', required: true },\n {\n name: 'actor',\n type: 'relationship',\n relationTo: 'users',\n },\n {\n name: 'message',\n type: 'json',\n required: true,\n typescriptSchema: [() => z.toJSONSchema(messageSchema) as JSONSchema4],\n },\n { name: 'url', type: 'text' },\n { name: 'meta', type: 'json' },\n {\n name: 'documentReference',\n type: 'group',\n fields: [\n {\n name: 'entity',\n type: 'select',\n options: ['collection', 'global'],\n },\n { name: 'slug', type: 'text', index: true },\n\n { name: 'documentId', type: 'text', index: true },\n ],\n },\n { name: 'readAt', type: 'date' },\n { name: 'emailSentAt', type: 'date' },\n { name: 'emailError', type: 'text' },\n ],\n});\n\nexport const Subscriptions = createCollectionConfigFactory({\n admin: { hidden: true },\n access: {\n read: ({ req }) => {\n if (!req.user) return false;\n return { user: { equals: req.user.id } };\n },\n create: () => false,\n update: () => false,\n delete: () => false,\n },\n fields: [\n {\n name: 'user',\n type: 'relationship',\n relationTo: 'users',\n required: true,\n index: true,\n },\n {\n name: 'documentReference',\n type: 'group',\n fields: [\n {\n name: 'entity',\n type: 'select',\n options: ['collection', 'global'],\n required: true,\n },\n { name: 'slug', type: 'text', required: true, index: true },\n { name: 'documentId', type: 'text', index: true },\n ],\n },\n ],\n});\n"],"names":["createCollectionConfigFactory","z","messageSchema","Notifications","admin","hidden","access","read","req","user","recipient","equals","id","create","update","delete","fields","name","type","relationTo","required","index","typescriptSchema","toJSONSchema","options","Subscriptions"],"mappings":"AAAA,SAASA,6BAA6B,QAAQ,eAAe;AAE7D,SAASC,CAAC,QAAQ,MAAM;AACxB,SAASC,aAAa,QAAQ,UAAU;AAExC,OAAO,MAAMC,gBAAgBH,8BAA8B;IACzDI,OAAO;QAAEC,QAAQ;IAAK;IACtBC,QAAQ;QACNC,MAAM,CAAC,EAAEC,GAAG,EAAE;YACZ,IAAI,CAACA,IAAIC,IAAI,EAAE,OAAO;YACtB,OAAO;gBAAEC,WAAW;oBAAEC,QAAQH,IAAIC,IAAI,CAACG,EAAE;gBAAC;YAAE;QAC9C;QACAC,QAAQ,IAAM;QACdC,QAAQ,CAAC,EAAEN,GAAG,EAAE;YACd,IAAI,CAACA,IAAIC,IAAI,EAAE,OAAO;YACtB,OAAO;gBAAEC,WAAW;oBAAEC,QAAQH,IAAIC,IAAI,CAACG,EAAE;gBAAC;YAAE;QAC9C;QACAG,QAAQ,CAAC,EAAEP,GAAG,EAAE;YACd,IAAI,CAACA,IAAIC,IAAI,EAAE,OAAO;YACtB,OAAO;gBAAEC,WAAW;oBAAEC,QAAQH,IAAIC,IAAI,CAACG,EAAE;gBAAC;YAAE;QAC9C;IACF;IACAI,QAAQ;QACN;YACEC,MAAM;YACNC,MAAM;YACNC,YAAY;YACZC,UAAU;YACVC,OAAO;QACT;QACA;YAAEJ,MAAM;YAASC,MAAM;YAAQE,UAAU;QAAK;QAC9C;YACEH,MAAM;YACNC,MAAM;YACNC,YAAY;QACd;QACA;YACEF,MAAM;YACNC,MAAM;YACNE,UAAU;YACVE,kBAAkB;gBAAC,IAAMrB,EAAEsB,YAAY,CAACrB;aAA8B;QACxE;QACA;YAAEe,MAAM;YAAOC,MAAM;QAAO;QAC5B;YAAED,MAAM;YAAQC,MAAM;QAAO;QAC7B;YACED,MAAM;YACNC,MAAM;YACNF,QAAQ;gBACN;oBACEC,MAAM;oBACNC,MAAM;oBACNM,SAAS;wBAAC;wBAAc;qBAAS;gBACnC;gBACA;oBAAEP,MAAM;oBAAQC,MAAM;oBAAQG,OAAO;gBAAK;gBAE1C;oBAAEJ,MAAM;oBAAcC,MAAM;oBAAQG,OAAO;gBAAK;aACjD;QACH;QACA;YAAEJ,MAAM;YAAUC,MAAM;QAAO;QAC/B;YAAED,MAAM;YAAeC,MAAM;QAAO;QACpC;YAAED,MAAM;YAAcC,MAAM;QAAO;KACpC;AACH,GAAG;AAEH,OAAO,MAAMO,gBAAgBzB,8BAA8B;IACzDI,OAAO;QAAEC,QAAQ;IAAK;IACtBC,QAAQ;QACNC,MAAM,CAAC,EAAEC,GAAG,EAAE;YACZ,IAAI,CAACA,IAAIC,IAAI,EAAE,OAAO;YACtB,OAAO;gBAAEA,MAAM;oBAAEE,QAAQH,IAAIC,IAAI,CAACG,EAAE;gBAAC;YAAE;QACzC;QACAC,QAAQ,IAAM;QACdC,QAAQ,IAAM;QACdC,QAAQ,IAAM;IAChB;IACAC,QAAQ;QACN;YACEC,MAAM;YACNC,MAAM;YACNC,YAAY;YACZC,UAAU;YACVC,OAAO;QACT;QACA;YACEJ,MAAM;YACNC,MAAM;YACNF,QAAQ;gBACN;oBACEC,MAAM;oBACNC,MAAM;oBACNM,SAAS;wBAAC;wBAAc;qBAAS;oBACjCJ,UAAU;gBACZ;gBACA;oBAAEH,MAAM;oBAAQC,MAAM;oBAAQE,UAAU;oBAAMC,OAAO;gBAAK;gBAC1D;oBAAEJ,MAAM;oBAAcC,MAAM;oBAAQG,OAAO;gBAAK;aACjD;QACH;KACD;AACH,GAAG"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/exports/client.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,gBAAgB,EAAE,MAAM,gCAAgC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/exports/client.ts"],"sourcesContent":["'use client';\n\nexport { NotificationBell } from '../components/NotificationBell';\n"],"names":["NotificationBell"],"mappings":"AAAA;AAEA,SAASA,gBAAgB,QAAQ,iCAAiC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rsc.d.ts","sourceRoot":"","sources":["../../src/exports/rsc.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/exports/rsc.ts"],"sourcesContent":["export {};\n"],"names":[],"mappings":"AAAA,WAAU"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { DocumentID, DocumentReference } from './internals/index.js';
|
|
2
|
+
import type { BasePayload } from 'payload';
|
|
3
|
+
import type { ResolvedUser, StoredDocumentReference } from './types';
|
|
4
|
+
/**
|
|
5
|
+
* Resolve a user ID into a display-name pair using the user collection's
|
|
6
|
+
* `admin.useAsTitle` config. Falls back to `email` when the configured
|
|
7
|
+
* field is missing or not a string.
|
|
8
|
+
*/
|
|
9
|
+
export declare function resolveUser(payload: BasePayload, userId: DocumentID): Promise<ResolvedUser>;
|
|
10
|
+
/** Convert a `DocumentReference` to the flat shape stored in the group field. */
|
|
11
|
+
export declare function toStoredReference(ref: DocumentReference): StoredDocumentReference;
|
|
12
|
+
/** Convert the flat stored shape back to a `DocumentReference` discriminated union. */
|
|
13
|
+
export declare function toDocumentReference(ref: StoredDocumentReference): DocumentReference;
|
|
14
|
+
//# sourceMappingURL=helpers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../src/helpers.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAElE,OAAO,KAAK,EAAE,WAAW,EAAkB,MAAM,SAAS,CAAC;AAE3D,OAAO,KAAK,EAEV,YAAY,EACZ,uBAAuB,EACxB,MAAM,SAAS,CAAC;AAEjB;;;;GAIG;AACH,wBAAsB,WAAW,CAC/B,OAAO,EAAE,WAAW,EACpB,MAAM,EAAE,UAAU,GACjB,OAAO,CAAC,YAAY,CAAC,CAuBvB;AAED,iFAAiF;AACjF,wBAAgB,iBAAiB,CAC/B,GAAG,EAAE,iBAAiB,GACrB,uBAAuB,CAMzB;AAED,uFAAuF;AACvF,wBAAgB,mBAAmB,CACjC,GAAG,EAAE,uBAAuB,GAC3B,iBAAiB,CAUnB"}
|
package/dist/helpers.js
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Resolve a user ID into a display-name pair using the user collection's
|
|
3
|
+
* `admin.useAsTitle` config. Falls back to `email` when the configured
|
|
4
|
+
* field is missing or not a string.
|
|
5
|
+
*/ export async function resolveUser(payload, userId) {
|
|
6
|
+
const userSlug = payload.config.admin?.user;
|
|
7
|
+
if (!userSlug) throw new Error('User collection not configured');
|
|
8
|
+
const user = await payload.findByID({
|
|
9
|
+
collection: userSlug,
|
|
10
|
+
id: userId,
|
|
11
|
+
depth: 0
|
|
12
|
+
});
|
|
13
|
+
const displayName = (()=>{
|
|
14
|
+
const { useAsTitle = 'email' } = payload.collections[userSlug].config.admin ?? {};
|
|
15
|
+
const title = user[useAsTitle];
|
|
16
|
+
if (typeof title === 'string') {
|
|
17
|
+
return title;
|
|
18
|
+
}
|
|
19
|
+
return user.email;
|
|
20
|
+
})();
|
|
21
|
+
return {
|
|
22
|
+
...user,
|
|
23
|
+
displayName
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
/** Convert a `DocumentReference` to the flat shape stored in the group field. */ export function toStoredReference(ref) {
|
|
27
|
+
return {
|
|
28
|
+
entity: ref.entity,
|
|
29
|
+
slug: ref.slug,
|
|
30
|
+
documentId: ref.entity === 'collection' ? String(ref.id) : undefined
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
/** Convert the flat stored shape back to a `DocumentReference` discriminated union. */ export function toDocumentReference(ref) {
|
|
34
|
+
if (ref.entity === 'collection') {
|
|
35
|
+
if (!ref.documentId) {
|
|
36
|
+
throw new Error(`Collection reference "${ref.slug}" is missing a documentId`);
|
|
37
|
+
}
|
|
38
|
+
return {
|
|
39
|
+
entity: ref.entity,
|
|
40
|
+
slug: ref.slug,
|
|
41
|
+
id: ref.documentId
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
return {
|
|
45
|
+
entity: ref.entity,
|
|
46
|
+
slug: ref.slug
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
//# sourceMappingURL=helpers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/helpers.ts"],"sourcesContent":["import type { DocumentID, DocumentReference } from '@repo/common';\nimport { getApiURL } from '@repo/common';\nimport type { BasePayload, PayloadRequest } from 'payload';\nimport { signUnsubscribeToken } from './email/email-token';\nimport type {\n NotificationEmailLinks,\n ResolvedUser,\n StoredDocumentReference,\n} from './types';\n\n/**\n * Resolve a user ID into a display-name pair using the user collection's\n * `admin.useAsTitle` config. Falls back to `email` when the configured\n * field is missing or not a string.\n */\nexport async function resolveUser(\n payload: BasePayload,\n userId: DocumentID,\n): Promise<ResolvedUser> {\n const userSlug = payload.config.admin?.user as 'users' | undefined;\n if (!userSlug) throw new Error('User collection not configured');\n\n const user = await payload.findByID({\n collection: userSlug,\n id: userId,\n depth: 0,\n });\n\n const displayName = (() => {\n const { useAsTitle = 'email' } =\n payload.collections[userSlug].config.admin ?? {};\n\n const title = user[useAsTitle as keyof typeof user];\n\n if (typeof title === 'string') {\n return title;\n }\n return user.email;\n })();\n\n return { ...user, displayName };\n}\n\n/** Convert a `DocumentReference` to the flat shape stored in the group field. */\nexport function toStoredReference(\n ref: DocumentReference,\n): StoredDocumentReference {\n return {\n entity: ref.entity,\n slug: ref.slug,\n documentId: ref.entity === 'collection' ? String(ref.id) : undefined,\n };\n}\n\n/** Convert the flat stored shape back to a `DocumentReference` discriminated union. */\nexport function toDocumentReference(\n ref: StoredDocumentReference,\n): DocumentReference {\n if (ref.entity === 'collection') {\n if (!ref.documentId) {\n throw new Error(\n `Collection reference \"${ref.slug}\" is missing a documentId`,\n );\n }\n return { entity: ref.entity, slug: ref.slug, id: ref.documentId };\n }\n return { entity: ref.entity, slug: ref.slug };\n}\n"],"names":["resolveUser","payload","userId","userSlug","config","admin","user","Error","findByID","collection","id","depth","displayName","useAsTitle","collections","title","email","toStoredReference","ref","entity","slug","documentId","String","undefined","toDocumentReference"],"mappings":"AAUA;;;;CAIC,GACD,OAAO,eAAeA,YACpBC,OAAoB,EACpBC,MAAkB;IAElB,MAAMC,WAAWF,QAAQG,MAAM,CAACC,KAAK,EAAEC;IACvC,IAAI,CAACH,UAAU,MAAM,IAAII,MAAM;IAE/B,MAAMD,OAAO,MAAML,QAAQO,QAAQ,CAAC;QAClCC,YAAYN;QACZO,IAAIR;QACJS,OAAO;IACT;IAEA,MAAMC,cAAc,AAAC,CAAA;QACnB,MAAM,EAAEC,aAAa,OAAO,EAAE,GAC5BZ,QAAQa,WAAW,CAACX,SAAS,CAACC,MAAM,CAACC,KAAK,IAAI,CAAC;QAEjD,MAAMU,QAAQT,IAAI,CAACO,WAAgC;QAEnD,IAAI,OAAOE,UAAU,UAAU;YAC7B,OAAOA;QACT;QACA,OAAOT,KAAKU,KAAK;IACnB,CAAA;IAEA,OAAO;QAAE,GAAGV,IAAI;QAAEM;IAAY;AAChC;AAEA,+EAA+E,GAC/E,OAAO,SAASK,kBACdC,GAAsB;IAEtB,OAAO;QACLC,QAAQD,IAAIC,MAAM;QAClBC,MAAMF,IAAIE,IAAI;QACdC,YAAYH,IAAIC,MAAM,KAAK,eAAeG,OAAOJ,IAAIR,EAAE,IAAIa;IAC7D;AACF;AAEA,qFAAqF,GACrF,OAAO,SAASC,oBACdN,GAA4B;IAE5B,IAAIA,IAAIC,MAAM,KAAK,cAAc;QAC/B,IAAI,CAACD,IAAIG,UAAU,EAAE;YACnB,MAAM,IAAId,MACR,CAAC,sBAAsB,EAAEW,IAAIE,IAAI,CAAC,yBAAyB,CAAC;QAEhE;QACA,OAAO;YAAED,QAAQD,IAAIC,MAAM;YAAEC,MAAMF,IAAIE,IAAI;YAAEV,IAAIQ,IAAIG,UAAU;QAAC;IAClE;IACA,OAAO;QAAEF,QAAQD,IAAIC,MAAM;QAAEC,MAAMF,IAAIE,IAAI;IAAC;AAC9C"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { Plugin } from 'payload';
|
|
2
|
+
import type { NotificationCallback, NotificationEmailConfig } from './types';
|
|
3
|
+
export { getSubscribers, notify, subscribe, unsubscribe } from './api';
|
|
4
|
+
export { createLiveMessage } from './message';
|
|
5
|
+
export type { LiveMessage, MessageContext, MessageFn, NotificationEmailLinks, NotifyInput, } from './types';
|
|
6
|
+
export interface NotificationsPluginConfig {
|
|
7
|
+
/** Email channel configuration. Pass `true` for default templates, or provide custom functions. */
|
|
8
|
+
email?: true | Partial<NotificationEmailConfig>;
|
|
9
|
+
/** External callback fired for every notification. */
|
|
10
|
+
onNotify?: NotificationCallback;
|
|
11
|
+
/** Slug for the notifications collection. @default "notifications" */
|
|
12
|
+
notificationsSlug?: string;
|
|
13
|
+
/** Slug for the subscriptions collection. @default "subscriptions" */
|
|
14
|
+
subscriptionsSlug?: string;
|
|
15
|
+
/** Poll interval in seconds for the bell icon. @default 30 */
|
|
16
|
+
pollInterval?: number;
|
|
17
|
+
}
|
|
18
|
+
export declare const notificationsPlugin: ({ notificationsSlug, subscriptionsSlug, pollInterval, email, onNotify, }?: NotificationsPluginConfig) => Plugin;
|
|
19
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAkB,MAAM,EAAE,MAAM,SAAS,CAAC;AAiBtD,OAAO,KAAK,EAAE,oBAAoB,EAAE,uBAAuB,EAAE,MAAM,SAAS,CAAC;AAE7E,OAAO,EAAE,cAAc,EAAE,MAAM,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,OAAO,CAAC;AACvE,OAAO,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAC;AAC9C,YAAY,EACV,WAAW,EACX,cAAc,EACd,SAAS,EACT,sBAAsB,EACtB,WAAW,GACZ,MAAM,SAAS,CAAC;AAEjB,MAAM,WAAW,yBAAyB;IACxC,mGAAmG;IACnG,KAAK,CAAC,EAAE,IAAI,GAAG,OAAO,CAAC,uBAAuB,CAAC,CAAC;IAChD,sDAAsD;IACtD,QAAQ,CAAC,EAAE,oBAAoB,CAAC;IAChC,sEAAsE;IACtE,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,sEAAsE;IACtE,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,8DAA8D;IAC9D,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,eAAO,MAAM,mBAAmB,8EAM7B,yBAAyB,KAAQ,MA6EnC,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { attachPluginContext } from './context';
|
|
2
|
+
import { defaultGenerateHTML, defaultGenerateSubject } from './email/default-email';
|
|
3
|
+
import { deleteNotificationEndpoint } from './endpoints/delete-notification';
|
|
4
|
+
import { emailUnsubscribeEndpoint } from './endpoints/email-unsubscribe';
|
|
5
|
+
import { markAllReadEndpoint } from './endpoints/mark-all-read';
|
|
6
|
+
import { markReadEndpoint } from './endpoints/mark-read';
|
|
7
|
+
import { openNotificationEndpoint } from './endpoints/open-notification';
|
|
8
|
+
import { readNotificationsEndpoint } from './endpoints/read-notifications';
|
|
9
|
+
import { unreadNotificationsEndpoint } from './endpoints/unread-notifications';
|
|
10
|
+
import { unsubscribeEndpoint } from './endpoints/unsubscribe';
|
|
11
|
+
import { updatePreferencesEndpoint } from './endpoints/update-preferences';
|
|
12
|
+
import { Notifications, Subscriptions } from './entities';
|
|
13
|
+
export { getSubscribers, notify, subscribe, unsubscribe } from './api';
|
|
14
|
+
export { createLiveMessage } from './message';
|
|
15
|
+
export const notificationsPlugin = ({ notificationsSlug = 'notifications', subscriptionsSlug = 'subscriptions', pollInterval = 30, email, onNotify } = {})=>{
|
|
16
|
+
const notifSlug = notificationsSlug;
|
|
17
|
+
const subsSlug = subscriptionsSlug;
|
|
18
|
+
const resolvedEmail = email !== undefined ? {
|
|
19
|
+
generateSubject: defaultGenerateSubject,
|
|
20
|
+
generateHTML: defaultGenerateHTML,
|
|
21
|
+
...typeof email === 'object' ? email : {}
|
|
22
|
+
} : undefined;
|
|
23
|
+
return (config)=>{
|
|
24
|
+
attachPluginContext(config, {
|
|
25
|
+
collectionSlugs: {
|
|
26
|
+
notifications: notifSlug,
|
|
27
|
+
subscriptions: subsSlug
|
|
28
|
+
},
|
|
29
|
+
pollInterval,
|
|
30
|
+
email: resolvedEmail,
|
|
31
|
+
onNotify
|
|
32
|
+
});
|
|
33
|
+
// Add Collections
|
|
34
|
+
config.collections ??= [];
|
|
35
|
+
config.collections.push(Notifications({
|
|
36
|
+
slug: notifSlug
|
|
37
|
+
}));
|
|
38
|
+
config.collections.push(Subscriptions({
|
|
39
|
+
slug: subsSlug
|
|
40
|
+
}));
|
|
41
|
+
// Add Notification Preferences
|
|
42
|
+
const usersCollection = config.collections.find(({ slug })=>slug === config.admin?.user);
|
|
43
|
+
if (usersCollection) {
|
|
44
|
+
usersCollection.fields ??= [];
|
|
45
|
+
usersCollection.fields.push({
|
|
46
|
+
name: 'notificationPreferences',
|
|
47
|
+
type: 'group',
|
|
48
|
+
fields: [
|
|
49
|
+
{
|
|
50
|
+
name: 'emailEnabled',
|
|
51
|
+
type: 'checkbox',
|
|
52
|
+
defaultValue: true,
|
|
53
|
+
label: 'Email notifications'
|
|
54
|
+
}
|
|
55
|
+
]
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
// Attach Endpoints
|
|
59
|
+
config.endpoints ??= [];
|
|
60
|
+
config.endpoints.push(unreadNotificationsEndpoint(notifSlug), readNotificationsEndpoint(notifSlug), markReadEndpoint(notifSlug), markAllReadEndpoint(notifSlug), updatePreferencesEndpoint(), deleteNotificationEndpoint(notifSlug), openNotificationEndpoint(notifSlug), unsubscribeEndpoint(), emailUnsubscribeEndpoint());
|
|
61
|
+
// Add admin components
|
|
62
|
+
config.admin ??= {};
|
|
63
|
+
config.admin.components ??= {};
|
|
64
|
+
config.admin.components.actions ??= [];
|
|
65
|
+
config.admin.components.actions.push({
|
|
66
|
+
path: 'payload-notifications/client#NotificationBell',
|
|
67
|
+
clientProps: {
|
|
68
|
+
pollInterval
|
|
69
|
+
}
|
|
70
|
+
});
|
|
71
|
+
return config;
|
|
72
|
+
};
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["import type { CollectionSlug, Plugin } from 'payload';\nimport type { NotificationBellProps } from './components/NotificationBell';\nimport { attachPluginContext } from './context';\nimport {\n defaultGenerateHTML,\n defaultGenerateSubject,\n} from './email/default-email';\nimport { deleteNotificationEndpoint } from './endpoints/delete-notification';\nimport { emailUnsubscribeEndpoint } from './endpoints/email-unsubscribe';\nimport { markAllReadEndpoint } from './endpoints/mark-all-read';\nimport { markReadEndpoint } from './endpoints/mark-read';\nimport { openNotificationEndpoint } from './endpoints/open-notification';\nimport { readNotificationsEndpoint } from './endpoints/read-notifications';\nimport { unreadNotificationsEndpoint } from './endpoints/unread-notifications';\nimport { unsubscribeEndpoint } from './endpoints/unsubscribe';\nimport { updatePreferencesEndpoint } from './endpoints/update-preferences';\nimport { Notifications, Subscriptions } from './entities';\nimport type { NotificationCallback, NotificationEmailConfig } from './types';\n\nexport { getSubscribers, notify, subscribe, unsubscribe } from './api';\nexport { createLiveMessage } from './message';\nexport type {\n LiveMessage,\n MessageContext,\n MessageFn,\n NotificationEmailLinks,\n NotifyInput,\n} from './types';\n\nexport interface NotificationsPluginConfig {\n /** Email channel configuration. Pass `true` for default templates, or provide custom functions. */\n email?: true | Partial<NotificationEmailConfig>;\n /** External callback fired for every notification. */\n onNotify?: NotificationCallback;\n /** Slug for the notifications collection. @default \"notifications\" */\n notificationsSlug?: string;\n /** Slug for the subscriptions collection. @default \"subscriptions\" */\n subscriptionsSlug?: string;\n /** Poll interval in seconds for the bell icon. @default 30 */\n pollInterval?: number;\n}\n\nexport const notificationsPlugin = ({\n notificationsSlug = 'notifications',\n subscriptionsSlug = 'subscriptions',\n pollInterval = 30,\n email,\n onNotify,\n}: NotificationsPluginConfig = {}): Plugin => {\n const notifSlug = notificationsSlug as CollectionSlug;\n const subsSlug = subscriptionsSlug as CollectionSlug;\n\n const resolvedEmail: NotificationEmailConfig | undefined =\n email !== undefined\n ? {\n generateSubject: defaultGenerateSubject,\n generateHTML: defaultGenerateHTML,\n ...(typeof email === 'object' ? email : {}),\n }\n : undefined;\n\n return (config) => {\n attachPluginContext(config, {\n collectionSlugs: {\n notifications: notifSlug,\n subscriptions: subsSlug,\n },\n pollInterval,\n email: resolvedEmail,\n onNotify,\n });\n\n // Add Collections\n config.collections ??= [];\n config.collections.push(Notifications({ slug: notifSlug }));\n config.collections.push(Subscriptions({ slug: subsSlug }));\n\n // Add Notification Preferences\n const usersCollection = config.collections.find(\n ({ slug }) => slug === config.admin?.user,\n );\n\n if (usersCollection) {\n usersCollection.fields ??= [];\n usersCollection.fields.push({\n name: 'notificationPreferences',\n type: 'group',\n fields: [\n {\n name: 'emailEnabled',\n type: 'checkbox',\n defaultValue: true,\n label: 'Email notifications',\n },\n ],\n });\n }\n\n // Attach Endpoints\n config.endpoints ??= [];\n config.endpoints.push(\n unreadNotificationsEndpoint(notifSlug),\n readNotificationsEndpoint(notifSlug),\n markReadEndpoint(notifSlug),\n markAllReadEndpoint(notifSlug),\n updatePreferencesEndpoint(),\n deleteNotificationEndpoint(notifSlug),\n openNotificationEndpoint(notifSlug),\n unsubscribeEndpoint(),\n emailUnsubscribeEndpoint(),\n );\n\n // Add admin components\n config.admin ??= {};\n config.admin.components ??= {};\n config.admin.components.actions ??= [];\n config.admin.components.actions.push({\n path: 'payload-notifications/client#NotificationBell',\n clientProps: {\n pollInterval,\n } satisfies NotificationBellProps,\n });\n\n return config;\n };\n};\n"],"names":["attachPluginContext","defaultGenerateHTML","defaultGenerateSubject","deleteNotificationEndpoint","emailUnsubscribeEndpoint","markAllReadEndpoint","markReadEndpoint","openNotificationEndpoint","readNotificationsEndpoint","unreadNotificationsEndpoint","unsubscribeEndpoint","updatePreferencesEndpoint","Notifications","Subscriptions","getSubscribers","notify","subscribe","unsubscribe","createLiveMessage","notificationsPlugin","notificationsSlug","subscriptionsSlug","pollInterval","email","onNotify","notifSlug","subsSlug","resolvedEmail","undefined","generateSubject","generateHTML","config","collectionSlugs","notifications","subscriptions","collections","push","slug","usersCollection","find","admin","user","fields","name","type","defaultValue","label","endpoints","components","actions","path","clientProps"],"mappings":"AAEA,SAASA,mBAAmB,QAAQ,YAAY;AAChD,SACEC,mBAAmB,EACnBC,sBAAsB,QACjB,wBAAwB;AAC/B,SAASC,0BAA0B,QAAQ,kCAAkC;AAC7E,SAASC,wBAAwB,QAAQ,gCAAgC;AACzE,SAASC,mBAAmB,QAAQ,4BAA4B;AAChE,SAASC,gBAAgB,QAAQ,wBAAwB;AACzD,SAASC,wBAAwB,QAAQ,gCAAgC;AACzE,SAASC,yBAAyB,QAAQ,iCAAiC;AAC3E,SAASC,2BAA2B,QAAQ,mCAAmC;AAC/E,SAASC,mBAAmB,QAAQ,0BAA0B;AAC9D,SAASC,yBAAyB,QAAQ,iCAAiC;AAC3E,SAASC,aAAa,EAAEC,aAAa,QAAQ,aAAa;AAG1D,SAASC,cAAc,EAAEC,MAAM,EAAEC,SAAS,EAAEC,WAAW,QAAQ,QAAQ;AACvE,SAASC,iBAAiB,QAAQ,YAAY;AAsB9C,OAAO,MAAMC,sBAAsB,CAAC,EAClCC,oBAAoB,eAAe,EACnCC,oBAAoB,eAAe,EACnCC,eAAe,EAAE,EACjBC,KAAK,EACLC,QAAQ,EACkB,GAAG,CAAC,CAAC;IAC/B,MAAMC,YAAYL;IAClB,MAAMM,WAAWL;IAEjB,MAAMM,gBACJJ,UAAUK,YACN;QACEC,iBAAiB3B;QACjB4B,cAAc7B;QACd,GAAI,OAAOsB,UAAU,WAAWA,QAAQ,CAAC,CAAC;IAC5C,IACAK;IAEN,OAAO,CAACG;QACN/B,oBAAoB+B,QAAQ;YAC1BC,iBAAiB;gBACfC,eAAeR;gBACfS,eAAeR;YACjB;YACAJ;YACAC,OAAOI;YACPH;QACF;QAEA,kBAAkB;QAClBO,OAAOI,WAAW,KAAK,EAAE;QACzBJ,OAAOI,WAAW,CAACC,IAAI,CAACxB,cAAc;YAAEyB,MAAMZ;QAAU;QACxDM,OAAOI,WAAW,CAACC,IAAI,CAACvB,cAAc;YAAEwB,MAAMX;QAAS;QAEvD,+BAA+B;QAC/B,MAAMY,kBAAkBP,OAAOI,WAAW,CAACI,IAAI,CAC7C,CAAC,EAAEF,IAAI,EAAE,GAAKA,SAASN,OAAOS,KAAK,EAAEC;QAGvC,IAAIH,iBAAiB;YACnBA,gBAAgBI,MAAM,KAAK,EAAE;YAC7BJ,gBAAgBI,MAAM,CAACN,IAAI,CAAC;gBAC1BO,MAAM;gBACNC,MAAM;gBACNF,QAAQ;oBACN;wBACEC,MAAM;wBACNC,MAAM;wBACNC,cAAc;wBACdC,OAAO;oBACT;iBACD;YACH;QACF;QAEA,mBAAmB;QACnBf,OAAOgB,SAAS,KAAK,EAAE;QACvBhB,OAAOgB,SAAS,CAACX,IAAI,CACnB3B,4BAA4BgB,YAC5BjB,0BAA0BiB,YAC1BnB,iBAAiBmB,YACjBpB,oBAAoBoB,YACpBd,6BACAR,2BAA2BsB,YAC3BlB,yBAAyBkB,YACzBf,uBACAN;QAGF,uBAAuB;QACvB2B,OAAOS,KAAK,KAAK,CAAC;QAClBT,OAAOS,KAAK,CAACQ,UAAU,KAAK,CAAC;QAC7BjB,OAAOS,KAAK,CAACQ,UAAU,CAACC,OAAO,KAAK,EAAE;QACtClB,OAAOS,KAAK,CAACQ,UAAU,CAACC,OAAO,CAACb,IAAI,CAAC;YACnCc,MAAM;YACNC,aAAa;gBACX7B;YACF;QACF;QAEA,OAAOS;IACT;AACF,EAAE"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { BasePayload, CollectionConfig, CollectionSlug, JsonObject, TypeWithID } from 'payload';
|
|
2
|
+
import z from 'zod';
|
|
3
|
+
export declare const documentIdSchema: z.ZodUnion<readonly [z.ZodNumber, z.ZodString]>;
|
|
4
|
+
export type DocumentID = TypeWithID['id'] & z.infer<typeof documentIdSchema>;
|
|
5
|
+
export declare const documentReferenceSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
6
|
+
entity: z.ZodLiteral<"collection">;
|
|
7
|
+
slug: z.ZodString;
|
|
8
|
+
id: z.ZodUnion<readonly [z.ZodNumber, z.ZodString]>;
|
|
9
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
10
|
+
entity: z.ZodLiteral<"global">;
|
|
11
|
+
slug: z.ZodString;
|
|
12
|
+
}, z.core.$strip>], "entity">;
|
|
13
|
+
export type DocumentReference = z.infer<typeof documentReferenceSchema>;
|
|
14
|
+
export declare const isPopulated: <T extends TypeWithID>(relationship: T | DocumentID) => relationship is T;
|
|
15
|
+
export declare function assertPopulated<T extends TypeWithID | null>(docsOrIds: (T | DocumentID)[], errorMessage?: (id: DocumentID) => string): T[];
|
|
16
|
+
export declare function assertPopulated<T extends TypeWithID | null>(docOrId: T | DocumentID, errorMessage?: (id: DocumentID) => string): T;
|
|
17
|
+
export declare const createCollectionConfigFactory: <T extends Record<string, unknown>>(factory: Omit<CollectionConfig, "slug"> | ((options: T & {
|
|
18
|
+
slug: string;
|
|
19
|
+
}) => Omit<CollectionConfig, "slug">)) => (options: T & {
|
|
20
|
+
slug: string;
|
|
21
|
+
}) => CollectionConfig;
|
|
22
|
+
export type IdentifiableDocument = TypeWithID['id'] | TypeWithID;
|
|
23
|
+
export declare function isIdentifiableDocument(value: unknown): value is IdentifiableDocument;
|
|
24
|
+
export declare const resolveDocumentID: (entity: IdentifiableDocument) => DocumentID;
|
|
25
|
+
export declare function fetchDocumentByReference(payload: BasePayload, ref: DocumentReference): Promise<JsonObject>;
|
|
26
|
+
export declare function updateDocumentByReference(payload: BasePayload, ref: DocumentReference, data: JsonObject): Promise<import("payload").DataFromCollectionSlug<CollectionSlug>>;
|
|
27
|
+
export { defineProcedure, type Procedure, type ProcedureBuilder, } from './procedure';
|
|
28
|
+
export { getAdminURL, getApiURL, getServerURL } from './urls';
|
|
29
|
+
export { findFields, uncaughtSwitchCase } from './utils';
|
|
30
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/internals/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,WAAW,EACX,gBAAgB,EAChB,cAAc,EAEd,UAAU,EACV,UAAU,EACX,MAAM,SAAS,CAAC;AACjB,OAAO,CAAC,MAAM,KAAK,CAAC;AAKpB,eAAO,MAAM,gBAAgB,iDAAoC,CAAC;AAClE,MAAM,MAAM,UAAU,GAAG,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAE7E,eAAO,MAAM,uBAAuB;;;;;;;6BAUlC,CAAC;AAEH,MAAM,MAAM,iBAAiB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,uBAAuB,CAAC,CAAC;AAIxE,eAAO,MAAM,WAAW,GAAI,CAAC,SAAS,UAAU,gBAChC,CAAC,GAAG,UAAU,KAC3B,YAAY,IAAI,CAAqC,CAAC;AAEzD,wBAAgB,eAAe,CAAC,CAAC,SAAS,UAAU,GAAG,IAAI,EACzD,SAAS,EAAE,CAAC,CAAC,GAAG,UAAU,CAAC,EAAE,EAC7B,YAAY,CAAC,EAAE,CAAC,EAAE,EAAE,UAAU,KAAK,MAAM,GACxC,CAAC,EAAE,CAAC;AACP,wBAAgB,eAAe,CAAC,CAAC,SAAS,UAAU,GAAG,IAAI,EACzD,OAAO,EAAE,CAAC,GAAG,UAAU,EACvB,YAAY,CAAC,EAAE,CAAC,EAAE,EAAE,UAAU,KAAK,MAAM,GACxC,CAAC,CAAC;AAeL,eAAO,MAAM,6BAA6B,GACvC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,WAE5B,IAAI,CAAC,gBAAgB,EAAE,MAAM,CAAC,GAC9B,CAAC,CAAC,OAAO,EAAE,CAAC,GAAG;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,KAAK,IAAI,CAAC,gBAAgB,EAAE,MAAM,CAAC,CAAC,eAE/D,CAAC,GAAG;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,KAAG,gBAG/B,CAAC;AAEL,MAAM,MAAM,oBAAoB,GAAG,UAAU,CAAC,IAAI,CAAC,GAAG,UAAU,CAAC;AAEjE,wBAAgB,sBAAsB,CACpC,KAAK,EAAE,OAAO,GACb,KAAK,IAAI,oBAAoB,CAO/B;AAED,eAAO,MAAM,iBAAiB,WAAY,oBAAoB,KAAG,UAChB,CAAC;AAElD,wBAAgB,wBAAwB,CACtC,OAAO,EAAE,WAAW,EACpB,GAAG,EAAE,iBAAiB,GACrB,OAAO,CAAC,UAAU,CAAC,CAgBrB;AAED,wBAAsB,yBAAyB,CAC7C,OAAO,EAAE,WAAW,EACpB,GAAG,EAAE,iBAAiB,EACtB,IAAI,EAAE,UAAU,qEAiBjB;AAED,OAAO,EACL,eAAe,EACf,KAAK,SAAS,EACd,KAAK,gBAAgB,GACtB,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AAC9D,OAAO,EAAE,UAAU,EAAE,kBAAkB,EAAE,MAAM,SAAS,CAAC"}
|