nesthub 1.0.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.
Files changed (143) hide show
  1. package/README.md +108 -0
  2. package/dist/cache/README.md +91 -0
  3. package/dist/cache/index.d.ts +10 -0
  4. package/dist/cache/index.js +75 -0
  5. package/dist/cache/index.js.map +1 -0
  6. package/dist/cache/index.spec.d.ts +1 -0
  7. package/dist/cache/index.spec.js +61 -0
  8. package/dist/cache/index.spec.js.map +1 -0
  9. package/dist/excel/README.md +132 -0
  10. package/dist/excel/excel.module.d.ts +2 -0
  11. package/dist/excel/excel.module.js +21 -0
  12. package/dist/excel/excel.module.js.map +1 -0
  13. package/dist/excel/excel.service.d.ts +23 -0
  14. package/dist/excel/excel.service.js +124 -0
  15. package/dist/excel/excel.service.js.map +1 -0
  16. package/dist/excel/index.d.ts +2 -0
  17. package/dist/excel/index.js +8 -0
  18. package/dist/excel/index.js.map +1 -0
  19. package/dist/excel/interfaces.d.ts +19 -0
  20. package/dist/excel/interfaces.js +3 -0
  21. package/dist/excel/interfaces.js.map +1 -0
  22. package/dist/index.d.ts +1 -0
  23. package/dist/index.js +5 -0
  24. package/dist/index.js.map +1 -0
  25. package/dist/index.spec.d.ts +1 -0
  26. package/dist/index.spec.js +11 -0
  27. package/dist/index.spec.js.map +1 -0
  28. package/dist/notification/README.md +237 -0
  29. package/dist/notification/channels/channel.interface.d.ts +10 -0
  30. package/dist/notification/channels/channel.interface.js +3 -0
  31. package/dist/notification/channels/channel.interface.js.map +1 -0
  32. package/dist/notification/channels/email.channel.d.ts +11 -0
  33. package/dist/notification/channels/email.channel.js +58 -0
  34. package/dist/notification/channels/email.channel.js.map +1 -0
  35. package/dist/notification/channels/firebase.channel.d.ts +11 -0
  36. package/dist/notification/channels/firebase.channel.js +69 -0
  37. package/dist/notification/channels/firebase.channel.js.map +1 -0
  38. package/dist/notification/channels/index.d.ts +5 -0
  39. package/dist/notification/channels/index.js +12 -0
  40. package/dist/notification/channels/index.js.map +1 -0
  41. package/dist/notification/channels/sms.channel.d.ts +8 -0
  42. package/dist/notification/channels/sms.channel.js +90 -0
  43. package/dist/notification/channels/sms.channel.js.map +1 -0
  44. package/dist/notification/channels/telegram.channel.d.ts +10 -0
  45. package/dist/notification/channels/telegram.channel.js +59 -0
  46. package/dist/notification/channels/telegram.channel.js.map +1 -0
  47. package/dist/notification/email/index.d.ts +62 -0
  48. package/dist/notification/email/index.js +253 -0
  49. package/dist/notification/email/index.js.map +1 -0
  50. package/dist/notification/email/index.spec.d.ts +1 -0
  51. package/dist/notification/email/index.spec.js +121 -0
  52. package/dist/notification/email/index.spec.js.map +1 -0
  53. package/dist/notification/entities/notification-log.entity.d.ts +15 -0
  54. package/dist/notification/entities/notification-log.entity.js +82 -0
  55. package/dist/notification/entities/notification-log.entity.js.map +1 -0
  56. package/dist/notification/firebase/index.d.ts +52 -0
  57. package/dist/notification/firebase/index.js +261 -0
  58. package/dist/notification/firebase/index.js.map +1 -0
  59. package/dist/notification/firebase/index.spec.d.ts +1 -0
  60. package/dist/notification/firebase/index.spec.js +114 -0
  61. package/dist/notification/firebase/index.spec.js.map +1 -0
  62. package/dist/notification/index.d.ts +12 -0
  63. package/dist/notification/index.js +26 -0
  64. package/dist/notification/index.js.map +1 -0
  65. package/dist/notification/index.spec.d.ts +1 -0
  66. package/dist/notification/index.spec.js +336 -0
  67. package/dist/notification/index.spec.js.map +1 -0
  68. package/dist/notification/interfaces.d.ts +98 -0
  69. package/dist/notification/interfaces.js +3 -0
  70. package/dist/notification/interfaces.js.map +1 -0
  71. package/dist/notification/notification.constants.d.ts +4 -0
  72. package/dist/notification/notification.constants.js +8 -0
  73. package/dist/notification/notification.constants.js.map +1 -0
  74. package/dist/notification/notification.module.d.ts +10 -0
  75. package/dist/notification/notification.module.js +160 -0
  76. package/dist/notification/notification.module.js.map +1 -0
  77. package/dist/notification/notification.service.d.ts +14 -0
  78. package/dist/notification/notification.service.js +184 -0
  79. package/dist/notification/notification.service.js.map +1 -0
  80. package/dist/notification/queue/index.d.ts +2 -0
  81. package/dist/notification/queue/index.js +6 -0
  82. package/dist/notification/queue/index.js.map +1 -0
  83. package/dist/notification/queue/notification-queue.service.d.ts +31 -0
  84. package/dist/notification/queue/notification-queue.service.js +134 -0
  85. package/dist/notification/queue/notification-queue.service.js.map +1 -0
  86. package/dist/notification/services/index.d.ts +1 -0
  87. package/dist/notification/services/index.js +6 -0
  88. package/dist/notification/services/index.js.map +1 -0
  89. package/dist/notification/services/template.service.d.ts +13 -0
  90. package/dist/notification/services/template.service.js +75 -0
  91. package/dist/notification/services/template.service.js.map +1 -0
  92. package/dist/notification/shared.d.ts +48 -0
  93. package/dist/notification/shared.js +95 -0
  94. package/dist/notification/shared.js.map +1 -0
  95. package/dist/notification/sms/index.d.ts +52 -0
  96. package/dist/notification/sms/index.js +234 -0
  97. package/dist/notification/sms/index.js.map +1 -0
  98. package/dist/notification/sms/index.spec.d.ts +1 -0
  99. package/dist/notification/sms/index.spec.js +123 -0
  100. package/dist/notification/sms/index.spec.js.map +1 -0
  101. package/dist/notification/telegram/index.d.ts +50 -0
  102. package/dist/notification/telegram/index.js +248 -0
  103. package/dist/notification/telegram/index.js.map +1 -0
  104. package/dist/notification/telegram/index.spec.d.ts +1 -0
  105. package/dist/notification/telegram/index.spec.js +108 -0
  106. package/dist/notification/telegram/index.spec.js.map +1 -0
  107. package/dist/notification/typeorm-storage.d.ts +28 -0
  108. package/dist/notification/typeorm-storage.js +56 -0
  109. package/dist/notification/typeorm-storage.js.map +1 -0
  110. package/dist/notification/unified.d.ts +47 -0
  111. package/dist/notification/unified.js +207 -0
  112. package/dist/notification/unified.js.map +1 -0
  113. package/dist/queue/README.md +82 -0
  114. package/dist/queue/index.d.ts +14 -0
  115. package/dist/queue/index.js +17 -0
  116. package/dist/queue/index.js.map +1 -0
  117. package/dist/queue/index.spec.d.ts +1 -0
  118. package/dist/queue/index.spec.js +76 -0
  119. package/dist/queue/index.spec.js.map +1 -0
  120. package/dist/tsconfig.build.tsbuildinfo +1 -0
  121. package/dist/tsconfig.tsbuildinfo +1 -0
  122. package/dist/typeorm/README.md +197 -0
  123. package/dist/typeorm/crud-controller.d.ts +4 -0
  124. package/dist/typeorm/crud-controller.js +81 -0
  125. package/dist/typeorm/crud-controller.js.map +1 -0
  126. package/dist/typeorm/crud-service.d.ts +6 -0
  127. package/dist/typeorm/crud-service.js +53 -0
  128. package/dist/typeorm/crud-service.js.map +1 -0
  129. package/dist/typeorm/crud.interface.d.ts +9 -0
  130. package/dist/typeorm/crud.interface.js +3 -0
  131. package/dist/typeorm/crud.interface.js.map +1 -0
  132. package/dist/typeorm/index.d.ts +23 -0
  133. package/dist/typeorm/index.js +66 -0
  134. package/dist/typeorm/index.js.map +1 -0
  135. package/dist/typeorm/index.spec.d.ts +1 -0
  136. package/dist/typeorm/index.spec.js +109 -0
  137. package/dist/typeorm/index.spec.js.map +1 -0
  138. package/package.json +229 -0
  139. package/src/cache/README.md +91 -0
  140. package/src/excel/README.md +132 -0
  141. package/src/notification/README.md +237 -0
  142. package/src/queue/README.md +82 -0
  143. package/src/typeorm/README.md +197 -0
@@ -0,0 +1,336 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ let nextJobId = 1;
4
+ jest.mock('bullmq', () => ({
5
+ Queue: jest.fn().mockImplementation(() => ({
6
+ add: jest
7
+ .fn()
8
+ .mockImplementation(() => Promise.resolve({ id: `bull-mock-job-${nextJobId++}` })),
9
+ remove: jest.fn().mockResolvedValue(undefined),
10
+ close: jest.fn().mockResolvedValue(undefined),
11
+ })),
12
+ Worker: jest.fn().mockImplementation(() => ({
13
+ close: jest.fn().mockResolvedValue(undefined),
14
+ })),
15
+ }));
16
+ const testing_1 = require("@nestjs/testing");
17
+ const index_1 = require("./index");
18
+ class InMemoryStorage {
19
+ records = new Map();
20
+ byDedup = new Map();
21
+ save(record) {
22
+ this.records.set(record.id, record);
23
+ if (record.dedupId)
24
+ this.byDedup.set(record.dedupId, record.id);
25
+ return Promise.resolve();
26
+ }
27
+ update(recordId, updates) {
28
+ const existing = this.records.get(recordId);
29
+ if (existing) {
30
+ this.records.set(recordId, { ...existing, ...updates });
31
+ }
32
+ return Promise.resolve();
33
+ }
34
+ findByDedupId(dedupId) {
35
+ const id = this.byDedup.get(dedupId);
36
+ if (!id)
37
+ return Promise.resolve(null);
38
+ return Promise.resolve(this.records.get(id) ?? null);
39
+ }
40
+ get(recordId) {
41
+ return this.records.get(recordId);
42
+ }
43
+ }
44
+ describe('@vn.chemgio/nestjs-utilities/notification', () => {
45
+ describe('NotificationModule.forRoot', () => {
46
+ it('should return a DynamicModule with provider and export', () => {
47
+ const mod = index_1.NotificationModule.forRoot({
48
+ sendgrid: { apiKey: 'test-key' },
49
+ });
50
+ expect(mod.module).toBe(index_1.NotificationModule);
51
+ expect(mod.providers).toHaveLength(1);
52
+ expect(mod.exports).toContain(index_1.NOTIFICATION_SERVICE);
53
+ });
54
+ it('should default to empty options', () => {
55
+ const mod = index_1.NotificationModule.forRoot();
56
+ expect(mod.module).toBe(index_1.NotificationModule);
57
+ });
58
+ });
59
+ describe('NotificationService (unified)', () => {
60
+ let service;
61
+ let storage;
62
+ let module;
63
+ afterEach(async () => {
64
+ if (module)
65
+ await module.close();
66
+ });
67
+ async function createModule(options) {
68
+ storage = new InMemoryStorage();
69
+ const opts = {
70
+ ...options,
71
+ storage: { provider: options.storage?.provider ?? storage },
72
+ };
73
+ module = await testing_1.Test.createTestingModule({
74
+ imports: [index_1.NotificationModule.forRoot(opts)],
75
+ }).compile();
76
+ await module.init();
77
+ return module.get(index_1.NOTIFICATION_SERVICE);
78
+ }
79
+ describe('sendEmail', () => {
80
+ it('should return success with mock messageId when no sendgrid', async () => {
81
+ service = await createModule({
82
+ defaultFrom: 'test@example.com',
83
+ sendgrid: {},
84
+ });
85
+ const result = await service.sendEmail({
86
+ to: 'user@example.com',
87
+ subject: 'Test',
88
+ html: '<p>Hello</p>',
89
+ });
90
+ expect(result.success).toBe(true);
91
+ expect(result.messageId).toMatch(/^mock-/);
92
+ });
93
+ it('should return error when no content provided', async () => {
94
+ service = await createModule({ sendgrid: {} });
95
+ const result = await service.sendEmail({ to: 'user@example.com' });
96
+ expect(result.success).toBe(false);
97
+ expect(result.error).toBe('No content to send');
98
+ });
99
+ it('should render subject from template in options', async () => {
100
+ service = await createModule({
101
+ defaultFrom: 'test@example.com',
102
+ sendgrid: {},
103
+ templates: {
104
+ templates: {
105
+ welcome: {
106
+ subject: 'Hello {{name}}!',
107
+ html: '<p>Welcome {{name}}</p>',
108
+ },
109
+ },
110
+ },
111
+ });
112
+ const result = await service.sendEmail({
113
+ to: 'user@example.com',
114
+ template: 'welcome',
115
+ context: { name: 'Alice' },
116
+ });
117
+ expect(result.success).toBe(true);
118
+ });
119
+ describe('with locale-based templates', () => {
120
+ it('should resolve locale-specific template', async () => {
121
+ service = await createModule({
122
+ defaultFrom: 'test@example.com',
123
+ sendgrid: {},
124
+ templates: {
125
+ templates: {
126
+ 'greeting.en': {
127
+ subject: 'Hello {{name}}!',
128
+ html: '<p>Hello {{name}}</p>',
129
+ },
130
+ 'greeting.vi': {
131
+ subject: 'Xin chào {{name}}!',
132
+ html: '<p>Xin chào {{name}}</p>',
133
+ },
134
+ },
135
+ },
136
+ });
137
+ const resultEn = await service.sendEmail({
138
+ to: 'user@example.com',
139
+ template: 'greeting',
140
+ context: { name: 'Alice' },
141
+ locale: 'en',
142
+ });
143
+ expect(resultEn.success).toBe(true);
144
+ const resultVi = await service.sendEmail({
145
+ to: 'user@example.com',
146
+ template: 'greeting',
147
+ context: { name: 'Alice' },
148
+ locale: 'vi',
149
+ });
150
+ expect(resultVi.success).toBe(true);
151
+ });
152
+ });
153
+ describe('with attachments', () => {
154
+ it('should pass attachments to send', async () => {
155
+ service = await createModule({
156
+ defaultFrom: 'test@example.com',
157
+ sendgrid: {},
158
+ });
159
+ const result = await service.sendEmail({
160
+ to: 'user@example.com',
161
+ subject: 'With attachment',
162
+ html: '<p>See attached</p>',
163
+ attachments: [
164
+ {
165
+ content: Buffer.from('test').toString('base64'),
166
+ filename: 'test.txt',
167
+ },
168
+ ],
169
+ });
170
+ expect(result.success).toBe(true);
171
+ });
172
+ });
173
+ describe('expiry and cancel', () => {
174
+ it('should cancel a pending job by dedupId', async () => {
175
+ service = await createModule({
176
+ defaultFrom: 'test@example.com',
177
+ sendgrid: {},
178
+ queue: {
179
+ useQueue: true,
180
+ connection: { url: 'redis://localhost:6379' },
181
+ worker: false,
182
+ },
183
+ });
184
+ const sendResult = await service.sendEmail({
185
+ to: 'user@example.com',
186
+ subject: 'OTP',
187
+ html: '<p>Your OTP is 1234</p>',
188
+ mode: 'queue',
189
+ dedupId: 'otp-user-123',
190
+ });
191
+ expect(sendResult.success).toBe(true);
192
+ expect(sendResult.jobId).toMatch(/^bull-mock-job-/);
193
+ await service.cancelJob('otp-user-123');
194
+ const record = storage.get(sendResult.jobId);
195
+ expect(record?.status).toBe('cancelled');
196
+ });
197
+ it('should leave unrelated jobs untouched when cancelling', async () => {
198
+ service = await createModule({
199
+ defaultFrom: 'test@example.com',
200
+ sendgrid: {},
201
+ queue: {
202
+ useQueue: true,
203
+ connection: { url: 'redis://localhost:6379' },
204
+ worker: false,
205
+ },
206
+ });
207
+ const result1 = await service.sendEmail({
208
+ to: 'user@example.com',
209
+ subject: 'Keep me',
210
+ html: '<p>Keep</p>',
211
+ mode: 'queue',
212
+ dedupId: 'keep-me',
213
+ });
214
+ await service.sendEmail({
215
+ to: 'user@example.com',
216
+ subject: 'Cancel me',
217
+ html: '<p>Cancel</p>',
218
+ mode: 'queue',
219
+ dedupId: 'cancel-me',
220
+ });
221
+ await service.cancelJob('cancel-me');
222
+ const r1 = storage.get(result1.jobId);
223
+ expect(r1?.status).toBe('pending');
224
+ });
225
+ });
226
+ describe('queue mode', () => {
227
+ it('should enqueue and save pending record when queue mode', async () => {
228
+ service = await createModule({
229
+ defaultFrom: 'test@example.com',
230
+ sendgrid: {},
231
+ queue: {
232
+ useQueue: true,
233
+ connection: { url: 'redis://localhost:6379' },
234
+ worker: false,
235
+ },
236
+ });
237
+ const result = await service.sendEmail({
238
+ to: 'user@example.com',
239
+ subject: 'Queued',
240
+ html: '<p>Queued message</p>',
241
+ mode: 'queue',
242
+ });
243
+ expect(result.success).toBe(true);
244
+ expect(result.jobId).toMatch(/^bull-mock-job-/);
245
+ const record = storage.get(result.jobId);
246
+ expect(record).toBeDefined();
247
+ expect(record?.status).toBe('pending');
248
+ expect(record?.subject).toBe('Queued');
249
+ });
250
+ it('should include dedupId in record when provided', async () => {
251
+ service = await createModule({
252
+ defaultFrom: 'test@example.com',
253
+ sendgrid: {},
254
+ queue: {
255
+ useQueue: true,
256
+ connection: { url: 'redis://localhost:6379' },
257
+ worker: false,
258
+ },
259
+ });
260
+ const result = await service.sendEmail({
261
+ to: 'user@example.com',
262
+ subject: 'Dedup test',
263
+ html: '<p>Dedup</p>',
264
+ mode: 'queue',
265
+ dedupId: 'dedup-test-456',
266
+ });
267
+ const record = storage.get(result.jobId);
268
+ expect(record?.dedupId).toBe('dedup-test-456');
269
+ expect(record?.status).toBe('pending');
270
+ });
271
+ });
272
+ });
273
+ describe('sendSms', () => {
274
+ it('should return not-configured error without twilio config', async () => {
275
+ service = await createModule({});
276
+ const result = await service.sendSms({
277
+ to: '+84123456789',
278
+ body: 'Test',
279
+ });
280
+ expect(result.success).toBe(false);
281
+ expect(result.error).toMatch(/not configured/i);
282
+ });
283
+ it('should send via console fallback with valid config', async () => {
284
+ service = await createModule({
285
+ twilio: { accountSid: 'sid', authToken: 'token' },
286
+ });
287
+ const result = await service.sendSms({
288
+ to: '+84123456789',
289
+ body: 'Hello from SMS',
290
+ });
291
+ expect(result.success).toBe(true);
292
+ expect(result.messageId).toMatch(/^mock-/);
293
+ });
294
+ });
295
+ describe('sendPush', () => {
296
+ it('should return not-configured error without firebase config', async () => {
297
+ service = await createModule({});
298
+ const result = await service.sendPush({
299
+ token: 'device-token',
300
+ title: 'Hi',
301
+ body: 'Test',
302
+ });
303
+ expect(result.success).toBe(false);
304
+ expect(result.error).toMatch(/not configured/i);
305
+ });
306
+ it('should send via console fallback with valid config', async () => {
307
+ service = await createModule({ firebase: {} });
308
+ const result = await service.sendPush({
309
+ token: 'device-token',
310
+ title: 'Hi',
311
+ body: 'Test',
312
+ });
313
+ expect(result.success).toBe(true);
314
+ expect(result.messageId).toMatch(/^mock-/);
315
+ });
316
+ });
317
+ describe('sendTelegram', () => {
318
+ it('should return not-configured error without botToken', async () => {
319
+ service = await createModule({});
320
+ const result = await service.sendTelegram({
321
+ chatId: 12345,
322
+ text: 'Hi',
323
+ });
324
+ expect(result.success).toBe(false);
325
+ expect(result.error).toMatch(/not configured/i);
326
+ });
327
+ it('should return no-content error when no text or template', async () => {
328
+ service = await createModule({ botToken: 'test-token' });
329
+ const result = await service.sendTelegram({ chatId: 12345 });
330
+ expect(result.success).toBe(false);
331
+ expect(result.error).toBe('No content to send');
332
+ });
333
+ });
334
+ });
335
+ });
336
+ //# sourceMappingURL=index.spec.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.spec.js","sourceRoot":"","sources":["../../src/notification/index.spec.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,98 @@
1
+ export type ChannelType = 'email' | 'sms' | 'firebase' | 'telegram';
2
+ export type NotificationStatus = 'pending' | 'sending' | 'sent' | 'failed' | 'expired';
3
+ export interface Attachment {
4
+ filename: string;
5
+ content?: Buffer | string;
6
+ path?: string;
7
+ contentType?: string;
8
+ }
9
+ export interface SendNotificationInput {
10
+ channel: ChannelType;
11
+ to: string | string[];
12
+ subject?: string;
13
+ template?: string;
14
+ context?: Record<string, unknown>;
15
+ content?: string;
16
+ sender?: string;
17
+ attachments?: Attachment[];
18
+ expiresAt?: Date | string;
19
+ priority?: 'low' | 'normal' | 'high';
20
+ metadata?: Record<string, unknown>;
21
+ }
22
+ export interface SendResult {
23
+ id: string;
24
+ channel: ChannelType;
25
+ to: string | string[];
26
+ success: boolean;
27
+ messageId?: string;
28
+ error?: string;
29
+ sentAt: Date;
30
+ }
31
+ export interface SmtpConfig {
32
+ host: string;
33
+ port: number;
34
+ secure?: boolean;
35
+ user?: string;
36
+ pass?: string;
37
+ }
38
+ export interface EmailChannelConfig {
39
+ smtp?: SmtpConfig;
40
+ transport?: string | Record<string, unknown>;
41
+ defaults?: {
42
+ from?: string;
43
+ replyTo?: string;
44
+ };
45
+ }
46
+ export interface SmsChannelConfig {
47
+ provider: 'twilio' | 'aws-sns' | 'http';
48
+ credentials: Record<string, string>;
49
+ from?: string;
50
+ }
51
+ export interface FirebaseChannelConfig {
52
+ serviceAccountPath?: string;
53
+ serviceAccount?: Record<string, unknown>;
54
+ databaseURL?: string;
55
+ }
56
+ export interface TelegramChannelConfig {
57
+ botToken: string;
58
+ apiBaseUrl?: string;
59
+ }
60
+ export interface StorageConfig {
61
+ enabled: boolean;
62
+ }
63
+ export interface NotificationLogRecord {
64
+ id: string;
65
+ channel: ChannelType;
66
+ to: string | string[];
67
+ subject?: string;
68
+ status: NotificationStatus;
69
+ content?: string;
70
+ messageId?: string;
71
+ error?: string;
72
+ metadata?: Record<string, unknown>;
73
+ createdAt: Date;
74
+ updatedAt: Date;
75
+ sentAt?: Date;
76
+ }
77
+ export type ChannelConfig<T> = T | T[];
78
+ export interface NotificationModuleOptions {
79
+ channels?: {
80
+ email?: ChannelConfig<EmailChannelConfig>;
81
+ sms?: ChannelConfig<SmsChannelConfig>;
82
+ firebase?: ChannelConfig<FirebaseChannelConfig>;
83
+ telegram?: ChannelConfig<TelegramChannelConfig>;
84
+ };
85
+ templates?: {
86
+ dir?: string;
87
+ };
88
+ queue?: {
89
+ enabled: boolean;
90
+ name?: string;
91
+ connection?: {
92
+ url: string;
93
+ };
94
+ prefix?: string;
95
+ defaultJobOptions?: Record<string, unknown>;
96
+ };
97
+ storage?: StorageConfig;
98
+ }
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=interfaces.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"interfaces.js","sourceRoot":"","sources":["../../src/notification/interfaces.ts"],"names":[],"mappings":""}
@@ -0,0 +1,4 @@
1
+ export declare const NOTIFICATION_LOG_REPOSITORY = "NOTIFICATION_LOG_REPOSITORY";
2
+ export declare const NOTIFICATION_CHANNELS = "NOTIFICATION_CHANNELS";
3
+ export declare const NOTIFICATION_QUEUE_OPTIONS = "NOTIFICATION_QUEUE_OPTIONS";
4
+ export declare const NOTIFICATION_OPTIONS = "NOTIFICATION_OPTIONS";
@@ -0,0 +1,8 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.NOTIFICATION_OPTIONS = exports.NOTIFICATION_QUEUE_OPTIONS = exports.NOTIFICATION_CHANNELS = exports.NOTIFICATION_LOG_REPOSITORY = void 0;
4
+ exports.NOTIFICATION_LOG_REPOSITORY = 'NOTIFICATION_LOG_REPOSITORY';
5
+ exports.NOTIFICATION_CHANNELS = 'NOTIFICATION_CHANNELS';
6
+ exports.NOTIFICATION_QUEUE_OPTIONS = 'NOTIFICATION_QUEUE_OPTIONS';
7
+ exports.NOTIFICATION_OPTIONS = 'NOTIFICATION_OPTIONS';
8
+ //# sourceMappingURL=notification.constants.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"notification.constants.js","sourceRoot":"","sources":["../../src/notification/notification.constants.ts"],"names":[],"mappings":";;;AAAa,QAAA,2BAA2B,GAAG,6BAA6B,CAAC;AAE5D,QAAA,qBAAqB,GAAG,uBAAuB,CAAC;AAEhD,QAAA,0BAA0B,GAAG,4BAA4B,CAAC;AAE1D,QAAA,oBAAoB,GAAG,sBAAsB,CAAC"}
@@ -0,0 +1,10 @@
1
+ import { DynamicModule } from '@nestjs/common';
2
+ import type { NotificationModuleOptions } from './interfaces';
3
+ export declare class NotificationModule {
4
+ static forRoot(options?: NotificationModuleOptions): DynamicModule;
5
+ static forRootAsync(options: {
6
+ useFactory: (...args: any[]) => NotificationModuleOptions | Promise<NotificationModuleOptions>;
7
+ inject?: any[];
8
+ imports?: any[];
9
+ }): DynamicModule;
10
+ }
@@ -0,0 +1,160 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var NotificationModule_1;
9
+ Object.defineProperty(exports, "__esModule", { value: true });
10
+ exports.NotificationModule = void 0;
11
+ const common_1 = require("@nestjs/common");
12
+ const notification_constants_1 = require("./notification.constants");
13
+ const notification_service_1 = require("./notification.service");
14
+ const services_1 = require("./services");
15
+ const queue_1 = require("./queue");
16
+ const channels_1 = require("./channels");
17
+ const channels_2 = require("./channels");
18
+ const channels_3 = require("./channels");
19
+ const channels_4 = require("./channels");
20
+ function toArray(value) {
21
+ if (!value)
22
+ return [];
23
+ return Array.isArray(value) ? value : [value];
24
+ }
25
+ function buildChannels(config) {
26
+ const map = new Map();
27
+ const emailCfgs = toArray(config?.email);
28
+ if (emailCfgs.length)
29
+ map.set('email', emailCfgs.map((c) => new channels_1.EmailChannel(c)));
30
+ const smsCfgs = toArray(config?.sms);
31
+ if (smsCfgs.length)
32
+ map.set('sms', smsCfgs.map((c) => new channels_2.SmsChannel(c)));
33
+ const fbCfgs = toArray(config?.firebase);
34
+ if (fbCfgs.length)
35
+ map.set('firebase', fbCfgs.map((c) => new channels_3.FirebaseChannel(c)));
36
+ const tgCfgs = toArray(config?.telegram);
37
+ if (tgCfgs.length)
38
+ map.set('telegram', tgCfgs.map((c) => new channels_4.TelegramChannel(c)));
39
+ return map;
40
+ }
41
+ function buildProviders(options) {
42
+ const channelMap = buildChannels(options.channels);
43
+ const providers = [
44
+ notification_service_1.NotificationService,
45
+ {
46
+ provide: notification_constants_1.NOTIFICATION_CHANNELS,
47
+ useValue: channelMap,
48
+ },
49
+ ];
50
+ if (options.templates?.dir) {
51
+ providers.push({
52
+ provide: services_1.TemplateService,
53
+ useFactory: () => new services_1.TemplateService(options.templates.dir),
54
+ });
55
+ }
56
+ if (options.queue?.enabled && options.queue.connection) {
57
+ providers.push({
58
+ provide: notification_constants_1.NOTIFICATION_QUEUE_OPTIONS,
59
+ useValue: {
60
+ name: options.queue.name ?? 'notification',
61
+ connection: options.queue.connection,
62
+ defaultJobOptions: options.queue.defaultJobOptions,
63
+ },
64
+ }, queue_1.NotificationQueueService);
65
+ }
66
+ if (options.storage?.enabled) {
67
+ providers.push({
68
+ provide: notification_constants_1.NOTIFICATION_LOG_REPOSITORY,
69
+ useFactory: () => {
70
+ throw new Error('Notification storage is enabled but no repository is configured. ' +
71
+ 'Provide a repository using the NOTIFICATION_LOG_REPOSITORY token. ' +
72
+ 'See README for TypeORM setup instructions.');
73
+ },
74
+ });
75
+ }
76
+ return providers;
77
+ }
78
+ let NotificationModule = NotificationModule_1 = class NotificationModule {
79
+ static forRoot(options = {}) {
80
+ return {
81
+ module: NotificationModule_1,
82
+ providers: buildProviders(options),
83
+ exports: [notification_service_1.NotificationService],
84
+ };
85
+ }
86
+ static forRootAsync(options) {
87
+ return {
88
+ module: NotificationModule_1,
89
+ imports: options.imports ?? [],
90
+ providers: [
91
+ {
92
+ provide: notification_constants_1.NOTIFICATION_OPTIONS,
93
+ useFactory: options.useFactory,
94
+ inject: options.inject,
95
+ },
96
+ ...buildProviderFactories(),
97
+ ],
98
+ exports: [notification_service_1.NotificationService],
99
+ };
100
+ }
101
+ };
102
+ exports.NotificationModule = NotificationModule;
103
+ exports.NotificationModule = NotificationModule = NotificationModule_1 = __decorate([
104
+ (0, common_1.Global)(),
105
+ (0, common_1.Module)({})
106
+ ], NotificationModule);
107
+ function buildProviderFactories() {
108
+ return [
109
+ notification_service_1.NotificationService,
110
+ {
111
+ provide: notification_constants_1.NOTIFICATION_CHANNELS,
112
+ inject: [notification_constants_1.NOTIFICATION_OPTIONS],
113
+ useFactory: (opts) => buildChannels(opts.channels),
114
+ },
115
+ {
116
+ provide: services_1.TemplateService,
117
+ inject: [notification_constants_1.NOTIFICATION_OPTIONS],
118
+ useFactory: (opts) => opts.templates?.dir
119
+ ? new services_1.TemplateService(opts.templates.dir)
120
+ : undefined,
121
+ },
122
+ {
123
+ provide: notification_constants_1.NOTIFICATION_QUEUE_OPTIONS,
124
+ inject: [notification_constants_1.NOTIFICATION_OPTIONS],
125
+ useFactory: (opts) => {
126
+ if (!opts.queue?.enabled || !opts.queue.connection)
127
+ return undefined;
128
+ return {
129
+ name: opts.queue.name ?? 'notification',
130
+ connection: opts.queue.connection,
131
+ defaultJobOptions: opts.queue.defaultJobOptions,
132
+ };
133
+ },
134
+ },
135
+ {
136
+ provide: queue_1.NotificationQueueService,
137
+ inject: [
138
+ notification_constants_1.NOTIFICATION_CHANNELS,
139
+ notification_constants_1.NOTIFICATION_QUEUE_OPTIONS,
140
+ notification_constants_1.NOTIFICATION_OPTIONS,
141
+ ],
142
+ useFactory: (channelMap, queueOpts, opts) => {
143
+ if (!opts.queue?.enabled || !opts.queue.connection || !queueOpts)
144
+ return undefined;
145
+ return new queue_1.NotificationQueueService(channelMap, queueOpts, undefined, undefined);
146
+ },
147
+ },
148
+ {
149
+ provide: notification_constants_1.NOTIFICATION_LOG_REPOSITORY,
150
+ inject: [notification_constants_1.NOTIFICATION_OPTIONS],
151
+ useFactory: (opts) => {
152
+ if (!opts.storage?.enabled)
153
+ return undefined;
154
+ throw new Error('Notification storage is enabled but no repository is configured. ' +
155
+ 'Provide a repository using the NOTIFICATION_LOG_REPOSITORY token.');
156
+ },
157
+ },
158
+ ];
159
+ }
160
+ //# sourceMappingURL=notification.module.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"notification.module.js","sourceRoot":"","sources":["../../src/notification/notification.module.ts"],"names":[],"mappings":"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"}