vintasend 0.1.0 → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/examples/nextjs-prisma-nodemailer-pug-temporal/Dockerfile.notifications-worker +0 -14
- package/src/examples/nextjs-prisma-nodemailer-pug-temporal/package-lock.json +254 -12
- package/src/examples/nextjs-prisma-nodemailer-pug-temporal/package.json +5 -0
- package/src/examples/nextjs-prisma-nodemailer-pug-temporal/src/app/api/auth/forgot-password/forgot-password-notification-context.ts +21 -21
- package/src/examples/nextjs-prisma-nodemailer-pug-temporal/src/lib/services/notifications.ts +3 -3
- package/src/examples/nextjs-prisma-nodemailer-pug-temporal/src/lib/services/temporal-queue-service.ts +2 -2
- package/src/examples/nextjs-prisma-nodemailer-pug-temporal/src/workers/notifications/activities.ts +6 -5
- package/src/examples/nextjs-prisma-nodemailer-pug-temporal/src/workers/notifications/workflows.ts +5 -2
- package/src/implementations/vintasend-nodemailer/nodemailer-notification-adapter.ts +26 -12
- package/src/implementations/vintasend-nodemailer/package.json +2 -1
- package/src/implementations/vintasend-prisma/package.json +2 -1
- package/src/implementations/vintasend-prisma/prisma-notification-backend.ts +9 -8
- package/src/implementations/vintasend-pug/package.json +2 -1
- package/src/implementations/vintasend-pug/pug-email-template-renderer.ts +11 -7
- package/src/implementations/vintasend-winston/package.json +2 -1
- package/src/implementations/vintasend-winston/winston-logger.ts +1 -1
- package/src/services/notification-adapters/base-notification-adapter.ts +8 -2
- package/src/services/notification-backends/base-notification-backend.ts +21 -17
- package/src/services/notification-queue-service/base-notification-queue-service.ts +3 -3
- package/src/services/notification-service.ts +39 -32
- package/src/services/notification-template-renderers/base-email-template-renderer.ts +13 -4
- package/src/services/notification-template-renderers/base-notification-template-renderer.ts +11 -2
package/package.json
CHANGED
|
@@ -9,20 +9,6 @@ COPY package*.json ./
|
|
|
9
9
|
# Install dependencies
|
|
10
10
|
RUN npm install
|
|
11
11
|
|
|
12
|
-
RUN mkdir -p src/vintasend-ts/services
|
|
13
|
-
RUN mkdir -p src/vintasend-ts/types
|
|
14
|
-
RUN mkdir -p src/vintasend-nodemailer
|
|
15
|
-
RUN mkdir -p src/vintasend-prisma
|
|
16
|
-
RUN mkdir -p src/vintasend-pug
|
|
17
|
-
RUN mkdir -p src/vintasend-winston
|
|
18
|
-
|
|
19
|
-
COPY ../../services ./src/vintasend-ts/services
|
|
20
|
-
COPY ../../types ./src/vintasend-ts/types
|
|
21
|
-
COPY ../../implementations/vintasend-nodemailer ./src/vintasend-nodemailer
|
|
22
|
-
COPY ../../implementations/vintasend-prisma ./src/vintasend-prisma
|
|
23
|
-
COPY ../../implementations/vintasend-pug ./src/vintasend-pug
|
|
24
|
-
COPY ../../implementations/vintasend-winston ./src/vintasend-winston
|
|
25
|
-
|
|
26
12
|
# Copy the rest of the application code
|
|
27
13
|
COPY . .
|
|
28
14
|
|
|
@@ -29,6 +29,11 @@
|
|
|
29
29
|
"react-hook-form": "^7.54.2",
|
|
30
30
|
"tailwind-merge": "^3.0.1",
|
|
31
31
|
"tailwindcss-animate": "^1.0.7",
|
|
32
|
+
"vintasend": "^0.1.0",
|
|
33
|
+
"vintasend-nodemailer": "^0.1.0",
|
|
34
|
+
"vintasend-prisma": "^0.1.0",
|
|
35
|
+
"vintasend-pug": "^0.1.0",
|
|
36
|
+
"vintasend-winston": "^0.1.0",
|
|
32
37
|
"zod": "^3.24.1"
|
|
33
38
|
},
|
|
34
39
|
"devDependencies": {
|
|
@@ -101,6 +106,24 @@
|
|
|
101
106
|
"node": ">=6.9.0"
|
|
102
107
|
}
|
|
103
108
|
},
|
|
109
|
+
"node_modules/@colors/colors": {
|
|
110
|
+
"version": "1.6.0",
|
|
111
|
+
"resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.6.0.tgz",
|
|
112
|
+
"integrity": "sha512-Ir+AOibqzrIsL6ajt3Rz3LskB7OiMVHqltZmspbW/TJuTVuyOMirVqAkjfY6JISiLHgyNqicAC8AyHHGzNd/dA==",
|
|
113
|
+
"engines": {
|
|
114
|
+
"node": ">=0.1.90"
|
|
115
|
+
}
|
|
116
|
+
},
|
|
117
|
+
"node_modules/@dabh/diagnostics": {
|
|
118
|
+
"version": "2.0.3",
|
|
119
|
+
"resolved": "https://registry.npmjs.org/@dabh/diagnostics/-/diagnostics-2.0.3.tgz",
|
|
120
|
+
"integrity": "sha512-hrlQOIi7hAfzsMqlGSFyVucrx38O+j6wiGOf//H2ecvIEqYN4ADBSS2iLMh5UFyDunCNniUIPk/q3riFv45xRA==",
|
|
121
|
+
"dependencies": {
|
|
122
|
+
"colorspace": "1.1.x",
|
|
123
|
+
"enabled": "2.0.x",
|
|
124
|
+
"kuler": "^2.0.0"
|
|
125
|
+
}
|
|
126
|
+
},
|
|
104
127
|
"node_modules/@emnapi/runtime": {
|
|
105
128
|
"version": "1.3.1",
|
|
106
129
|
"resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.3.1.tgz",
|
|
@@ -1423,14 +1446,12 @@
|
|
|
1423
1446
|
"node_modules/@prisma/debug": {
|
|
1424
1447
|
"version": "6.3.1",
|
|
1425
1448
|
"resolved": "https://registry.npmjs.org/@prisma/debug/-/debug-6.3.1.tgz",
|
|
1426
|
-
"integrity": "sha512-RrEBkd+HLZx+ydfmYT0jUj7wjLiS95wfTOSQ+8FQbvb6vHh5AeKfEPt/XUQ5+Buljj8hltEfOslEW57/wQIVeA=="
|
|
1427
|
-
"devOptional": true
|
|
1449
|
+
"integrity": "sha512-RrEBkd+HLZx+ydfmYT0jUj7wjLiS95wfTOSQ+8FQbvb6vHh5AeKfEPt/XUQ5+Buljj8hltEfOslEW57/wQIVeA=="
|
|
1428
1450
|
},
|
|
1429
1451
|
"node_modules/@prisma/engines": {
|
|
1430
1452
|
"version": "6.3.1",
|
|
1431
1453
|
"resolved": "https://registry.npmjs.org/@prisma/engines/-/engines-6.3.1.tgz",
|
|
1432
1454
|
"integrity": "sha512-sXdqEVLyGAJ5/iUoG/Ea5AdHMN71m6PzMBWRQnLmhhOejzqAaEr8rUd623ql6OJpED4s/U4vIn4dg1qkF7vGag==",
|
|
1433
|
-
"devOptional": true,
|
|
1434
1455
|
"hasInstallScript": true,
|
|
1435
1456
|
"dependencies": {
|
|
1436
1457
|
"@prisma/debug": "6.3.1",
|
|
@@ -1442,14 +1463,12 @@
|
|
|
1442
1463
|
"node_modules/@prisma/engines-version": {
|
|
1443
1464
|
"version": "6.3.0-17.acc0b9dd43eb689cbd20c9470515d719db10d0b0",
|
|
1444
1465
|
"resolved": "https://registry.npmjs.org/@prisma/engines-version/-/engines-version-6.3.0-17.acc0b9dd43eb689cbd20c9470515d719db10d0b0.tgz",
|
|
1445
|
-
"integrity": "sha512-R/ZcMuaWZT2UBmgX3Ko6PAV3f8//ZzsjRIG1eKqp3f2rqEqVtCv+mtzuH2rBPUC9ujJ5kCb9wwpxeyCkLcHVyA=="
|
|
1446
|
-
"devOptional": true
|
|
1466
|
+
"integrity": "sha512-R/ZcMuaWZT2UBmgX3Ko6PAV3f8//ZzsjRIG1eKqp3f2rqEqVtCv+mtzuH2rBPUC9ujJ5kCb9wwpxeyCkLcHVyA=="
|
|
1447
1467
|
},
|
|
1448
1468
|
"node_modules/@prisma/fetch-engine": {
|
|
1449
1469
|
"version": "6.3.1",
|
|
1450
1470
|
"resolved": "https://registry.npmjs.org/@prisma/fetch-engine/-/fetch-engine-6.3.1.tgz",
|
|
1451
1471
|
"integrity": "sha512-HOf/0umOgt+/S2xtZze+FHKoxpVg4YpVxROr6g2YG09VsI3Ipyb+rGvD6QGbCqkq5NTWAAZoOGNL+oy7t+IhaQ==",
|
|
1452
|
-
"devOptional": true,
|
|
1453
1472
|
"dependencies": {
|
|
1454
1473
|
"@prisma/debug": "6.3.1",
|
|
1455
1474
|
"@prisma/engines-version": "6.3.0-17.acc0b9dd43eb689cbd20c9470515d719db10d0b0",
|
|
@@ -1460,7 +1479,6 @@
|
|
|
1460
1479
|
"version": "6.3.1",
|
|
1461
1480
|
"resolved": "https://registry.npmjs.org/@prisma/get-platform/-/get-platform-6.3.1.tgz",
|
|
1462
1481
|
"integrity": "sha512-AYLq6Hk9xG73JdLWJ3Ip9Wg/vlP7xPvftGBalsPzKDOHr/ImhwJ09eS8xC2vNT12DlzGxhfk8BkL0ve2OriNhQ==",
|
|
1463
|
-
"devOptional": true,
|
|
1464
1482
|
"dependencies": {
|
|
1465
1483
|
"@prisma/debug": "6.3.1"
|
|
1466
1484
|
}
|
|
@@ -3334,6 +3352,11 @@
|
|
|
3334
3352
|
"@types/react": "^19.0.0"
|
|
3335
3353
|
}
|
|
3336
3354
|
},
|
|
3355
|
+
"node_modules/@types/triple-beam": {
|
|
3356
|
+
"version": "1.3.5",
|
|
3357
|
+
"resolved": "https://registry.npmjs.org/@types/triple-beam/-/triple-beam-1.3.5.tgz",
|
|
3358
|
+
"integrity": "sha512-6WaYesThRMCl19iryMYP7/x2OVgCtbIVflDGFpWnb9irXI3UjYE4AzmYuiUKY1AJstGijoY+MgUszMgRxIYTYw=="
|
|
3359
|
+
},
|
|
3337
3360
|
"node_modules/@typescript-eslint/eslint-plugin": {
|
|
3338
3361
|
"version": "8.23.0",
|
|
3339
3362
|
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.23.0.tgz",
|
|
@@ -4027,6 +4050,11 @@
|
|
|
4027
4050
|
"integrity": "sha512-OH/2E5Fg20h2aPrbe+QL8JZQFko0YZaF+j4mnQ7BGhfavO7OpSLa8a0y9sBwomHdSbkhTS8TQNayBfnW5DwbvQ==",
|
|
4028
4051
|
"dev": true
|
|
4029
4052
|
},
|
|
4053
|
+
"node_modules/async": {
|
|
4054
|
+
"version": "3.2.6",
|
|
4055
|
+
"resolved": "https://registry.npmjs.org/async/-/async-3.2.6.tgz",
|
|
4056
|
+
"integrity": "sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA=="
|
|
4057
|
+
},
|
|
4030
4058
|
"node_modules/async-function": {
|
|
4031
4059
|
"version": "1.0.0",
|
|
4032
4060
|
"resolved": "https://registry.npmjs.org/async-function/-/async-function-1.0.0.tgz",
|
|
@@ -4457,12 +4485,42 @@
|
|
|
4457
4485
|
"version": "1.9.1",
|
|
4458
4486
|
"resolved": "https://registry.npmjs.org/color-string/-/color-string-1.9.1.tgz",
|
|
4459
4487
|
"integrity": "sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==",
|
|
4460
|
-
"optional": true,
|
|
4461
4488
|
"dependencies": {
|
|
4462
4489
|
"color-name": "^1.0.0",
|
|
4463
4490
|
"simple-swizzle": "^0.2.2"
|
|
4464
4491
|
}
|
|
4465
4492
|
},
|
|
4493
|
+
"node_modules/colorspace": {
|
|
4494
|
+
"version": "1.1.4",
|
|
4495
|
+
"resolved": "https://registry.npmjs.org/colorspace/-/colorspace-1.1.4.tgz",
|
|
4496
|
+
"integrity": "sha512-BgvKJiuVu1igBUF2kEjRCZXol6wiiGbY5ipL/oVPwm0BL9sIpMIzM8IK7vwuxIIzOXMV3Ey5w+vxhm0rR/TN8w==",
|
|
4497
|
+
"dependencies": {
|
|
4498
|
+
"color": "^3.1.3",
|
|
4499
|
+
"text-hex": "1.0.x"
|
|
4500
|
+
}
|
|
4501
|
+
},
|
|
4502
|
+
"node_modules/colorspace/node_modules/color": {
|
|
4503
|
+
"version": "3.2.1",
|
|
4504
|
+
"resolved": "https://registry.npmjs.org/color/-/color-3.2.1.tgz",
|
|
4505
|
+
"integrity": "sha512-aBl7dZI9ENN6fUGC7mWpMTPNHmWUSNan9tuWN6ahh5ZLNk9baLJOnSMlrQkHcrfFgz2/RigjUVAjdx36VcemKA==",
|
|
4506
|
+
"dependencies": {
|
|
4507
|
+
"color-convert": "^1.9.3",
|
|
4508
|
+
"color-string": "^1.6.0"
|
|
4509
|
+
}
|
|
4510
|
+
},
|
|
4511
|
+
"node_modules/colorspace/node_modules/color-convert": {
|
|
4512
|
+
"version": "1.9.3",
|
|
4513
|
+
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
|
|
4514
|
+
"integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
|
|
4515
|
+
"dependencies": {
|
|
4516
|
+
"color-name": "1.1.3"
|
|
4517
|
+
}
|
|
4518
|
+
},
|
|
4519
|
+
"node_modules/colorspace/node_modules/color-name": {
|
|
4520
|
+
"version": "1.1.3",
|
|
4521
|
+
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
|
|
4522
|
+
"integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw=="
|
|
4523
|
+
},
|
|
4466
4524
|
"node_modules/commander": {
|
|
4467
4525
|
"version": "4.1.1",
|
|
4468
4526
|
"resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz",
|
|
@@ -4707,6 +4765,11 @@
|
|
|
4707
4765
|
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz",
|
|
4708
4766
|
"integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg=="
|
|
4709
4767
|
},
|
|
4768
|
+
"node_modules/enabled": {
|
|
4769
|
+
"version": "2.0.0",
|
|
4770
|
+
"resolved": "https://registry.npmjs.org/enabled/-/enabled-2.0.0.tgz",
|
|
4771
|
+
"integrity": "sha512-AKrN98kuwOzMIdAizXGI86UFBoo26CL21UM763y1h/GMSJ4/OHU9k2YlsmBpyScFo/wbLzWQJBMCW4+IO3/+OQ=="
|
|
4772
|
+
},
|
|
4710
4773
|
"node_modules/enhanced-resolve": {
|
|
4711
4774
|
"version": "5.18.1",
|
|
4712
4775
|
"resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.18.1.tgz",
|
|
@@ -5456,6 +5519,11 @@
|
|
|
5456
5519
|
"reusify": "^1.0.4"
|
|
5457
5520
|
}
|
|
5458
5521
|
},
|
|
5522
|
+
"node_modules/fecha": {
|
|
5523
|
+
"version": "4.2.3",
|
|
5524
|
+
"resolved": "https://registry.npmjs.org/fecha/-/fecha-4.2.3.tgz",
|
|
5525
|
+
"integrity": "sha512-OP2IUU6HeYKJi3i0z4A19kHMQoLVs4Hc+DPqqxI2h/DPZHTm/vjsfC6P0b4jCMy14XizLBqvndQ+UilD7707Jw=="
|
|
5526
|
+
},
|
|
5459
5527
|
"node_modules/file-entry-cache": {
|
|
5460
5528
|
"version": "8.0.0",
|
|
5461
5529
|
"resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz",
|
|
@@ -5514,6 +5582,11 @@
|
|
|
5514
5582
|
"integrity": "sha512-AiwGJM8YcNOaobumgtng+6NHuOqC3A7MixFeDafM3X9cIUM+xUXoS5Vfgf+OihAYe20fxqNM9yPBXJzRtZ/4eA==",
|
|
5515
5583
|
"dev": true
|
|
5516
5584
|
},
|
|
5585
|
+
"node_modules/fn.name": {
|
|
5586
|
+
"version": "1.1.0",
|
|
5587
|
+
"resolved": "https://registry.npmjs.org/fn.name/-/fn.name-1.1.0.tgz",
|
|
5588
|
+
"integrity": "sha512-GRnmB5gPyJpAhTQdSZTSp9uaPSvl09KoYcMQtsB9rQoOmzs9dH6ffeccH+Z+cv6P68Hu5bC6JjRh4Ah/mHSNRw=="
|
|
5589
|
+
},
|
|
5517
5590
|
"node_modules/for-each": {
|
|
5518
5591
|
"version": "0.3.4",
|
|
5519
5592
|
"resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.4.tgz",
|
|
@@ -5930,6 +6003,11 @@
|
|
|
5930
6003
|
"node": ">=0.8.19"
|
|
5931
6004
|
}
|
|
5932
6005
|
},
|
|
6006
|
+
"node_modules/inherits": {
|
|
6007
|
+
"version": "2.0.4",
|
|
6008
|
+
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
|
|
6009
|
+
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
|
|
6010
|
+
},
|
|
5933
6011
|
"node_modules/internal-slot": {
|
|
5934
6012
|
"version": "1.1.0",
|
|
5935
6013
|
"resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.1.0.tgz",
|
|
@@ -5964,8 +6042,7 @@
|
|
|
5964
6042
|
"node_modules/is-arrayish": {
|
|
5965
6043
|
"version": "0.3.2",
|
|
5966
6044
|
"resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz",
|
|
5967
|
-
"integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ=="
|
|
5968
|
-
"optional": true
|
|
6045
|
+
"integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ=="
|
|
5969
6046
|
},
|
|
5970
6047
|
"node_modules/is-async-function": {
|
|
5971
6048
|
"version": "2.1.1",
|
|
@@ -6261,6 +6338,17 @@
|
|
|
6261
6338
|
"url": "https://github.com/sponsors/ljharb"
|
|
6262
6339
|
}
|
|
6263
6340
|
},
|
|
6341
|
+
"node_modules/is-stream": {
|
|
6342
|
+
"version": "2.0.1",
|
|
6343
|
+
"resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz",
|
|
6344
|
+
"integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==",
|
|
6345
|
+
"engines": {
|
|
6346
|
+
"node": ">=8"
|
|
6347
|
+
},
|
|
6348
|
+
"funding": {
|
|
6349
|
+
"url": "https://github.com/sponsors/sindresorhus"
|
|
6350
|
+
}
|
|
6351
|
+
},
|
|
6264
6352
|
"node_modules/is-string": {
|
|
6265
6353
|
"version": "1.1.1",
|
|
6266
6354
|
"resolved": "https://registry.npmjs.org/is-string/-/is-string-1.1.1.tgz",
|
|
@@ -6559,6 +6647,11 @@
|
|
|
6559
6647
|
"json-buffer": "3.0.1"
|
|
6560
6648
|
}
|
|
6561
6649
|
},
|
|
6650
|
+
"node_modules/kuler": {
|
|
6651
|
+
"version": "2.0.0",
|
|
6652
|
+
"resolved": "https://registry.npmjs.org/kuler/-/kuler-2.0.0.tgz",
|
|
6653
|
+
"integrity": "sha512-Xq9nH7KlWZmXAtodXDDRE7vs6DU1gTU8zYDHDiWLSip45Egwq3plLHzPn27NgvzL2r1LMPC1vdqh98sQxtqj4A=="
|
|
6654
|
+
},
|
|
6562
6655
|
"node_modules/language-subtag-registry": {
|
|
6563
6656
|
"version": "0.3.23",
|
|
6564
6657
|
"resolved": "https://registry.npmjs.org/language-subtag-registry/-/language-subtag-registry-0.3.23.tgz",
|
|
@@ -6675,6 +6768,22 @@
|
|
|
6675
6768
|
"resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz",
|
|
6676
6769
|
"integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg=="
|
|
6677
6770
|
},
|
|
6771
|
+
"node_modules/logform": {
|
|
6772
|
+
"version": "2.7.0",
|
|
6773
|
+
"resolved": "https://registry.npmjs.org/logform/-/logform-2.7.0.tgz",
|
|
6774
|
+
"integrity": "sha512-TFYA4jnP7PVbmlBIfhlSe+WKxs9dklXMTEGcBCIvLhE/Tn3H6Gk1norupVW7m5Cnd4bLcr08AytbyV/xj7f/kQ==",
|
|
6775
|
+
"dependencies": {
|
|
6776
|
+
"@colors/colors": "1.6.0",
|
|
6777
|
+
"@types/triple-beam": "^1.3.2",
|
|
6778
|
+
"fecha": "^4.2.0",
|
|
6779
|
+
"ms": "^2.1.1",
|
|
6780
|
+
"safe-stable-stringify": "^2.3.1",
|
|
6781
|
+
"triple-beam": "^1.3.0"
|
|
6782
|
+
},
|
|
6783
|
+
"engines": {
|
|
6784
|
+
"node": ">= 12.0.0"
|
|
6785
|
+
}
|
|
6786
|
+
},
|
|
6678
6787
|
"node_modules/long": {
|
|
6679
6788
|
"version": "5.2.4",
|
|
6680
6789
|
"resolved": "https://registry.npmjs.org/long/-/long-5.2.4.tgz",
|
|
@@ -7069,6 +7178,14 @@
|
|
|
7069
7178
|
"url": "https://github.com/sponsors/ljharb"
|
|
7070
7179
|
}
|
|
7071
7180
|
},
|
|
7181
|
+
"node_modules/one-time": {
|
|
7182
|
+
"version": "1.0.0",
|
|
7183
|
+
"resolved": "https://registry.npmjs.org/one-time/-/one-time-1.0.0.tgz",
|
|
7184
|
+
"integrity": "sha512-5DXOiRKwuSEcQ/l0kGCF6Q3jcADFv5tSmRaJck/OqkVFcOzutB134KRSfF0xDrL39MNnqxbHBbUUcjZIhTgb2g==",
|
|
7185
|
+
"dependencies": {
|
|
7186
|
+
"fn.name": "1.x.x"
|
|
7187
|
+
}
|
|
7188
|
+
},
|
|
7072
7189
|
"node_modules/optionator": {
|
|
7073
7190
|
"version": "0.9.4",
|
|
7074
7191
|
"resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz",
|
|
@@ -7396,7 +7513,6 @@
|
|
|
7396
7513
|
"version": "6.3.1",
|
|
7397
7514
|
"resolved": "https://registry.npmjs.org/prisma/-/prisma-6.3.1.tgz",
|
|
7398
7515
|
"integrity": "sha512-JKCZWvBC3enxk51tY4TWzS4b5iRt4sSU1uHn2I183giZTvonXaQonzVtjLzpOHE7qu9MxY510kAtFGJwryKe3Q==",
|
|
7399
|
-
"devOptional": true,
|
|
7400
7516
|
"hasInstallScript": true,
|
|
7401
7517
|
"dependencies": {
|
|
7402
7518
|
"@prisma/engines": "6.3.1"
|
|
@@ -7804,6 +7920,19 @@
|
|
|
7804
7920
|
"pify": "^2.3.0"
|
|
7805
7921
|
}
|
|
7806
7922
|
},
|
|
7923
|
+
"node_modules/readable-stream": {
|
|
7924
|
+
"version": "3.6.2",
|
|
7925
|
+
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz",
|
|
7926
|
+
"integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==",
|
|
7927
|
+
"dependencies": {
|
|
7928
|
+
"inherits": "^2.0.3",
|
|
7929
|
+
"string_decoder": "^1.1.1",
|
|
7930
|
+
"util-deprecate": "^1.0.1"
|
|
7931
|
+
},
|
|
7932
|
+
"engines": {
|
|
7933
|
+
"node": ">= 6"
|
|
7934
|
+
}
|
|
7935
|
+
},
|
|
7807
7936
|
"node_modules/readdirp": {
|
|
7808
7937
|
"version": "3.6.0",
|
|
7809
7938
|
"resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
|
|
@@ -8020,6 +8149,14 @@
|
|
|
8020
8149
|
"url": "https://github.com/sponsors/ljharb"
|
|
8021
8150
|
}
|
|
8022
8151
|
},
|
|
8152
|
+
"node_modules/safe-stable-stringify": {
|
|
8153
|
+
"version": "2.5.0",
|
|
8154
|
+
"resolved": "https://registry.npmjs.org/safe-stable-stringify/-/safe-stable-stringify-2.5.0.tgz",
|
|
8155
|
+
"integrity": "sha512-b3rppTKm9T+PsVCBEOUR46GWI7fdOs00VKZ1+9c1EWDaDMvjQc6tUwuFyIprgGgTcWoVHSKrU8H31ZHA2e0RHA==",
|
|
8156
|
+
"engines": {
|
|
8157
|
+
"node": ">=10"
|
|
8158
|
+
}
|
|
8159
|
+
},
|
|
8023
8160
|
"node_modules/safer-buffer": {
|
|
8024
8161
|
"version": "2.1.2",
|
|
8025
8162
|
"resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
|
|
@@ -8257,7 +8394,6 @@
|
|
|
8257
8394
|
"version": "0.2.2",
|
|
8258
8395
|
"resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz",
|
|
8259
8396
|
"integrity": "sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==",
|
|
8260
|
-
"optional": true,
|
|
8261
8397
|
"dependencies": {
|
|
8262
8398
|
"is-arrayish": "^0.3.1"
|
|
8263
8399
|
}
|
|
@@ -8320,6 +8456,14 @@
|
|
|
8320
8456
|
"integrity": "sha512-LjdcbuBeLcdETCrPn9i8AYAZ1eCtu4ECAWtP7UleOiZ9LzVxRzzUZEoZ8zB24nhkQnDWyET0I+3sWokSDS3E7g==",
|
|
8321
8457
|
"dev": true
|
|
8322
8458
|
},
|
|
8459
|
+
"node_modules/stack-trace": {
|
|
8460
|
+
"version": "0.0.10",
|
|
8461
|
+
"resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.10.tgz",
|
|
8462
|
+
"integrity": "sha512-KGzahc7puUKkzyMt+IqAep+TVNbKP+k2Lmwhub39m1AsTSkaDutx56aDCo+HLDzf/D26BIHTJWNiTG1KAJiQCg==",
|
|
8463
|
+
"engines": {
|
|
8464
|
+
"node": "*"
|
|
8465
|
+
}
|
|
8466
|
+
},
|
|
8323
8467
|
"node_modules/streamsearch": {
|
|
8324
8468
|
"version": "1.1.0",
|
|
8325
8469
|
"resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-1.1.0.tgz",
|
|
@@ -8328,6 +8472,14 @@
|
|
|
8328
8472
|
"node": ">=10.0.0"
|
|
8329
8473
|
}
|
|
8330
8474
|
},
|
|
8475
|
+
"node_modules/string_decoder": {
|
|
8476
|
+
"version": "1.3.0",
|
|
8477
|
+
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz",
|
|
8478
|
+
"integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==",
|
|
8479
|
+
"dependencies": {
|
|
8480
|
+
"safe-buffer": "~5.2.0"
|
|
8481
|
+
}
|
|
8482
|
+
},
|
|
8331
8483
|
"node_modules/string-width": {
|
|
8332
8484
|
"version": "5.1.2",
|
|
8333
8485
|
"resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz",
|
|
@@ -8813,6 +8965,11 @@
|
|
|
8813
8965
|
"resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
|
|
8814
8966
|
"integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ=="
|
|
8815
8967
|
},
|
|
8968
|
+
"node_modules/text-hex": {
|
|
8969
|
+
"version": "1.0.0",
|
|
8970
|
+
"resolved": "https://registry.npmjs.org/text-hex/-/text-hex-1.0.0.tgz",
|
|
8971
|
+
"integrity": "sha512-uuVGNWzgJ4yhRaNSiubPY7OjISw4sw4E5Uv0wbjp+OzcbmVU/rsT8ujgcXJhn9ypzsgr5vlzpPqP+MBBKcGvbg=="
|
|
8972
|
+
},
|
|
8816
8973
|
"node_modules/thenify": {
|
|
8817
8974
|
"version": "3.3.1",
|
|
8818
8975
|
"resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz",
|
|
@@ -8874,6 +9031,14 @@
|
|
|
8874
9031
|
"tslib": "2"
|
|
8875
9032
|
}
|
|
8876
9033
|
},
|
|
9034
|
+
"node_modules/triple-beam": {
|
|
9035
|
+
"version": "1.4.1",
|
|
9036
|
+
"resolved": "https://registry.npmjs.org/triple-beam/-/triple-beam-1.4.1.tgz",
|
|
9037
|
+
"integrity": "sha512-aZbgViZrg1QNcG+LULa7nhZpJTZSLm/mXnHXnbAbjmN5aSa0y7V+wvv6+4WaBtpISJzThKy+PIPxc1Nq1EJ9mg==",
|
|
9038
|
+
"engines": {
|
|
9039
|
+
"node": ">= 14.0.0"
|
|
9040
|
+
}
|
|
9041
|
+
},
|
|
8877
9042
|
"node_modules/ts-api-utils": {
|
|
8878
9043
|
"version": "2.0.1",
|
|
8879
9044
|
"resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.0.1.tgz",
|
|
@@ -9152,6 +9317,49 @@
|
|
|
9152
9317
|
"uuid": "dist/bin/uuid"
|
|
9153
9318
|
}
|
|
9154
9319
|
},
|
|
9320
|
+
"node_modules/vintasend": {
|
|
9321
|
+
"version": "0.1.0",
|
|
9322
|
+
"resolved": "https://registry.npmjs.org/vintasend/-/vintasend-0.1.0.tgz",
|
|
9323
|
+
"integrity": "sha512-36Mkkf6yv/Y5zpuBc0TCIitOuUjsbQzVPqu56bbv3KLmoeT59UDE7OWTJkzrlRdA5iYwTB/sUk7VsYDzLF2wuQ=="
|
|
9324
|
+
},
|
|
9325
|
+
"node_modules/vintasend-nodemailer": {
|
|
9326
|
+
"version": "0.1.0",
|
|
9327
|
+
"resolved": "https://registry.npmjs.org/vintasend-nodemailer/-/vintasend-nodemailer-0.1.0.tgz",
|
|
9328
|
+
"integrity": "sha512-VNKJTDnLzGDZncgy4t/3iHUZ1cwQ+7Db4BNMwn7Gd1zsiL03l9iyB4zzeiu1MdLiSEiMtDrpmPaFx9ZkfPWGww==",
|
|
9329
|
+
"dependencies": {
|
|
9330
|
+
"nodemailer": "^6.10.0",
|
|
9331
|
+
"vintasend": "^0.1.0"
|
|
9332
|
+
}
|
|
9333
|
+
},
|
|
9334
|
+
"node_modules/vintasend-prisma": {
|
|
9335
|
+
"version": "0.1.0",
|
|
9336
|
+
"resolved": "https://registry.npmjs.org/vintasend-prisma/-/vintasend-prisma-0.1.0.tgz",
|
|
9337
|
+
"integrity": "sha512-eHakQHyUeHe95NucnX/ZovfWZcHil/1zswf0pg8wnc8dytOk8s3sR2kqP9MrQk6SbYRxe06tf1uZrHm0SxzaaA==",
|
|
9338
|
+
"dependencies": {
|
|
9339
|
+
"@prisma/client": "^6.3.1",
|
|
9340
|
+
"prisma": "^6.3.1",
|
|
9341
|
+
"vintasend": "^0.1.0"
|
|
9342
|
+
}
|
|
9343
|
+
},
|
|
9344
|
+
"node_modules/vintasend-pug": {
|
|
9345
|
+
"version": "0.1.0",
|
|
9346
|
+
"resolved": "https://registry.npmjs.org/vintasend-pug/-/vintasend-pug-0.1.0.tgz",
|
|
9347
|
+
"integrity": "sha512-SNgUUHJK/3ejydcgkF0AGwVINIrgt3NkPPO21P6RkBIRcF5PCJ6KrINJtr0kYhTHDLpRaZk2Ma2NPh9kNLUUgA==",
|
|
9348
|
+
"dependencies": {
|
|
9349
|
+
"pug": "^3.0.3",
|
|
9350
|
+
"vintasend": "^0.1.0"
|
|
9351
|
+
}
|
|
9352
|
+
},
|
|
9353
|
+
"node_modules/vintasend-winston": {
|
|
9354
|
+
"version": "0.1.0",
|
|
9355
|
+
"resolved": "https://registry.npmjs.org/vintasend-winston/-/vintasend-winston-0.1.0.tgz",
|
|
9356
|
+
"integrity": "sha512-pbirMH+n1uH3Aa7N32AC7kAjvb8u2A59gT8lSLvjA2qRa1cATBFci+FawsB5Jyxfhxm0iAPtbPsLrLBANAyeaw==",
|
|
9357
|
+
"dependencies": {
|
|
9358
|
+
"jsonwebtoken": "^9.0.2",
|
|
9359
|
+
"vintasend": "^0.1.0",
|
|
9360
|
+
"winston": "^3.17.0"
|
|
9361
|
+
}
|
|
9362
|
+
},
|
|
9155
9363
|
"node_modules/void-elements": {
|
|
9156
9364
|
"version": "3.1.0",
|
|
9157
9365
|
"resolved": "https://registry.npmjs.org/void-elements/-/void-elements-3.1.0.tgz",
|
|
@@ -9343,6 +9551,40 @@
|
|
|
9343
9551
|
"url": "https://github.com/sponsors/ljharb"
|
|
9344
9552
|
}
|
|
9345
9553
|
},
|
|
9554
|
+
"node_modules/winston": {
|
|
9555
|
+
"version": "3.17.0",
|
|
9556
|
+
"resolved": "https://registry.npmjs.org/winston/-/winston-3.17.0.tgz",
|
|
9557
|
+
"integrity": "sha512-DLiFIXYC5fMPxaRg832S6F5mJYvePtmO5G9v9IgUFPhXm9/GkXarH/TUrBAVzhTCzAj9anE/+GjrgXp/54nOgw==",
|
|
9558
|
+
"dependencies": {
|
|
9559
|
+
"@colors/colors": "^1.6.0",
|
|
9560
|
+
"@dabh/diagnostics": "^2.0.2",
|
|
9561
|
+
"async": "^3.2.3",
|
|
9562
|
+
"is-stream": "^2.0.0",
|
|
9563
|
+
"logform": "^2.7.0",
|
|
9564
|
+
"one-time": "^1.0.0",
|
|
9565
|
+
"readable-stream": "^3.4.0",
|
|
9566
|
+
"safe-stable-stringify": "^2.3.1",
|
|
9567
|
+
"stack-trace": "0.0.x",
|
|
9568
|
+
"triple-beam": "^1.3.0",
|
|
9569
|
+
"winston-transport": "^4.9.0"
|
|
9570
|
+
},
|
|
9571
|
+
"engines": {
|
|
9572
|
+
"node": ">= 12.0.0"
|
|
9573
|
+
}
|
|
9574
|
+
},
|
|
9575
|
+
"node_modules/winston-transport": {
|
|
9576
|
+
"version": "4.9.0",
|
|
9577
|
+
"resolved": "https://registry.npmjs.org/winston-transport/-/winston-transport-4.9.0.tgz",
|
|
9578
|
+
"integrity": "sha512-8drMJ4rkgaPo1Me4zD/3WLfI/zPdA9o2IipKODunnGDcuqbHwjsbB79ylv04LCGGzU0xQ6vTznOMpQGaLhhm6A==",
|
|
9579
|
+
"dependencies": {
|
|
9580
|
+
"logform": "^2.7.0",
|
|
9581
|
+
"readable-stream": "^3.6.2",
|
|
9582
|
+
"triple-beam": "^1.3.0"
|
|
9583
|
+
},
|
|
9584
|
+
"engines": {
|
|
9585
|
+
"node": ">= 12.0.0"
|
|
9586
|
+
}
|
|
9587
|
+
},
|
|
9346
9588
|
"node_modules/with": {
|
|
9347
9589
|
"version": "7.0.2",
|
|
9348
9590
|
"resolved": "https://registry.npmjs.org/with/-/with-7.0.2.tgz",
|
|
@@ -34,6 +34,11 @@
|
|
|
34
34
|
"react-hook-form": "^7.54.2",
|
|
35
35
|
"tailwind-merge": "^3.0.1",
|
|
36
36
|
"tailwindcss-animate": "^1.0.7",
|
|
37
|
+
"vintasend": "^0.1.0",
|
|
38
|
+
"vintasend-nodemailer": "^0.1.0",
|
|
39
|
+
"vintasend-prisma": "^0.1.0",
|
|
40
|
+
"vintasend-pug": "^0.1.0",
|
|
41
|
+
"vintasend-winston": "^0.1.0",
|
|
37
42
|
"zod": "^3.24.1"
|
|
38
43
|
},
|
|
39
44
|
"devDependencies": {
|
|
@@ -1,21 +1,21 @@
|
|
|
1
|
-
import { PrismaClient } from '@prisma/client';
|
|
2
|
-
import type { ContextGenerator } from 'vintasend/services/notification-context-registry';
|
|
3
|
-
|
|
4
|
-
export class ForgotPasswordContextGenerator implements ContextGenerator {
|
|
5
|
-
async generate(params: { token: string }): Promise<{ firstName: string | null }> {
|
|
6
|
-
const prisma = new PrismaClient();
|
|
7
|
-
|
|
8
|
-
const token = await prisma.token.findUnique({
|
|
9
|
-
where: { token: params.token },
|
|
10
|
-
select: { user: true },
|
|
11
|
-
});
|
|
12
|
-
|
|
13
|
-
if (!token || !token.user) {
|
|
14
|
-
throw new Error('Token not found');
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
return {
|
|
18
|
-
firstName: token.user.firstName,
|
|
19
|
-
};
|
|
20
|
-
}
|
|
21
|
-
}
|
|
1
|
+
import { PrismaClient } from '@prisma/client';
|
|
2
|
+
import type { ContextGenerator } from 'vintasend/src/services/notification-context-registry';
|
|
3
|
+
|
|
4
|
+
export class ForgotPasswordContextGenerator implements ContextGenerator {
|
|
5
|
+
async generate(params: { token: string }): Promise<{ firstName: string | null }> {
|
|
6
|
+
const prisma = new PrismaClient();
|
|
7
|
+
|
|
8
|
+
const token = await prisma.token.findUnique({
|
|
9
|
+
where: { token: params.token },
|
|
10
|
+
select: { user: true },
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
if (!token || !token.user) {
|
|
14
|
+
throw new Error('Token not found');
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
return {
|
|
18
|
+
firstName: token.user.firstName,
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
}
|
package/src/examples/nextjs-prisma-nodemailer-pug-temporal/src/lib/services/notifications.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { PrismaClient } from '@prisma/client';
|
|
2
|
-
import { NotificationService } from 'vintasend/services/notification-service';
|
|
3
|
-
import { NotificationContextRegistry } from 'vintasend/services/notification-context-registry';
|
|
2
|
+
import { NotificationService } from 'vintasend/src/services/notification-service';
|
|
3
|
+
import { NotificationContextRegistry } from 'vintasend/src/services/notification-context-registry';
|
|
4
4
|
import { PrismaNotificationBackend } from 'vintasend-prisma/prisma-notification-backend';
|
|
5
5
|
import { PugEmailTemplateRenderer } from 'vintasend-pug/pug-email-template-renderer';
|
|
6
6
|
import { NodemailerNotificationAdapter } from 'vintasend-nodemailer/nodemailer-notification-adapter';
|
|
@@ -21,7 +21,7 @@ export function getNotificationService() {
|
|
|
21
21
|
number,
|
|
22
22
|
number
|
|
23
23
|
>(prisma);
|
|
24
|
-
return new NotificationService<ContextMap>(
|
|
24
|
+
return new NotificationService<ContextMap, number, number>(
|
|
25
25
|
[new NodemailerNotificationAdapter<
|
|
26
26
|
PugEmailTemplateRenderer<ContextMap>,
|
|
27
27
|
PrismaNotificationBackend<
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import type { Client } from '@temporalio/client';
|
|
2
2
|
import { sendNotificationWorkflow } from "@/workers/notifications/workflows";
|
|
3
|
-
import type { BaseNotificationQueueService } from "vintasend/services/notification-queue-service/base-notification-queue-service";
|
|
3
|
+
import type { BaseNotificationQueueService } from "vintasend/src/services/notification-queue-service/base-notification-queue-service";
|
|
4
4
|
|
|
5
|
-
export class TemporalQueueService<NotificationIdType> implements BaseNotificationQueueService {
|
|
5
|
+
export class TemporalQueueService<NotificationIdType> implements BaseNotificationQueueService<NotificationIdType> {
|
|
6
6
|
constructor(private client: Client, private taskQueue: string, ) {}
|
|
7
7
|
|
|
8
8
|
async enqueueNotification(notificationId: NotificationIdType): Promise<void> {
|
package/src/examples/nextjs-prisma-nodemailer-pug-temporal/src/workers/notifications/activities.ts
CHANGED
|
@@ -1,19 +1,20 @@
|
|
|
1
|
-
import type { Notification } from 'vintasend/types/notification'
|
|
1
|
+
import type { Notification } from 'vintasend/src/types/notification'
|
|
2
2
|
|
|
3
3
|
import { type ContextMap, getNotificationService } from '@/lib/services/notifications';
|
|
4
4
|
|
|
5
|
+
type NotificationIdType = Parameters<ReturnType<typeof getNotificationService>['getNotification']>[0];
|
|
5
6
|
|
|
6
|
-
export async function sendNotification
|
|
7
|
-
const
|
|
7
|
+
export async function sendNotification(notificationId: NotificationIdType): Promise<void> {
|
|
8
|
+
const notificationService = getNotificationService();
|
|
8
9
|
|
|
9
10
|
if (!notificationId) {
|
|
10
11
|
throw new Error("Notification ID is required");
|
|
11
12
|
}
|
|
12
13
|
|
|
13
|
-
await
|
|
14
|
+
await notificationService.delayedSend(notificationId);
|
|
14
15
|
};
|
|
15
16
|
|
|
16
|
-
export const getAllPendingNotifications = async (): Promise<
|
|
17
|
+
export const getAllPendingNotifications = async (): Promise<NotificationIdType[]> => {
|
|
17
18
|
const notificationServices = getNotificationService();
|
|
18
19
|
const pendingNotifications = await notificationServices.getPendingNotifications();
|
|
19
20
|
return pendingNotifications.map((notification) => notification.id);
|
package/src/examples/nextjs-prisma-nodemailer-pug-temporal/src/workers/notifications/workflows.ts
CHANGED
|
@@ -1,13 +1,16 @@
|
|
|
1
1
|
import { proxyActivities } from '@temporalio/workflow';
|
|
2
2
|
import type { EmailActivities } from './activities';
|
|
3
|
+
import type { getNotificationService } from '@/lib/services/notifications';
|
|
3
4
|
|
|
4
5
|
// Configure activities with a timeout (adjust as needed)
|
|
5
6
|
const { sendNotification, getAllPendingNotifications } = proxyActivities<EmailActivities>({
|
|
6
7
|
startToCloseTimeout: '1 minute',
|
|
7
8
|
});
|
|
8
9
|
|
|
9
|
-
|
|
10
|
-
|
|
10
|
+
type NotificationIdType = Parameters<ReturnType<typeof getNotificationService>['getNotification']>[0];
|
|
11
|
+
|
|
12
|
+
export async function sendNotificationWorkflow(notificationId: NotificationIdType): Promise<void> {
|
|
13
|
+
await sendNotification(notificationId);
|
|
11
14
|
}
|
|
12
15
|
|
|
13
16
|
export async function sendAllPendingNotificationsWorkflow(): Promise<void> {
|
|
@@ -1,18 +1,29 @@
|
|
|
1
1
|
import nodemailer from 'nodemailer';
|
|
2
2
|
|
|
3
|
-
import type { BaseNotificationAdapter } from 'vintasend/services/notification-adapters/base-notification-adapter';
|
|
4
|
-
import type { BaseEmailTemplateRenderer } from 'vintasend/services/notification-template-renderers/base-email-template-renderer';
|
|
5
|
-
import type { BaseNotificationBackend } from 'vintasend/services/notification-backends/base-notification-backend';
|
|
6
|
-
import type { Notification } from 'vintasend/types/notification';
|
|
7
|
-
import type { JsonObject } from 'vintasend/types/json-values';
|
|
8
|
-
import type { NotificationType } from 'vintasend/types/notification-type';
|
|
9
|
-
import type { ContextGenerator } from 'vintasend/services/notification-context-registry';
|
|
3
|
+
import type { BaseNotificationAdapter } from 'vintasend/src/services/notification-adapters/base-notification-adapter';
|
|
4
|
+
import type { BaseEmailTemplateRenderer } from 'vintasend/src/services/notification-template-renderers/base-email-template-renderer';
|
|
5
|
+
import type { BaseNotificationBackend } from 'vintasend/src/services/notification-backends/base-notification-backend';
|
|
6
|
+
import type { Notification } from 'vintasend/src/types/notification';
|
|
7
|
+
import type { JsonObject } from 'vintasend/src/types/json-values';
|
|
8
|
+
import type { NotificationType } from 'vintasend/src/types/notification-type';
|
|
9
|
+
import type { ContextGenerator } from 'vintasend/src/services/notification-context-registry';
|
|
10
|
+
import type { Identifier } from 'vintasend/src/types/identifier';
|
|
10
11
|
|
|
11
12
|
export class NodemailerNotificationAdapter<
|
|
12
13
|
TemplateRenderer extends BaseEmailTemplateRenderer<AvailableContexts>,
|
|
13
14
|
Backend extends BaseNotificationBackend<AvailableContexts>,
|
|
14
|
-
AvailableContexts extends Record<string, ContextGenerator
|
|
15
|
-
|
|
15
|
+
AvailableContexts extends Record<string, ContextGenerator>,
|
|
16
|
+
NotificationIdType extends Identifier = Identifier,
|
|
17
|
+
UserIdType extends Identifier = Identifier,
|
|
18
|
+
> implements
|
|
19
|
+
BaseNotificationAdapter<
|
|
20
|
+
TemplateRenderer,
|
|
21
|
+
Backend,
|
|
22
|
+
AvailableContexts,
|
|
23
|
+
NotificationIdType,
|
|
24
|
+
UserIdType
|
|
25
|
+
>
|
|
26
|
+
{
|
|
16
27
|
private transporter: nodemailer.Transporter;
|
|
17
28
|
public readonly notificationType: NotificationType = 'EMAIL';
|
|
18
29
|
public readonly key = 'nodemailer';
|
|
@@ -21,19 +32,22 @@ export class NodemailerNotificationAdapter<
|
|
|
21
32
|
public templateRenderer: TemplateRenderer,
|
|
22
33
|
public backend: Backend,
|
|
23
34
|
public readonly enqueueNotifications: boolean,
|
|
24
|
-
transportOptions: nodemailer.SendMailOptions
|
|
35
|
+
transportOptions: nodemailer.SendMailOptions,
|
|
25
36
|
) {
|
|
26
37
|
this.transporter = nodemailer.createTransport(transportOptions);
|
|
27
38
|
}
|
|
28
39
|
|
|
29
|
-
async send(
|
|
40
|
+
async send(
|
|
41
|
+
notification: Notification<AvailableContexts, NotificationIdType, UserIdType>,
|
|
42
|
+
context: JsonObject,
|
|
43
|
+
): Promise<void> {
|
|
30
44
|
const template = await this.templateRenderer.render(notification, context);
|
|
31
45
|
|
|
32
46
|
if (!notification.id) {
|
|
33
47
|
throw new Error('Notification ID is required');
|
|
34
48
|
}
|
|
35
49
|
|
|
36
|
-
const userEmail = await this.backend.getUserEmailFromNotification(notification.id)
|
|
50
|
+
const userEmail = await this.backend.getUserEmailFromNotification(notification.id);
|
|
37
51
|
|
|
38
52
|
if (!userEmail) {
|
|
39
53
|
throw new Error('User email not found');
|
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
import type { BaseNotificationBackend } from 'vintasend/services/notification-backends/base-notification-backend';
|
|
2
|
-
import type { ContextGenerator } from 'vintasend/services/notification-context-registry';
|
|
3
|
-
import type { InputJsonValue, JsonValue } from 'vintasend/types/json-values';
|
|
4
|
-
import type { Notification, NotificationInput } from 'vintasend/types/notification';
|
|
5
|
-
import type { NotificationStatus } from 'vintasend/types/notification-status';
|
|
6
|
-
import type { NotificationType } from 'vintasend/types/notification-type';
|
|
1
|
+
import type { BaseNotificationBackend } from 'vintasend/src/services/notification-backends/base-notification-backend';
|
|
2
|
+
import type { ContextGenerator } from 'vintasend/src/services/notification-context-registry';
|
|
3
|
+
import type { InputJsonValue, JsonValue } from 'vintasend/src/types/json-values';
|
|
4
|
+
import type { Notification, NotificationInput } from 'vintasend/src/types/notification';
|
|
5
|
+
import type { NotificationStatus } from 'vintasend/src/types/notification-status';
|
|
6
|
+
import type { NotificationType } from 'vintasend/src/types/notification-type';
|
|
7
|
+
import type { Identifier } from 'vintasend/src/types/identifier';
|
|
7
8
|
|
|
8
9
|
export const NotificationStatusEnum = {
|
|
9
10
|
PENDING_SEND: 'PENDING_SEND',
|
|
@@ -145,8 +146,8 @@ function convertJsonValueToRecord(jsonValue: JsonValue): Record<string, string |
|
|
|
145
146
|
export class PrismaNotificationBackend<
|
|
146
147
|
Client extends NotificationPrismaClientInterface<NotificationIdType, UserIdType>,
|
|
147
148
|
AvailableContexts extends Record<string, ContextGenerator>,
|
|
148
|
-
NotificationIdType extends
|
|
149
|
-
UserIdType extends
|
|
149
|
+
NotificationIdType extends Identifier = Identifier,
|
|
150
|
+
UserIdType extends Identifier = Identifier,
|
|
150
151
|
> implements BaseNotificationBackend<AvailableContexts>
|
|
151
152
|
{
|
|
152
153
|
constructor(private prismaClient: Client) {}
|
|
@@ -1,20 +1,24 @@
|
|
|
1
|
-
import type { ContextGenerator } from 'vintasend/services/notification-context-registry';
|
|
1
|
+
import type { ContextGenerator } from 'vintasend/src/services/notification-context-registry';
|
|
2
2
|
import type {
|
|
3
3
|
BaseEmailTemplateRenderer,
|
|
4
4
|
EmailTemplate,
|
|
5
|
-
} from 'vintasend/services/notification-template-renderers/base-email-template-renderer';
|
|
6
|
-
import type { JsonObject } from 'vintasend/types/json-values';
|
|
7
|
-
import type { Notification } from 'vintasend/types/notification';
|
|
5
|
+
} from 'vintasend/src/services/notification-template-renderers/base-email-template-renderer';
|
|
6
|
+
import type { JsonObject } from 'vintasend/src/types/json-values';
|
|
7
|
+
import type { Notification } from 'vintasend/src/types/notification';
|
|
8
|
+
import type { Identifier } from 'vintasend/src/types/identifier';
|
|
8
9
|
|
|
9
10
|
import pug from 'pug';
|
|
10
11
|
|
|
11
|
-
export class PugEmailTemplateRenderer<
|
|
12
|
-
|
|
12
|
+
export class PugEmailTemplateRenderer<
|
|
13
|
+
AvailableContexts extends Record<string, ContextGenerator>,
|
|
14
|
+
NotificationIdType extends Identifier = Identifier,
|
|
15
|
+
UserIdType extends Identifier = Identifier,
|
|
16
|
+
> implements BaseEmailTemplateRenderer<AvailableContexts, NotificationIdType, UserIdType>
|
|
13
17
|
{
|
|
14
18
|
constructor(private options: pug.Options = {}) {}
|
|
15
19
|
|
|
16
20
|
render(
|
|
17
|
-
notification: Notification<AvailableContexts>,
|
|
21
|
+
notification: Notification<AvailableContexts, NotificationIdType, UserIdType>,
|
|
18
22
|
context: JsonObject,
|
|
19
23
|
): Promise<EmailTemplate> {
|
|
20
24
|
const bodyTemplate = pug.compileFile(notification.bodyTemplate, this.options);
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"name": "vintasend-
|
|
2
|
+
"name": "vintasend-winston",
|
|
3
3
|
"version": "0.1.0",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "index.js",
|
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
"license": "ISC",
|
|
11
11
|
"dependencies": {
|
|
12
12
|
"jsonwebtoken": "^9.0.2",
|
|
13
|
+
"vintasend": "^0.1.0",
|
|
13
14
|
"winston": "^3.17.0"
|
|
14
15
|
}
|
|
15
16
|
}
|
|
@@ -4,11 +4,14 @@ import type { BaseNotificationBackend } from '../notification-backends/base-noti
|
|
|
4
4
|
import type { BaseNotificationTemplateRenderer } from '../notification-template-renderers/base-notification-template-renderer';
|
|
5
5
|
import type { ContextGenerator } from '../notification-context-registry';
|
|
6
6
|
import type { JsonValue } from '../../types/json-values';
|
|
7
|
+
import type { Identifier } from '../../types/identifier';
|
|
7
8
|
|
|
8
9
|
export interface BaseNotificationAdapter<
|
|
9
10
|
TemplateRenderer extends BaseNotificationTemplateRenderer<AvailableContexts>,
|
|
10
11
|
Backend extends BaseNotificationBackend<AvailableContexts>,
|
|
11
|
-
AvailableContexts extends Record<string, ContextGenerator
|
|
12
|
+
AvailableContexts extends Record<string, ContextGenerator>,
|
|
13
|
+
NotificationIdType extends Identifier = Identifier,
|
|
14
|
+
UserIdType extends Identifier = Identifier,
|
|
12
15
|
> {
|
|
13
16
|
notificationType: NotificationType;
|
|
14
17
|
key: string;
|
|
@@ -16,5 +19,8 @@ export interface BaseNotificationAdapter<
|
|
|
16
19
|
backend: Backend;
|
|
17
20
|
enqueueNotifications: boolean;
|
|
18
21
|
|
|
19
|
-
send(
|
|
22
|
+
send(
|
|
23
|
+
notification: Notification<AvailableContexts, NotificationIdType, UserIdType>,
|
|
24
|
+
context: JsonValue,
|
|
25
|
+
): Promise<void>;
|
|
20
26
|
}
|
|
@@ -3,38 +3,42 @@ import type { Identifier } from '../../types/identifier';
|
|
|
3
3
|
import type { Notification } from '../../types/notification';
|
|
4
4
|
import type { ContextGenerator } from '../notification-context-registry';
|
|
5
5
|
|
|
6
|
-
export interface BaseNotificationBackend<
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
6
|
+
export interface BaseNotificationBackend<
|
|
7
|
+
AvailableContexts extends Record<string, ContextGenerator>,
|
|
8
|
+
NotificationIdType extends Identifier = Identifier,
|
|
9
|
+
UserIdType extends Identifier = Identifier,
|
|
10
|
+
> {
|
|
11
|
+
getAllPendingNotifications(): Promise<Notification<AvailableContexts, NotificationIdType, UserIdType>[]>;
|
|
12
|
+
getPendingNotifications(): Promise<Notification<AvailableContexts, NotificationIdType, UserIdType>[]>;
|
|
13
|
+
getAllFutureNotifications(): Promise<Notification<AvailableContexts, NotificationIdType, UserIdType>[]>;
|
|
14
|
+
getFutureNotifications(): Promise<Notification<AvailableContexts, NotificationIdType, UserIdType>[]>;
|
|
11
15
|
getAllFutureNotificationsFromUser(
|
|
12
16
|
userId: Identifier,
|
|
13
|
-
): Promise<Notification<AvailableContexts>[]>;
|
|
14
|
-
getFutureNotificationsFromUser(userId: Identifier): Promise<Notification<AvailableContexts>[]>;
|
|
17
|
+
): Promise<Notification<AvailableContexts, NotificationIdType, UserIdType>[]>;
|
|
18
|
+
getFutureNotificationsFromUser(userId: Identifier): Promise<Notification<AvailableContexts, NotificationIdType, UserIdType>[]>;
|
|
15
19
|
persistNotification(
|
|
16
|
-
notification: Omit<Notification<AvailableContexts>, 'id'>,
|
|
17
|
-
): Promise<Notification<AvailableContexts>>;
|
|
20
|
+
notification: Omit<Notification<AvailableContexts, NotificationIdType, UserIdType>, 'id'>,
|
|
21
|
+
): Promise<Notification<AvailableContexts, NotificationIdType, UserIdType>>;
|
|
18
22
|
persistNotificationUpdate(
|
|
19
23
|
notificationId: Identifier,
|
|
20
|
-
notification: Partial<Omit<Notification<AvailableContexts>, 'id'>>,
|
|
21
|
-
): Promise<Notification<AvailableContexts>>;
|
|
22
|
-
markPendingAsSent(notificationId: Identifier): Promise<Notification<AvailableContexts>>;
|
|
23
|
-
markPendingAsFailed(notificationId: Identifier): Promise<Notification<AvailableContexts>>;
|
|
24
|
-
markSentAsRead(notificationId: Identifier): Promise<Notification<AvailableContexts>>;
|
|
24
|
+
notification: Partial<Omit<Notification<AvailableContexts, NotificationIdType, UserIdType>, 'id'>>,
|
|
25
|
+
): Promise<Notification<AvailableContexts, NotificationIdType, UserIdType>>;
|
|
26
|
+
markPendingAsSent(notificationId: Identifier): Promise<Notification<AvailableContexts, NotificationIdType, UserIdType>>;
|
|
27
|
+
markPendingAsFailed(notificationId: Identifier): Promise<Notification<AvailableContexts, NotificationIdType, UserIdType>>;
|
|
28
|
+
markSentAsRead(notificationId: Identifier): Promise<Notification<AvailableContexts, NotificationIdType, UserIdType>>;
|
|
25
29
|
cancelNotification(notificationId: Identifier): Promise<void>;
|
|
26
30
|
getNotification(
|
|
27
31
|
notificationId: Identifier,
|
|
28
32
|
forUpdate: boolean,
|
|
29
|
-
): Promise<Notification<AvailableContexts> | null>;
|
|
33
|
+
): Promise<Notification<AvailableContexts, NotificationIdType, UserIdType> | null>;
|
|
30
34
|
filterAllInAppUnreadNotifications(
|
|
31
35
|
userId: Identifier,
|
|
32
|
-
): Promise<Notification<AvailableContexts>[]>;
|
|
36
|
+
): Promise<Notification<AvailableContexts, NotificationIdType, UserIdType>[]>;
|
|
33
37
|
filterInAppUnreadNotifications(
|
|
34
38
|
userId: Identifier,
|
|
35
39
|
page: number,
|
|
36
40
|
pageSize: number,
|
|
37
|
-
): Promise<Notification<AvailableContexts>[]>;
|
|
41
|
+
): Promise<Notification<AvailableContexts, NotificationIdType, UserIdType>[]>;
|
|
38
42
|
getUserEmailFromNotification(notificationId: Identifier): Promise<string | undefined>;
|
|
39
43
|
storeContextUsed(
|
|
40
44
|
notificationId: Identifier,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type { Identifier } from
|
|
1
|
+
import type { Identifier } from '../../types/identifier';
|
|
2
2
|
|
|
3
|
-
export interface BaseNotificationQueueService {
|
|
4
|
-
enqueueNotification(notificationId:
|
|
3
|
+
export interface BaseNotificationQueueService<NotificationIdType extends Identifier = Identifier> {
|
|
4
|
+
enqueueNotification(notificationId: NotificationIdType): Promise<void>;
|
|
5
5
|
}
|
|
@@ -9,25 +9,33 @@ import {
|
|
|
9
9
|
type ContextGenerator,
|
|
10
10
|
NotificationContextRegistry,
|
|
11
11
|
} from './notification-context-registry';
|
|
12
|
-
import type { JsonObject
|
|
12
|
+
import type { JsonObject } from '../types/json-values';
|
|
13
13
|
|
|
14
|
-
export class NotificationService<
|
|
14
|
+
export class NotificationService<
|
|
15
|
+
AvailableContexts extends Record<string, ContextGenerator>,
|
|
16
|
+
NotificationIdType extends Identifier = Identifier,
|
|
17
|
+
UserIdType extends Identifier = Identifier,
|
|
18
|
+
> {
|
|
15
19
|
constructor(
|
|
16
20
|
private adapters: BaseNotificationAdapter<
|
|
17
|
-
BaseNotificationTemplateRenderer<AvailableContexts>,
|
|
18
|
-
BaseNotificationBackend<AvailableContexts>,
|
|
19
|
-
AvailableContexts
|
|
21
|
+
BaseNotificationTemplateRenderer<AvailableContexts, NotificationIdType, UserIdType>,
|
|
22
|
+
BaseNotificationBackend<AvailableContexts, NotificationIdType, UserIdType>,
|
|
23
|
+
AvailableContexts,
|
|
24
|
+
NotificationIdType,
|
|
25
|
+
UserIdType
|
|
20
26
|
>[],
|
|
21
27
|
private backend: BaseNotificationBackend<AvailableContexts>,
|
|
22
28
|
private logger: BaseLogger,
|
|
23
|
-
private queueService?: BaseNotificationQueueService
|
|
29
|
+
private queueService?: BaseNotificationQueueService<NotificationIdType>,
|
|
24
30
|
) {}
|
|
25
31
|
|
|
26
|
-
registerQueueService(queueService: BaseNotificationQueueService): void {
|
|
32
|
+
registerQueueService(queueService: BaseNotificationQueueService<NotificationIdType>): void {
|
|
27
33
|
this.queueService = queueService;
|
|
28
34
|
}
|
|
29
35
|
|
|
30
|
-
async send(
|
|
36
|
+
async send(
|
|
37
|
+
notification: Notification<AvailableContexts, NotificationIdType, UserIdType>,
|
|
38
|
+
): Promise<void> {
|
|
31
39
|
const adaptersOfType = this.adapters.filter(
|
|
32
40
|
(adapter) => adapter.notificationType === notification.notificationType,
|
|
33
41
|
);
|
|
@@ -85,9 +93,9 @@ export class NotificationService<AvailableContexts extends Record<string, Contex
|
|
|
85
93
|
}
|
|
86
94
|
|
|
87
95
|
async createNotification(
|
|
88
|
-
notification: Omit<Notification<AvailableContexts>, 'id'>,
|
|
89
|
-
): Promise<Notification<AvailableContexts>> {
|
|
90
|
-
const createdNotification = await this.backend.persistNotification(notification)
|
|
96
|
+
notification: Omit<Notification<AvailableContexts, NotificationIdType, UserIdType>, 'id'>,
|
|
97
|
+
): Promise<Notification<AvailableContexts, NotificationIdType, UserIdType>> {
|
|
98
|
+
const createdNotification = await this.backend.persistNotification(notification) as Notification<AvailableContexts, NotificationIdType, UserIdType>;
|
|
91
99
|
|
|
92
100
|
if (notification.sendAfter && notification.sendAfter > new Date()) {
|
|
93
101
|
this.send(createdNotification);
|
|
@@ -98,28 +106,26 @@ export class NotificationService<AvailableContexts extends Record<string, Contex
|
|
|
98
106
|
|
|
99
107
|
async updateNotification(
|
|
100
108
|
notificationId: Identifier,
|
|
101
|
-
notification: Partial<
|
|
102
|
-
|
|
109
|
+
notification: Partial<
|
|
110
|
+
Omit<Notification<AvailableContexts, NotificationIdType, UserIdType>, 'id'>
|
|
111
|
+
>,
|
|
112
|
+
) {
|
|
103
113
|
return this.backend.persistNotificationUpdate(notificationId, notification);
|
|
104
114
|
}
|
|
105
115
|
|
|
106
|
-
async getAllFutureNotifications()
|
|
116
|
+
async getAllFutureNotifications() {
|
|
107
117
|
return this.backend.getAllFutureNotifications();
|
|
108
118
|
}
|
|
109
119
|
|
|
110
|
-
async getAllFutureNotificationsFromUser(
|
|
111
|
-
userId: Identifier,
|
|
112
|
-
): Promise<Notification<AvailableContexts>[]> {
|
|
120
|
+
async getAllFutureNotificationsFromUser(userId: NotificationIdType) {
|
|
113
121
|
return this.backend.getAllFutureNotificationsFromUser(userId);
|
|
114
122
|
}
|
|
115
123
|
|
|
116
|
-
async getFutureNotificationsFromUser(
|
|
117
|
-
userId: Identifier,
|
|
118
|
-
): Promise<Notification<AvailableContexts>[]> {
|
|
124
|
+
async getFutureNotificationsFromUser(userId: NotificationIdType) {
|
|
119
125
|
return this.backend.getFutureNotificationsFromUser(userId);
|
|
120
126
|
}
|
|
121
127
|
|
|
122
|
-
async getFutureNotifications()
|
|
128
|
+
async getFutureNotifications() {
|
|
123
129
|
return this.backend.getFutureNotifications();
|
|
124
130
|
}
|
|
125
131
|
|
|
@@ -132,33 +138,34 @@ export class NotificationService<AvailableContexts extends Record<string, Contex
|
|
|
132
138
|
|
|
133
139
|
async sendPendingNotifications(): Promise<void> {
|
|
134
140
|
const pendingNotifications = await this.backend.getAllPendingNotifications();
|
|
135
|
-
await Promise.all(
|
|
141
|
+
await Promise.all(
|
|
142
|
+
pendingNotifications.map((notification) =>
|
|
143
|
+
this.send(notification as Notification<AvailableContexts, NotificationIdType, UserIdType>),
|
|
144
|
+
),
|
|
145
|
+
);
|
|
136
146
|
}
|
|
137
147
|
|
|
138
|
-
async getPendingNotifications()
|
|
148
|
+
async getPendingNotifications() {
|
|
139
149
|
return this.backend.getPendingNotifications();
|
|
140
150
|
}
|
|
141
151
|
|
|
142
|
-
async getNotification(
|
|
143
|
-
notificationId: Identifier,
|
|
144
|
-
forUpdate: boolean,
|
|
145
|
-
): Promise<Notification<AvailableContexts> | null> {
|
|
152
|
+
async getNotification(notificationId: NotificationIdType, forUpdate: boolean) {
|
|
146
153
|
return this.backend.getNotification(notificationId, forUpdate);
|
|
147
154
|
}
|
|
148
155
|
|
|
149
|
-
async markRead(notificationId:
|
|
156
|
+
async markRead(notificationId: NotificationIdType) {
|
|
150
157
|
return this.backend.markSentAsRead(notificationId);
|
|
151
158
|
}
|
|
152
159
|
|
|
153
|
-
async getInAppUnread(userId:
|
|
160
|
+
async getInAppUnread(userId: NotificationIdType) {
|
|
154
161
|
return this.backend.filterAllInAppUnreadNotifications(userId);
|
|
155
162
|
}
|
|
156
163
|
|
|
157
|
-
async cancelNotification(notificationId:
|
|
164
|
+
async cancelNotification(notificationId: NotificationIdType): Promise<void> {
|
|
158
165
|
return this.backend.cancelNotification(notificationId);
|
|
159
166
|
}
|
|
160
167
|
|
|
161
|
-
async delayedSend(notificationId:
|
|
168
|
+
async delayedSend(notificationId: NotificationIdType): Promise<void> {
|
|
162
169
|
const notification = await this.getNotification(notificationId, false);
|
|
163
170
|
|
|
164
171
|
if (!notification) {
|
|
@@ -189,7 +196,7 @@ export class NotificationService<AvailableContexts extends Record<string, Contex
|
|
|
189
196
|
|
|
190
197
|
for (const adapter of enqueueNotificationsAdapters) {
|
|
191
198
|
try {
|
|
192
|
-
await adapter.send(notification, context);
|
|
199
|
+
await adapter.send(notification as Notification<AvailableContexts, NotificationIdType, UserIdType>, context);
|
|
193
200
|
} catch (sendError) {
|
|
194
201
|
this.logger.error(
|
|
195
202
|
`Error sending notification ${notification.id} with adapter ${adapter.constructor.name}: ${sendError}`,
|
|
@@ -3,6 +3,7 @@ import type { Notification } from '../../types/notification';
|
|
|
3
3
|
import type { Buffer } from 'node:buffer';
|
|
4
4
|
import type { ContextGenerator } from '../notification-context-registry';
|
|
5
5
|
import type { JsonObject } from '../../types/json-values';
|
|
6
|
+
import type { Identifier } from '../../types/identifier';
|
|
6
7
|
|
|
7
8
|
export type Attachment = File | Buffer | string;
|
|
8
9
|
|
|
@@ -11,10 +12,18 @@ export type EmailTemplate = {
|
|
|
11
12
|
body: string;
|
|
12
13
|
};
|
|
13
14
|
|
|
14
|
-
export interface BaseEmailTemplateRenderer<
|
|
15
|
-
extends
|
|
15
|
+
export interface BaseEmailTemplateRenderer<
|
|
16
|
+
AvailableContexts extends Record<string, ContextGenerator>,
|
|
17
|
+
NotificationIdType extends Identifier = Identifier,
|
|
18
|
+
UserIdType extends Identifier = Identifier,
|
|
19
|
+
> extends BaseNotificationTemplateRenderer<
|
|
20
|
+
AvailableContexts,
|
|
21
|
+
NotificationIdType,
|
|
22
|
+
UserIdType,
|
|
23
|
+
EmailTemplate
|
|
24
|
+
> {
|
|
16
25
|
render(
|
|
17
|
-
notification: Notification<AvailableContexts>,
|
|
18
|
-
context: JsonObject
|
|
26
|
+
notification: Notification<AvailableContexts, NotificationIdType, UserIdType>,
|
|
27
|
+
context: JsonObject,
|
|
19
28
|
): Promise<EmailTemplate>;
|
|
20
29
|
}
|
|
@@ -1,7 +1,16 @@
|
|
|
1
|
+
import type { Identifier } from '../../types/identifier';
|
|
1
2
|
import type { JsonObject } from '../../types/json-values';
|
|
2
3
|
import type { Notification } from '../../types/notification';
|
|
3
4
|
import type { ContextGenerator } from '../notification-context-registry';
|
|
4
5
|
|
|
5
|
-
export interface BaseNotificationTemplateRenderer<
|
|
6
|
-
|
|
6
|
+
export interface BaseNotificationTemplateRenderer<
|
|
7
|
+
AvailableContexts extends Record<string, ContextGenerator>,
|
|
8
|
+
NotificationIdType extends Identifier = Identifier,
|
|
9
|
+
UserIdType extends Identifier = Identifier,
|
|
10
|
+
T = unknown,
|
|
11
|
+
> {
|
|
12
|
+
render(
|
|
13
|
+
notification: Notification<AvailableContexts, NotificationIdType, UserIdType>,
|
|
14
|
+
context: JsonObject,
|
|
15
|
+
): Promise<T>;
|
|
7
16
|
}
|