@manyos/smileconnect-api 1.28.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (141) hide show
  1. package/.github/workflows/nodejs.yml +26 -0
  2. package/CHANGELOG.md +75 -0
  3. package/Dockerfile +21 -0
  4. package/README.md +1 -0
  5. package/app.js +316 -0
  6. package/conf/clients.json +2491 -0
  7. package/conf/mapping.json +1048 -0
  8. package/conf/scripts/p1.js +11 -0
  9. package/conf/scripts/p2.js +1 -0
  10. package/conf/scripts/p3.js +1 -0
  11. package/conf/scripts/p4.js +2 -0
  12. package/conf/scripts/script1.js +2 -0
  13. package/conf/scripts/script2.js +2 -0
  14. package/conf/scripts/script3.js +2 -0
  15. package/controller/cmdbobjectController.js +291 -0
  16. package/controller/eventLogController.js +78 -0
  17. package/controller/orgdataController.js +440 -0
  18. package/controller/relatedObjectsController.js +194 -0
  19. package/controller/scriptController.js +213 -0
  20. package/controller/taskController.js +368 -0
  21. package/controller/templateController.js +97 -0
  22. package/controller/ticketCIRelationController.js +522 -0
  23. package/controller/ticketController.js +329 -0
  24. package/controller/ticketWorkLogController.js +195 -0
  25. package/docs/.gitattributes +48 -0
  26. package/docs/404.html +13 -0
  27. package/docs/CNAME +1 -0
  28. package/docs/Gemfile +7 -0
  29. package/docs/Gemfile.lock +249 -0
  30. package/docs/_config.yml +257 -0
  31. package/docs/_data/SocialNetworks.yml +92 -0
  32. package/docs/_data/ui-text.yml +494 -0
  33. package/docs/_includes/disqus.html +17 -0
  34. package/docs/_includes/ext-css.html +7 -0
  35. package/docs/_includes/ext-js.html +7 -0
  36. package/docs/_includes/fb-comment.html +14 -0
  37. package/docs/_includes/footer-minimal.html +16 -0
  38. package/docs/_includes/footer-scripts.html +32 -0
  39. package/docs/_includes/footer.html +51 -0
  40. package/docs/_includes/google_analytics.html +14 -0
  41. package/docs/_includes/gtag.html +11 -0
  42. package/docs/_includes/gtm_body.html +6 -0
  43. package/docs/_includes/gtm_head.html +9 -0
  44. package/docs/_includes/head.html +131 -0
  45. package/docs/_includes/header.html +76 -0
  46. package/docs/_includes/just_comments.html +4 -0
  47. package/docs/_includes/matomo.html +17 -0
  48. package/docs/_includes/nav.html +57 -0
  49. package/docs/_includes/social-share.html +42 -0
  50. package/docs/_includes/staticman-comment.html +22 -0
  51. package/docs/_includes/staticman-comments.html +81 -0
  52. package/docs/_layouts/base.html +35 -0
  53. package/docs/_layouts/default.html +9 -0
  54. package/docs/_layouts/minimal.html +26 -0
  55. package/docs/_layouts/page.html +26 -0
  56. package/docs/_layouts/post.html +82 -0
  57. package/docs/_posts/2015-02-28-test-markdown.md +77 -0
  58. package/docs/aboutme.md +18 -0
  59. package/docs/css/bootstrap-social.css +147 -0
  60. package/docs/css/bootstrap-theme.css +476 -0
  61. package/docs/css/bootstrap-theme.css.map +1 -0
  62. package/docs/css/bootstrap-theme.min.css +5 -0
  63. package/docs/css/bootstrap.css +6566 -0
  64. package/docs/css/bootstrap.css.map +1 -0
  65. package/docs/css/bootstrap.min.css +5 -0
  66. package/docs/css/main-minimal.css +13 -0
  67. package/docs/css/main.css +788 -0
  68. package/docs/css/normalize.css +427 -0
  69. package/docs/css/pygment_highlights.css +61 -0
  70. package/docs/css/staticman.css +180 -0
  71. package/docs/eventlog/events.md +65 -0
  72. package/docs/feed.xml +24 -0
  73. package/docs/general/architecture.md +10 -0
  74. package/docs/general/config.md +192 -0
  75. package/docs/general/field-management.md +119 -0
  76. package/docs/general/release-notes.md +9 -0
  77. package/docs/getting-started.md +19 -0
  78. package/docs/howto/cmdbobjects.md +339 -0
  79. package/docs/howto/incident-worklogs.md +186 -0
  80. package/docs/howto/incidents.md +244 -0
  81. package/docs/howto/sample-config.md +518 -0
  82. package/docs/howto/token.md +71 -0
  83. package/docs/howto/worklog-attachment.md +113 -0
  84. package/docs/img/404-southpark.jpg +0 -0
  85. package/docs/img/architecture.jpeg +0 -0
  86. package/docs/img/attachment-upload.png +0 -0
  87. package/docs/img/avatar-icon.png +0 -0
  88. package/docs/img/bgimage.png +0 -0
  89. package/docs/img/gb-isapi.jpg +0 -0
  90. package/docs/img/install-steps.gif +0 -0
  91. package/docs/img/workflow.png +0 -0
  92. package/docs/index.md +41 -0
  93. package/docs/installation.md +123 -0
  94. package/docs/js/bootstrap.js +2306 -0
  95. package/docs/js/bootstrap.min.js +7 -0
  96. package/docs/js/jquery-1.11.2.min.js +4 -0
  97. package/docs/js/main.js +140 -0
  98. package/docs/js/staticman.js +54 -0
  99. package/docs/openapi.json +15097 -0
  100. package/docs/postinstall.md +169 -0
  101. package/docs/preinstall.md +19 -0
  102. package/docs/spec/index.html +24 -0
  103. package/docs/staticman.yml +110 -0
  104. package/docs/tags.html +34 -0
  105. package/docs/workflow.md +127 -0
  106. package/nodemon.json +3 -0
  107. package/package.json +46 -0
  108. package/routes/appConfigRoutes.js +352 -0
  109. package/routes/ciRelationRoutes.js +38 -0
  110. package/routes/cmdbObjectRoutes.js +154 -0
  111. package/routes/organisationRoutes.js +121 -0
  112. package/routes/peopleRelationRoutes.js +38 -0
  113. package/routes/personRoutes.js +131 -0
  114. package/routes/supportgroupRoutes.js +122 -0
  115. package/routes/taskRoutes.js +306 -0
  116. package/routes/templateRoutes.js +67 -0
  117. package/routes/ticketRoutes.js +181 -0
  118. package/routes/ticketWorkLogRoutes.js +185 -0
  119. package/screwdriver.yaml +52 -0
  120. package/test/appTest.js +3 -0
  121. package/test/changeTest.js +541 -0
  122. package/test/cmdbobjectTest.js +167 -0
  123. package/test/files/logo.png +0 -0
  124. package/test/incidentTest.js +539 -0
  125. package/test/orgdataTest.js +156 -0
  126. package/test/problemTest.js +512 -0
  127. package/test/templateTest.js +80 -0
  128. package/test/testUtils.js +21 -0
  129. package/test/workorderTest.js +544 -0
  130. package/util/arquery.js +416 -0
  131. package/util/auth.js +37 -0
  132. package/util/cache.service.js +52 -0
  133. package/util/config.js +361 -0
  134. package/util/constants.js +73 -0
  135. package/util/mappingUtil.js +96 -0
  136. package/util/paramHelper.js +43 -0
  137. package/util/relationUtil.js +63 -0
  138. package/util/responsehandler.js +92 -0
  139. package/util/schemas/clientConfigSchema.js +180 -0
  140. package/util/schemas/fieldMappingSchema.js +211 -0
  141. package/util/searchUtil.js +148 -0
@@ -0,0 +1,92 @@
1
+ const path = require('path');
2
+ const log = require('@manyos/logger').setupLog('SMILEconnect_' + path.basename(__filename));
3
+ const eventLog = require('../controller/eventLogController');
4
+
5
+ const VERSION = process.env.version;
6
+
7
+ function logRequest (req, res, next) {
8
+ let user = 'unauthorized';
9
+ if (req.user) {
10
+ user = req.user.id;
11
+ }
12
+ log.info ({
13
+ user: user,
14
+ method: req.method,
15
+ url: req.url,
16
+ smileId: req.smileId,
17
+ rateLimit: req.rateLimit
18
+ });
19
+ //log.info({req: req});
20
+ next();
21
+ }
22
+
23
+ function logErrors(err, req, res, next) {
24
+ /*log.error({
25
+ smileId : req.smileId,
26
+ error : err.stack || String(err)
27
+ });*/
28
+ log.error({err: err}, "oops");
29
+ //write to eventQueue if provided
30
+ if (req.eventData) {
31
+ const eventData = req.eventData;
32
+ eventLog.createErrorLog(
33
+ req.id,
34
+ req.user.azp,
35
+ eventData.ticketNumber,
36
+ eventData.schema,
37
+ eventData.event,
38
+ req.method + ':' + req.url,
39
+ JSON.stringify(err, null, 2) || String(err),
40
+ eventData.jsonData,
41
+ eventData.ticketNumber2);
42
+ }
43
+
44
+ next(err);
45
+ }
46
+
47
+ function errorHandler(err, req, res, next) {
48
+ const errorStack = err.stack;
49
+ const errorStatus = err.status || req.errorStatus || 500;
50
+ if (errorStatus == 401) {
51
+ res.status(errorStatus).json({"error": "You are not authorized for this request.", stackTrace: errorStack});
52
+ } else if (typeof errorStack === "string") {
53
+ res.status(errorStatus).json({"error": "Ooops. Something unexpected just happened.", "stackTrace":errorStack});
54
+ } else {
55
+ res.status(errorStatus).json({"error": err});
56
+ }
57
+ }
58
+
59
+ //createSuccessLog(client, ticketNumber, schemaName, eventName, url, jsonData) {
60
+ function eventQueueHandler(req, res, next) {
61
+ //add version to header as debug info
62
+ res.setHeader('x-smileconnect-version', VERSION || '0.0.0');
63
+ log.debug({req:req}, 'start');
64
+ //write to eventQueue if provided
65
+ if (req.eventData) {
66
+ const eventData = req.eventData;
67
+ eventLog.createSuccessLog(
68
+ req.id,
69
+ req.user.azp,
70
+ eventData.ticketNumber,
71
+ eventData.schema,
72
+ eventData.event,
73
+ req.method + ':' + req.url,
74
+ eventData.jsonData,
75
+ eventData.ticketNumber2).then( success => {
76
+ if (req.downloadResult) {
77
+ res.set('Content-disposition', 'attachment; filename=' + req.downloadResult.fileName);
78
+ res.status(200).send(req.downloadResult.data);
79
+ } else {
80
+ res.status(req.responseStatus || 200).json(req.result)
81
+ }
82
+ }).catch(error => {
83
+ next(error);
84
+ });
85
+ } else {
86
+ next();
87
+ }
88
+ }
89
+
90
+ module.exports = {
91
+ logErrors, errorHandler, eventQueueHandler, logRequest
92
+ };
@@ -0,0 +1,180 @@
1
+ const clientConfigSchema = {
2
+ 'data.name': {
3
+ in: ['body'],
4
+ isLength: {options: { min: 3 }}
5
+ },
6
+ 'data.config.incident.basequery': {
7
+ in: ['body'],
8
+ isString : {
9
+ errorMessage: 'Needs to be a string'
10
+ }
11
+ },
12
+ 'data.config.incident.constants.*.name': {
13
+ in: ['body'],
14
+ exists: {
15
+ errorMessage: 'name is required'
16
+ },
17
+ isString : {
18
+ errorMessage: 'Needs to be a string'
19
+ }
20
+ },
21
+ 'data.config.incident.constants.*.value': {
22
+ in: ['body'],
23
+ exists: {
24
+ errorMessage: 'Value is required'
25
+ },
26
+ isString : {
27
+ errorMessage: 'Needs to be a string'
28
+ }
29
+ },
30
+ 'data.config.incident.fields': {
31
+ in: ['body'],
32
+ exists: {
33
+ errorMessage: 'Fields need to be defined'
34
+ }
35
+ },
36
+ 'data.config.incident.fields.*': {
37
+ in: ['body'],
38
+ exists: {
39
+ errorMessage: 'Fields need to be defined'
40
+ },
41
+ isString : {
42
+ errorMessage: 'Needs to be a string'
43
+ }
44
+ },
45
+ 'data.config.workOrder.basequery': {
46
+ in: ['body'],
47
+ isString : {
48
+ errorMessage: 'Needs to be a string'
49
+ }
50
+ },
51
+ 'data.config.workOrder.constants.*.name': {
52
+ in: ['body'],
53
+ exists: {
54
+ errorMessage: 'name is required'
55
+ },
56
+ isString : {
57
+ errorMessage: 'Needs to be a string'
58
+ }
59
+ },
60
+ 'data.config.workOrder.constants.*.value': {
61
+ in: ['body'],
62
+ exists: {
63
+ errorMessage: 'Value is required'
64
+ },
65
+ isString : {
66
+ errorMessage: 'Needs to be a string'
67
+ }
68
+ },
69
+ 'data.config.workOrder.fields': {
70
+ in: ['body'],
71
+ exists: {
72
+ errorMessage: 'Fields need to be defined'
73
+ }
74
+ },
75
+ 'data.config.workOrder.fields.*': {
76
+ in: ['body'],
77
+ exists: {
78
+ errorMessage: 'Fields need to be defined'
79
+ },
80
+ isString : {
81
+ errorMessage: 'Needs to be a string'
82
+ }
83
+ },
84
+ 'data.config.change.basequery': {
85
+ in: ['body'],
86
+ isString : {
87
+ errorMessage: 'Needs to be a string'
88
+ }
89
+ },
90
+ 'data.config.change.constants.*.name': {
91
+ in: ['body'],
92
+ exists: {
93
+ errorMessage: 'name is required'
94
+ },
95
+ isString : {
96
+ errorMessage: 'Needs to be a string'
97
+ }
98
+ },
99
+ 'data.config.change.constants.*.value': {
100
+ in: ['body'],
101
+ exists: {
102
+ errorMessage: 'Value is required'
103
+ },
104
+ isString : {
105
+ errorMessage: 'Needs to be a string'
106
+ }
107
+ },
108
+ 'data.config.change.fields': {
109
+ in: ['body'],
110
+ exists: {
111
+ errorMessage: 'Fields need to be defined'
112
+ }
113
+ },
114
+ 'data.config.change.fields.*': {
115
+ in: ['body'],
116
+ exists: {
117
+ errorMessage: 'Fields need to be defined'
118
+ },
119
+ isString : {
120
+ errorMessage: 'Needs to be a string'
121
+ }
122
+ },
123
+ 'data.config.problem.basequery': {
124
+ in: ['body'],
125
+ isString : {
126
+ errorMessage: 'Needs to be a string'
127
+ }
128
+ },
129
+ 'data.config.problem.constants.*.name': {
130
+ in: ['body'],
131
+ exists: {
132
+ errorMessage: 'name is required'
133
+ },
134
+ isString : {
135
+ errorMessage: 'Needs to be a string'
136
+ }
137
+ },
138
+ 'data.config.problem.constants.*.value': {
139
+ in: ['body'],
140
+ exists: {
141
+ errorMessage: 'Value is required'
142
+ },
143
+ isString : {
144
+ errorMessage: 'Needs to be a string'
145
+ }
146
+ },
147
+ 'data.config.problem.fields': {
148
+ in: ['body'],
149
+ exists: {
150
+ errorMessage: 'Fields need to be defined'
151
+ }
152
+ },
153
+ 'data.config.problem.fields.*': {
154
+ in: ['body'],
155
+ exists: {
156
+ errorMessage: 'Fields need to be defined'
157
+ },
158
+ isString : {
159
+ errorMessage: 'Needs to be a string'
160
+ }
161
+ }
162
+ /*Find some samples here,
163
+ text: {
164
+ isString : {
165
+ errorMessage: 'Needs to be a string'
166
+ },
167
+ isAlphanumeric: {
168
+ errorMessage: 'Needs to be alphanumeric'
169
+ },
170
+ isLength: {
171
+ errorMessage: 'Needs to be between 3 and 30 chars',
172
+ options: {min: 3, max: 30}
173
+ },
174
+ exists: {
175
+ errorMessage: 'is required'
176
+ }
177
+ }*/
178
+ };
179
+
180
+ module.exports = clientConfigSchema;
@@ -0,0 +1,211 @@
1
+ const fieldMappingItemSchema = {
2
+ 'data' : {
3
+ in: ['body'],
4
+ exists: {
5
+ errorMessage: 'Is required'
6
+ }
7
+ },
8
+ 'data.*.oldName': {
9
+ in: ['body'],
10
+ exists: {
11
+ errorMessage: 'Is required'
12
+ },
13
+ isString : {
14
+ errorMessage: 'Needs to be a string'
15
+ }
16
+ },
17
+ 'data.*.newName': {
18
+ in: ['body'],
19
+ exists: {
20
+ errorMessage: 'Is required'
21
+ },
22
+ isString : {
23
+ errorMessage: 'Needs to be a string'
24
+ }
25
+ }
26
+ /*Find some samples here,
27
+ text: {
28
+ isString : {
29
+ errorMessage: 'Needs to be a string'
30
+ },
31
+ isAlphanumeric: {
32
+ errorMessage: 'Needs to be alphanumeric'
33
+ },
34
+ isLength: {
35
+ errorMessage: 'Needs to be between 3 and 30 chars',
36
+ options: {min: 3, max: 30}
37
+ },
38
+ exists: {
39
+ errorMessage: 'is required'
40
+ }
41
+ }*/
42
+ };
43
+
44
+ const validateCMDBDataSchema = {
45
+ 'ciChanges' : {
46
+ in: ['body'],
47
+ exists: {
48
+ errorMessage: 'Is required'
49
+ }
50
+ },
51
+ 'ciChanges.*.ciId': {
52
+ in: ['body'],
53
+ exists: {
54
+ errorMessage: 'Is required'
55
+ },
56
+ isString : {
57
+ errorMessage: 'Needs to be a string'
58
+ }
59
+ },
60
+ 'ciChanges.*.attributes': {
61
+ in: ['body'],
62
+ exists: {
63
+ errorMessage: 'Is required'
64
+ }
65
+ }
66
+ };
67
+
68
+ const fieldMappingSchema = {
69
+ 'data' : {
70
+ in: ['body'],
71
+ exists: {
72
+ errorMessage: 'Is required'
73
+ }
74
+ },
75
+ 'data.cmdbobject' : {
76
+ in: ['body'],
77
+ exists: {
78
+ errorMessage: 'Is required'
79
+ }
80
+ },
81
+ 'data.person' : {
82
+ in: ['body'],
83
+ exists: {
84
+ errorMessage: 'Is required'
85
+ }
86
+ },
87
+ 'data.change' : {
88
+ in: ['body'],
89
+ exists: {
90
+ errorMessage: 'Is required'
91
+ }
92
+ },
93
+ 'data.newChange' : {
94
+ in: ['body'],
95
+ exists: {
96
+ errorMessage: 'Is required'
97
+ }
98
+ },
99
+ 'data.changeWorklog' : {
100
+ in: ['body'],
101
+ exists: {
102
+ errorMessage: 'Is required'
103
+ }
104
+ },
105
+ 'data.workOrder' : {
106
+ in: ['body'],
107
+ exists: {
108
+ errorMessage: 'Is required'
109
+ }
110
+ },
111
+ 'data.newWorkOrder' : {
112
+ in: ['body'],
113
+ exists: {
114
+ errorMessage: 'Is required'
115
+ }
116
+ },
117
+ 'data.workOrderWorklog' : {
118
+ in: ['body'],
119
+ exists: {
120
+ errorMessage: 'Is required'
121
+ }
122
+ },
123
+ 'data.incident' : {
124
+ in: ['body'],
125
+ exists: {
126
+ errorMessage: 'Is required'
127
+ }
128
+ },
129
+ 'data.newIncident' : {
130
+ in: ['body'],
131
+ exists: {
132
+ errorMessage: 'Is required'
133
+ }
134
+ },
135
+ 'data.incidentWorklog' : {
136
+ in: ['body'],
137
+ exists: {
138
+ errorMessage: 'Is required'
139
+ }
140
+ },
141
+ 'data.problem' : {
142
+ in: ['body'],
143
+ exists: {
144
+ errorMessage: 'Is required'
145
+ }
146
+ },
147
+ 'data.newProblem' : {
148
+ in: ['body'],
149
+ exists: {
150
+ errorMessage: 'Is required'
151
+ }
152
+ },
153
+ 'data.problemWorklog' : {
154
+ in: ['body'],
155
+ exists: {
156
+ errorMessage: 'Is required'
157
+ }
158
+ },
159
+ 'data.task' : {
160
+ in: ['body'],
161
+ exists: {
162
+ errorMessage: 'Is required'
163
+ }
164
+ },
165
+ 'data.newTask' : {
166
+ in: ['body'],
167
+ exists: {
168
+ errorMessage: 'Is required'
169
+ }
170
+ },
171
+ 'data.taskWorklog' : {
172
+ in: ['body'],
173
+ exists: {
174
+ errorMessage: 'Is required'
175
+ }
176
+ },
177
+ 'data.flowBuilder' : {
178
+ in: ['body'],
179
+ exists: {
180
+ errorMessage: 'Is required'
181
+ }
182
+ },
183
+ 'data.cmdbobject' : {
184
+ in: ['body'],
185
+ exists: {
186
+ errorMessage: 'Is required'
187
+ }
188
+ },
189
+ 'data.*.*.oldName': {
190
+ in: ['body'],
191
+ exists: {
192
+ errorMessage: 'Is required'
193
+ },
194
+ isString : {
195
+ errorMessage: 'Needs to be a string'
196
+ }
197
+ },
198
+ 'data.*.*.newName': {
199
+ in: ['body'],
200
+ exists: {
201
+ errorMessage: 'Is required'
202
+ },
203
+ isString : {
204
+ errorMessage: 'Needs to be a string'
205
+ }
206
+ }
207
+ };
208
+
209
+ module.exports = {
210
+ fieldMappingSchema, fieldMappingItemSchema, validateCMDBDataSchema
211
+ };
@@ -0,0 +1,148 @@
1
+ const path = require('path');
2
+ const log = require('@manyos/logger').setupLog('SMILEconnect_' + path.basename(__filename));
3
+
4
+ function applyMapping(searchString, mapping) {
5
+ log.debug('Apply mapping on', searchString, mapping);
6
+ let mappedString = searchString;
7
+ mapping.forEach(function (mappingEntry) {
8
+ mappedString = mappedString.replace(new RegExp("'" + mappingEntry.newName + "'", 'g'), "'" + mappingEntry.oldName + "'");
9
+ });
10
+ log.debug('Mapped searchString', mappedString);
11
+ return mappedString;
12
+ }
13
+
14
+ function applySortMapping(sortOptions, mapping) {
15
+ log.debug('Apply mapping on', sortOptions, mapping);
16
+ if (sortOptions == null || sortOptions == undefined) {
17
+ return sortOptions;
18
+ }
19
+ const mappedOptions = {};
20
+ Object.keys(sortOptions).forEach(key => {
21
+ mapping.forEach(function (mappingEntry) {
22
+ if (mappingEntry.newName === key) {
23
+ mappedOptions[mappingEntry.oldName] = sortOptions[key];
24
+ }
25
+ });
26
+ });
27
+ log.debug('Mapped sortOptions', mappedOptions);
28
+ return mappedOptions;
29
+ }
30
+
31
+ function getCustomFields(clientFields, mapping, requestedFields) {
32
+ log.debug('get custom fields', requestedFields);
33
+ log.debug('clientFields fields', clientFields);
34
+ //return clientFields if null
35
+ if (requestedFields === null || requestedFields === undefined || !Array.isArray(requestedFields)) {
36
+ log.debug('no custom fields requested. return clientFields');
37
+ return clientFields;
38
+ } else {
39
+ const customFields = [];
40
+ const mappedFields = mapFieldNames(requestedFields, mapping);
41
+ mappedFields.forEach(requestedField => {
42
+ if (clientFields.includes(requestedField)) {
43
+ customFields.push(requestedField);
44
+ }
45
+ });
46
+ log.debug('customFields', customFields);
47
+ return customFields;
48
+ }
49
+ }
50
+
51
+ function mapFieldNames(customFields, mapping) {
52
+ log.debug('Apply field mapping on', customFields, mapping);
53
+ const mappedFields = [];
54
+ customFields.forEach(customField => {
55
+ mapping.forEach(mappingEntry => {
56
+ if (mappingEntry.newName === customField) {
57
+ mappedFields.push(mappingEntry.oldName);
58
+ }
59
+ });
60
+ });
61
+ log.debug('mapped fields', mappedFields);
62
+ return mappedFields;
63
+ }
64
+
65
+ function mapFieldName(customField, mapping) {
66
+ const result = mapFieldNames([customField], mapping);
67
+ if (result !== null && result !== undefined) {
68
+ return result[0];
69
+ } else {
70
+ return null;
71
+ }
72
+ }
73
+
74
+ function mapFieldNamesReverse(customFields, mapping) {
75
+ log.debug('Apply field mapping on', customFields, mapping);
76
+ const mappedFields = [];
77
+ customFields.forEach(customField => {
78
+ mapping.forEach(mappingEntry => {
79
+ if (mappingEntry.oldName === customField) {
80
+ mappedFields.push(mappingEntry.newName);
81
+ }
82
+ });
83
+ });
84
+ log.debug('mapped fields', mappedFields);
85
+ return mappedFields;
86
+ }
87
+
88
+ function mapFieldNameReverse(customField, mapping) {
89
+ const result = mapFieldNamesReverse([customField], mapping);
90
+ if (result !== null && result !== undefined) {
91
+ return result[0];
92
+ } else {
93
+ return null;
94
+ }
95
+ }
96
+
97
+ function applyMapping2record (myEntry, clientConfig, mapping) {
98
+ const constants = clientConfig['cmdbobject'].constants;
99
+ const allowedFields = clientConfig['cmdbobject'].fields;
100
+ //apply mapping
101
+ if (mapping != null && mapping != undefined) {
102
+ Object.keys(myEntry).forEach(function (objectKey) {
103
+ const found = mapping.find(function(element) {
104
+ //check if field is included in mapping and if it in accessible field list
105
+ return (element.newName === objectKey && allowedFields.includes(element.oldName));
106
+ });
107
+
108
+ if (found == null || found=== undefined) {
109
+ log.debug('delete', objectKey)
110
+ delete myEntry[objectKey];
111
+ }
112
+ });
113
+ mapping.forEach(function (mappingEntry) {
114
+ try {
115
+ Object.defineProperty(myEntry, mappingEntry.oldName, Object.getOwnPropertyDescriptor(myEntry, mappingEntry.newName));
116
+ //delete mapping only if no self mapping
117
+ if (!(mappingEntry.newName == mappingEntry.oldName)) {
118
+ delete myEntry[mappingEntry.newName];
119
+ }
120
+ } catch (e) {
121
+ //ignore missing mapping
122
+ }
123
+ });
124
+ }
125
+ //add constant values (defaults)
126
+ if (constants && Array.isArray(constants) && constants.length) {
127
+
128
+ constants.forEach(function (element) {
129
+ log.debug('add constant', element);
130
+ try {
131
+ myEntry[element.name] = element.value;
132
+ } catch (e) {
133
+ log.error(e);
134
+ }
135
+
136
+ });
137
+ }
138
+ return myEntry;
139
+ }
140
+
141
+ module.exports = {
142
+ applyMapping,
143
+ applySortMapping,
144
+ getCustomFields,
145
+ mapFieldName,
146
+ mapFieldNameReverse,
147
+ applyMapping2record
148
+ };