@contractspec/module.notifications 1.57.0 → 1.58.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/browser/channels/index.js +124 -0
- package/dist/browser/contracts/index.js +340 -0
- package/dist/browser/entities/index.js +223 -0
- package/dist/browser/index.js +864 -0
- package/dist/browser/notifications.capability.js +16 -0
- package/dist/browser/notifications.feature.js +34 -0
- package/dist/browser/templates/index.js +147 -0
- package/dist/channels/index.d.ts +64 -67
- package/dist/channels/index.d.ts.map +1 -1
- package/dist/channels/index.js +123 -125
- package/dist/contracts/index.d.ts +571 -577
- package/dist/contracts/index.d.ts.map +1 -1
- package/dist/contracts/index.js +324 -416
- package/dist/entities/index.d.ts +145 -150
- package/dist/entities/index.d.ts.map +1 -1
- package/dist/entities/index.js +215 -245
- package/dist/index.d.ts +6 -6
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +864 -6
- package/dist/node/channels/index.js +124 -0
- package/dist/node/contracts/index.js +340 -0
- package/dist/node/entities/index.js +223 -0
- package/dist/node/index.js +864 -0
- package/dist/node/notifications.capability.js +16 -0
- package/dist/node/notifications.feature.js +34 -0
- package/dist/node/templates/index.js +147 -0
- package/dist/notifications.capability.d.ts +1 -6
- package/dist/notifications.capability.d.ts.map +1 -1
- package/dist/notifications.capability.js +17 -20
- package/dist/notifications.feature.d.ts +1 -6
- package/dist/notifications.feature.d.ts.map +1 -1
- package/dist/notifications.feature.js +33 -75
- package/dist/templates/index.d.ts +47 -50
- package/dist/templates/index.d.ts.map +1 -1
- package/dist/templates/index.js +127 -181
- package/package.json +102 -27
- package/dist/channels/index.js.map +0 -1
- package/dist/contracts/index.js.map +0 -1
- package/dist/entities/index.js.map +0 -1
- package/dist/notifications.capability.js.map +0 -1
- package/dist/notifications.feature.js.map +0 -1
- package/dist/templates/index.js.map +0 -1
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
// src/notifications.capability.ts
|
|
2
|
+
import { defineCapability, StabilityEnum } from "@contractspec/lib.contracts";
|
|
3
|
+
var NotificationsCapability = defineCapability({
|
|
4
|
+
meta: {
|
|
5
|
+
key: "notifications",
|
|
6
|
+
version: "1.0.0",
|
|
7
|
+
kind: "ui",
|
|
8
|
+
stability: StabilityEnum.Experimental,
|
|
9
|
+
description: "User notifications and alerts",
|
|
10
|
+
owners: ["@platform.messaging"],
|
|
11
|
+
tags: ["notifications", "messaging", "alerts"]
|
|
12
|
+
}
|
|
13
|
+
});
|
|
14
|
+
export {
|
|
15
|
+
NotificationsCapability
|
|
16
|
+
};
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
// src/notifications.feature.ts
|
|
2
|
+
import { defineFeature } from "@contractspec/lib.contracts";
|
|
3
|
+
var NotificationsFeature = defineFeature({
|
|
4
|
+
meta: {
|
|
5
|
+
key: "notifications",
|
|
6
|
+
title: "Notifications",
|
|
7
|
+
description: "Multi-channel notification delivery with preference management",
|
|
8
|
+
domain: "platform",
|
|
9
|
+
version: "1.0.0",
|
|
10
|
+
owners: ["@platform.notifications"],
|
|
11
|
+
tags: ["notifications", "email", "push", "in-app"],
|
|
12
|
+
stability: "stable"
|
|
13
|
+
},
|
|
14
|
+
operations: [
|
|
15
|
+
{ key: "notifications.send", version: "1.0.0" },
|
|
16
|
+
{ key: "notifications.markRead", version: "1.0.0" },
|
|
17
|
+
{ key: "notifications.markAllRead", version: "1.0.0" },
|
|
18
|
+
{ key: "notifications.delete", version: "1.0.0" },
|
|
19
|
+
{ key: "notifications.list", version: "1.0.0" },
|
|
20
|
+
{ key: "notifications.preferences.update", version: "1.0.0" },
|
|
21
|
+
{ key: "notifications.preferences.get", version: "1.0.0" }
|
|
22
|
+
],
|
|
23
|
+
events: [],
|
|
24
|
+
presentations: [],
|
|
25
|
+
opToPresentation: [],
|
|
26
|
+
presentationsTargets: [],
|
|
27
|
+
capabilities: {
|
|
28
|
+
provides: [{ key: "notifications", version: "1.0.0" }],
|
|
29
|
+
requires: [{ key: "identity", version: "1.0.0" }]
|
|
30
|
+
}
|
|
31
|
+
});
|
|
32
|
+
export {
|
|
33
|
+
NotificationsFeature
|
|
34
|
+
};
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
// src/templates/index.ts
|
|
2
|
+
function defineTemplate(def) {
|
|
3
|
+
return def;
|
|
4
|
+
}
|
|
5
|
+
function renderTemplate(content, variables) {
|
|
6
|
+
return content.replace(/\{\{(\w+)\}\}/g, (match, key) => {
|
|
7
|
+
const value = variables[key];
|
|
8
|
+
if (value === undefined || value === null) {
|
|
9
|
+
return match;
|
|
10
|
+
}
|
|
11
|
+
return String(value);
|
|
12
|
+
});
|
|
13
|
+
}
|
|
14
|
+
function renderNotificationTemplate(template, channel, variables) {
|
|
15
|
+
const channelContent = template.channels[channel];
|
|
16
|
+
if (!channelContent) {
|
|
17
|
+
return null;
|
|
18
|
+
}
|
|
19
|
+
const title = channelContent.title ? renderTemplate(channelContent.title, variables) : template.name;
|
|
20
|
+
const body = renderTemplate(channelContent.body, variables);
|
|
21
|
+
const actionUrl = channelContent.actionUrl ? renderTemplate(channelContent.actionUrl, variables) : undefined;
|
|
22
|
+
const result = {
|
|
23
|
+
title,
|
|
24
|
+
body,
|
|
25
|
+
actionUrl
|
|
26
|
+
};
|
|
27
|
+
if (channel === "email" && channelContent.subject) {
|
|
28
|
+
result.email = {
|
|
29
|
+
subject: renderTemplate(channelContent.subject, variables),
|
|
30
|
+
html: body,
|
|
31
|
+
text: stripHtml(body)
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
return result;
|
|
35
|
+
}
|
|
36
|
+
function stripHtml(html) {
|
|
37
|
+
return html.replace(/<[^>]*>/g, "").replace(/\s+/g, " ").trim();
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
class TemplateRegistry {
|
|
41
|
+
templates = new Map;
|
|
42
|
+
register(template) {
|
|
43
|
+
this.templates.set(template.id, template);
|
|
44
|
+
}
|
|
45
|
+
get(templateId) {
|
|
46
|
+
return this.templates.get(templateId);
|
|
47
|
+
}
|
|
48
|
+
getAll() {
|
|
49
|
+
return Array.from(this.templates.values());
|
|
50
|
+
}
|
|
51
|
+
getByCategory(category) {
|
|
52
|
+
return this.getAll().filter((t) => t.category === category);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
function createTemplateRegistry() {
|
|
56
|
+
return new TemplateRegistry;
|
|
57
|
+
}
|
|
58
|
+
var WelcomeTemplate = defineTemplate({
|
|
59
|
+
id: "welcome",
|
|
60
|
+
name: "Welcome",
|
|
61
|
+
description: "Sent when a user signs up.",
|
|
62
|
+
category: "onboarding",
|
|
63
|
+
variables: [
|
|
64
|
+
{ name: "name", type: "string", required: true },
|
|
65
|
+
{ name: "appName", type: "string", default: "ContractSpec" },
|
|
66
|
+
{ name: "actionUrl", type: "url" }
|
|
67
|
+
],
|
|
68
|
+
defaultChannels: ["EMAIL", "IN_APP"],
|
|
69
|
+
channels: {
|
|
70
|
+
email: {
|
|
71
|
+
subject: "Welcome to {{appName}}, {{name}}!",
|
|
72
|
+
body: `
|
|
73
|
+
<h1>Welcome, {{name}}!</h1>
|
|
74
|
+
<p>Thanks for joining {{appName}}. We're excited to have you on board.</p>
|
|
75
|
+
<p><a href="{{actionUrl}}">Get started now</a></p>
|
|
76
|
+
`
|
|
77
|
+
},
|
|
78
|
+
inApp: {
|
|
79
|
+
title: "Welcome to {{appName}}!",
|
|
80
|
+
body: "Thanks for joining. Click to complete your profile.",
|
|
81
|
+
actionUrl: "{{actionUrl}}"
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
});
|
|
85
|
+
var OrgInviteTemplate = defineTemplate({
|
|
86
|
+
id: "org-invite",
|
|
87
|
+
name: "Organization Invitation",
|
|
88
|
+
description: "Sent when a user is invited to an organization.",
|
|
89
|
+
category: "organization",
|
|
90
|
+
variables: [
|
|
91
|
+
{ name: "inviterName", type: "string", required: true },
|
|
92
|
+
{ name: "orgName", type: "string", required: true },
|
|
93
|
+
{ name: "role", type: "string", default: "member" },
|
|
94
|
+
{ name: "actionUrl", type: "url", required: true }
|
|
95
|
+
],
|
|
96
|
+
defaultChannels: ["EMAIL"],
|
|
97
|
+
channels: {
|
|
98
|
+
email: {
|
|
99
|
+
subject: "{{inviterName}} invited you to join {{orgName}}",
|
|
100
|
+
body: `
|
|
101
|
+
<h1>You've been invited!</h1>
|
|
102
|
+
<p>{{inviterName}} has invited you to join <strong>{{orgName}}</strong> as a {{role}}.</p>
|
|
103
|
+
<p><a href="{{actionUrl}}">Accept invitation</a></p>
|
|
104
|
+
`
|
|
105
|
+
},
|
|
106
|
+
inApp: {
|
|
107
|
+
title: "Invitation to {{orgName}}",
|
|
108
|
+
body: "{{inviterName}} invited you to join as {{role}}.",
|
|
109
|
+
actionUrl: "{{actionUrl}}",
|
|
110
|
+
actionText: "Accept"
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
});
|
|
114
|
+
var MentionTemplate = defineTemplate({
|
|
115
|
+
id: "mention",
|
|
116
|
+
name: "Mention",
|
|
117
|
+
description: "Sent when a user is mentioned.",
|
|
118
|
+
category: "social",
|
|
119
|
+
variables: [
|
|
120
|
+
{ name: "mentionerName", type: "string", required: true },
|
|
121
|
+
{ name: "context", type: "string", required: true },
|
|
122
|
+
{ name: "preview", type: "string" },
|
|
123
|
+
{ name: "actionUrl", type: "url", required: true }
|
|
124
|
+
],
|
|
125
|
+
defaultChannels: ["IN_APP", "PUSH"],
|
|
126
|
+
channels: {
|
|
127
|
+
inApp: {
|
|
128
|
+
title: "{{mentionerName}} mentioned you",
|
|
129
|
+
body: 'In {{context}}: "{{preview}}"',
|
|
130
|
+
actionUrl: "{{actionUrl}}"
|
|
131
|
+
},
|
|
132
|
+
push: {
|
|
133
|
+
title: "{{mentionerName}} mentioned you",
|
|
134
|
+
body: "{{preview}}"
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
});
|
|
138
|
+
export {
|
|
139
|
+
renderTemplate,
|
|
140
|
+
renderNotificationTemplate,
|
|
141
|
+
defineTemplate,
|
|
142
|
+
createTemplateRegistry,
|
|
143
|
+
WelcomeTemplate,
|
|
144
|
+
TemplateRegistry,
|
|
145
|
+
OrgInviteTemplate,
|
|
146
|
+
MentionTemplate
|
|
147
|
+
};
|
package/dist/channels/index.d.ts
CHANGED
|
@@ -1,107 +1,104 @@
|
|
|
1
|
-
//#region src/channels/index.d.ts
|
|
2
1
|
/**
|
|
3
2
|
* Notification channel interface.
|
|
4
3
|
*/
|
|
5
|
-
interface NotificationChannel {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
4
|
+
export interface NotificationChannel {
|
|
5
|
+
/** Channel identifier */
|
|
6
|
+
readonly channelId: string;
|
|
7
|
+
/** Deliver a notification */
|
|
8
|
+
send(notification: ChannelNotification): Promise<ChannelDeliveryResult>;
|
|
9
|
+
/** Check if channel is available */
|
|
10
|
+
isAvailable(): Promise<boolean>;
|
|
12
11
|
}
|
|
13
12
|
/**
|
|
14
13
|
* Notification to deliver via a channel.
|
|
15
14
|
*/
|
|
16
|
-
interface ChannelNotification {
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
15
|
+
export interface ChannelNotification {
|
|
16
|
+
id: string;
|
|
17
|
+
userId: string;
|
|
18
|
+
title: string;
|
|
19
|
+
body: string;
|
|
20
|
+
actionUrl?: string;
|
|
21
|
+
imageUrl?: string;
|
|
22
|
+
metadata?: Record<string, unknown>;
|
|
23
|
+
email?: {
|
|
24
|
+
to: string;
|
|
25
|
+
subject: string;
|
|
26
|
+
html?: string;
|
|
27
|
+
text?: string;
|
|
28
|
+
};
|
|
29
|
+
push?: {
|
|
30
|
+
token: string;
|
|
31
|
+
badge?: number;
|
|
32
|
+
sound?: string;
|
|
33
|
+
data?: Record<string, unknown>;
|
|
34
|
+
};
|
|
35
|
+
webhook?: {
|
|
36
|
+
url: string;
|
|
37
|
+
headers?: Record<string, string>;
|
|
38
|
+
};
|
|
40
39
|
}
|
|
41
40
|
/**
|
|
42
41
|
* Result of channel delivery attempt.
|
|
43
42
|
*/
|
|
44
|
-
interface ChannelDeliveryResult {
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
43
|
+
export interface ChannelDeliveryResult {
|
|
44
|
+
success: boolean;
|
|
45
|
+
externalId?: string;
|
|
46
|
+
responseCode?: string;
|
|
47
|
+
responseMessage?: string;
|
|
48
|
+
metadata?: Record<string, unknown>;
|
|
50
49
|
}
|
|
51
50
|
/**
|
|
52
51
|
* In-app notification channel (stores in database).
|
|
53
52
|
*/
|
|
54
|
-
declare class InAppChannel implements NotificationChannel {
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
53
|
+
export declare class InAppChannel implements NotificationChannel {
|
|
54
|
+
readonly channelId = "IN_APP";
|
|
55
|
+
send(_notification: ChannelNotification): Promise<ChannelDeliveryResult>;
|
|
56
|
+
isAvailable(): Promise<boolean>;
|
|
58
57
|
}
|
|
59
58
|
/**
|
|
60
59
|
* Console channel for development/testing.
|
|
61
60
|
*/
|
|
62
|
-
declare class ConsoleChannel implements NotificationChannel {
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
61
|
+
export declare class ConsoleChannel implements NotificationChannel {
|
|
62
|
+
readonly channelId = "CONSOLE";
|
|
63
|
+
send(notification: ChannelNotification): Promise<ChannelDeliveryResult>;
|
|
64
|
+
isAvailable(): Promise<boolean>;
|
|
66
65
|
}
|
|
67
66
|
/**
|
|
68
67
|
* Email channel interface (to be implemented with provider).
|
|
69
68
|
*/
|
|
70
|
-
declare abstract class EmailChannel implements NotificationChannel {
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
69
|
+
export declare abstract class EmailChannel implements NotificationChannel {
|
|
70
|
+
readonly channelId = "EMAIL";
|
|
71
|
+
abstract send(notification: ChannelNotification): Promise<ChannelDeliveryResult>;
|
|
72
|
+
isAvailable(): Promise<boolean>;
|
|
74
73
|
}
|
|
75
74
|
/**
|
|
76
75
|
* Push notification channel interface (to be implemented with provider).
|
|
77
76
|
*/
|
|
78
|
-
declare abstract class PushChannel implements NotificationChannel {
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
77
|
+
export declare abstract class PushChannel implements NotificationChannel {
|
|
78
|
+
readonly channelId = "PUSH";
|
|
79
|
+
abstract send(notification: ChannelNotification): Promise<ChannelDeliveryResult>;
|
|
80
|
+
isAvailable(): Promise<boolean>;
|
|
82
81
|
}
|
|
83
82
|
/**
|
|
84
83
|
* Webhook channel for external integrations.
|
|
85
84
|
*/
|
|
86
|
-
declare class WebhookChannel implements NotificationChannel {
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
85
|
+
export declare class WebhookChannel implements NotificationChannel {
|
|
86
|
+
readonly channelId = "WEBHOOK";
|
|
87
|
+
send(notification: ChannelNotification): Promise<ChannelDeliveryResult>;
|
|
88
|
+
isAvailable(): Promise<boolean>;
|
|
90
89
|
}
|
|
91
90
|
/**
|
|
92
91
|
* Channel registry for managing available channels.
|
|
93
92
|
*/
|
|
94
|
-
declare class ChannelRegistry {
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
93
|
+
export declare class ChannelRegistry {
|
|
94
|
+
private channels;
|
|
95
|
+
register(channel: NotificationChannel): void;
|
|
96
|
+
get(channelId: string): NotificationChannel | undefined;
|
|
97
|
+
getAll(): NotificationChannel[];
|
|
98
|
+
getAvailable(): Promise<NotificationChannel[]>;
|
|
100
99
|
}
|
|
101
100
|
/**
|
|
102
101
|
* Create a default channel registry with standard channels.
|
|
103
102
|
*/
|
|
104
|
-
declare function createChannelRegistry(): ChannelRegistry;
|
|
105
|
-
//#endregion
|
|
106
|
-
export { ChannelDeliveryResult, ChannelNotification, ChannelRegistry, ConsoleChannel, EmailChannel, InAppChannel, NotificationChannel, PushChannel, WebhookChannel, createChannelRegistry };
|
|
103
|
+
export declare function createChannelRegistry(): ChannelRegistry;
|
|
107
104
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/channels/index.ts"],"names":[],"mappings":"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"}
|
package/dist/channels/index.js
CHANGED
|
@@ -1,127 +1,125 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
return true;
|
|
15
|
-
}
|
|
16
|
-
};
|
|
17
|
-
/**
|
|
18
|
-
* Console channel for development/testing.
|
|
19
|
-
*/
|
|
20
|
-
var ConsoleChannel = class {
|
|
21
|
-
channelId = "CONSOLE";
|
|
22
|
-
async send(notification) {
|
|
23
|
-
console.log(`📬 [${notification.id}] ${notification.title}`);
|
|
24
|
-
console.log(` ${notification.body}`);
|
|
25
|
-
if (notification.actionUrl) console.log(` Action: ${notification.actionUrl}`);
|
|
26
|
-
return {
|
|
27
|
-
success: true,
|
|
28
|
-
responseMessage: "Logged to console"
|
|
29
|
-
};
|
|
30
|
-
}
|
|
31
|
-
async isAvailable() {
|
|
32
|
-
return true;
|
|
33
|
-
}
|
|
34
|
-
};
|
|
35
|
-
/**
|
|
36
|
-
* Email channel interface (to be implemented with provider).
|
|
37
|
-
*/
|
|
38
|
-
var EmailChannel = class {
|
|
39
|
-
channelId = "EMAIL";
|
|
40
|
-
async isAvailable() {
|
|
41
|
-
return true;
|
|
42
|
-
}
|
|
43
|
-
};
|
|
44
|
-
/**
|
|
45
|
-
* Push notification channel interface (to be implemented with provider).
|
|
46
|
-
*/
|
|
47
|
-
var PushChannel = class {
|
|
48
|
-
channelId = "PUSH";
|
|
49
|
-
async isAvailable() {
|
|
50
|
-
return true;
|
|
51
|
-
}
|
|
52
|
-
};
|
|
53
|
-
/**
|
|
54
|
-
* Webhook channel for external integrations.
|
|
55
|
-
*/
|
|
56
|
-
var WebhookChannel = class {
|
|
57
|
-
channelId = "WEBHOOK";
|
|
58
|
-
async send(notification) {
|
|
59
|
-
if (!notification.webhook?.url) return {
|
|
60
|
-
success: false,
|
|
61
|
-
responseMessage: "No webhook URL configured"
|
|
62
|
-
};
|
|
63
|
-
try {
|
|
64
|
-
const response = await fetch(notification.webhook.url, {
|
|
65
|
-
method: "POST",
|
|
66
|
-
headers: {
|
|
67
|
-
"Content-Type": "application/json",
|
|
68
|
-
...notification.webhook.headers
|
|
69
|
-
},
|
|
70
|
-
body: JSON.stringify({
|
|
71
|
-
id: notification.id,
|
|
72
|
-
title: notification.title,
|
|
73
|
-
body: notification.body,
|
|
74
|
-
actionUrl: notification.actionUrl,
|
|
75
|
-
metadata: notification.metadata
|
|
76
|
-
})
|
|
77
|
-
});
|
|
78
|
-
return {
|
|
79
|
-
success: response.ok,
|
|
80
|
-
responseCode: String(response.status),
|
|
81
|
-
responseMessage: response.statusText
|
|
82
|
-
};
|
|
83
|
-
} catch (error) {
|
|
84
|
-
return {
|
|
85
|
-
success: false,
|
|
86
|
-
responseMessage: error instanceof Error ? error.message : "Unknown error"
|
|
87
|
-
};
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
async isAvailable() {
|
|
91
|
-
return true;
|
|
92
|
-
}
|
|
93
|
-
};
|
|
94
|
-
/**
|
|
95
|
-
* Channel registry for managing available channels.
|
|
96
|
-
*/
|
|
97
|
-
var ChannelRegistry = class {
|
|
98
|
-
channels = /* @__PURE__ */ new Map();
|
|
99
|
-
register(channel) {
|
|
100
|
-
this.channels.set(channel.channelId, channel);
|
|
101
|
-
}
|
|
102
|
-
get(channelId) {
|
|
103
|
-
return this.channels.get(channelId);
|
|
104
|
-
}
|
|
105
|
-
getAll() {
|
|
106
|
-
return Array.from(this.channels.values());
|
|
107
|
-
}
|
|
108
|
-
async getAvailable() {
|
|
109
|
-
const available = [];
|
|
110
|
-
for (const channel of this.channels.values()) if (await channel.isAvailable()) available.push(channel);
|
|
111
|
-
return available;
|
|
112
|
-
}
|
|
113
|
-
};
|
|
114
|
-
/**
|
|
115
|
-
* Create a default channel registry with standard channels.
|
|
116
|
-
*/
|
|
117
|
-
function createChannelRegistry() {
|
|
118
|
-
const registry = new ChannelRegistry();
|
|
119
|
-
registry.register(new InAppChannel());
|
|
120
|
-
registry.register(new ConsoleChannel());
|
|
121
|
-
registry.register(new WebhookChannel());
|
|
122
|
-
return registry;
|
|
1
|
+
// @bun
|
|
2
|
+
// src/channels/index.ts
|
|
3
|
+
class InAppChannel {
|
|
4
|
+
channelId = "IN_APP";
|
|
5
|
+
async send(_notification) {
|
|
6
|
+
return {
|
|
7
|
+
success: true,
|
|
8
|
+
responseMessage: "Stored in database"
|
|
9
|
+
};
|
|
10
|
+
}
|
|
11
|
+
async isAvailable() {
|
|
12
|
+
return true;
|
|
13
|
+
}
|
|
123
14
|
}
|
|
124
15
|
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
16
|
+
class ConsoleChannel {
|
|
17
|
+
channelId = "CONSOLE";
|
|
18
|
+
async send(notification) {
|
|
19
|
+
console.log(`\uD83D\uDCEC [${notification.id}] ${notification.title}`);
|
|
20
|
+
console.log(` ${notification.body}`);
|
|
21
|
+
if (notification.actionUrl) {
|
|
22
|
+
console.log(` Action: ${notification.actionUrl}`);
|
|
23
|
+
}
|
|
24
|
+
return {
|
|
25
|
+
success: true,
|
|
26
|
+
responseMessage: "Logged to console"
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
async isAvailable() {
|
|
30
|
+
return true;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
class EmailChannel {
|
|
35
|
+
channelId = "EMAIL";
|
|
36
|
+
async isAvailable() {
|
|
37
|
+
return true;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
class PushChannel {
|
|
42
|
+
channelId = "PUSH";
|
|
43
|
+
async isAvailable() {
|
|
44
|
+
return true;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
class WebhookChannel {
|
|
49
|
+
channelId = "WEBHOOK";
|
|
50
|
+
async send(notification) {
|
|
51
|
+
if (!notification.webhook?.url) {
|
|
52
|
+
return {
|
|
53
|
+
success: false,
|
|
54
|
+
responseMessage: "No webhook URL configured"
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
try {
|
|
58
|
+
const response = await fetch(notification.webhook.url, {
|
|
59
|
+
method: "POST",
|
|
60
|
+
headers: {
|
|
61
|
+
"Content-Type": "application/json",
|
|
62
|
+
...notification.webhook.headers
|
|
63
|
+
},
|
|
64
|
+
body: JSON.stringify({
|
|
65
|
+
id: notification.id,
|
|
66
|
+
title: notification.title,
|
|
67
|
+
body: notification.body,
|
|
68
|
+
actionUrl: notification.actionUrl,
|
|
69
|
+
metadata: notification.metadata
|
|
70
|
+
})
|
|
71
|
+
});
|
|
72
|
+
return {
|
|
73
|
+
success: response.ok,
|
|
74
|
+
responseCode: String(response.status),
|
|
75
|
+
responseMessage: response.statusText
|
|
76
|
+
};
|
|
77
|
+
} catch (error) {
|
|
78
|
+
return {
|
|
79
|
+
success: false,
|
|
80
|
+
responseMessage: error instanceof Error ? error.message : "Unknown error"
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
async isAvailable() {
|
|
85
|
+
return true;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
class ChannelRegistry {
|
|
90
|
+
channels = new Map;
|
|
91
|
+
register(channel) {
|
|
92
|
+
this.channels.set(channel.channelId, channel);
|
|
93
|
+
}
|
|
94
|
+
get(channelId) {
|
|
95
|
+
return this.channels.get(channelId);
|
|
96
|
+
}
|
|
97
|
+
getAll() {
|
|
98
|
+
return Array.from(this.channels.values());
|
|
99
|
+
}
|
|
100
|
+
async getAvailable() {
|
|
101
|
+
const available = [];
|
|
102
|
+
for (const channel of this.channels.values()) {
|
|
103
|
+
if (await channel.isAvailable()) {
|
|
104
|
+
available.push(channel);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
return available;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
function createChannelRegistry() {
|
|
111
|
+
const registry = new ChannelRegistry;
|
|
112
|
+
registry.register(new InAppChannel);
|
|
113
|
+
registry.register(new ConsoleChannel);
|
|
114
|
+
registry.register(new WebhookChannel);
|
|
115
|
+
return registry;
|
|
116
|
+
}
|
|
117
|
+
export {
|
|
118
|
+
createChannelRegistry,
|
|
119
|
+
WebhookChannel,
|
|
120
|
+
PushChannel,
|
|
121
|
+
InAppChannel,
|
|
122
|
+
EmailChannel,
|
|
123
|
+
ConsoleChannel,
|
|
124
|
+
ChannelRegistry
|
|
125
|
+
};
|