@neoimpulse/cap-js-notifications 1.0.6 → 1.0.7

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/lib/utils.js CHANGED
@@ -1,247 +1,252 @@
1
- const { existsSync, readFileSync } = require('fs');
2
- const { basename } = require('path');
1
+ const { existsSync, readFileSync } = require("fs");
2
+ const { basename } = require("path");
3
3
  const cds = require("@sap/cds");
4
- const LOG = cds.log('notifications');
4
+ const LOG = cds.log("notifications");
5
5
  const { getDestination } = require("@sap-cloud-sdk/connectivity");
6
6
  const PRIORITIES = ["LOW", "NEUTRAL", "MEDIUM", "HIGH"];
7
7
 
8
8
  const messages = {
9
- TYPES_FILE_NOT_EXISTS: "Notification Types file path is incorrect.",
10
- INVALID_NOTIFICATION_TYPES: "Notification Types must contain the following key: 'NotificationTypeKey'.",
11
- DESTINATION_NOT_FOUND: "Failed to get destination: ",
12
- MANDATORY_PARAMETER_NOT_PASSED_FOR_DEFAULT_NOTIFICATION: "Recipients and title are mandatory parameters.",
13
- MANDATORY_PARAMETER_NOT_PASSED_FOR_CUSTOM_NOTIFICATION: "Recipients are mandatory parameters.",
14
- RECIPIENTS_IS_NOT_ARRAY: "Recipients is not an array or it is empty.",
15
- TITLE_IS_NOT_STRING: "Title is not a string.",
16
- DESCRIPTION_IS_NOT_STRING: "Description is not a string.",
17
- PROPERTIES_IS_NOT_OBJECT: "Properties is not an object.",
18
- NAVIGATION_IS_NOT_OBJECT: "Navigation is not an object.",
19
- PAYLOAD_IS_NOT_OBJECT: "Payload is not an object.",
20
- EMPTY_OBJECT_FOR_NOTIFY: "Empty object is passed a single parameter to notify function.",
21
- NO_OBJECT_FOR_NOTIFY: "An object must be passed to notify function."
9
+ TYPES_FILE_NOT_EXISTS: "Notification Types file path is incorrect.",
10
+ INVALID_NOTIFICATION_TYPES: "Notification Types must contain the following key: 'NotificationTypeKey'.",
11
+ DESTINATION_NOT_FOUND: "Failed to get destination: ",
12
+ MANDATORY_PARAMETER_NOT_PASSED_FOR_DEFAULT_NOTIFICATION: "Recipients and title are mandatory parameters.",
13
+ MANDATORY_PARAMETER_NOT_PASSED_FOR_CUSTOM_NOTIFICATION: "Recipients are mandatory parameters.",
14
+ RECIPIENTS_IS_NOT_ARRAY: "Recipients is not an array or it is empty.",
15
+ TITLE_IS_NOT_STRING: "Title is not a string.",
16
+ DESCRIPTION_IS_NOT_STRING: "Description is not a string.",
17
+ PROPERTIES_IS_NOT_OBJECT: "Properties is not an object.",
18
+ NAVIGATION_IS_NOT_OBJECT: "Navigation is not an object.",
19
+ PAYLOAD_IS_NOT_OBJECT: "Payload is not an object.",
20
+ EMPTY_OBJECT_FOR_NOTIFY: "Empty object is passed a single parameter to notify function.",
21
+ NO_OBJECT_FOR_NOTIFY: "An object must be passed to notify function."
22
22
  };
23
23
 
24
24
  function validateNotificationTypes(notificationTypes) {
25
- for(let notificationType of notificationTypes){
26
- if (!("NotificationTypeKey" in notificationType)) {
27
- LOG._warn && LOG.warn(messages.INVALID_NOTIFICATION_TYPES);
28
- return false;
25
+ for (let notificationType of notificationTypes) {
26
+ if (!("NotificationTypeKey" in notificationType)) {
27
+ LOG._warn && LOG.warn(messages.INVALID_NOTIFICATION_TYPES);
28
+ return false;
29
+ }
29
30
  }
30
- }
31
31
 
32
- return true;
32
+ return true;
33
33
  }
34
34
 
35
35
  function validateDefaultNotifyParameters(recipients, priority, title, description) {
36
- if (!recipients || !title) {
37
- LOG._warn && LOG.warn(messages.MANDATORY_PARAMETER_NOT_PASSED_FOR_DEFAULT_NOTIFICATION);
38
- return false;
39
- }
40
-
41
- if (!Array.isArray(recipients) || recipients.length == 0) {
42
- LOG._warn && LOG.warn(messages.RECIPIENTS_IS_NOT_ARRAY);
43
- return false;
44
- }
45
-
46
- if (typeof title !== "string") {
47
- LOG._warn && LOG.warn(messages.TITLE_IS_NOT_STRING);
48
- return false;
49
- }
50
-
51
- if (priority && !PRIORITIES.includes(priority.toUpperCase())) {
52
- LOG._warn && LOG.warn(`Invalid priority ${priority}. Allowed priorities are LOW, NEUTRAL, MEDIUM, HIGH`);
53
- return false;
54
- }
55
-
56
- if (description && typeof description !== "string") {
57
- LOG._warn && LOG.warn(messages.DESCRIPTION_IS_NOT_STRING);
58
- return false;
59
- }
60
-
61
- return true;
36
+ if (!recipients || !title) {
37
+ LOG._warn && LOG.warn(messages.MANDATORY_PARAMETER_NOT_PASSED_FOR_DEFAULT_NOTIFICATION);
38
+ return false;
39
+ }
40
+
41
+ if (!Array.isArray(recipients) || recipients.length == 0) {
42
+ LOG._warn && LOG.warn(messages.RECIPIENTS_IS_NOT_ARRAY);
43
+ return false;
44
+ }
45
+
46
+ if (typeof title !== "string") {
47
+ LOG._warn && LOG.warn(messages.TITLE_IS_NOT_STRING);
48
+ return false;
49
+ }
50
+
51
+ if (priority && !PRIORITIES.includes(priority.toUpperCase())) {
52
+ LOG._warn && LOG.warn(`Invalid priority ${priority}. Allowed priorities are LOW, NEUTRAL, MEDIUM, HIGH`);
53
+ return false;
54
+ }
55
+
56
+ if (description && typeof description !== "string") {
57
+ LOG._warn && LOG.warn(messages.DESCRIPTION_IS_NOT_STRING);
58
+ return false;
59
+ }
60
+
61
+ return true;
62
62
  }
63
63
 
64
64
  function validateCustomNotifyParameters(type, recipients, properties, navigation, priority, payload) {
65
- if (!recipients) {
66
- LOG._warn && LOG.warn(messages.MANDATORY_PARAMETER_NOT_PASSED_FOR_CUSTOM_NOTIFICATION);
67
- return false;
68
- }
69
-
70
- if (!Array.isArray(recipients) || recipients.length == 0) {
71
- LOG._warn && LOG.warn(messages.RECIPIENTS_IS_NOT_ARRAY);
72
- return false;
73
- }
74
-
75
- if (priority && !PRIORITIES.includes(priority.toUpperCase())) {
76
- LOG._warn && LOG.warn(`Invalid priority ${priority}. Allowed priorities are LOW, NEUTRAL, MEDIUM, HIGH`);
77
- return false;
78
- }
79
-
80
- if (properties && !Array.isArray(properties)) {
81
- LOG._warn && LOG.warn(messages.PROPERTIES_IS_NOT_OBJECT);
82
- return false;
83
- }
84
-
85
- if (navigation && typeof navigation !== "object") {
86
- LOG._warn && LOG.warn(messages.NAVIGATION_IS_NOT_OBJECT);
87
- return false;
88
- }
89
-
90
- if (payload && typeof payload !== "object") {
91
- LOG._warn && LOG.warn(messages.PAYLOAD_IS_NOT_OBJECT);
92
- return false;
93
- }
94
-
95
- return true;
96
- }
65
+ if (!recipients) {
66
+ LOG._warn && LOG.warn(messages.MANDATORY_PARAMETER_NOT_PASSED_FOR_CUSTOM_NOTIFICATION);
67
+ return false;
68
+ }
97
69
 
70
+ if (!Array.isArray(recipients) || recipients.length == 0) {
71
+ LOG._warn && LOG.warn(messages.RECIPIENTS_IS_NOT_ARRAY);
72
+ return false;
73
+ }
74
+
75
+ if (priority && !PRIORITIES.includes(priority.toUpperCase())) {
76
+ LOG._warn && LOG.warn(`Invalid priority ${priority}. Allowed priorities are LOW, NEUTRAL, MEDIUM, HIGH`);
77
+ return false;
78
+ }
79
+
80
+ if (properties && !Array.isArray(properties)) {
81
+ LOG._warn && LOG.warn(messages.PROPERTIES_IS_NOT_OBJECT);
82
+ return false;
83
+ }
84
+
85
+ if (navigation && typeof navigation !== "object") {
86
+ LOG._warn && LOG.warn(messages.NAVIGATION_IS_NOT_OBJECT);
87
+ return false;
88
+ }
89
+
90
+ if (payload && typeof payload !== "object") {
91
+ LOG._warn && LOG.warn(messages.PAYLOAD_IS_NOT_OBJECT);
92
+ return false;
93
+ }
94
+
95
+ return true;
96
+ }
98
97
 
99
98
  function readFile(filePath) {
100
- if (!existsSync(filePath)) {
101
- LOG._warn && LOG.warn(messages.TYPES_FILE_NOT_EXISTS);
102
- return [];
103
- }
99
+ if (!existsSync(filePath)) {
100
+ LOG._warn && LOG.warn(messages.TYPES_FILE_NOT_EXISTS);
101
+ return [];
102
+ }
104
103
 
105
- return JSON.parse(readFileSync(filePath));
104
+ return JSON.parse(readFileSync(filePath));
106
105
  }
107
106
 
108
107
  async function getNotificationDestination() {
109
- const destinationName = cds.env.requires.notifications?.destination ?? "SAP_Notifications";
110
- const notificationDestination = await getDestination({ destinationName, useCache: true });
111
- if (!notificationDestination) {
112
- // TODO: What to do if destination isn't found??
113
- throw new Error(messages.DESTINATION_NOT_FOUND + destinationName);
114
- }
115
- return notificationDestination;
108
+ const destinationName = cds.env.requires.notifications?.destination ?? "SAP_Notifications";
109
+ const notificationDestination = await getDestination({ destinationName, useCache: true });
110
+ if (!notificationDestination) {
111
+ // TODO: What to do if destination isn't found??
112
+ throw new Error(messages.DESTINATION_NOT_FOUND + destinationName);
113
+ }
114
+ return notificationDestination;
116
115
  }
117
116
 
118
- let prefix // be filled in below...
117
+ let prefix; // be filled in below...
119
118
  function getPrefix() {
120
- if (!prefix) {
121
- prefix = cds.env.requires.notifications?.prefix
122
- if (prefix === "$app-name") try {
123
- prefix = require(cds.root + '/package.json').name
124
- } catch { prefix = null }
125
- if (!prefix) prefix = basename(cds.root)
126
- }
127
- return prefix
119
+ if (!prefix) {
120
+ prefix = cds.env.requires.notifications?.prefix;
121
+ if (prefix === "$app-name")
122
+ try {
123
+ prefix = require(cds.root + "/package.json").name;
124
+ } catch {
125
+ prefix = null;
126
+ }
127
+ if (!prefix) prefix = basename(cds.root);
128
+ }
129
+ return prefix;
128
130
  }
129
131
 
130
132
  function getNotificationTypesKeyWithPrefix(notificationTypeKey) {
131
- const prefix = getPrefix();
132
- return `${prefix}/${notificationTypeKey}`;
133
+ const prefix = getPrefix();
134
+ return `${prefix}/${notificationTypeKey}`;
133
135
  }
134
136
 
135
- function buildDefaultNotification(
136
- recipients,
137
- priority = "NEUTRAL",
138
- title,
139
- description = ""
140
- ) {
141
- const properties = [
142
- {
143
- Key: "title",
144
- Language: "en",
145
- Value: title,
146
- Type: "String",
147
- IsSensitive: false,
148
- },
149
- {
150
- Key: "description",
151
- Language: "en",
152
- Value: description,
153
- Type: "String",
154
- IsSensitive: false,
155
- },
156
- ];
157
-
158
- return {
159
- NotificationTypeKey: "Default",
160
- NotificationTypeVersion: "1",
161
- Priority: priority,
162
- Properties: properties,
163
- Recipients: recipients.map((recipient) => ({ RecipientId: recipient }))
164
- };
137
+ function buildDefaultNotification(recipients, priority = "NEUTRAL", title, description = "") {
138
+ const properties = [
139
+ {
140
+ Key: "title",
141
+ Language: "en",
142
+ Value: title,
143
+ Type: "String",
144
+ IsSensitive: false
145
+ },
146
+ {
147
+ Key: "description",
148
+ Language: "en",
149
+ Value: description,
150
+ Type: "String",
151
+ IsSensitive: false
152
+ }
153
+ ];
154
+
155
+ return {
156
+ NotificationTypeKey: "Default",
157
+ NotificationTypeVersion: "1",
158
+ Priority: priority,
159
+ Properties: properties,
160
+ Recipients: recipients.map((recipient) => ({ RecipientId: recipient }))
161
+ };
165
162
  }
166
163
 
167
164
  function buildCustomNotification(_) {
168
- let notification = {
169
-
170
- // Properties with simple API variants
171
- NotificationTypeKey: getNotificationTypesKeyWithPrefix(_.NotificationTypeKey || _.type),
172
- Recipients: _.Recipients || _.recipients?.map(id => ({ RecipientId: id })),
173
- Priority: _.Priority || _.priority || "NEUTRAL",
174
- Properties: _.Properties || Object.entries(_.data).map(([k,v]) => ({
175
- Key:k, Value:v, Language: "en", Type: typeof v, // IsSensitive: false
176
- })),
177
-
178
- // Low-level API properties
179
- OriginId: _.OriginId,
180
- NotificationTypeId: _.NotificationTypeId,
181
- NotificationTypeVersion: _.NotificationTypeVersion || "1",
182
- NavigationTargetAction: _.NavigationTargetAction,
183
- NavigationTargetObject: _.NavigationTargetObject,
184
- ProviderId: _.ProviderId,
185
- ActorId: _.ActorId,
186
- ActorDisplayText: _.ActorDisplayText,
187
- ActorImageURL: _.ActorImageURL,
188
- TargetParameters: _.TargetParameters,
189
- NotificationTypeTimestamp: _.NotificationTypeTimestamp,
190
- }
191
- return notification
165
+ let notification = {
166
+ // Properties with simple API variants
167
+ NotificationTypeKey: getNotificationTypesKeyWithPrefix(_.NotificationTypeKey || _.type),
168
+ Recipients: _.Recipients || _.recipients?.map((id) => ({ RecipientId: id })),
169
+ Priority: _.Priority || _.priority || "NEUTRAL",
170
+ Properties:
171
+ _.Properties ||
172
+ Object.entries(_.data).map(([k, v]) => ({
173
+ Key: k,
174
+ Value: v,
175
+ Language: "en",
176
+ Type: typeof v // IsSensitive: false
177
+ })),
178
+
179
+ // Low-level API properties
180
+ OriginId: _.OriginId,
181
+ NotificationTypeId: _.NotificationTypeId,
182
+ NotificationTypeVersion: _.NotificationTypeVersion || "1",
183
+ NavigationTargetAction: _.NavigationTargetAction,
184
+ NavigationTargetObject: _.NavigationTargetObject,
185
+ ProviderId: _.ProviderId,
186
+ ActorId: _.ActorId,
187
+ ActorDisplayText: _.ActorDisplayText,
188
+ ActorImageURL: _.ActorImageURL,
189
+ TargetParameters: _.TargetParameters,
190
+ NotificationTypeTimestamp: _.NotificationTypeTimestamp
191
+ };
192
+ return notification;
192
193
  }
193
194
 
194
195
  function buildNotification(notificationData) {
195
- let notification;
196
-
197
- if (Object.keys(notificationData).length === 0) {
198
- LOG._warn && LOG.warn(messages.EMPTY_OBJECT_FOR_NOTIFY);
199
- return;
200
- }
201
-
202
- if (notificationData.type) {
203
- if (!validateCustomNotifyParameters(
204
- notificationData.type,
205
- notificationData.recipients,
206
- notificationData.properties,
207
- notificationData.navigation,
208
- notificationData.priority,
209
- notificationData.payload)
210
- ) {
211
- return;
212
- }
213
-
214
- notification = buildCustomNotification(notificationData);
215
- } else if (notificationData.NotificationTypeKey) {
216
- notificationData.NotificationTypeKey = getNotificationTypesKeyWithPrefix(notificationData.NotificationTypeKey);
217
- notification = notificationData;
218
- } else {
219
- if (!validateDefaultNotifyParameters(
220
- notificationData.recipients,
221
- notificationData.priority,
222
- notificationData.title,
223
- notificationData.description)
224
- ) {
225
- return;
226
- }
227
-
228
- notification = buildDefaultNotification(
229
- notificationData.recipients,
230
- notificationData.priority,
231
- notificationData.title,
232
- notificationData.description
233
- );
234
- }
235
-
236
- return JSON.parse(JSON.stringify(notification));
196
+ let notification;
197
+
198
+ if (Object.keys(notificationData).length === 0) {
199
+ LOG._warn && LOG.warn(messages.EMPTY_OBJECT_FOR_NOTIFY);
200
+ return;
201
+ }
202
+
203
+ if (notificationData.type) {
204
+ if (
205
+ !validateCustomNotifyParameters(
206
+ notificationData.type,
207
+ notificationData.recipients,
208
+ notificationData.properties,
209
+ notificationData.navigation,
210
+ notificationData.priority,
211
+ notificationData.payload
212
+ )
213
+ ) {
214
+ return;
215
+ }
216
+
217
+ notification = buildCustomNotification(notificationData);
218
+ } else if (notificationData.NotificationTypeKey) {
219
+ notificationData.NotificationTypeKey = getNotificationTypesKeyWithPrefix(notificationData.NotificationTypeKey);
220
+ notification = notificationData;
221
+ } else {
222
+ if (
223
+ !validateDefaultNotifyParameters(
224
+ notificationData.recipients,
225
+ notificationData.priority,
226
+ notificationData.title,
227
+ notificationData.description
228
+ )
229
+ ) {
230
+ return;
231
+ }
232
+
233
+ notification = buildDefaultNotification(
234
+ notificationData.recipients,
235
+ notificationData.priority,
236
+ notificationData.title,
237
+ notificationData.description
238
+ );
239
+ }
240
+
241
+ return JSON.parse(JSON.stringify(notification));
237
242
  }
238
243
 
239
244
  module.exports = {
240
- messages,
241
- validateNotificationTypes,
242
- readFile,
243
- getNotificationDestination,
244
- getPrefix,
245
- getNotificationTypesKeyWithPrefix,
246
- buildNotification
245
+ messages,
246
+ validateNotificationTypes,
247
+ readFile,
248
+ getNotificationDestination,
249
+ getPrefix,
250
+ getNotificationTypesKeyWithPrefix,
251
+ buildNotification
247
252
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@neoimpulse/cap-js-notifications",
3
- "version": "1.0.6",
3
+ "version": "1.0.7",
4
4
  "description": "A CDS plugin to provide an easy action for the notification service",
5
5
  "main": "cds-plugin.js",
6
6
  "scripts": {
@@ -1,16 +1,16 @@
1
1
  [
2
- {
3
- "NotificationTypeKey": "ExampleMessage",
4
- "NotificationTypeVersion": "1",
5
- "Templates": [
6
- {
7
- "Language": "en",
8
- "TemplateSensitive": "Example {{Example_ID}} completed.",
9
- "TemplatePublic": "Rejected Example detected.",
10
- "TemplateGrouped": "Example for which you are responsible have been rejected.",
11
- "TemplateLanguage": "Mustache",
12
- "Subtitle": "The user {{Username}} has completed the unloading process for Example {{Example_ID}}. Please review and proceed with posting."
13
- }
14
- ]
15
- }
2
+ {
3
+ "NotificationTypeKey": "ExampleMessage",
4
+ "NotificationTypeVersion": "1",
5
+ "Templates": [
6
+ {
7
+ "Language": "en",
8
+ "TemplateSensitive": "Example {{Example_ID}} completed.",
9
+ "TemplatePublic": "Rejected Example detected.",
10
+ "TemplateGrouped": "Example for which you are responsible have been rejected.",
11
+ "TemplateLanguage": "Mustache",
12
+ "Subtitle": "The user {{Username}} has completed the unloading process for Example {{Example_ID}}. Please review and proceed with posting."
13
+ }
14
+ ]
15
+ }
16
16
  ]
@@ -1,44 +1,42 @@
1
1
  const cds = require("@sap/cds");
2
- const LOG = cds.log('notifications');
2
+ const LOG = cds.log("notifications");
3
3
  const { readFile, buildNotification } = require("../lib/utils");
4
4
 
5
5
  module.exports = class NotifyToConsole extends cds.Service {
6
- async init() {
6
+ async init() {
7
+ const notificationTypes = readFile(cds.env.requires?.notifications?.types);
8
+ const eventsToListen = notificationTypes.map((notificationType) => notificationType.NotificationTypeKey);
9
+ LOG._info && LOG.info(`Listening to events: ${eventsToListen.join(", ")}`);
7
10
 
8
- const notificationTypes = readFile(cds.env.requires?.notifications?.types);
9
- const eventsToListen = notificationTypes.map(notificationType => notificationType.NotificationTypeKey);
10
- LOG._info && LOG.info(`Listening to events: ${eventsToListen.join(", ")}`);
11
+ this.on(eventsToListen, (req) => {
12
+ LOG._debug && LOG.debug("Handling notification event:", req.event);
13
+ const type = req.event;
14
+ let message = req.data;
15
+ message.type = type;
16
+ message = buildNotification(message);
17
+ console.log(
18
+ "\n---------------------------------------------------------------\n" + "Notification:",
19
+ req.event,
20
+ message,
21
+ "\n---------------------------------------------------------------\n"
22
+ );
11
23
 
12
- this.on(eventsToListen, req => {
13
- LOG._debug && LOG.debug('Handling notification event:', req.event)
14
- const type = req.event
15
- let message = req.data
16
- message.type = type
17
- message = buildNotification(message);
18
- console.log (
19
- '\n---------------------------------------------------------------\n' +
20
- 'Notification:', req.event,
21
- message,
22
- '\n---------------------------------------------------------------\n',
23
- )
24
+ const { NotificationTypeKey, NotificationTypeVersion } = notification;
25
+ const types = cds.notifications.local.types; // REVISIT: what is this?
24
26
 
25
- const { NotificationTypeKey, NotificationTypeVersion } = notification
26
- const types = cds.notifications.local.types // REVISIT: what is this?
27
+ if (!(NotificationTypeKey in types)) {
28
+ LOG._warn && LOG.warn(`Notification Type ${NotificationTypeKey} is not in the notification types file`);
29
+ return;
30
+ }
27
31
 
28
- if (!(NotificationTypeKey in types)) {
29
- LOG._warn && LOG.warn(
30
- `Notification Type ${NotificationTypeKey} is not in the notification types file`
31
- );
32
- return;
33
- }
32
+ if (!(NotificationTypeVersion in types[NotificationTypeKey])) {
33
+ LOG._warn &&
34
+ LOG.warn(
35
+ `Notification Type Version ${NotificationTypeVersion} for type ${NotificationTypeKey} is not in the notification types file`
36
+ );
37
+ }
38
+ });
34
39
 
35
- if (!(NotificationTypeVersion in types[NotificationTypeKey])) {
36
- LOG._warn && LOG.warn(
37
- `Notification Type Version ${NotificationTypeVersion} for type ${NotificationTypeKey} is not in the notification types file`
38
- );
39
- }
40
- })
41
-
42
- return super.init()
43
- }
44
- }
40
+ return super.init();
41
+ }
42
+ };