1
+ const { executeHttpRequest, buildCsrfHeaders } = require ( "@sap-cloud-sdk/core" ) ;
2
+ const { getNotificationDestination, doesKeyExist, getPrefix, getNotificationTypesKeyWithPrefix } = require ( "./utils" ) ;
3
+
4
+ const NOTIFICATION_TYPES_API_ENDPOINT = "v2/NotificationType.svc" ;
5
+
6
+ function createNotificationTypesMap ( notificationTypesJSON ) {
7
+ const types = { } ;
8
+ notificationTypesJSON . forEach ( ( notificationType ) => {
9
+ const notificationTypeKeyWithPrefix = getNotificationTypesKeyWithPrefix ( notificationType . NotificationTypeKey ) ;
10
+
11
+ // update the notification type key with prefix
12
+ notificationType . NotificationTypeKey = notificationTypeKeyWithPrefix ;
13
+
14
+
15
+ if ( ! doesKeyExist ( types , notificationTypeKeyWithPrefix ) ) {
16
+ types [ notificationTypeKeyWithPrefix ] = { } ;
17
+ }
18
+
19
+ types [ notificationTypeKeyWithPrefix ] [ notificationType . NotificationTypeVersion ] = notificationType ;
20
+ } ) ;
21
+
22
+ return types ;
23
+ }
24
+
25
+ async function getNotificationTypes ( destination ) {
26
+ const notificationDestination = await getNotificationDestination ( destination ) ;
27
+ const response = await executeHttpRequest ( notificationDestination , {
28
+ url : `${ NOTIFICATION_TYPES_API_ENDPOINT } /NotificationTypes?$format=json&$expand=Templates,Actions,DeliveryChannels` ,
29
+ method : "get" ,
30
+ } ) ;
31
+ return response . data . d . results ;
32
+ }
33
+
34
+ async function createNotificationType ( notificationType , destination ) {
35
+ const notificationDestination = await getNotificationDestination ( destination ) ;
36
+ const csrfHeaders = await buildCsrfHeaders ( notificationDestination , {
37
+ url : NOTIFICATION_TYPES_API_ENDPOINT ,
38
+ } ) ;
39
+
40
+ console . log (
41
+ `Notification Type of key ${ notificationType . NotificationTypeKey } and version ${ notificationType . NotificationTypeVersion } was not found. Creating it...`
42
+ ) ;
43
+
44
+ const response = await executeHttpRequest ( notificationDestination , {
45
+ url : `${ NOTIFICATION_TYPES_API_ENDPOINT } /NotificationTypes` ,
46
+ method : "post" ,
47
+ data : notificationType ,
48
+ headers : csrfHeaders ,
49
+ } ) ;
50
+ return response . data . d ;
51
+ }
52
+
53
+ async function updateNotificationType ( id , notificationType , destination ) {
54
+ const notificationDestination = await getNotificationDestination ( destination ) ;
55
+ const csrfHeaders = await buildCsrfHeaders ( notificationDestination , {
56
+ url : NOTIFICATION_TYPES_API_ENDPOINT ,
57
+ } ) ;
58
+
59
+ console . log (
60
+ `Detected change in notification type of key ${ notificationType . NotificationTypeKey } and version ${ notificationType . NotificationTypeVersion } . Updating it...`
61
+ ) ;
62
+
63
+ const response = await executeHttpRequest ( notificationDestination , {
64
+ url : `${ NOTIFICATION_TYPES_API_ENDPOINT } /NotificationTypes(guid'${ id } ')` ,
65
+ method : "patch" ,
66
+ data : notificationType ,
67
+ headers : csrfHeaders ,
68
+ } ) ;
69
+ return response . data . d ;
70
+ }
71
+
72
+ async function deleteNotificationType ( notificationType , destination ) {
73
+ const notificationDestination = await getNotificationDestination ( destination ) ;
74
+ const csrfHeaders = await buildCsrfHeaders ( notificationDestination , {
75
+ url : NOTIFICATION_TYPES_API_ENDPOINT ,
76
+ } ) ;
77
+
78
+ console . log (
79
+ `Notification Type of key ${ notificationType . NotificationTypeKey } and version ${ notificationType . NotificationTypeVersion } not present in the types file. Deleting it...`
80
+ ) ;
81
+
82
+ const response = await executeHttpRequest ( notificationDestination , {
83
+ url : `${ NOTIFICATION_TYPES_API_ENDPOINT } /NotificationTypes(guid'${ notificationType . NotificationTypeId } ')` ,
84
+ method : "delete" ,
85
+ headers : csrfHeaders ,
86
+ } ) ;
87
+ return response . data . d ;
88
+ }
89
+
90
+ function _createChannelsMap ( channels ) {
91
+ const channelMap = { } ;
92
+
93
+ channels . forEach ( ( channel ) => {
94
+ channelMap [ channel . Type ] = channel ;
95
+ } )
96
+
97
+ return channelMap ;
98
+ }
99
+
100
+ function areDeliveryChannelsSame ( oldChannels , newChannels ) {
101
+ if ( oldChannels . length !== newChannels . length ) {
102
+ return false ;
103
+ }
104
+
105
+ const oldChannelsMap = _createChannelsMap ( oldChannels ) ;
106
+ const newChannelsMap = _createChannelsMap ( newChannels ) ;
107
+
108
+ for ( type in Object . keys ( oldChannelsMap ) ) {
109
+ if ( ! ( type in newChannelsMap ) ) return false ;
110
+
111
+ const oldChannel = oldChannelsMap [ type ] ;
112
+ const newChannel = newChannelsMap [ type ] ;
113
+
114
+ // TODO: Check if language is not there
115
+ const same =
116
+ oldChannel . Language == newChannel . Language . toUpperCase ( ) &&
117
+ oldChannel . ActionId == newChannel . ActionId &&
118
+ oldChannel . ActionText == newChannel . ActionText &&
119
+ oldChannel . GroupActionText == newChannel . GroupActionText &&
120
+ oldChannel . Nature == newChannel . Nature ;
121
+
122
+ if ( ! same ) return false ;
123
+ delete newChannelsMap [ type ] ;
124
+ }
125
+
126
+ return Object . keys ( newChannelsMap ) . length == 0 ;
127
+ }
128
+
129
+ function _createActionsMap ( actions ) {
130
+ const actionsMap = { } ;
131
+
132
+ actions . forEach ( ( action ) => {
133
+ actionsMap [ ActionId ] = action ;
134
+ } )
135
+
136
+ return actionsMap ;
137
+ }
138
+
139
+ function areActionsSame ( oldActions , newActions ) {
140
+ if ( oldActions . length !== newActions . length ) {
141
+ return false ;
142
+ }
143
+
144
+ const oldActionsMap = _createActionsMap ( oldActions ) ;
145
+ const newActionsMap = _createActionsMap ( newActions ) ;
146
+
147
+ for ( actionId in Object . keys ( oldActionsMap ) ) {
148
+ if ( ! ( actionId in newActionsMap ) ) return false ;
149
+
150
+ const oldAction = oldActionsMap [ actionId ] ;
151
+ const newAction = newActionsMap [ actionId ] ;
152
+
153
+ const same =
154
+ oldAction . Language == newAction . Language . toUpperCase ( ) &&
155
+ oldAction . ActionId == newAction . ActionId &&
156
+ oldAction . ActionText == newAction . ActionText &&
157
+ oldAction . GroupActionText == newAction . GroupActionText &&
158
+ oldAction . Nature == newAction . Nature ;
159
+
160
+ if ( ! same ) return false ;
161
+ delete newAction [ actionId ] ;
162
+ }
163
+
164
+ return Object . keys ( newActionsMap ) . length == 0 ;
165
+ }
166
+
167
+ function _createTemplatesMap ( templates ) {
168
+ const templatesObj = { } ;
169
+
170
+ templates . forEach ( ( template ) => {
171
+ templatesObj [ template . Language ] = template ;
172
+ } )
173
+
174
+ return templatesObj ;
175
+ }
176
+
177
+ function areTemplatesSame ( oldTemplates , newTemplates ) {
178
+ if ( oldTemplates . length !== newTemplates . length ) {
179
+ return false ;
180
+ }
181
+
182
+ const oldTemplatesMap = _createTemplatesMap ( oldTemplates ) ;
183
+ const newTemplatesMap = _createTemplatesMap ( newTemplates ) ;
184
+
185
+ for ( language in Object . keys ( oldTemplatesMap ) ) {
186
+ if ( ! ( language in newTemplatesMap ) ) return false ;
187
+
188
+ const oldTemplate = oldTemplatesMap [ language ] ;
189
+ const newTemplate = newTemplatesMap [ language ] ;
190
+
191
+ const same =
192
+ oldTemplate . Language == newTemplate . Language . toUpperCase ( ) &&
193
+ oldTemplate . TemplatePublic == newTemplate . TemplatePublic &&
194
+ oldTemplate . TemplateSensitive == newTemplate . TemplateSensitive &&
195
+ oldTemplate . TemplateGrouped == newTemplate . TemplateGrouped &&
196
+ oldTemplate . Description == newTemplate . Description &&
197
+ oldTemplate . TemplateLanguage == newTemplate . TemplateLanguage . toUpperCase ( ) &&
198
+ oldTemplate . Subtitle == newTemplate . Subtitle &&
199
+ oldTemplate . EmailSubject == newTemplate . EmailSubject &&
200
+ oldTemplate . EmailText == newTemplate . EmailText &&
201
+ oldTemplate . EmailHtml == newTemplate . EmailHtml ;
202
+
203
+ if ( ! same ) return false ;
204
+ delete newTemplate [ language ] ;
205
+ }
206
+
207
+ return Object . keys ( newTemplates ) . length == 0 ;
208
+ }
209
+
210
+ function isNotificationTypeSame ( oldNotificationType , newNotificationType ) {
211
+ if ( oldNotificationType . IsGroupable != newNotificationType . IsGroupable ) {
212
+ return false ;
213
+ }
214
+
215
+ if ( ! areTemplatesSame ( oldNotificationType . Templates . results , newNotificationType . Templates ) ) {
216
+ return false ;
217
+ }
218
+
219
+ if ( ! areActionsSame ( oldNotificationType . Actions . results , newNotificationType . Actions ) ) {
220
+ return false ;
221
+ }
222
+
223
+ if ( ! areDeliveryChannelsSame ( oldNotificationType . DeliveryChannels . results , newNotificationType . DeliveryChannels ) ) {
224
+ return false ;
225
+ }
226
+
227
+ return true ;
228
+ }
229
+
230
+ async function processNotificationTypes ( notificationTypes , destination ) {
231
+ const prefix = getPrefix ( ) ;
232
+
233
+ // get notficationTypes
234
+ const existingTypes = await getNotificationTypes ( destination ) ;
235
+
236
+ // iterate through notification types
237
+ existingTypes . forEach ( ( existingType ) => {
238
+ if ( ! existingType . NotificationTypeKey . startsWith ( `${ prefix } /` ) ) {
239
+ return ;
240
+ }
241
+
242
+ // if the type isn't present in the JSON file, delete it
243
+ if ( notificationTypes [ existingType . NotificationTypeKey ] === undefined || notificationTypes [ existingType . NotificationTypeKey ] [ NotificationTypeVersion ] === undefined ) {
244
+ deleteNotificationType ( existingType . NotificationTypeId , destination ) ;
245
+ }
246
+
247
+ const newType = JSON . parse ( JSON . stringify ( notificationTypes [ existingType . NotificationTypeKey ] [ NotificationTypeVersion ] ) ) ;
248
+
249
+ // if the type is there then verify if everything is same or not
250
+ if ( ! isNotificationTypeSame ( existingType , newType ) ) {
251
+ updateNotificationType ( existingType . NotificationTypeId , notificationTypes [ existingType . NotificationTypeKey ] [ NotificationTypeVersion ] , destination )
252
+ }
253
+
254
+ // if notification type is same, remove it from new types map
255
+ delete notificationTypes [ existingType . NotificationTypeKey ] [ NotificationTypeVersion ] ;
256
+ if ( Object . keys ( notificationTypes [ existingType . NotificationTypeKey ] ) . length == 0 ) {
257
+ delete notificationTypes [ existingType . NotificationTypeKey ] ;
258
+ }
259
+ } )
260
+
261
+
262
+ // create notification types that aren't there
263
+ for ( let notificationTypeKey in notificationTypes ) {
264
+ for ( let notificationTypeVersion in notificationTypes [ notificationTypeKey ] ) {
265
+ createNotificationType ( notificationTypes [ notificationTypeKey ] [ notificationTypeVersion ] , destination ) ;
266
+ }
267
+ }
268
+ }
269
+
270
+ module . exports = {
271
+ createNotificationTypesMap,
272
+ processNotificationTypes
273
+ }
0 commit comments