@quatrain/messaging 1.0.2 → 1.0.4

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 (34) hide show
  1. package/LICENSE.md +15 -0
  2. package/lib/AbstractMessagingAdapter.d.ts +0 -3
  3. package/lib/AbstractMessagingAdapter.js +0 -7
  4. package/lib/MessageFormatter.d.ts +1 -3
  5. package/lib/MessageFormatter.js +2 -2
  6. package/lib/Messaging.d.ts +8 -8
  7. package/lib/Messaging.js +9 -9
  8. package/lib/Messaging.test.d.ts +1 -0
  9. package/lib/Messaging.test.js +258 -0
  10. package/lib/MockMessagingAdapter.d.ts +32 -0
  11. package/lib/MockMessagingAdapter.js +131 -0
  12. package/lib/index.d.ts +3 -2
  13. package/lib/index.js +3 -1
  14. package/lib/types/{AbstractMessage.d.ts → MessageType.d.ts} +1 -1
  15. package/lib/types/NotificationCapableAdapter.d.ts +1 -2
  16. package/lib/types/NotificationMessage.d.ts +2 -2
  17. package/lib/types/TextCapableAdapter.d.ts +6 -0
  18. package/package.json +38 -40
  19. package/src/AbstractMessagingAdapter.ts +9 -0
  20. package/src/MessageFormatter.ts +11 -0
  21. package/src/Messaging.test.ts +318 -0
  22. package/src/Messaging.ts +44 -0
  23. package/src/MockMessagingAdapter.ts +163 -0
  24. package/src/index.ts +20 -0
  25. package/src/types/EmailCapableAdapter.ts +14 -0
  26. package/src/types/MessageType.ts +6 -0
  27. package/src/types/MessagingRecipient.ts +6 -0
  28. package/src/types/MessagingTemplate.ts +3 -0
  29. package/src/types/NotificationCapableAdapter.ts +14 -0
  30. package/src/types/NotificationMessage.ts +3 -0
  31. package/src/types/TextCapableAdapter.ts +14 -0
  32. package/lib/types/MessagingInterface.d.ts +0 -6
  33. /package/lib/types/{AbstractMessage.js → MessageType.js} +0 -0
  34. /package/lib/types/{MessagingInterface.js → TextCapableAdapter.js} +0 -0
package/package.json CHANGED
@@ -1,41 +1,39 @@
1
1
  {
2
- "name": "@quatrain/messaging",
3
- "version": "1.0.2",
4
- "license": "MIT",
5
- "description": "Messaging adapters commons",
6
- "main": "lib/index.js",
7
- "types": "lib/index.d.ts",
8
- "files": [
9
- "lib/",
10
- "README.md"
11
- ],
12
- "author": "Quatrain Développement SAS <developers@quatrain.com>",
13
- "dependencies": {
14
- "@quatrain/core": "^1.1.19",
15
- "mustache": "^4.2.0"
16
- },
17
- "devDependencies": {
18
- "@tsconfig/recommended": "^1.0.1",
19
- "@types/jest": "^27.0.3",
20
- "@types/mustache": "^4",
21
- "@types/node": "^22.10.1",
22
- "jest": "^27.4.7",
23
- "jest-node-exports-resolver": "^1.1.6",
24
- "jest-serial-runner": "^1.2.1",
25
- "trace-unhandled": "^2.0.1",
26
- "ts-jest": "^27.1.2",
27
- "ts-node": "^10.9.1",
28
- "typescript": "^5.1.5"
29
- },
30
- "scripts": {
31
- "test-ci": "jest --runInBand",
32
- "build": "tsc",
33
- "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"
40
- }
41
- }
2
+ "name": "@quatrain/messaging",
3
+ "version": "1.0.4",
4
+ "license": "AGPL-3.0-only",
5
+ "description": "Messaging adapters commons",
6
+ "main": "lib/index.js",
7
+ "types": "lib/index.d.ts",
8
+ "bun": "src/index.ts",
9
+ "files": [
10
+ "LICENSE.md",
11
+ "src/",
12
+ "lib/",
13
+ "README.md"
14
+ ],
15
+ "author": "Quatrain Développement SAS <developers@quatrain.com>",
16
+ "dependencies": {
17
+ "@quatrain/core": "^1.1.43",
18
+ "mustache": "^4.2.0"
19
+ },
20
+ "devDependencies": {
21
+ "@tsconfig/recommended": "^1.0.1",
22
+ "@types/jest": "^27.0.3",
23
+ "@types/mustache": "^4",
24
+ "@types/node": "^22.10.1",
25
+ "jest": "^30.2.0",
26
+ "jest-node-exports-resolver": "^1.1.6",
27
+ "jest-serial-runner": "^1.2.1",
28
+ "trace-unhandled": "^2.0.1",
29
+ "ts-jest": "^27.1.2",
30
+ "ts-node": "^10.9.1",
31
+ "typescript": "^5.1.5"
32
+ },
33
+ "scripts": {
34
+ "test-ci": "jest --runInBand",
35
+ "build": "tsc",
36
+ "wbuild": "tsc --watch",
37
+ "bump-to": "yarn version"
38
+ }
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
+ }