@quatrain/messaging 1.0.3 → 1.0.5

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.
Files changed (47) hide show
  1. package/LICENSE.md +15 -0
  2. package/dist/Messaging.test.d.ts +1 -0
  3. package/dist/Messaging.test.js +258 -0
  4. package/dist/MockMessagingAdapter.d.ts +32 -0
  5. package/dist/MockMessagingAdapter.js +131 -0
  6. package/package.json +11 -13
  7. package/src/AbstractMessagingAdapter.ts +9 -0
  8. package/src/MessageFormatter.ts +11 -0
  9. package/src/Messaging.test.ts +318 -0
  10. package/src/Messaging.ts +44 -0
  11. package/src/MockMessagingAdapter.ts +163 -0
  12. package/src/index.ts +20 -0
  13. package/src/types/EmailCapableAdapter.ts +14 -0
  14. package/src/types/MessageType.ts +6 -0
  15. package/src/types/MessagingRecipient.ts +6 -0
  16. package/src/types/MessagingTemplate.ts +3 -0
  17. package/src/types/NotificationCapableAdapter.ts +14 -0
  18. package/src/types/NotificationMessage.ts +3 -0
  19. package/src/types/TextCapableAdapter.ts +14 -0
  20. package/lib/types/AbstractMessage.d.ts +0 -6
  21. package/lib/types/AbstractMessage.js +0 -2
  22. package/lib/types/EmailCapableAdapter copy.d.ts +0 -6
  23. package/lib/types/EmailCapableAdapter copy.js +0 -2
  24. package/lib/types/MessagingInterface.d.ts +0 -6
  25. package/lib/types/MessagingInterface.js +0 -2
  26. /package/{lib → dist}/AbstractMessagingAdapter.d.ts +0 -0
  27. /package/{lib → dist}/AbstractMessagingAdapter.js +0 -0
  28. /package/{lib → dist}/MessageFormatter.d.ts +0 -0
  29. /package/{lib → dist}/MessageFormatter.js +0 -0
  30. /package/{lib → dist}/Messaging.d.ts +0 -0
  31. /package/{lib → dist}/Messaging.js +0 -0
  32. /package/{lib → dist}/index.d.ts +0 -0
  33. /package/{lib → dist}/index.js +0 -0
  34. /package/{lib → dist}/types/EmailCapableAdapter.d.ts +0 -0
  35. /package/{lib → dist}/types/EmailCapableAdapter.js +0 -0
  36. /package/{lib → dist}/types/MessageType.d.ts +0 -0
  37. /package/{lib → dist}/types/MessageType.js +0 -0
  38. /package/{lib → dist}/types/MessagingRecipient.d.ts +0 -0
  39. /package/{lib → dist}/types/MessagingRecipient.js +0 -0
  40. /package/{lib → dist}/types/MessagingTemplate.d.ts +0 -0
  41. /package/{lib → dist}/types/MessagingTemplate.js +0 -0
  42. /package/{lib → dist}/types/NotificationCapableAdapter.d.ts +0 -0
  43. /package/{lib → dist}/types/NotificationCapableAdapter.js +0 -0
  44. /package/{lib → dist}/types/NotificationMessage.d.ts +0 -0
  45. /package/{lib → dist}/types/NotificationMessage.js +0 -0
  46. /package/{lib → dist}/types/TextCapableAdapter.d.ts +0 -0
  47. /package/{lib → dist}/types/TextCapableAdapter.js +0 -0
package/LICENSE.md ADDED
@@ -0,0 +1,15 @@
1
+ # LICENSE UPDATE NOTICE
2
+
3
+ As of 01/01/2026, Quatrain Core is licensed under the **GNU Affero General Public License v3.0 (AGPL v3)**.
4
+ Previous versions remain under the MIT License.
5
+
6
+ ## Why AGPL?
7
+
8
+ We believe in open collaboration for the development ecosystem. The AGPL ensures that any modification or deployment of this BaaS stack, including over a network, benefits the entire community.
9
+
10
+ ## Commercial Services & Enterprise Usage
11
+
12
+ We provide official deployment services, technical training, and certification for Quatrain Core.
13
+ For organizations requiring a non-copyleft license (commercial license) or custom proprietary integrations, please contact the copyright holder: **Quatrain Technologies**.
14
+
15
+ Copyright © 2024-2026 Quatrain Technologies. All Rights Reserved.
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,258 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ const Messaging_1 = require("./Messaging");
13
+ const MockMessagingAdapter_1 = require("./MockMessagingAdapter");
14
+ describe('Messaging', () => {
15
+ let mockAdapter1;
16
+ let mockAdapter2;
17
+ beforeEach(() => {
18
+ // Reset messagers before each test
19
+ ;
20
+ Messaging_1.Messaging._messagers = {};
21
+ Messaging_1.Messaging.defaultMessager = 'default';
22
+ // Create fresh mock adapters
23
+ mockAdapter1 = new MockMessagingAdapter_1.MockMessagingAdapter({ debug: false });
24
+ mockAdapter2 = new MockMessagingAdapter_1.MockMessagingAdapter({ debug: false });
25
+ });
26
+ afterEach(() => {
27
+ // Clean up
28
+ mockAdapter1 === null || mockAdapter1 === void 0 ? void 0 : mockAdapter1.clearMessages();
29
+ mockAdapter2 === null || mockAdapter2 === void 0 ? void 0 : mockAdapter2.clearMessages();
30
+ });
31
+ describe('addMessager', () => {
32
+ it('should add a messager with an alias', () => {
33
+ Messaging_1.Messaging.addMessager(mockAdapter1, 'test-messager');
34
+ const messager = Messaging_1.Messaging.getMessager('test-messager');
35
+ expect(messager).toBe(mockAdapter1);
36
+ });
37
+ it('should add multiple messagers with different aliases', () => {
38
+ Messaging_1.Messaging.addMessager(mockAdapter1, 'messager1');
39
+ Messaging_1.Messaging.addMessager(mockAdapter2, 'messager2');
40
+ const messager1 = Messaging_1.Messaging.getMessager('messager1');
41
+ const messager2 = Messaging_1.Messaging.getMessager('messager2');
42
+ expect(messager1).toBe(mockAdapter1);
43
+ expect(messager2).toBe(mockAdapter2);
44
+ });
45
+ it('should set default messager when setDefault is true', () => {
46
+ Messaging_1.Messaging.addMessager(mockAdapter1, 'custom-messager', true);
47
+ expect(Messaging_1.Messaging.defaultMessager).toBe('custom-messager');
48
+ const messager = Messaging_1.Messaging.getMessager(); // Should use default
49
+ expect(messager).toBe(mockAdapter1);
50
+ });
51
+ it('should not change default messager when setDefault is false', () => {
52
+ const originalDefault = Messaging_1.Messaging.defaultMessager;
53
+ Messaging_1.Messaging.addMessager(mockAdapter1, 'custom-messager', false);
54
+ expect(Messaging_1.Messaging.defaultMessager).toBe(originalDefault);
55
+ });
56
+ it('should allow overriding an existing messager', () => {
57
+ Messaging_1.Messaging.addMessager(mockAdapter1, 'messager');
58
+ Messaging_1.Messaging.addMessager(mockAdapter2, 'messager');
59
+ const messager = Messaging_1.Messaging.getMessager('messager');
60
+ expect(messager).toBe(mockAdapter2);
61
+ });
62
+ });
63
+ describe('getMessager', () => {
64
+ it('should return the correct messager by alias', () => {
65
+ Messaging_1.Messaging.addMessager(mockAdapter1, 'test-messager');
66
+ const messager = Messaging_1.Messaging.getMessager('test-messager');
67
+ expect(messager).toBe(mockAdapter1);
68
+ });
69
+ it('should return the default messager when no alias is specified', () => {
70
+ Messaging_1.Messaging.addMessager(mockAdapter1, 'default', true);
71
+ const messager = Messaging_1.Messaging.getMessager();
72
+ expect(messager).toBe(mockAdapter1);
73
+ });
74
+ it('should throw error when messager alias does not exist', () => {
75
+ expect(() => {
76
+ Messaging_1.Messaging.getMessager('non-existent');
77
+ }).toThrow("Unknown messager alias: 'non-existent'");
78
+ });
79
+ it('should throw error when getting default messager that does not exist', () => {
80
+ expect(() => {
81
+ Messaging_1.Messaging.getMessager();
82
+ }).toThrow("Unknown messager alias: 'default'");
83
+ });
84
+ });
85
+ describe('defaultMessager property', () => {
86
+ it('should have a default value of "default"', () => {
87
+ expect(Messaging_1.Messaging.defaultMessager).toBe('default');
88
+ });
89
+ it('should allow changing the default messager', () => {
90
+ Messaging_1.Messaging.addMessager(mockAdapter1, 'new-default', true);
91
+ expect(Messaging_1.Messaging.defaultMessager).toBe('new-default');
92
+ });
93
+ });
94
+ describe('Integration with MockMessagingAdapter - Notifications', () => {
95
+ const recipient = {
96
+ firstname: 'John',
97
+ lastname: 'Doe',
98
+ email: 'john@example.com',
99
+ messageToken: 'test-token-123',
100
+ };
101
+ const message = {
102
+ title: 'Test Notification',
103
+ body: 'This is a test',
104
+ };
105
+ it('should send single notification', () => __awaiter(void 0, void 0, void 0, function* () {
106
+ Messaging_1.Messaging.addMessager(mockAdapter1, 'test');
107
+ const messager = Messaging_1.Messaging.getMessager('test');
108
+ const result = yield messager.sendNotification(recipient, message);
109
+ expect(result.success).toBe(true);
110
+ expect(result.messageId).toMatch(/^notif-/);
111
+ expect(messager.getMessageCount('notification')).toBe(1);
112
+ }));
113
+ it('should send batch notifications', () => __awaiter(void 0, void 0, void 0, function* () {
114
+ Messaging_1.Messaging.addMessager(mockAdapter1, 'test');
115
+ const messager = Messaging_1.Messaging.getMessager('test');
116
+ const recipients = [
117
+ recipient,
118
+ Object.assign(Object.assign({}, recipient), { email: 'jane@example.com' }),
119
+ ];
120
+ const result = yield messager.sendNotifications(recipients, message);
121
+ expect(result.success).toBe(true);
122
+ expect(result.count).toBe(2);
123
+ expect(messager.getMessageCount('notification')).toBe(1); // One batch
124
+ }));
125
+ });
126
+ describe('Integration with MockMessagingAdapter - Emails', () => {
127
+ const recipient = {
128
+ firstname: 'John',
129
+ lastname: 'Doe',
130
+ email: 'john@example.com',
131
+ messageToken: 'test-token-123',
132
+ };
133
+ const message = {
134
+ title: 'Test Email',
135
+ body: 'This is a test email',
136
+ };
137
+ it('should send single email', () => __awaiter(void 0, void 0, void 0, function* () {
138
+ Messaging_1.Messaging.addMessager(mockAdapter1, 'test');
139
+ const messager = Messaging_1.Messaging.getMessager('test');
140
+ const result = yield messager.sendEmail(recipient, message);
141
+ expect(result.success).toBe(true);
142
+ expect(result.messageId).toMatch(/^email-/);
143
+ expect(messager.getMessageCount('email')).toBe(1);
144
+ }));
145
+ it('should send batch emails', () => __awaiter(void 0, void 0, void 0, function* () {
146
+ Messaging_1.Messaging.addMessager(mockAdapter1, 'test');
147
+ const messager = Messaging_1.Messaging.getMessager('test');
148
+ const recipients = [
149
+ recipient,
150
+ Object.assign(Object.assign({}, recipient), { email: 'jane@example.com' }),
151
+ ];
152
+ const result = yield messager.sendEmails(recipients, message);
153
+ expect(result.success).toBe(true);
154
+ expect(result.count).toBe(2);
155
+ expect(messager.getMessageCount('email')).toBe(1); // One batch
156
+ }));
157
+ });
158
+ describe('Integration with MockMessagingAdapter - Text Messages', () => {
159
+ const recipient = {
160
+ firstname: 'John',
161
+ lastname: 'Doe',
162
+ email: 'john@example.com',
163
+ messageToken: 'test-token-123',
164
+ };
165
+ const message = {
166
+ title: 'Test SMS',
167
+ body: 'This is a test SMS',
168
+ };
169
+ it('should send single text message', () => __awaiter(void 0, void 0, void 0, function* () {
170
+ Messaging_1.Messaging.addMessager(mockAdapter1, 'test');
171
+ const messager = Messaging_1.Messaging.getMessager('test');
172
+ const result = yield messager.sendTextMessage(recipient, message);
173
+ expect(result.success).toBe(true);
174
+ expect(result.messageId).toMatch(/^text-/);
175
+ expect(messager.getMessageCount('text')).toBe(1);
176
+ }));
177
+ it('should send batch text messages', () => __awaiter(void 0, void 0, void 0, function* () {
178
+ Messaging_1.Messaging.addMessager(mockAdapter1, 'test');
179
+ const messager = Messaging_1.Messaging.getMessager('test');
180
+ const recipients = [
181
+ recipient,
182
+ Object.assign(Object.assign({}, recipient), { email: 'jane@example.com' }),
183
+ ];
184
+ const result = yield messager.sendTextMessages(recipients, message);
185
+ expect(result.success).toBe(true);
186
+ expect(result.count).toBe(2);
187
+ expect(messager.getMessageCount('text')).toBe(1); // One batch
188
+ }));
189
+ });
190
+ describe('Integration - Multiple message types', () => {
191
+ it('should maintain separate state between messagers', () => __awaiter(void 0, void 0, void 0, function* () {
192
+ Messaging_1.Messaging.addMessager(mockAdapter1, 'messager1');
193
+ Messaging_1.Messaging.addMessager(mockAdapter2, 'messager2');
194
+ const adapter1 = Messaging_1.Messaging.getMessager('messager1');
195
+ const adapter2 = Messaging_1.Messaging.getMessager('messager2');
196
+ const recipient = {
197
+ firstname: 'Test',
198
+ lastname: 'User',
199
+ email: 'test@example.com',
200
+ messageToken: 'test-token-123',
201
+ };
202
+ const message = {
203
+ title: 'Test',
204
+ body: 'Test message',
205
+ };
206
+ yield adapter1.sendNotification(recipient, message);
207
+ yield adapter2.sendEmail(recipient, message);
208
+ expect(adapter1.getMessageCount('notification')).toBe(1);
209
+ expect(adapter1.getMessageCount('email')).toBe(0);
210
+ expect(adapter2.getMessageCount('email')).toBe(1);
211
+ expect(adapter2.getMessageCount('notification')).toBe(0);
212
+ }));
213
+ it('should track different message types', () => __awaiter(void 0, void 0, void 0, function* () {
214
+ Messaging_1.Messaging.addMessager(mockAdapter1, 'test');
215
+ const messager = Messaging_1.Messaging.getMessager('test');
216
+ const recipient = {
217
+ firstname: 'Test',
218
+ lastname: 'User',
219
+ email: 'test@example.com',
220
+ messageToken: 'test-token-123',
221
+ };
222
+ const message = {
223
+ title: 'Test',
224
+ body: 'Test message',
225
+ };
226
+ yield messager.sendNotification(recipient, message);
227
+ yield messager.sendEmail(recipient, message);
228
+ yield messager.sendTextMessage(recipient, message);
229
+ expect(messager.getMessageCount()).toBe(3);
230
+ expect(messager.getMessageCount('notification')).toBe(1);
231
+ expect(messager.getMessageCount('email')).toBe(1);
232
+ expect(messager.getMessageCount('text')).toBe(1);
233
+ }));
234
+ });
235
+ describe('Messaging registry behavior', () => {
236
+ it('should maintain messagers across multiple operations', () => {
237
+ Messaging_1.Messaging.addMessager(mockAdapter1, 'persistent');
238
+ // Multiple get operations
239
+ const messager1 = Messaging_1.Messaging.getMessager('persistent');
240
+ const messager2 = Messaging_1.Messaging.getMessager('persistent');
241
+ expect(messager1).toBe(messager2);
242
+ expect(messager1).toBe(mockAdapter1);
243
+ });
244
+ it('should handle switching default messager multiple times', () => {
245
+ Messaging_1.Messaging.addMessager(mockAdapter1, 'messager1', true);
246
+ expect(Messaging_1.Messaging.defaultMessager).toBe('messager1');
247
+ Messaging_1.Messaging.addMessager(mockAdapter2, 'messager2', true);
248
+ expect(Messaging_1.Messaging.defaultMessager).toBe('messager2');
249
+ const defaultMessager = Messaging_1.Messaging.getMessager();
250
+ expect(defaultMessager).toBe(mockAdapter2);
251
+ });
252
+ });
253
+ describe('logger', () => {
254
+ it('should have a logger instance', () => {
255
+ expect(Messaging_1.Messaging.logger).toBeDefined();
256
+ });
257
+ });
258
+ });
@@ -0,0 +1,32 @@
1
+ import { AbstractMessagingAdapter } from './AbstractMessagingAdapter';
2
+ import { NotificationCapableAdapter } from './types/NotificationCapableAdapter';
3
+ import { EmailCapableAdapter } from './types/EmailCapableAdapter';
4
+ import { TextCapableAdapter } from './types/TextCapableAdapter';
5
+ import { MessagingRecipient } from './types/MessagingRecipient';
6
+ import { NotificationMessage } from './types/NotificationMessage';
7
+ import { MessagingParameters } from './Messaging';
8
+ interface SentMessage {
9
+ type: 'notification' | 'email' | 'text';
10
+ recipient: MessagingRecipient | MessagingRecipient[];
11
+ message: NotificationMessage;
12
+ timestamp: number;
13
+ }
14
+ /**
15
+ * Mock Messaging Adapter for testing purposes
16
+ * Implements all three capability interfaces
17
+ */
18
+ export declare class MockMessagingAdapter extends AbstractMessagingAdapter implements NotificationCapableAdapter, EmailCapableAdapter, TextCapableAdapter {
19
+ private sentMessages;
20
+ constructor(params?: MessagingParameters);
21
+ sendNotification(recipient: MessagingRecipient, message: NotificationMessage): Promise<any>;
22
+ sendNotifications(recipients: MessagingRecipient[], message: NotificationMessage): Promise<any>;
23
+ sendEmail(recipient: MessagingRecipient, message: NotificationMessage): Promise<any>;
24
+ sendEmails(recipients: MessagingRecipient[], message: NotificationMessage): Promise<any>;
25
+ sendTextMessage(recipient: MessagingRecipient, message: NotificationMessage): Promise<any>;
26
+ sendTextMessages(recipients: MessagingRecipient[], message: NotificationMessage): Promise<any>;
27
+ getSentMessages(type?: 'notification' | 'email' | 'text'): SentMessage[];
28
+ clearMessages(): void;
29
+ getMessageCount(type?: 'notification' | 'email' | 'text'): number;
30
+ getLastMessage(type?: 'notification' | 'email' | 'text'): SentMessage | undefined;
31
+ }
32
+ export {};
@@ -0,0 +1,131 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.MockMessagingAdapter = void 0;
13
+ const AbstractMessagingAdapter_1 = require("./AbstractMessagingAdapter");
14
+ /**
15
+ * Mock Messaging Adapter for testing purposes
16
+ * Implements all three capability interfaces
17
+ */
18
+ class MockMessagingAdapter extends AbstractMessagingAdapter_1.AbstractMessagingAdapter {
19
+ constructor(params = {}) {
20
+ super(params);
21
+ this.sentMessages = [];
22
+ }
23
+ sendNotification(recipient, message) {
24
+ return __awaiter(this, void 0, void 0, function* () {
25
+ this.sentMessages.push({
26
+ type: 'notification',
27
+ recipient,
28
+ message,
29
+ timestamp: Date.now(),
30
+ });
31
+ return {
32
+ success: true,
33
+ messageId: `notif-${Date.now()}`,
34
+ recipient: recipient.email,
35
+ };
36
+ });
37
+ }
38
+ sendNotifications(recipients, message) {
39
+ return __awaiter(this, void 0, void 0, function* () {
40
+ this.sentMessages.push({
41
+ type: 'notification',
42
+ recipient: recipients,
43
+ message,
44
+ timestamp: Date.now(),
45
+ });
46
+ return {
47
+ success: true,
48
+ count: recipients.length,
49
+ messageIds: recipients.map((r, i) => `notif-batch-${Date.now()}-${i}`),
50
+ };
51
+ });
52
+ }
53
+ sendEmail(recipient, message) {
54
+ return __awaiter(this, void 0, void 0, function* () {
55
+ this.sentMessages.push({
56
+ type: 'email',
57
+ recipient,
58
+ message,
59
+ timestamp: Date.now(),
60
+ });
61
+ return {
62
+ success: true,
63
+ messageId: `email-${Date.now()}`,
64
+ recipient: recipient.email,
65
+ };
66
+ });
67
+ }
68
+ sendEmails(recipients, message) {
69
+ return __awaiter(this, void 0, void 0, function* () {
70
+ this.sentMessages.push({
71
+ type: 'email',
72
+ recipient: recipients,
73
+ message,
74
+ timestamp: Date.now(),
75
+ });
76
+ return {
77
+ success: true,
78
+ count: recipients.length,
79
+ messageIds: recipients.map((r, i) => `email-batch-${Date.now()}-${i}`),
80
+ };
81
+ });
82
+ }
83
+ sendTextMessage(recipient, message) {
84
+ return __awaiter(this, void 0, void 0, function* () {
85
+ this.sentMessages.push({
86
+ type: 'text',
87
+ recipient,
88
+ message,
89
+ timestamp: Date.now(),
90
+ });
91
+ return {
92
+ success: true,
93
+ messageId: `text-${Date.now()}`,
94
+ recipient: recipient.email,
95
+ };
96
+ });
97
+ }
98
+ sendTextMessages(recipients, message) {
99
+ return __awaiter(this, void 0, void 0, function* () {
100
+ this.sentMessages.push({
101
+ type: 'text',
102
+ recipient: recipients,
103
+ message,
104
+ timestamp: Date.now(),
105
+ });
106
+ return {
107
+ success: true,
108
+ count: recipients.length,
109
+ messageIds: recipients.map((r, i) => `text-batch-${Date.now()}-${i}`),
110
+ };
111
+ });
112
+ }
113
+ // Helper methods for testing
114
+ getSentMessages(type) {
115
+ if (type) {
116
+ return this.sentMessages.filter((msg) => msg.type === type);
117
+ }
118
+ return this.sentMessages;
119
+ }
120
+ clearMessages() {
121
+ this.sentMessages = [];
122
+ }
123
+ getMessageCount(type) {
124
+ return this.getSentMessages(type).length;
125
+ }
126
+ getLastMessage(type) {
127
+ const messages = this.getSentMessages(type);
128
+ return messages[messages.length - 1];
129
+ }
130
+ }
131
+ exports.MockMessagingAdapter = MockMessagingAdapter;
package/package.json CHANGED
@@ -1,17 +1,20 @@
1
1
  {
2
2
  "name": "@quatrain/messaging",
3
- "version": "1.0.3",
4
- "license": "MIT",
3
+ "version": "1.0.5",
4
+ "license": "AGPL-3.0-only",
5
5
  "description": "Messaging adapters commons",
6
- "main": "lib/index.js",
7
- "types": "lib/index.d.ts",
6
+ "main": "dist/index.js",
7
+ "types": "dist/index.d.ts",
8
+ "bun": "src/index.ts",
8
9
  "files": [
9
- "lib/",
10
+ "LICENSE.md",
11
+ "src/",
12
+ "dist/",
10
13
  "README.md"
11
14
  ],
12
15
  "author": "Quatrain Développement SAS <developers@quatrain.com>",
13
16
  "dependencies": {
14
- "@quatrain/core": "^1.1.19",
17
+ "@quatrain/core": "^1.1.45",
15
18
  "mustache": "^4.2.0"
16
19
  },
17
20
  "devDependencies": {
@@ -19,7 +22,7 @@
19
22
  "@types/jest": "^27.0.3",
20
23
  "@types/mustache": "^4",
21
24
  "@types/node": "^22.10.1",
22
- "jest": "^27.4.7",
25
+ "jest": "^30.2.0",
23
26
  "jest-node-exports-resolver": "^1.1.6",
24
27
  "jest-serial-runner": "^1.2.1",
25
28
  "trace-unhandled": "^2.0.1",
@@ -31,11 +34,6 @@
31
34
  "test-ci": "jest --runInBand",
32
35
  "build": "tsc",
33
36
  "wbuild": "tsc --watch",
34
- "bump-to": "yarn version",
35
- "hash": "node ../../bin/hashFolder.js",
36
- "hash:persist": "yarn hash > .hash_latest.txt",
37
- "hash:compare": "yarn hash > .hash_newest.txt && cmp -s .hash_latest.txt .hash_newest.txt",
38
- "publish": "yarn hash:compare || yarn publish:process",
39
- "publish:process": "yarn version patch && yarn build && yarn npm publish --access public && yarn hash:persist"
37
+ "bump-to": "yarn version"
40
38
  }
41
39
  }
@@ -0,0 +1,9 @@
1
+ import { MessagingParameters } from './Messaging'
2
+
3
+ export abstract class AbstractMessagingAdapter {
4
+ protected _params: MessagingParameters = {}
5
+
6
+ constructor(params: MessagingParameters = {}) {
7
+ this._params = params
8
+ }
9
+ }
@@ -0,0 +1,11 @@
1
+ import Mustache from 'mustache'
2
+
3
+ export class MessageFormatter {
4
+ static formatTitle(title: string) {
5
+ return title.replace(/(<([^>]+)>)/gi, '')
6
+ }
7
+
8
+ static formatBody(body: string, data?: {}) {
9
+ return Mustache.render(body, data)
10
+ }
11
+ }
@@ -0,0 +1,318 @@
1
+ import { Messaging, MessagingParameters } from './Messaging'
2
+ import { MockMessagingAdapter } from './MockMessagingAdapter'
3
+ import { MessagingRecipient } from './types/MessagingRecipient'
4
+ import { NotificationMessage } from './types/NotificationMessage'
5
+
6
+ describe('Messaging', () => {
7
+ let mockAdapter1: MockMessagingAdapter
8
+ let mockAdapter2: MockMessagingAdapter
9
+
10
+ beforeEach(() => {
11
+ // Reset messagers before each test
12
+ ;(Messaging as any)._messagers = {}
13
+ Messaging.defaultMessager = 'default'
14
+
15
+ // Create fresh mock adapters
16
+ mockAdapter1 = new MockMessagingAdapter({ debug: false })
17
+ mockAdapter2 = new MockMessagingAdapter({ debug: false })
18
+ })
19
+
20
+ afterEach(() => {
21
+ // Clean up
22
+ mockAdapter1?.clearMessages()
23
+ mockAdapter2?.clearMessages()
24
+ })
25
+
26
+ describe('addMessager', () => {
27
+ it('should add a messager with an alias', () => {
28
+ Messaging.addMessager(mockAdapter1, 'test-messager')
29
+
30
+ const messager = Messaging.getMessager('test-messager')
31
+ expect(messager).toBe(mockAdapter1)
32
+ })
33
+
34
+ it('should add multiple messagers with different aliases', () => {
35
+ Messaging.addMessager(mockAdapter1, 'messager1')
36
+ Messaging.addMessager(mockAdapter2, 'messager2')
37
+
38
+ const messager1 = Messaging.getMessager('messager1')
39
+ const messager2 = Messaging.getMessager('messager2')
40
+
41
+ expect(messager1).toBe(mockAdapter1)
42
+ expect(messager2).toBe(mockAdapter2)
43
+ })
44
+
45
+ it('should set default messager when setDefault is true', () => {
46
+ Messaging.addMessager(mockAdapter1, 'custom-messager', true)
47
+
48
+ expect(Messaging.defaultMessager).toBe('custom-messager')
49
+ const messager = Messaging.getMessager() // Should use default
50
+ expect(messager).toBe(mockAdapter1)
51
+ })
52
+
53
+ it('should not change default messager when setDefault is false', () => {
54
+ const originalDefault = Messaging.defaultMessager
55
+ Messaging.addMessager(mockAdapter1, 'custom-messager', false)
56
+
57
+ expect(Messaging.defaultMessager).toBe(originalDefault)
58
+ })
59
+
60
+ it('should allow overriding an existing messager', () => {
61
+ Messaging.addMessager(mockAdapter1, 'messager')
62
+ Messaging.addMessager(mockAdapter2, 'messager')
63
+
64
+ const messager = Messaging.getMessager('messager')
65
+ expect(messager).toBe(mockAdapter2)
66
+ })
67
+ })
68
+
69
+ describe('getMessager', () => {
70
+ it('should return the correct messager by alias', () => {
71
+ Messaging.addMessager(mockAdapter1, 'test-messager')
72
+
73
+ const messager = Messaging.getMessager('test-messager')
74
+ expect(messager).toBe(mockAdapter1)
75
+ })
76
+
77
+ it('should return the default messager when no alias is specified', () => {
78
+ Messaging.addMessager(mockAdapter1, 'default', true)
79
+
80
+ const messager = Messaging.getMessager()
81
+ expect(messager).toBe(mockAdapter1)
82
+ })
83
+
84
+ it('should throw error when messager alias does not exist', () => {
85
+ expect(() => {
86
+ Messaging.getMessager('non-existent')
87
+ }).toThrow("Unknown messager alias: 'non-existent'")
88
+ })
89
+
90
+ it('should throw error when getting default messager that does not exist', () => {
91
+ expect(() => {
92
+ Messaging.getMessager()
93
+ }).toThrow("Unknown messager alias: 'default'")
94
+ })
95
+ })
96
+
97
+ describe('defaultMessager property', () => {
98
+ it('should have a default value of "default"', () => {
99
+ expect(Messaging.defaultMessager).toBe('default')
100
+ })
101
+
102
+ it('should allow changing the default messager', () => {
103
+ Messaging.addMessager(mockAdapter1, 'new-default', true)
104
+ expect(Messaging.defaultMessager).toBe('new-default')
105
+ })
106
+ })
107
+
108
+ describe('Integration with MockMessagingAdapter - Notifications', () => {
109
+ const recipient: MessagingRecipient = {
110
+ firstname: 'John',
111
+ lastname: 'Doe',
112
+ email: 'john@example.com',
113
+ messageToken: 'test-token-123',
114
+ }
115
+
116
+ const message: NotificationMessage = {
117
+ title: 'Test Notification',
118
+ body: 'This is a test',
119
+ }
120
+
121
+ it('should send single notification', async () => {
122
+ Messaging.addMessager(mockAdapter1, 'test')
123
+ const messager = Messaging.getMessager('test') as MockMessagingAdapter
124
+
125
+ const result = await messager.sendNotification(recipient, message)
126
+
127
+ expect(result.success).toBe(true)
128
+ expect(result.messageId).toMatch(/^notif-/)
129
+ expect(messager.getMessageCount('notification')).toBe(1)
130
+ })
131
+
132
+ it('should send batch notifications', async () => {
133
+ Messaging.addMessager(mockAdapter1, 'test')
134
+ const messager = Messaging.getMessager('test') as MockMessagingAdapter
135
+
136
+ const recipients = [
137
+ recipient,
138
+ { ...recipient, email: 'jane@example.com' },
139
+ ]
140
+ const result = await messager.sendNotifications(recipients, message)
141
+
142
+ expect(result.success).toBe(true)
143
+ expect(result.count).toBe(2)
144
+ expect(messager.getMessageCount('notification')).toBe(1) // One batch
145
+ })
146
+ })
147
+
148
+ describe('Integration with MockMessagingAdapter - Emails', () => {
149
+ const recipient: MessagingRecipient = {
150
+ firstname: 'John',
151
+ lastname: 'Doe',
152
+ email: 'john@example.com',
153
+ messageToken: 'test-token-123',
154
+ }
155
+
156
+ const message: NotificationMessage = {
157
+ title: 'Test Email',
158
+ body: 'This is a test email',
159
+ }
160
+
161
+ it('should send single email', async () => {
162
+ Messaging.addMessager(mockAdapter1, 'test')
163
+ const messager = Messaging.getMessager('test') as MockMessagingAdapter
164
+
165
+ const result = await messager.sendEmail(recipient, message)
166
+
167
+ expect(result.success).toBe(true)
168
+ expect(result.messageId).toMatch(/^email-/)
169
+ expect(messager.getMessageCount('email')).toBe(1)
170
+ })
171
+
172
+ it('should send batch emails', async () => {
173
+ Messaging.addMessager(mockAdapter1, 'test')
174
+ const messager = Messaging.getMessager('test') as MockMessagingAdapter
175
+
176
+ const recipients = [
177
+ recipient,
178
+ { ...recipient, email: 'jane@example.com' },
179
+ ]
180
+ const result = await messager.sendEmails(recipients, message)
181
+
182
+ expect(result.success).toBe(true)
183
+ expect(result.count).toBe(2)
184
+ expect(messager.getMessageCount('email')).toBe(1) // One batch
185
+ })
186
+ })
187
+
188
+ describe('Integration with MockMessagingAdapter - Text Messages', () => {
189
+ const recipient: MessagingRecipient = {
190
+ firstname: 'John',
191
+ lastname: 'Doe',
192
+ email: 'john@example.com',
193
+ messageToken: 'test-token-123',
194
+ }
195
+
196
+ const message: NotificationMessage = {
197
+ title: 'Test SMS',
198
+ body: 'This is a test SMS',
199
+ }
200
+
201
+ it('should send single text message', async () => {
202
+ Messaging.addMessager(mockAdapter1, 'test')
203
+ const messager = Messaging.getMessager('test') as MockMessagingAdapter
204
+
205
+ const result = await messager.sendTextMessage(recipient, message)
206
+
207
+ expect(result.success).toBe(true)
208
+ expect(result.messageId).toMatch(/^text-/)
209
+ expect(messager.getMessageCount('text')).toBe(1)
210
+ })
211
+
212
+ it('should send batch text messages', async () => {
213
+ Messaging.addMessager(mockAdapter1, 'test')
214
+ const messager = Messaging.getMessager('test') as MockMessagingAdapter
215
+
216
+ const recipients = [
217
+ recipient,
218
+ { ...recipient, email: 'jane@example.com' },
219
+ ]
220
+ const result = await messager.sendTextMessages(recipients, message)
221
+
222
+ expect(result.success).toBe(true)
223
+ expect(result.count).toBe(2)
224
+ expect(messager.getMessageCount('text')).toBe(1) // One batch
225
+ })
226
+ })
227
+
228
+ describe('Integration - Multiple message types', () => {
229
+ it('should maintain separate state between messagers', async () => {
230
+ Messaging.addMessager(mockAdapter1, 'messager1')
231
+ Messaging.addMessager(mockAdapter2, 'messager2')
232
+
233
+ const adapter1 = Messaging.getMessager(
234
+ 'messager1'
235
+ ) as MockMessagingAdapter
236
+ const adapter2 = Messaging.getMessager(
237
+ 'messager2'
238
+ ) as MockMessagingAdapter
239
+
240
+ const recipient: MessagingRecipient = {
241
+ firstname: 'Test',
242
+ lastname: 'User',
243
+ email: 'test@example.com',
244
+ messageToken: 'test-token-123',
245
+ }
246
+
247
+ const message: NotificationMessage = {
248
+ title: 'Test',
249
+ body: 'Test message',
250
+ }
251
+
252
+ await adapter1.sendNotification(recipient, message)
253
+ await adapter2.sendEmail(recipient, message)
254
+
255
+ expect(adapter1.getMessageCount('notification')).toBe(1)
256
+ expect(adapter1.getMessageCount('email')).toBe(0)
257
+
258
+ expect(adapter2.getMessageCount('email')).toBe(1)
259
+ expect(adapter2.getMessageCount('notification')).toBe(0)
260
+ })
261
+
262
+ it('should track different message types', async () => {
263
+ Messaging.addMessager(mockAdapter1, 'test')
264
+ const messager = Messaging.getMessager('test') as MockMessagingAdapter
265
+
266
+ const recipient: MessagingRecipient = {
267
+ firstname: 'Test',
268
+ lastname: 'User',
269
+ email: 'test@example.com',
270
+ messageToken: 'test-token-123',
271
+ }
272
+
273
+ const message: NotificationMessage = {
274
+ title: 'Test',
275
+ body: 'Test message',
276
+ }
277
+
278
+ await messager.sendNotification(recipient, message)
279
+ await messager.sendEmail(recipient, message)
280
+ await messager.sendTextMessage(recipient, message)
281
+
282
+ expect(messager.getMessageCount()).toBe(3)
283
+ expect(messager.getMessageCount('notification')).toBe(1)
284
+ expect(messager.getMessageCount('email')).toBe(1)
285
+ expect(messager.getMessageCount('text')).toBe(1)
286
+ })
287
+ })
288
+
289
+ describe('Messaging registry behavior', () => {
290
+ it('should maintain messagers across multiple operations', () => {
291
+ Messaging.addMessager(mockAdapter1, 'persistent')
292
+
293
+ // Multiple get operations
294
+ const messager1 = Messaging.getMessager('persistent')
295
+ const messager2 = Messaging.getMessager('persistent')
296
+
297
+ expect(messager1).toBe(messager2)
298
+ expect(messager1).toBe(mockAdapter1)
299
+ })
300
+
301
+ it('should handle switching default messager multiple times', () => {
302
+ Messaging.addMessager(mockAdapter1, 'messager1', true)
303
+ expect(Messaging.defaultMessager).toBe('messager1')
304
+
305
+ Messaging.addMessager(mockAdapter2, 'messager2', true)
306
+ expect(Messaging.defaultMessager).toBe('messager2')
307
+
308
+ const defaultMessager = Messaging.getMessager()
309
+ expect(defaultMessager).toBe(mockAdapter2)
310
+ })
311
+ })
312
+
313
+ describe('logger', () => {
314
+ it('should have a logger instance', () => {
315
+ expect(Messaging.logger).toBeDefined()
316
+ })
317
+ })
318
+ })
@@ -0,0 +1,44 @@
1
+ import { Core } from '@quatrain/core'
2
+ import { NotificationCapableAdapter } from './types/NotificationCapableAdapter'
3
+ import { EmailCapableAdapter } from './types/EmailCapableAdapter'
4
+ import { TextCapableAdapter } from './types/TextCapableAdapter'
5
+
6
+ export type MessagingRegistry<T extends NotificationCapableAdapter
7
+ | EmailCapableAdapter
8
+ | TextCapableAdapter> = {
9
+ [x: string]: T
10
+ }
11
+
12
+ export interface MessagingParameters {
13
+ config?: any
14
+ debug?: boolean
15
+ }
16
+
17
+ export class Messaging extends Core {
18
+ static defaultMessager = 'default'
19
+ static logger = this.addLogger('Messaging')
20
+
21
+ protected static _messagers: MessagingRegistry<any> = {}
22
+
23
+ static addMessager(
24
+ messager:
25
+ | NotificationCapableAdapter
26
+ | EmailCapableAdapter
27
+ | TextCapableAdapter,
28
+ alias: string,
29
+ setDefault: boolean = false
30
+ ) {
31
+ this._messagers[alias] = messager
32
+ if (setDefault) {
33
+ this.defaultMessager = alias
34
+ }
35
+ }
36
+
37
+ static getMessager(alias: string = this.defaultMessager) {
38
+ if (this._messagers[alias]) {
39
+ return this._messagers[alias]
40
+ } else {
41
+ throw new Error(`Unknown messager alias: '${alias}'`)
42
+ }
43
+ }
44
+ }
@@ -0,0 +1,163 @@
1
+ import { AbstractMessagingAdapter } from './AbstractMessagingAdapter'
2
+ import { NotificationCapableAdapter } from './types/NotificationCapableAdapter'
3
+ import { EmailCapableAdapter } from './types/EmailCapableAdapter'
4
+ import { TextCapableAdapter } from './types/TextCapableAdapter'
5
+ import { MessagingRecipient } from './types/MessagingRecipient'
6
+ import { NotificationMessage } from './types/NotificationMessage'
7
+ import { MessagingParameters } from './Messaging'
8
+
9
+ interface SentMessage {
10
+ type: 'notification' | 'email' | 'text'
11
+ recipient: MessagingRecipient | MessagingRecipient[]
12
+ message: NotificationMessage
13
+ timestamp: number
14
+ }
15
+
16
+ /**
17
+ * Mock Messaging Adapter for testing purposes
18
+ * Implements all three capability interfaces
19
+ */
20
+ export class MockMessagingAdapter
21
+ extends AbstractMessagingAdapter
22
+ implements
23
+ NotificationCapableAdapter,
24
+ EmailCapableAdapter,
25
+ TextCapableAdapter
26
+ {
27
+ private sentMessages: SentMessage[] = []
28
+
29
+ constructor(params: MessagingParameters = {}) {
30
+ super(params)
31
+ }
32
+
33
+ async sendNotification(
34
+ recipient: MessagingRecipient,
35
+ message: NotificationMessage
36
+ ): Promise<any> {
37
+ this.sentMessages.push({
38
+ type: 'notification',
39
+ recipient,
40
+ message,
41
+ timestamp: Date.now(),
42
+ })
43
+
44
+ return {
45
+ success: true,
46
+ messageId: `notif-${Date.now()}`,
47
+ recipient: recipient.email,
48
+ }
49
+ }
50
+
51
+ async sendNotifications(
52
+ recipients: MessagingRecipient[],
53
+ message: NotificationMessage
54
+ ): Promise<any> {
55
+ this.sentMessages.push({
56
+ type: 'notification',
57
+ recipient: recipients,
58
+ message,
59
+ timestamp: Date.now(),
60
+ })
61
+
62
+ return {
63
+ success: true,
64
+ count: recipients.length,
65
+ messageIds: recipients.map((r, i) => `notif-batch-${Date.now()}-${i}`),
66
+ }
67
+ }
68
+
69
+ async sendEmail(
70
+ recipient: MessagingRecipient,
71
+ message: NotificationMessage
72
+ ): Promise<any> {
73
+ this.sentMessages.push({
74
+ type: 'email',
75
+ recipient,
76
+ message,
77
+ timestamp: Date.now(),
78
+ })
79
+
80
+ return {
81
+ success: true,
82
+ messageId: `email-${Date.now()}`,
83
+ recipient: recipient.email,
84
+ }
85
+ }
86
+
87
+ async sendEmails(
88
+ recipients: MessagingRecipient[],
89
+ message: NotificationMessage
90
+ ): Promise<any> {
91
+ this.sentMessages.push({
92
+ type: 'email',
93
+ recipient: recipients,
94
+ message,
95
+ timestamp: Date.now(),
96
+ })
97
+
98
+ return {
99
+ success: true,
100
+ count: recipients.length,
101
+ messageIds: recipients.map((r, i) => `email-batch-${Date.now()}-${i}`),
102
+ }
103
+ }
104
+
105
+ async sendTextMessage(
106
+ recipient: MessagingRecipient,
107
+ message: NotificationMessage
108
+ ): Promise<any> {
109
+ this.sentMessages.push({
110
+ type: 'text',
111
+ recipient,
112
+ message,
113
+ timestamp: Date.now(),
114
+ })
115
+
116
+ return {
117
+ success: true,
118
+ messageId: `text-${Date.now()}`,
119
+ recipient: recipient.email,
120
+ }
121
+ }
122
+
123
+ async sendTextMessages(
124
+ recipients: MessagingRecipient[],
125
+ message: NotificationMessage
126
+ ): Promise<any> {
127
+ this.sentMessages.push({
128
+ type: 'text',
129
+ recipient: recipients,
130
+ message,
131
+ timestamp: Date.now(),
132
+ })
133
+
134
+ return {
135
+ success: true,
136
+ count: recipients.length,
137
+ messageIds: recipients.map((r, i) => `text-batch-${Date.now()}-${i}`),
138
+ }
139
+ }
140
+
141
+ // Helper methods for testing
142
+ getSentMessages(type?: 'notification' | 'email' | 'text'): SentMessage[] {
143
+ if (type) {
144
+ return this.sentMessages.filter((msg) => msg.type === type)
145
+ }
146
+ return this.sentMessages
147
+ }
148
+
149
+ clearMessages(): void {
150
+ this.sentMessages = []
151
+ }
152
+
153
+ getMessageCount(type?: 'notification' | 'email' | 'text'): number {
154
+ return this.getSentMessages(type).length
155
+ }
156
+
157
+ getLastMessage(
158
+ type?: 'notification' | 'email' | 'text'
159
+ ): SentMessage | undefined {
160
+ const messages = this.getSentMessages(type)
161
+ return messages[messages.length - 1]
162
+ }
163
+ }
package/src/index.ts ADDED
@@ -0,0 +1,20 @@
1
+ import { Messaging, MessagingParameters } from './Messaging'
2
+ import { AbstractMessagingAdapter } from './AbstractMessagingAdapter'
3
+ import { MessagingRecipient } from './types/MessagingRecipient'
4
+ import { NotificationMessage } from './types/NotificationMessage'
5
+ import { MessageType } from './types/MessageType'
6
+ import { EmailCapableAdapter } from './types/EmailCapableAdapter'
7
+ import { NotificationCapableAdapter } from './types/NotificationCapableAdapter'
8
+ import { MessageFormatter } from './MessageFormatter'
9
+
10
+ export {
11
+ Messaging,
12
+ MessagingParameters,
13
+ AbstractMessagingAdapter,
14
+ MessagingRecipient,
15
+ NotificationMessage,
16
+ MessageType,
17
+ EmailCapableAdapter,
18
+ NotificationCapableAdapter,
19
+ MessageFormatter,
20
+ }
@@ -0,0 +1,14 @@
1
+ import { MessagingRecipient } from './MessagingRecipient'
2
+ import { NotificationMessage } from './NotificationMessage'
3
+
4
+ export interface EmailCapableAdapter {
5
+ sendEmail(
6
+ recipient: MessagingRecipient,
7
+ message: NotificationMessage
8
+ ): Promise<any>
9
+
10
+ sendEmails(
11
+ recipients: MessagingRecipient[],
12
+ message: NotificationMessage
13
+ ): Promise<any>
14
+ }
@@ -0,0 +1,6 @@
1
+ export interface MessageType {
2
+ token?: string
3
+ title: string
4
+ body: string
5
+ data?: any
6
+ }
@@ -0,0 +1,6 @@
1
+ import { UserType } from '@quatrain/core'
2
+
3
+ export type MessagingRecipient = Pick<
4
+ UserType,
5
+ 'firstname' | 'lastname' | 'email' | 'messageToken'
6
+ > & { data?: { [x: string]: any } }
@@ -0,0 +1,3 @@
1
+ export type MessagingTemplate = {
2
+
3
+ }
@@ -0,0 +1,14 @@
1
+ import { MessagingRecipient } from './MessagingRecipient'
2
+ import { NotificationMessage } from './NotificationMessage'
3
+
4
+ export interface NotificationCapableAdapter {
5
+ sendNotification(
6
+ recipient: MessagingRecipient,
7
+ message: NotificationMessage
8
+ ): Promise<any>
9
+
10
+ sendNotifications(
11
+ recipients: MessagingRecipient[],
12
+ message: NotificationMessage
13
+ ): Promise<any>
14
+ }
@@ -0,0 +1,3 @@
1
+ import { MessageType } from './MessageType'
2
+
3
+ export interface NotificationMessage extends MessageType {}
@@ -0,0 +1,14 @@
1
+ import { MessagingRecipient } from './MessagingRecipient'
2
+ import { NotificationMessage } from './NotificationMessage'
3
+
4
+ export interface TextCapableAdapter {
5
+ sendTextMessage(
6
+ recipient: MessagingRecipient,
7
+ message: NotificationMessage
8
+ ): Promise<any>
9
+
10
+ sendTextMessages(
11
+ recipients: MessagingRecipient[],
12
+ message: NotificationMessage
13
+ ): Promise<any>
14
+ }
@@ -1,6 +0,0 @@
1
- export interface AbstractMessage {
2
- token?: string;
3
- title: string;
4
- body: string;
5
- data?: any;
6
- }
@@ -1,2 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
@@ -1,6 +0,0 @@
1
- import { MessagingRecipient } from './MessagingRecipient';
2
- import { NotificationMessage } from './NotificationMessage';
3
- export interface EmailCapableAdapter {
4
- sendEmail(recipient: MessagingRecipient, message: NotificationMessage): Promise<any>;
5
- sendEmails(recipients: MessagingRecipient[], message: NotificationMessage): Promise<any>;
6
- }
@@ -1,2 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
@@ -1,6 +0,0 @@
1
- import { AbstractMessage } from './AbstractMessage';
2
- import { MessagingRecipient } from './MessagingRecipient';
3
- export interface MessagingInterface {
4
- sendNotification(recipient: MessagingRecipient, message: AbstractMessage): Promise<any>;
5
- sendNotifications(recipients: MessagingRecipient[], message: AbstractMessage): Promise<any>;
6
- }
@@ -1,2 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes