@bernierllc/email-webhook-events 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.
- package/.eslintrc.cjs +29 -0
- package/README.md +349 -0
- package/__tests__/EmailWebhookEventsService.test.ts +247 -0
- package/__tests__/analytics/AnalyticsEngine.test.ts +244 -0
- package/__tests__/normalizers/MailgunNormalizer.test.ts +149 -0
- package/__tests__/normalizers/PostmarkNormalizer.test.ts +112 -0
- package/__tests__/normalizers/SESNormalizer.test.ts +168 -0
- package/__tests__/normalizers/SMTP2GONormalizer.test.ts +83 -0
- package/__tests__/normalizers/SendGridNormalizer.test.ts +181 -0
- package/__tests__/persistence/PersistenceAdapter.test.ts +103 -0
- package/coverage/clover.xml +328 -0
- package/coverage/coverage-final.json +10 -0
- package/coverage/lcov-report/base.css +224 -0
- package/coverage/lcov-report/block-navigation.js +87 -0
- package/coverage/lcov-report/favicon.png +0 -0
- package/coverage/lcov-report/index.html +161 -0
- package/coverage/lcov-report/prettify.css +1 -0
- package/coverage/lcov-report/prettify.js +2 -0
- package/coverage/lcov-report/sort-arrow-sprite.png +0 -0
- package/coverage/lcov-report/sorter.js +210 -0
- package/coverage/lcov-report/src/EmailWebhookEventsService.ts.html +826 -0
- package/coverage/lcov-report/src/analytics/AnalyticsEngine.ts.html +775 -0
- package/coverage/lcov-report/src/analytics/index.html +116 -0
- package/coverage/lcov-report/src/index.html +131 -0
- package/coverage/lcov-report/src/normalizers/MailgunNormalizer.ts.html +301 -0
- package/coverage/lcov-report/src/normalizers/PostmarkNormalizer.ts.html +301 -0
- package/coverage/lcov-report/src/normalizers/SESNormalizer.ts.html +436 -0
- package/coverage/lcov-report/src/normalizers/SMTP2GONormalizer.ts.html +247 -0
- package/coverage/lcov-report/src/normalizers/SendGridNormalizer.ts.html +274 -0
- package/coverage/lcov-report/src/normalizers/index.html +176 -0
- package/coverage/lcov-report/src/persistence/InMemoryPersistenceAdapter.ts.html +289 -0
- package/coverage/lcov-report/src/persistence/index.html +116 -0
- package/coverage/lcov-report/src/types.ts.html +823 -0
- package/coverage/lcov.info +710 -0
- package/dist/EmailWebhookEventsService.d.ts +53 -0
- package/dist/EmailWebhookEventsService.d.ts.map +1 -0
- package/dist/EmailWebhookEventsService.js +198 -0
- package/dist/EmailWebhookEventsService.js.map +1 -0
- package/dist/analytics/AnalyticsEngine.d.ts +20 -0
- package/dist/analytics/AnalyticsEngine.d.ts.map +1 -0
- package/dist/analytics/AnalyticsEngine.js +160 -0
- package/dist/analytics/AnalyticsEngine.js.map +1 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +31 -0
- package/dist/index.js.map +1 -0
- package/dist/normalizers/EventNormalizer.d.ts +5 -0
- package/dist/normalizers/EventNormalizer.d.ts.map +1 -0
- package/dist/normalizers/EventNormalizer.js +10 -0
- package/dist/normalizers/EventNormalizer.js.map +1 -0
- package/dist/normalizers/MailgunNormalizer.d.ts +9 -0
- package/dist/normalizers/MailgunNormalizer.d.ts.map +1 -0
- package/dist/normalizers/MailgunNormalizer.js +73 -0
- package/dist/normalizers/MailgunNormalizer.js.map +1 -0
- package/dist/normalizers/PostmarkNormalizer.d.ts +10 -0
- package/dist/normalizers/PostmarkNormalizer.d.ts.map +1 -0
- package/dist/normalizers/PostmarkNormalizer.js +75 -0
- package/dist/normalizers/PostmarkNormalizer.js.map +1 -0
- package/dist/normalizers/SESNormalizer.d.ts +16 -0
- package/dist/normalizers/SESNormalizer.d.ts.map +1 -0
- package/dist/normalizers/SESNormalizer.js +107 -0
- package/dist/normalizers/SESNormalizer.js.map +1 -0
- package/dist/normalizers/SMTP2GONormalizer.d.ts +9 -0
- package/dist/normalizers/SMTP2GONormalizer.d.ts.map +1 -0
- package/dist/normalizers/SMTP2GONormalizer.js +55 -0
- package/dist/normalizers/SMTP2GONormalizer.js.map +1 -0
- package/dist/normalizers/SendGridNormalizer.d.ts +9 -0
- package/dist/normalizers/SendGridNormalizer.d.ts.map +1 -0
- package/dist/normalizers/SendGridNormalizer.js +64 -0
- package/dist/normalizers/SendGridNormalizer.js.map +1 -0
- package/dist/persistence/InMemoryPersistenceAdapter.d.ts +12 -0
- package/dist/persistence/InMemoryPersistenceAdapter.d.ts.map +1 -0
- package/dist/persistence/InMemoryPersistenceAdapter.js +58 -0
- package/dist/persistence/InMemoryPersistenceAdapter.js.map +1 -0
- package/dist/persistence/PersistenceAdapter.d.ts +7 -0
- package/dist/persistence/PersistenceAdapter.d.ts.map +1 -0
- package/dist/persistence/PersistenceAdapter.js +10 -0
- package/dist/persistence/PersistenceAdapter.js.map +1 -0
- package/dist/types.d.ts +178 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +41 -0
- package/dist/types.js.map +1 -0
- package/jest.config.cjs +29 -0
- package/package.json +51 -0
- package/src/EmailWebhookEventsService.ts +247 -0
- package/src/analytics/AnalyticsEngine.ts +230 -0
- package/src/index.ts +39 -0
- package/src/normalizers/EventNormalizer.ts +13 -0
- package/src/normalizers/MailgunNormalizer.ts +72 -0
- package/src/normalizers/PostmarkNormalizer.ts +72 -0
- package/src/normalizers/SESNormalizer.ts +117 -0
- package/src/normalizers/SMTP2GONormalizer.ts +54 -0
- package/src/normalizers/SendGridNormalizer.ts +63 -0
- package/src/persistence/InMemoryPersistenceAdapter.ts +68 -0
- package/src/persistence/PersistenceAdapter.ts +15 -0
- package/src/types.ts +246 -0
- package/tsconfig.json +31 -0
|
@@ -0,0 +1,436 @@
|
|
|
1
|
+
|
|
2
|
+
<!doctype html>
|
|
3
|
+
<html lang="en">
|
|
4
|
+
|
|
5
|
+
<head>
|
|
6
|
+
<title>Code coverage report for src/normalizers/SESNormalizer.ts</title>
|
|
7
|
+
<meta charset="utf-8" />
|
|
8
|
+
<link rel="stylesheet" href="../../prettify.css" />
|
|
9
|
+
<link rel="stylesheet" href="../../base.css" />
|
|
10
|
+
<link rel="shortcut icon" type="image/x-icon" href="../../favicon.png" />
|
|
11
|
+
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
12
|
+
<style type='text/css'>
|
|
13
|
+
.coverage-summary .sorter {
|
|
14
|
+
background-image: url(../../sort-arrow-sprite.png);
|
|
15
|
+
}
|
|
16
|
+
</style>
|
|
17
|
+
</head>
|
|
18
|
+
|
|
19
|
+
<body>
|
|
20
|
+
<div class='wrapper'>
|
|
21
|
+
<div class='pad1'>
|
|
22
|
+
<h1><a href="../../index.html">All files</a> / <a href="index.html">src/normalizers</a> SESNormalizer.ts</h1>
|
|
23
|
+
<div class='clearfix'>
|
|
24
|
+
|
|
25
|
+
<div class='fl pad1y space-right2'>
|
|
26
|
+
<span class="strong">100% </span>
|
|
27
|
+
<span class="quiet">Statements</span>
|
|
28
|
+
<span class='fraction'>44/44</span>
|
|
29
|
+
</div>
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
<div class='fl pad1y space-right2'>
|
|
33
|
+
<span class="strong">80% </span>
|
|
34
|
+
<span class="quiet">Branches</span>
|
|
35
|
+
<span class='fraction'>16/20</span>
|
|
36
|
+
</div>
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
<div class='fl pad1y space-right2'>
|
|
40
|
+
<span class="strong">100% </span>
|
|
41
|
+
<span class="quiet">Functions</span>
|
|
42
|
+
<span class='fraction'>11/11</span>
|
|
43
|
+
</div>
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
<div class='fl pad1y space-right2'>
|
|
47
|
+
<span class="strong">100% </span>
|
|
48
|
+
<span class="quiet">Lines</span>
|
|
49
|
+
<span class='fraction'>42/42</span>
|
|
50
|
+
</div>
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
</div>
|
|
54
|
+
<p class="quiet">
|
|
55
|
+
Press <em>n</em> or <em>j</em> to go to the next uncovered block, <em>b</em>, <em>p</em> or <em>k</em> for the previous block.
|
|
56
|
+
</p>
|
|
57
|
+
<template id="filterTemplate">
|
|
58
|
+
<div class="quiet">
|
|
59
|
+
Filter:
|
|
60
|
+
<input type="search" id="fileSearch">
|
|
61
|
+
</div>
|
|
62
|
+
</template>
|
|
63
|
+
</div>
|
|
64
|
+
<div class='status-line high'></div>
|
|
65
|
+
<pre><table class="coverage">
|
|
66
|
+
<tr><td class="line-count quiet"><a name='L1'></a><a href='#L1'>1</a>
|
|
67
|
+
<a name='L2'></a><a href='#L2'>2</a>
|
|
68
|
+
<a name='L3'></a><a href='#L3'>3</a>
|
|
69
|
+
<a name='L4'></a><a href='#L4'>4</a>
|
|
70
|
+
<a name='L5'></a><a href='#L5'>5</a>
|
|
71
|
+
<a name='L6'></a><a href='#L6'>6</a>
|
|
72
|
+
<a name='L7'></a><a href='#L7'>7</a>
|
|
73
|
+
<a name='L8'></a><a href='#L8'>8</a>
|
|
74
|
+
<a name='L9'></a><a href='#L9'>9</a>
|
|
75
|
+
<a name='L10'></a><a href='#L10'>10</a>
|
|
76
|
+
<a name='L11'></a><a href='#L11'>11</a>
|
|
77
|
+
<a name='L12'></a><a href='#L12'>12</a>
|
|
78
|
+
<a name='L13'></a><a href='#L13'>13</a>
|
|
79
|
+
<a name='L14'></a><a href='#L14'>14</a>
|
|
80
|
+
<a name='L15'></a><a href='#L15'>15</a>
|
|
81
|
+
<a name='L16'></a><a href='#L16'>16</a>
|
|
82
|
+
<a name='L17'></a><a href='#L17'>17</a>
|
|
83
|
+
<a name='L18'></a><a href='#L18'>18</a>
|
|
84
|
+
<a name='L19'></a><a href='#L19'>19</a>
|
|
85
|
+
<a name='L20'></a><a href='#L20'>20</a>
|
|
86
|
+
<a name='L21'></a><a href='#L21'>21</a>
|
|
87
|
+
<a name='L22'></a><a href='#L22'>22</a>
|
|
88
|
+
<a name='L23'></a><a href='#L23'>23</a>
|
|
89
|
+
<a name='L24'></a><a href='#L24'>24</a>
|
|
90
|
+
<a name='L25'></a><a href='#L25'>25</a>
|
|
91
|
+
<a name='L26'></a><a href='#L26'>26</a>
|
|
92
|
+
<a name='L27'></a><a href='#L27'>27</a>
|
|
93
|
+
<a name='L28'></a><a href='#L28'>28</a>
|
|
94
|
+
<a name='L29'></a><a href='#L29'>29</a>
|
|
95
|
+
<a name='L30'></a><a href='#L30'>30</a>
|
|
96
|
+
<a name='L31'></a><a href='#L31'>31</a>
|
|
97
|
+
<a name='L32'></a><a href='#L32'>32</a>
|
|
98
|
+
<a name='L33'></a><a href='#L33'>33</a>
|
|
99
|
+
<a name='L34'></a><a href='#L34'>34</a>
|
|
100
|
+
<a name='L35'></a><a href='#L35'>35</a>
|
|
101
|
+
<a name='L36'></a><a href='#L36'>36</a>
|
|
102
|
+
<a name='L37'></a><a href='#L37'>37</a>
|
|
103
|
+
<a name='L38'></a><a href='#L38'>38</a>
|
|
104
|
+
<a name='L39'></a><a href='#L39'>39</a>
|
|
105
|
+
<a name='L40'></a><a href='#L40'>40</a>
|
|
106
|
+
<a name='L41'></a><a href='#L41'>41</a>
|
|
107
|
+
<a name='L42'></a><a href='#L42'>42</a>
|
|
108
|
+
<a name='L43'></a><a href='#L43'>43</a>
|
|
109
|
+
<a name='L44'></a><a href='#L44'>44</a>
|
|
110
|
+
<a name='L45'></a><a href='#L45'>45</a>
|
|
111
|
+
<a name='L46'></a><a href='#L46'>46</a>
|
|
112
|
+
<a name='L47'></a><a href='#L47'>47</a>
|
|
113
|
+
<a name='L48'></a><a href='#L48'>48</a>
|
|
114
|
+
<a name='L49'></a><a href='#L49'>49</a>
|
|
115
|
+
<a name='L50'></a><a href='#L50'>50</a>
|
|
116
|
+
<a name='L51'></a><a href='#L51'>51</a>
|
|
117
|
+
<a name='L52'></a><a href='#L52'>52</a>
|
|
118
|
+
<a name='L53'></a><a href='#L53'>53</a>
|
|
119
|
+
<a name='L54'></a><a href='#L54'>54</a>
|
|
120
|
+
<a name='L55'></a><a href='#L55'>55</a>
|
|
121
|
+
<a name='L56'></a><a href='#L56'>56</a>
|
|
122
|
+
<a name='L57'></a><a href='#L57'>57</a>
|
|
123
|
+
<a name='L58'></a><a href='#L58'>58</a>
|
|
124
|
+
<a name='L59'></a><a href='#L59'>59</a>
|
|
125
|
+
<a name='L60'></a><a href='#L60'>60</a>
|
|
126
|
+
<a name='L61'></a><a href='#L61'>61</a>
|
|
127
|
+
<a name='L62'></a><a href='#L62'>62</a>
|
|
128
|
+
<a name='L63'></a><a href='#L63'>63</a>
|
|
129
|
+
<a name='L64'></a><a href='#L64'>64</a>
|
|
130
|
+
<a name='L65'></a><a href='#L65'>65</a>
|
|
131
|
+
<a name='L66'></a><a href='#L66'>66</a>
|
|
132
|
+
<a name='L67'></a><a href='#L67'>67</a>
|
|
133
|
+
<a name='L68'></a><a href='#L68'>68</a>
|
|
134
|
+
<a name='L69'></a><a href='#L69'>69</a>
|
|
135
|
+
<a name='L70'></a><a href='#L70'>70</a>
|
|
136
|
+
<a name='L71'></a><a href='#L71'>71</a>
|
|
137
|
+
<a name='L72'></a><a href='#L72'>72</a>
|
|
138
|
+
<a name='L73'></a><a href='#L73'>73</a>
|
|
139
|
+
<a name='L74'></a><a href='#L74'>74</a>
|
|
140
|
+
<a name='L75'></a><a href='#L75'>75</a>
|
|
141
|
+
<a name='L76'></a><a href='#L76'>76</a>
|
|
142
|
+
<a name='L77'></a><a href='#L77'>77</a>
|
|
143
|
+
<a name='L78'></a><a href='#L78'>78</a>
|
|
144
|
+
<a name='L79'></a><a href='#L79'>79</a>
|
|
145
|
+
<a name='L80'></a><a href='#L80'>80</a>
|
|
146
|
+
<a name='L81'></a><a href='#L81'>81</a>
|
|
147
|
+
<a name='L82'></a><a href='#L82'>82</a>
|
|
148
|
+
<a name='L83'></a><a href='#L83'>83</a>
|
|
149
|
+
<a name='L84'></a><a href='#L84'>84</a>
|
|
150
|
+
<a name='L85'></a><a href='#L85'>85</a>
|
|
151
|
+
<a name='L86'></a><a href='#L86'>86</a>
|
|
152
|
+
<a name='L87'></a><a href='#L87'>87</a>
|
|
153
|
+
<a name='L88'></a><a href='#L88'>88</a>
|
|
154
|
+
<a name='L89'></a><a href='#L89'>89</a>
|
|
155
|
+
<a name='L90'></a><a href='#L90'>90</a>
|
|
156
|
+
<a name='L91'></a><a href='#L91'>91</a>
|
|
157
|
+
<a name='L92'></a><a href='#L92'>92</a>
|
|
158
|
+
<a name='L93'></a><a href='#L93'>93</a>
|
|
159
|
+
<a name='L94'></a><a href='#L94'>94</a>
|
|
160
|
+
<a name='L95'></a><a href='#L95'>95</a>
|
|
161
|
+
<a name='L96'></a><a href='#L96'>96</a>
|
|
162
|
+
<a name='L97'></a><a href='#L97'>97</a>
|
|
163
|
+
<a name='L98'></a><a href='#L98'>98</a>
|
|
164
|
+
<a name='L99'></a><a href='#L99'>99</a>
|
|
165
|
+
<a name='L100'></a><a href='#L100'>100</a>
|
|
166
|
+
<a name='L101'></a><a href='#L101'>101</a>
|
|
167
|
+
<a name='L102'></a><a href='#L102'>102</a>
|
|
168
|
+
<a name='L103'></a><a href='#L103'>103</a>
|
|
169
|
+
<a name='L104'></a><a href='#L104'>104</a>
|
|
170
|
+
<a name='L105'></a><a href='#L105'>105</a>
|
|
171
|
+
<a name='L106'></a><a href='#L106'>106</a>
|
|
172
|
+
<a name='L107'></a><a href='#L107'>107</a>
|
|
173
|
+
<a name='L108'></a><a href='#L108'>108</a>
|
|
174
|
+
<a name='L109'></a><a href='#L109'>109</a>
|
|
175
|
+
<a name='L110'></a><a href='#L110'>110</a>
|
|
176
|
+
<a name='L111'></a><a href='#L111'>111</a>
|
|
177
|
+
<a name='L112'></a><a href='#L112'>112</a>
|
|
178
|
+
<a name='L113'></a><a href='#L113'>113</a>
|
|
179
|
+
<a name='L114'></a><a href='#L114'>114</a>
|
|
180
|
+
<a name='L115'></a><a href='#L115'>115</a>
|
|
181
|
+
<a name='L116'></a><a href='#L116'>116</a>
|
|
182
|
+
<a name='L117'></a><a href='#L117'>117</a>
|
|
183
|
+
<a name='L118'></a><a href='#L118'>118</a></td><td class="line-coverage quiet"><span class="cline-any cline-neutral"> </span>
|
|
184
|
+
<span class="cline-any cline-neutral"> </span>
|
|
185
|
+
<span class="cline-any cline-neutral"> </span>
|
|
186
|
+
<span class="cline-any cline-neutral"> </span>
|
|
187
|
+
<span class="cline-any cline-neutral"> </span>
|
|
188
|
+
<span class="cline-any cline-neutral"> </span>
|
|
189
|
+
<span class="cline-any cline-neutral"> </span>
|
|
190
|
+
<span class="cline-any cline-neutral"> </span>
|
|
191
|
+
<span class="cline-any cline-neutral"> </span>
|
|
192
|
+
<span class="cline-any cline-yes">2x</span>
|
|
193
|
+
<span class="cline-any cline-neutral"> </span>
|
|
194
|
+
<span class="cline-any cline-yes">2x</span>
|
|
195
|
+
<span class="cline-any cline-neutral"> </span>
|
|
196
|
+
<span class="cline-any cline-yes">5x</span>
|
|
197
|
+
<span class="cline-any cline-yes">5x</span>
|
|
198
|
+
<span class="cline-any cline-yes">5x</span>
|
|
199
|
+
<span class="cline-any cline-neutral"> </span>
|
|
200
|
+
<span class="cline-any cline-yes">5x</span>
|
|
201
|
+
<span class="cline-any cline-neutral"> </span>
|
|
202
|
+
<span class="cline-any cline-neutral"> </span>
|
|
203
|
+
<span class="cline-any cline-neutral"> </span>
|
|
204
|
+
<span class="cline-any cline-neutral"> </span>
|
|
205
|
+
<span class="cline-any cline-neutral"> </span>
|
|
206
|
+
<span class="cline-any cline-neutral"> </span>
|
|
207
|
+
<span class="cline-any cline-neutral"> </span>
|
|
208
|
+
<span class="cline-any cline-neutral"> </span>
|
|
209
|
+
<span class="cline-any cline-neutral"> </span>
|
|
210
|
+
<span class="cline-any cline-neutral"> </span>
|
|
211
|
+
<span class="cline-any cline-neutral"> </span>
|
|
212
|
+
<span class="cline-any cline-neutral"> </span>
|
|
213
|
+
<span class="cline-any cline-neutral"> </span>
|
|
214
|
+
<span class="cline-any cline-neutral"> </span>
|
|
215
|
+
<span class="cline-any cline-neutral"> </span>
|
|
216
|
+
<span class="cline-any cline-neutral"> </span>
|
|
217
|
+
<span class="cline-any cline-neutral"> </span>
|
|
218
|
+
<span class="cline-any cline-neutral"> </span>
|
|
219
|
+
<span class="cline-any cline-neutral"> </span>
|
|
220
|
+
<span class="cline-any cline-neutral"> </span>
|
|
221
|
+
<span class="cline-any cline-yes">5x</span>
|
|
222
|
+
<span class="cline-any cline-neutral"> </span>
|
|
223
|
+
<span class="cline-any cline-neutral"> </span>
|
|
224
|
+
<span class="cline-any cline-neutral"> </span>
|
|
225
|
+
<span class="cline-any cline-neutral"> </span>
|
|
226
|
+
<span class="cline-any cline-neutral"> </span>
|
|
227
|
+
<span class="cline-any cline-neutral"> </span>
|
|
228
|
+
<span class="cline-any cline-neutral"> </span>
|
|
229
|
+
<span class="cline-any cline-yes">5x</span>
|
|
230
|
+
<span class="cline-any cline-neutral"> </span>
|
|
231
|
+
<span class="cline-any cline-neutral"> </span>
|
|
232
|
+
<span class="cline-any cline-neutral"> </span>
|
|
233
|
+
<span class="cline-any cline-yes">10x</span>
|
|
234
|
+
<span class="cline-any cline-yes">10x</span>
|
|
235
|
+
<span class="cline-any cline-neutral"> </span>
|
|
236
|
+
<span class="cline-any cline-neutral"> </span>
|
|
237
|
+
<span class="cline-any cline-neutral"> </span>
|
|
238
|
+
<span class="cline-any cline-yes">5x</span>
|
|
239
|
+
<span class="cline-any cline-yes">5x</span>
|
|
240
|
+
<span class="cline-any cline-yes">5x</span>
|
|
241
|
+
<span class="cline-any cline-neutral"> </span>
|
|
242
|
+
<span class="cline-any cline-yes">5x</span>
|
|
243
|
+
<span class="cline-any cline-yes">1x</span>
|
|
244
|
+
<span class="cline-any cline-yes">1x</span>
|
|
245
|
+
<span class="cline-any cline-yes">1x</span>
|
|
246
|
+
<span class="cline-any cline-neutral"> </span>
|
|
247
|
+
<span class="cline-any cline-neutral"> </span>
|
|
248
|
+
<span class="cline-any cline-neutral"> </span>
|
|
249
|
+
<span class="cline-any cline-yes">4x</span>
|
|
250
|
+
<span class="cline-any cline-yes">1x</span>
|
|
251
|
+
<span class="cline-any cline-yes">1x</span>
|
|
252
|
+
<span class="cline-any cline-yes">1x</span>
|
|
253
|
+
<span class="cline-any cline-neutral"> </span>
|
|
254
|
+
<span class="cline-any cline-neutral"> </span>
|
|
255
|
+
<span class="cline-any cline-neutral"> </span>
|
|
256
|
+
<span class="cline-any cline-yes">3x</span>
|
|
257
|
+
<span class="cline-any cline-yes">3x</span>
|
|
258
|
+
<span class="cline-any cline-neutral"> </span>
|
|
259
|
+
<span class="cline-any cline-neutral"> </span>
|
|
260
|
+
<span class="cline-any cline-neutral"> </span>
|
|
261
|
+
<span class="cline-any cline-yes">5x</span>
|
|
262
|
+
<span class="cline-any cline-yes">5x</span>
|
|
263
|
+
<span class="cline-any cline-yes">1x</span>
|
|
264
|
+
<span class="cline-any cline-neutral"> </span>
|
|
265
|
+
<span class="cline-any cline-neutral"> </span>
|
|
266
|
+
<span class="cline-any cline-neutral"> </span>
|
|
267
|
+
<span class="cline-any cline-yes">5x</span>
|
|
268
|
+
<span class="cline-any cline-yes">5x</span>
|
|
269
|
+
<span class="cline-any cline-yes">1x</span>
|
|
270
|
+
<span class="cline-any cline-yes">1x</span>
|
|
271
|
+
<span class="cline-any cline-neutral"> </span>
|
|
272
|
+
<span class="cline-any cline-neutral"> </span>
|
|
273
|
+
<span class="cline-any cline-neutral"> </span>
|
|
274
|
+
<span class="cline-any cline-yes">5x</span>
|
|
275
|
+
<span class="cline-any cline-yes">5x</span>
|
|
276
|
+
<span class="cline-any cline-neutral"> </span>
|
|
277
|
+
<span class="cline-any cline-neutral"> </span>
|
|
278
|
+
<span class="cline-any cline-neutral"> </span>
|
|
279
|
+
<span class="cline-any cline-yes">5x</span>
|
|
280
|
+
<span class="cline-any cline-yes">5x</span>
|
|
281
|
+
<span class="cline-any cline-neutral"> </span>
|
|
282
|
+
<span class="cline-any cline-neutral"> </span>
|
|
283
|
+
<span class="cline-any cline-neutral"> </span>
|
|
284
|
+
<span class="cline-any cline-yes">5x</span>
|
|
285
|
+
<span class="cline-any cline-yes">5x</span>
|
|
286
|
+
<span class="cline-any cline-yes">5x</span>
|
|
287
|
+
<span class="cline-any cline-neutral"> </span>
|
|
288
|
+
<span class="cline-any cline-neutral"> </span>
|
|
289
|
+
<span class="cline-any cline-neutral"> </span>
|
|
290
|
+
<span class="cline-any cline-yes">5x</span>
|
|
291
|
+
<span class="cline-any cline-yes">5x</span>
|
|
292
|
+
<span class="cline-any cline-yes">5x</span>
|
|
293
|
+
<span class="cline-any cline-neutral"> </span>
|
|
294
|
+
<span class="cline-any cline-neutral"> </span>
|
|
295
|
+
<span class="cline-any cline-neutral"> </span>
|
|
296
|
+
<span class="cline-any cline-yes">5x</span>
|
|
297
|
+
<span class="cline-any cline-yes">5x</span>
|
|
298
|
+
<span class="cline-any cline-neutral"> </span>
|
|
299
|
+
<span class="cline-any cline-neutral"> </span>
|
|
300
|
+
<span class="cline-any cline-neutral"> </span></td><td class="text"><pre class="prettyprint lang-js">/*
|
|
301
|
+
Copyright (c) 2025 Bernier LLC
|
|
302
|
+
|
|
303
|
+
This file is licensed to the client under a limited-use license.
|
|
304
|
+
The client may use and modify this code *only within the scope of the project it was delivered for*.
|
|
305
|
+
Redistribution or use in other products or commercial offerings is not permitted without written consent from Bernier LLC.
|
|
306
|
+
*/
|
|
307
|
+
|
|
308
|
+
import { EventNormalizer } from './EventNormalizer';
|
|
309
|
+
import { EmailEvent, EmailEventType, EmailProvider, WebhookPayload } from '../types';
|
|
310
|
+
|
|
311
|
+
export class SESNormalizer implements EventNormalizer {
|
|
312
|
+
normalize(webhook: WebhookPayload): EmailEvent {
|
|
313
|
+
const payload = webhook.payload as Record<string, unknown>;
|
|
314
|
+
const message = JSON.parse(payload.Message as string) as Record<string, unknown>;
|
|
315
|
+
const eventType = message.eventType as string;
|
|
316
|
+
|
|
317
|
+
return {
|
|
318
|
+
id: this.generateEventId(message),
|
|
319
|
+
emailId: this.extractMessageId(message),
|
|
320
|
+
messageId: this.extractMessageId(message),
|
|
321
|
+
type: this.mapEventType(eventType),
|
|
322
|
+
recipient: this.extractRecipient(message),
|
|
323
|
+
timestamp: new Date((message.mail as Record<string, unknown>).timestamp as string),
|
|
324
|
+
provider: EmailProvider.AWS_SES,
|
|
325
|
+
metadata: {
|
|
326
|
+
bounceType: this.extractBounceType(message),
|
|
327
|
+
bounceReason: this.extractBounceReason(message),
|
|
328
|
+
complaintFeedbackType: this.extractComplaintType(message),
|
|
329
|
+
url: this.extractClickUrl(message),
|
|
330
|
+
ipAddress: this.extractIpAddress(message),
|
|
331
|
+
userAgent: this.extractUserAgent(message)
|
|
332
|
+
},
|
|
333
|
+
rawEvent: message
|
|
334
|
+
};
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
private mapEventType(sesEvent: string): EmailEventType {
|
|
338
|
+
const mapping: Record<string, EmailEventType> = {
|
|
339
|
+
'Delivery': EmailEventType.DELIVERED,
|
|
340
|
+
'Open': EmailEventType.OPENED,
|
|
341
|
+
'Click': EmailEventType.CLICKED,
|
|
342
|
+
'Bounce': EmailEventType.BOUNCED,
|
|
343
|
+
'Complaint': EmailEventType.COMPLAINED,
|
|
344
|
+
'Reject': EmailEventType.FAILED
|
|
345
|
+
};
|
|
346
|
+
return mapping[sesEvent] || <span class="branch-1 cbranch-no" title="branch not covered" >EmailEventType.FAILED;</span>
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
private extractMessageId(message: Record<string, unknown>): string {
|
|
350
|
+
const mail = message.mail as Record<string, unknown>;
|
|
351
|
+
return (mail?.messageId as string) || <span class="branch-1 cbranch-no" title="branch not covered" >'';</span>
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
private extractRecipient(message: Record<string, unknown>): string {
|
|
355
|
+
const bounce = message.bounce as Record<string, unknown> | undefined;
|
|
356
|
+
const complaint = message.complaint as Record<string, unknown> | undefined;
|
|
357
|
+
const mail = message.mail as Record<string, unknown>;
|
|
358
|
+
|
|
359
|
+
if (bounce) {
|
|
360
|
+
const bouncedRecipients = bounce.bouncedRecipients as Array<Record<string, string>> | undefined;
|
|
361
|
+
if (bouncedRecipients?.[0]?.emailAddress) {
|
|
362
|
+
return bouncedRecipients[0].emailAddress;
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
if (complaint) {
|
|
367
|
+
const complainedRecipients = complaint.complainedRecipients as Array<Record<string, string>> | undefined;
|
|
368
|
+
if (complainedRecipients?.[0]?.emailAddress) {
|
|
369
|
+
return complainedRecipients[0].emailAddress;
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
const destination = mail.destination as string[] | undefined;
|
|
374
|
+
return destination?.[0] || <span class="branch-1 cbranch-no" title="branch not covered" >'';</span>
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
private extractBounceType(message: Record<string, unknown>): 'hard' | 'soft' | undefined {
|
|
378
|
+
const bounce = message.bounce as Record<string, unknown> | undefined;
|
|
379
|
+
if (!bounce) return undefined;
|
|
380
|
+
return (bounce.bounceType as string)?.toLowerCase() as 'hard' | 'soft' | undefined;
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
private extractBounceReason(message: Record<string, unknown>): string | undefined {
|
|
384
|
+
const bounce = message.bounce as Record<string, unknown> | undefined;
|
|
385
|
+
if (!bounce) return undefined;
|
|
386
|
+
const bouncedRecipients = bounce.bouncedRecipients as Array<Record<string, string>> | undefined;
|
|
387
|
+
return bouncedRecipients?.[0]?.diagnosticCode;
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
private extractComplaintType(message: Record<string, unknown>): string | undefined {
|
|
391
|
+
const complaint = message.complaint as Record<string, unknown> | undefined;
|
|
392
|
+
return complaint?.complaintFeedbackType as string | undefined;
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
private extractClickUrl(message: Record<string, unknown>): string | undefined {
|
|
396
|
+
const click = message.click as Record<string, unknown> | undefined;
|
|
397
|
+
return click?.link as string | undefined;
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
private extractIpAddress(message: Record<string, unknown>): string | undefined {
|
|
401
|
+
const open = message.open as Record<string, unknown> | undefined;
|
|
402
|
+
const click = message.click as Record<string, unknown> | undefined;
|
|
403
|
+
return (open?.ipAddress as string) || (click?.ipAddress as string) || undefined;
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
private extractUserAgent(message: Record<string, unknown>): string | undefined {
|
|
407
|
+
const open = message.open as Record<string, unknown> | undefined;
|
|
408
|
+
const click = message.click as Record<string, unknown> | undefined;
|
|
409
|
+
return (open?.userAgent as string) || (click?.userAgent as string) || undefined;
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
private generateEventId(message: Record<string, unknown>): string {
|
|
413
|
+
const mail = message.mail as Record<string, unknown>;
|
|
414
|
+
return `ses-${(mail?.messageId as string) || <span class="branch-1 cbranch-no" title="branch not covered" >''}</span>-${Date.now()}`;
|
|
415
|
+
}
|
|
416
|
+
}
|
|
417
|
+
</pre></td></tr></table></pre>
|
|
418
|
+
|
|
419
|
+
<div class='push'></div><!-- for sticky footer -->
|
|
420
|
+
</div><!-- /wrapper -->
|
|
421
|
+
<div class='footer quiet pad2 space-top1 center small'>
|
|
422
|
+
Code coverage generated by
|
|
423
|
+
<a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
|
|
424
|
+
at 2025-11-25T22:14:07.056Z
|
|
425
|
+
</div>
|
|
426
|
+
<script src="../../prettify.js"></script>
|
|
427
|
+
<script>
|
|
428
|
+
window.onload = function () {
|
|
429
|
+
prettyPrint();
|
|
430
|
+
};
|
|
431
|
+
</script>
|
|
432
|
+
<script src="../../sorter.js"></script>
|
|
433
|
+
<script src="../../block-navigation.js"></script>
|
|
434
|
+
</body>
|
|
435
|
+
</html>
|
|
436
|
+
|