@contrail/flexplm 1.3.0-alpha.0 → 1.3.0-alpha.3

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 (123) hide show
  1. package/.github/pull_request_template.md +31 -31
  2. package/.github/workflows/flexplm-lib.yml +27 -27
  3. package/CHANGELOG.md +1 -1
  4. package/lib/entity-processor/base-entity-processor.d.ts +42 -0
  5. package/lib/entity-processor/base-entity-processor.js +377 -0
  6. package/lib/entity-processor/base-entity-processor.spec.d.ts +1 -0
  7. package/lib/entity-processor/base-entity-processor.spec.js +426 -0
  8. package/lib/flexplm-request.d.ts +3 -0
  9. package/lib/flexplm-request.js +34 -0
  10. package/lib/flexplm-utils.d.ts +5 -0
  11. package/lib/flexplm-utils.js +33 -0
  12. package/lib/flexplm-utils.spec.d.ts +1 -0
  13. package/lib/flexplm-utils.spec.js +26 -0
  14. package/lib/index.d.ts +22 -0
  15. package/lib/index.js +38 -0
  16. package/lib/interfaces/interfaces.d.ts +105 -0
  17. package/lib/interfaces/interfaces.js +2 -0
  18. package/lib/interfaces/item-family-changes.d.ts +20 -0
  19. package/lib/interfaces/item-family-changes.js +56 -0
  20. package/lib/interfaces/publish-change-data.d.ts +19 -0
  21. package/lib/interfaces/publish-change-data.js +32 -0
  22. package/lib/publish/base-process-publish-assortment-callback.d.ts +9 -0
  23. package/lib/publish/base-process-publish-assortment-callback.js +38 -0
  24. package/lib/publish/base-process-publish-assortment.d.ts +93 -0
  25. package/lib/publish/base-process-publish-assortment.js +944 -0
  26. package/lib/publish/base-process-publish-assortment.spec.d.ts +1 -0
  27. package/lib/publish/base-process-publish-assortment.spec.js +1670 -0
  28. package/lib/publish/mockData.d.ts +1389 -0
  29. package/lib/publish/mockData.js +4519 -0
  30. package/lib/transform/identifier-conversion-spec-mockData.d.ts +0 -0
  31. package/lib/transform/identifier-conversion-spec-mockData.js +444 -0
  32. package/lib/transform/identifier-conversion.d.ts +15 -0
  33. package/lib/transform/identifier-conversion.js +212 -0
  34. package/lib/transform/identifier-conversion.spec.d.ts +1 -0
  35. package/lib/transform/identifier-conversion.spec.js +339 -0
  36. package/lib/util/config-defaults.d.ts +8 -0
  37. package/lib/util/config-defaults.js +85 -0
  38. package/lib/util/config-defaults.spec.d.ts +1 -0
  39. package/lib/util/config-defaults.spec.js +293 -0
  40. package/lib/util/data-converter-spec-mockData.d.ts +0 -0
  41. package/lib/util/data-converter-spec-mockData.js +205 -0
  42. package/lib/util/data-converter.d.ts +39 -0
  43. package/lib/util/data-converter.js +592 -0
  44. package/lib/util/data-converter.spec.d.ts +1 -0
  45. package/lib/util/data-converter.spec.js +904 -0
  46. package/lib/util/error-response-object.d.ts +4 -0
  47. package/lib/util/error-response-object.js +47 -0
  48. package/lib/util/error-response-object.spec.d.ts +1 -0
  49. package/lib/util/error-response-object.spec.js +99 -0
  50. package/lib/util/event-short-message-status.d.ts +18 -0
  51. package/lib/util/event-short-message-status.js +22 -0
  52. package/lib/util/federation.d.ts +15 -0
  53. package/lib/util/federation.js +149 -0
  54. package/lib/util/flexplm-connect.d.ts +22 -0
  55. package/lib/util/flexplm-connect.js +176 -0
  56. package/lib/util/flexplm-connect.spec.d.ts +1 -0
  57. package/lib/util/flexplm-connect.spec.js +88 -0
  58. package/lib/util/logger-config.d.ts +1 -0
  59. package/lib/util/logger-config.js +26 -0
  60. package/lib/util/map-util-spec-mockData.d.ts +0 -0
  61. package/lib/util/map-util-spec-mockData.js +205 -0
  62. package/lib/util/map-utils.d.ts +6 -0
  63. package/lib/util/map-utils.js +15 -0
  64. package/lib/util/map-utils.spec.d.ts +1 -0
  65. package/lib/util/map-utils.spec.js +89 -0
  66. package/lib/util/mockData.d.ts +79 -0
  67. package/lib/util/mockData.js +99 -0
  68. package/lib/util/thumbnail-util.d.ts +28 -0
  69. package/lib/util/thumbnail-util.js +202 -0
  70. package/lib/util/thumbnail-util.spec.d.ts +1 -0
  71. package/lib/util/thumbnail-util.spec.js +398 -0
  72. package/lib/util/type-conversion-utils-spec-mockData.d.ts +0 -0
  73. package/lib/util/type-conversion-utils-spec-mockData.js +259 -0
  74. package/lib/util/type-conversion-utils.d.ts +23 -0
  75. package/lib/util/type-conversion-utils.js +266 -0
  76. package/lib/util/type-conversion-utils.spec.d.ts +1 -0
  77. package/lib/util/type-conversion-utils.spec.js +868 -0
  78. package/lib/util/type-defaults.d.ts +16 -0
  79. package/lib/util/type-defaults.js +221 -0
  80. package/lib/util/type-defaults.spec.d.ts +1 -0
  81. package/lib/util/type-defaults.spec.js +516 -0
  82. package/lib/util/type-utils.d.ts +13 -0
  83. package/lib/util/type-utils.js +114 -0
  84. package/lib/util/type-utils.spec.d.ts +1 -0
  85. package/lib/util/type-utils.spec.js +190 -0
  86. package/package.json +1 -1
  87. package/publish.bat +4 -4
  88. package/publish.sh +4 -4
  89. package/src/entity-processor/base-entity-processor.spec.ts +157 -0
  90. package/src/entity-processor/base-entity-processor.ts +21 -2
  91. package/src/flexplm-request.ts +28 -28
  92. package/src/flexplm-utils.spec.ts +27 -27
  93. package/src/flexplm-utils.ts +29 -29
  94. package/src/index.ts +21 -21
  95. package/src/interfaces/item-family-changes.ts +66 -66
  96. package/src/interfaces/publish-change-data.ts +42 -42
  97. package/src/publish/base-process-publish-assortment-callback.ts +50 -50
  98. package/src/transform/identifier-conversion-spec-mockData.ts +495 -495
  99. package/src/transform/identifier-conversion.spec.ts +353 -353
  100. package/src/transform/identifier-conversion.ts +281 -281
  101. package/src/util/config-defaults.spec.ts +350 -350
  102. package/src/util/config-defaults.ts +92 -92
  103. package/src/util/data-converter-spec-mockData.ts +230 -230
  104. package/src/util/error-response-object.spec.ts +115 -115
  105. package/src/util/error-response-object.ts +49 -49
  106. package/src/util/federation.ts +172 -172
  107. package/src/util/logger-config.ts +19 -19
  108. package/src/util/map-util-spec-mockData.ts +230 -230
  109. package/src/util/map-utils.spec.ts +102 -102
  110. package/src/util/map-utils.ts +40 -40
  111. package/src/util/mockData.ts +97 -97
  112. package/src/util/thumbnail-util.spec.ts +190 -0
  113. package/src/util/thumbnail-util.ts +109 -1
  114. package/src/util/type-conversion-utils.spec.ts +25 -25
  115. package/src/util/type-conversion-utils.ts +10 -9
  116. package/src/util/type-defaults.spec.ts +668 -668
  117. package/src/util/type-defaults.ts +280 -280
  118. package/src/util/type-utils.spec.ts +227 -227
  119. package/src/util/type-utils.ts +144 -144
  120. package/tsconfig.json +28 -26
  121. package/tslint.json +57 -57
  122. package/scripts/output.png +0 -0
  123. package/scripts/test-get-request.ts +0 -35
@@ -0,0 +1,592 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.DataConverter = void 0;
4
+ const sdk_1 = require("@contrail/sdk");
5
+ const type_utils_1 = require("./type-utils");
6
+ const app_framework_1 = require("@contrail/app-framework");
7
+ const util_1 = require("@contrail/util");
8
+ const type_conversion_utils_1 = require("./type-conversion-utils");
9
+ const map_utils_1 = require("./map-utils");
10
+ class DataConverter {
11
+ static clearStaticUserCache() {
12
+ DataConverter.staticUserCache = {};
13
+ }
14
+ static getFromStaticCache(id) {
15
+ return DataConverter.staticUserCache[id];
16
+ }
17
+ static setToStaticCache(id, value) {
18
+ DataConverter.staticUserCache[id] = value;
19
+ }
20
+ constructor(config, mapFileUtil) {
21
+ this.config = config;
22
+ this.mapFileUtil = mapFileUtil;
23
+ this.useDisplayForEnumerationMatching = false;
24
+ this.verboseDebug = false;
25
+ this.objRefCache = {};
26
+ this.userRefCache = {};
27
+ this.typeUtils = new type_utils_1.TypeUtils();
28
+ this.transformMapFile = this.config['transformMapFile'];
29
+ this.useDisplayForEnumerationMatching = this.config['dataConverter']
30
+ && this.config['dataConverter']['useDisplayForEnumerationMatching'];
31
+ this.verboseDebug = this.config['dataConverter']
32
+ && this.config['dataConverter']['verboseDebug'];
33
+ }
34
+ setVerboseDebug(val = false) {
35
+ this.verboseDebug = val;
36
+ }
37
+ isVerboseDebugOn() {
38
+ return this.verboseDebug && app_framework_1.Logger.isDebugOn();
39
+ }
40
+ async getFlexPLMObjectDataFromEvent(event, dataToSkip) {
41
+ return this.getFlexPLMObjectData(event.newData, dataToSkip, true);
42
+ }
43
+ async getFlexPLMObjectData(newData, dataToSkip, inflateObjRef) {
44
+ if (this.isVerboseDebugOn()) {
45
+ console.debug('newData: ' + JSON.stringify(newData));
46
+ }
47
+ dataToSkip = dataToSkip.concat(['updatedOn', 'updatedById', 'createdOn', 'createdById', 'modifiedAt', 'orgId', 'createdAt', 'id', 'typeId', 'workspaceId']);
48
+ const data = {};
49
+ const typeId = newData?.typeId;
50
+ if (!typeId) {
51
+ return;
52
+ }
53
+ data['typePath'] = newData['typePath'];
54
+ const type = await this.typeUtils.getTypeById(typeId);
55
+ const typeProps = this.typeUtils.filterTypeProperties(type, newData);
56
+ for (const prop of typeProps) {
57
+ const slug = prop['slug'];
58
+ if (dataToSkip.includes(slug)) {
59
+ continue;
60
+ }
61
+ data[slug] = await this.getFlexPLMValue(prop, newData, inflateObjRef);
62
+ }
63
+ if (this.isVerboseDebugOn()) {
64
+ console.debug('getFlexPLMObjectData-data: ' + JSON.stringify(data));
65
+ }
66
+ return data;
67
+ }
68
+ async getFlexPLMValue(prop, newData, inflateObjRef) {
69
+ const propertyType = prop['propertyType'];
70
+ const slug = prop['slug'];
71
+ const nd = newData[slug];
72
+ let value;
73
+ if (['string', 'text'].includes(propertyType)) {
74
+ value = nd || '';
75
+ }
76
+ else if (['number', 'currency', 'percent', 'sequence'].includes(propertyType)) {
77
+ value = nd || 0;
78
+ }
79
+ else if ('date' === propertyType) {
80
+ if (nd) {
81
+ value = nd;
82
+ }
83
+ else {
84
+ value = null;
85
+ }
86
+ }
87
+ else if ('boolean' === propertyType) {
88
+ value = (nd) ? true : false;
89
+ }
90
+ else if ('choice' === propertyType) {
91
+ value = this.getEnumerationValue(prop, nd);
92
+ }
93
+ else if ('multi_select' === propertyType) {
94
+ value = this.getEnumerationValue(prop, nd);
95
+ }
96
+ else if ('object_reference' === propertyType) {
97
+ value = await this.getObjectReferenceValue(prop, newData, inflateObjRef);
98
+ if (this.isVerboseDebugOn()) {
99
+ console.debug('object_reference: ' + JSON.stringify(value));
100
+ }
101
+ }
102
+ else if ('image' === propertyType) {
103
+ }
104
+ else if ('formula' === propertyType) {
105
+ value = nd;
106
+ }
107
+ else if ('json' === propertyType) {
108
+ value = nd;
109
+ }
110
+ else if ('userList' === propertyType) {
111
+ value = await this.getUserListValue(prop, newData);
112
+ }
113
+ return value;
114
+ }
115
+ getEnumerationValue(prop, nd) {
116
+ const propertyType = prop['propertyType'];
117
+ let value;
118
+ if (['choice', 'multi_select'].includes(propertyType)) {
119
+ const options = prop['options'] || [];
120
+ if ('choice' === propertyType) {
121
+ if (nd) {
122
+ const option = options.find(option => option.value == nd);
123
+ if (option) {
124
+ value = Object.assign({}, option);
125
+ }
126
+ }
127
+ if (!value) {
128
+ value = {};
129
+ }
130
+ }
131
+ else if ('multi_select' === propertyType) {
132
+ value = [];
133
+ if (nd instanceof Array) {
134
+ nd.forEach(key => {
135
+ const optionObject = options.find(option => option.value == key);
136
+ if (optionObject) {
137
+ const option = Object.assign({}, optionObject);
138
+ value.push(option);
139
+ }
140
+ });
141
+ }
142
+ else if (typeof nd === 'string' && '' !== nd) {
143
+ const optionObject = options.find(option => option.value == nd);
144
+ if (optionObject) {
145
+ const option = Object.assign({}, optionObject);
146
+ value.push(option);
147
+ }
148
+ }
149
+ }
150
+ }
151
+ return value;
152
+ }
153
+ async getObjectReferenceValue(prop, newData, inflateObjRef = false) {
154
+ const slug = prop['slug'];
155
+ if (app_framework_1.Logger.isDebugOn()) {
156
+ console.debug('getObjectReferenceValue-prop: ' + slug);
157
+ }
158
+ let value = newData[slug];
159
+ const entityType = prop['referencedTypeRootSlug'];
160
+ const entityId = newData[slug + 'Id'];
161
+ if ((!value || typeof value === 'string') && inflateObjRef) {
162
+ if (entityId) {
163
+ if (this.objRefCache[entityId]) {
164
+ if (app_framework_1.Logger.isDebugOn()) {
165
+ console.debug('cache hit: ' + entityId);
166
+ }
167
+ return this.objRefCache[entityId];
168
+ }
169
+ const criteria = {
170
+ id: entityId
171
+ };
172
+ const entities = await new sdk_1.Entities().get({
173
+ entityName: entityType,
174
+ criteria
175
+ });
176
+ value = (entities && entities[0]) ? entities[0] : undefined;
177
+ }
178
+ }
179
+ if (value && !(typeof value === 'string')) {
180
+ const unprocessedValue = value;
181
+ const objectClass = await type_conversion_utils_1.TypeConversionUtils.getObjectClass(this.transformMapFile, this.mapFileUtil, unprocessedValue);
182
+ const flexPLMTypePath = await type_conversion_utils_1.TypeConversionUtils.getObjectTypePath(this.transformMapFile, this.mapFileUtil, unprocessedValue);
183
+ value = await this.getFlexPLMObjectData(value, [], false);
184
+ value['entityReference'] = entityType + ':' + entityId;
185
+ value['objectClass'] = objectClass;
186
+ value['flexPLMTypePath'] = flexPLMTypePath;
187
+ if (this.transformMapFile) {
188
+ const mapKey = await type_conversion_utils_1.TypeConversionUtils.getMapKey(this.transformMapFile, this.mapFileUtil, unprocessedValue, type_conversion_utils_1.TypeConversionUtils.VIBE2FLEX_DIRECTION);
189
+ value = await map_utils_1.MapUtil.applyTransformMap(this.transformMapFile, this.mapFileUtil, value, mapKey, type_conversion_utils_1.TypeConversionUtils.VIBE2FLEX_DIRECTION);
190
+ }
191
+ }
192
+ else {
193
+ value = {};
194
+ }
195
+ this.objRefCache[entityId] = value;
196
+ return value;
197
+ }
198
+ getMappingClass(entity, mapping) {
199
+ const entityTypePath = entity['typePath'];
200
+ const typeMapKey = mapping['typeMapKey'];
201
+ let objClass = typeMapKey[entityTypePath];
202
+ const entityType = entity['entityType'];
203
+ if (!objClass) {
204
+ objClass = this.typeUtils.getEventObjectClass(entityType, entity);
205
+ }
206
+ if (!objClass) {
207
+ objClass = entityType;
208
+ }
209
+ return objClass;
210
+ }
211
+ async setEntityValues(entity, data, keysToSkip = []) {
212
+ const type = await this.typeUtils.getTypeById(entity.typeId);
213
+ keysToSkip = keysToSkip.concat(['updatedOn', 'updatedById', 'createdOn', 'createdById', 'modifiedAt', 'orgId', 'createdAt', 'id', 'typeId', 'typePath', 'workspaceId']);
214
+ let typeProps = this.typeUtils.filterTypeProperties(type, entity);
215
+ typeProps = typeProps.filter(prop => !keysToSkip.includes(prop['slug']));
216
+ const dataKeys = Object.getOwnPropertyNames(data);
217
+ typeProps = typeProps.filter(prop => dataKeys.includes(prop['slug']));
218
+ for (const prop of typeProps) {
219
+ const propertyType = prop['propertyType'];
220
+ const slug = prop['slug'];
221
+ let keyName = slug;
222
+ if (propertyType === 'userList' || propertyType === 'object_reference') {
223
+ keyName = slug + 'Id';
224
+ }
225
+ entity[keyName] = await this.getEntityValue(prop, data);
226
+ }
227
+ return entity;
228
+ }
229
+ async getEntityValues(objectClass, data, keysToSkip = []) {
230
+ const entityValues = {};
231
+ const tco = await this.typeUtils.getEntityTypeClientOptionsUsingMapping(this.transformMapFile, this.mapFileUtil, data);
232
+ const type = await this.typeUtils.getByRootAndPath(tco);
233
+ const typePath = type['typePath'];
234
+ if (typePath && (typePath.startsWith('item') || typePath.startsWith('project-item'))) {
235
+ if (['LCSProduct', 'LCSProductSeasonLink'].includes(objectClass)) {
236
+ entityValues['roles'] = ['family'];
237
+ }
238
+ else {
239
+ entityValues['roles'] = ['color', 'option'];
240
+ }
241
+ }
242
+ let typeProps = this.typeUtils.filterTypeProperties(type, entityValues);
243
+ typeProps = typeProps.filter(prop => !keysToSkip.includes(prop['slug']));
244
+ for (const prop of typeProps) {
245
+ const slug = prop['slug'];
246
+ const value = await this.getEntityValue(prop, data);
247
+ if (value) {
248
+ entityValues[slug] = value;
249
+ }
250
+ }
251
+ return entityValues;
252
+ }
253
+ async getEntityValue(prop, data) {
254
+ const propertyType = prop['propertyType'];
255
+ const slug = prop['slug'];
256
+ const nd = data[slug];
257
+ let value;
258
+ if (['string', 'text'].includes(propertyType)) {
259
+ value = nd;
260
+ }
261
+ else if (['number', 'currency', 'percent', 'sequence'].includes(propertyType)) {
262
+ value = (null === nd) ? 0 : nd;
263
+ }
264
+ else if ('date' === propertyType) {
265
+ if (nd) {
266
+ const d = new Date(nd);
267
+ value = d.toISOString();
268
+ }
269
+ else {
270
+ value = null;
271
+ }
272
+ }
273
+ else if ('boolean' === propertyType) {
274
+ value = (nd) ? true : false;
275
+ }
276
+ else if ('choice' === propertyType) {
277
+ value = this.setEnumerationKeys(prop, nd, this.useDisplayForEnumerationMatching);
278
+ }
279
+ else if ('multi_select' === propertyType) {
280
+ value = this.setEnumerationKeys(prop, nd, this.useDisplayForEnumerationMatching);
281
+ }
282
+ else if ('object_reference' === propertyType) {
283
+ value = await this.setObjectReferenceValue(prop, nd);
284
+ }
285
+ else if ('image' === propertyType) {
286
+ }
287
+ else if ('formula' === propertyType) {
288
+ }
289
+ else if ('json' === propertyType) {
290
+ }
291
+ else if ('userList' === propertyType) {
292
+ value = await this.setUserListValue(prop, nd);
293
+ }
294
+ return value;
295
+ }
296
+ setEnumerationKeys(prop, nd, matchByDisplay) {
297
+ const propertyType = prop['propertyType'];
298
+ let value;
299
+ if (['choice', 'multi_select'].includes(propertyType)) {
300
+ const options = prop['options'] || [];
301
+ if ('choice' === propertyType) {
302
+ if (nd) {
303
+ const matchKey = (matchByDisplay) ? 'display' : 'value';
304
+ const option = options.find(option => option[matchKey] == nd[matchKey]);
305
+ if (option) {
306
+ value = option.value;
307
+ }
308
+ }
309
+ else {
310
+ value = undefined;
311
+ }
312
+ }
313
+ else if ('multi_select' === propertyType) {
314
+ value = [];
315
+ const matchKey = (matchByDisplay) ? 'display' : 'value';
316
+ if (nd instanceof Array) {
317
+ nd.forEach(selectedOpt => {
318
+ const optionObject = options.find(option => option[matchKey] == selectedOpt[matchKey]);
319
+ if (optionObject) {
320
+ const option = optionObject.value;
321
+ value.push(option);
322
+ }
323
+ });
324
+ }
325
+ }
326
+ }
327
+ return value;
328
+ }
329
+ getPersistableChanges(entity, changes) {
330
+ const entityCompareValues = {};
331
+ for (const key of (Object.getOwnPropertyNames(changes))) {
332
+ entityCompareValues[key] = entity[key];
333
+ }
334
+ const diffs = util_1.ObjectUtil.compareDeep(entityCompareValues, changes, '');
335
+ const diffValues = {};
336
+ if (diffs && diffs.length > 0) {
337
+ for (const diff of diffs) {
338
+ diffValues[diff.propertyName] = diff.newValue;
339
+ }
340
+ }
341
+ return diffValues;
342
+ }
343
+ async setObjectReferenceValue(prop, nd) {
344
+ let objectReferenceId = "";
345
+ if (!nd) {
346
+ return objectReferenceId;
347
+ }
348
+ if (this.transformMapFile) {
349
+ const mapKey = await type_conversion_utils_1.TypeConversionUtils.getMapKeyFromObject(this.transformMapFile, this.mapFileUtil, nd, type_conversion_utils_1.TypeConversionUtils.FLEX2VIBE_DIRECTION);
350
+ nd = await map_utils_1.MapUtil.applyTransformMap(this.transformMapFile, this.mapFileUtil, nd, mapKey, type_conversion_utils_1.TypeConversionUtils.FLEX2VIBE_DIRECTION);
351
+ }
352
+ const entityType = prop['referencedTypeRootSlug'];
353
+ const entityTypePath = prop['referencedTypePath'];
354
+ const entityKeys = Object.keys(nd);
355
+ const identifierKeys = await type_conversion_utils_1.TypeConversionUtils.getIdentifierPropertiesFromObject(this.transformMapFile, this.mapFileUtil, nd);
356
+ const hasAllIdentifiers = identifierKeys.every(key => entityKeys.includes(key));
357
+ if (identifierKeys.length == 0 || !hasAllIdentifiers) {
358
+ console.warn(`The inbound ${entityType} for prop '${prop['slug']}' doesnt have all "identifier" properties, so there is no processing. Identifier properties: ${identifierKeys}`);
359
+ return objectReferenceId;
360
+ }
361
+ const rootType = await this.typeUtils.getByRootAndPath({ root: entityType });
362
+ const rootTypeProps = this.typeUtils.filterTypeProperties(rootType, nd);
363
+ let rootTypeCriteria = {};
364
+ let typeCriteria = {};
365
+ identifierKeys.forEach(keyName => {
366
+ const foundInObjects = rootTypeProps.some(obj => obj.slug === keyName);
367
+ if (foundInObjects) {
368
+ rootTypeCriteria[keyName] = nd[keyName];
369
+ }
370
+ else {
371
+ typeCriteria[keyName] = nd[keyName];
372
+ }
373
+ });
374
+ const combinedCriteria = { ...rootTypeCriteria, ...typeCriteria, typePath: entityTypePath };
375
+ const cacheKey = Object.values(combinedCriteria).join('_');
376
+ if (this.objRefCache[cacheKey]) {
377
+ if (app_framework_1.Logger.isDebugOn()) {
378
+ console.debug(`object reference cache hit: ${cacheKey}`);
379
+ }
380
+ return this.objRefCache[cacheKey];
381
+ }
382
+ let arrObjectReferences = await this.getAllObjectReferences(entityType, rootTypeCriteria);
383
+ if (entityType !== entityTypePath) {
384
+ arrObjectReferences = this.checkKeysAndValues(typeCriteria, arrObjectReferences, entityTypePath);
385
+ }
386
+ if (arrObjectReferences.length) {
387
+ if (arrObjectReferences.length === 1) {
388
+ objectReferenceId = arrObjectReferences[0].id;
389
+ }
390
+ else {
391
+ console.warn(`The passed in object reference criteria has duplicate records found ${JSON.stringify(combinedCriteria)}.`);
392
+ }
393
+ }
394
+ if (!objectReferenceId) {
395
+ console.warn(`The passed in object reference criteria ${JSON.stringify(combinedCriteria)} didn't match any entities.`);
396
+ return objectReferenceId;
397
+ }
398
+ this.objRefCache[cacheKey] = objectReferenceId;
399
+ return objectReferenceId;
400
+ }
401
+ async getAllObjectReferences(entityType, rootTypeCriteria, postProcessCriteria = null) {
402
+ const entities = new sdk_1.Entities();
403
+ let loads = [];
404
+ let nextPageKey;
405
+ let usedV2 = false;
406
+ do {
407
+ const take = 1000;
408
+ const loadPage = await entities.get({
409
+ entityName: entityType,
410
+ criteria: rootTypeCriteria,
411
+ apiVersion: sdk_1.API_VERSION.V2,
412
+ take,
413
+ nextPageKey,
414
+ });
415
+ nextPageKey = loadPage?.nextPageKey;
416
+ if (Object.keys(loadPage).includes('results')) {
417
+ usedV2 = true;
418
+ let postProcessedResults = this.filterOutArchivedAndTrashedEntities(loadPage?.results);
419
+ if (postProcessedResults?.length > 0 && postProcessCriteria && Object.keys(postProcessCriteria).length !== 0) {
420
+ const subEntityTypePath = rootTypeCriteria.typePath || entityType;
421
+ postProcessedResults = this.checkKeysAndValues(postProcessCriteria, postProcessedResults, subEntityTypePath);
422
+ }
423
+ loads.push(...postProcessedResults);
424
+ }
425
+ else {
426
+ nextPageKey = null;
427
+ }
428
+ } while (nextPageKey);
429
+ if (!usedV2) {
430
+ const take = 1000;
431
+ let skip = 0;
432
+ let done = false;
433
+ while (!done) {
434
+ const loadPage = await entities.get({
435
+ entityName: entityType,
436
+ criteria: rootTypeCriteria,
437
+ take,
438
+ skip,
439
+ });
440
+ let postProcessedResults = this.filterOutArchivedAndTrashedEntities(loadPage);
441
+ if (postProcessCriteria && Object.keys(postProcessCriteria).length !== 0) {
442
+ const subEntityTypePath = rootTypeCriteria.typePath || entityType;
443
+ postProcessedResults = this.checkKeysAndValues(postProcessCriteria, postProcessedResults, subEntityTypePath);
444
+ }
445
+ loads.push(...postProcessedResults);
446
+ if (loadPage.length !== take) {
447
+ done = true;
448
+ }
449
+ else {
450
+ skip += take;
451
+ }
452
+ }
453
+ }
454
+ return loads;
455
+ }
456
+ checkKeysAndValues(criteria, arrayOfObjects, entityTypePath) {
457
+ let arrOfMatchObjects = [];
458
+ for (let i = 0; i < arrayOfObjects.length; i++) {
459
+ const currentObj = arrayOfObjects[i];
460
+ let found = true;
461
+ if (entityTypePath && currentObj['typePath']) {
462
+ const currentObjPath = '' + currentObj['typePath'];
463
+ if (!currentObjPath.startsWith(entityTypePath)) {
464
+ found = false;
465
+ }
466
+ }
467
+ for (const key in criteria) {
468
+ if (!(key in currentObj) || currentObj[key] !== criteria[key]) {
469
+ found = false;
470
+ break;
471
+ }
472
+ }
473
+ if (found) {
474
+ arrOfMatchObjects.push(currentObj);
475
+ }
476
+ }
477
+ return arrOfMatchObjects;
478
+ }
479
+ filterOutArchivedAndTrashedEntities(entities) {
480
+ if (!entities || !Array.isArray(entities) || entities.length === 0) {
481
+ return [];
482
+ }
483
+ return entities.filter(entity => {
484
+ const isArchived = entity?.isArchived;
485
+ const isTrashed = entity?.isTrashed;
486
+ return !isArchived && !isTrashed;
487
+ });
488
+ }
489
+ async setUserListValue(prop, nd) {
490
+ if (!nd?.email) {
491
+ return "";
492
+ }
493
+ let cacheUser = DataConverter.getFromStaticCache(nd.email);
494
+ if (cacheUser) {
495
+ if (app_framework_1.Logger.isDebugOn()) {
496
+ console.debug('user cache hit: ' + nd.email);
497
+ }
498
+ await this.processGroupMemberCheck(prop, nd.email);
499
+ return cacheUser;
500
+ }
501
+ const user = await this.getUserByEmail(nd);
502
+ const userId = (user) ? user.id : undefined;
503
+ if (userId) {
504
+ DataConverter.setToStaticCache(nd.email, userId);
505
+ await this.processGroupMemberCheck(prop, nd.email);
506
+ }
507
+ return userId;
508
+ }
509
+ async getUserByEmail(nd) {
510
+ let userOrg = undefined;
511
+ let count = 0;
512
+ let size = 0;
513
+ let emailInput = nd?.email.toLowerCase();
514
+ const entities = new sdk_1.Entities();
515
+ const getOptionsCriteria = {
516
+ entityName: 'user-org',
517
+ take: 1000
518
+ };
519
+ do {
520
+ const userBatch = await entities.get(getOptionsCriteria);
521
+ userOrg = userBatch.find(uo => uo?.userEmail.toLowerCase() === emailInput);
522
+ } while (!userOrg && size == getOptionsCriteria.take && count < 15);
523
+ return userOrg?.user;
524
+ }
525
+ async processGroupMemberCheck(prop, userEmail) {
526
+ let arrUserList = [];
527
+ if (this.userRefCache[prop.typePropertyUserListId]) {
528
+ arrUserList = this.userRefCache[prop.typePropertyUserListId];
529
+ }
530
+ else {
531
+ const userListResult = await new sdk_1.Entities().get({
532
+ entityName: 'user-list',
533
+ id: prop.typePropertyUserListId
534
+ });
535
+ if (userListResult && Object.keys(userListResult).length) {
536
+ arrUserList = userListResult.userList;
537
+ this.userRefCache[prop.typePropertyUserListId] = arrUserList;
538
+ }
539
+ }
540
+ if (arrUserList.length) {
541
+ const result = arrUserList.find(element => element['display'] === userEmail);
542
+ if (!result) {
543
+ console.warn(`The passed in user ${userEmail} in property slug ${prop.slug} should be a member of the group associated with the property 'typePropertyUserListId'`);
544
+ }
545
+ }
546
+ }
547
+ async getUserListValue(prop, newData) {
548
+ const slug = prop['slug'];
549
+ if (app_framework_1.Logger.isDebugOn()) {
550
+ console.debug('getUserListValue-prop: ' + slug);
551
+ }
552
+ const entityId = newData[slug + 'Id'];
553
+ if (!entityId) {
554
+ return {};
555
+ }
556
+ const cacheUser = DataConverter.getFromStaticCache(entityId);
557
+ if (cacheUser) {
558
+ if (app_framework_1.Logger.isDebugOn()) {
559
+ console.debug('user cache hit: ' + entityId);
560
+ }
561
+ return Object.assign({}, cacheUser);
562
+ }
563
+ const user = await this.getUserById(entityId);
564
+ const value = (user) ? {
565
+ email: user.email,
566
+ firstName: user.first,
567
+ lastName: user.last,
568
+ isSsoUser: user.isSsoUser,
569
+ } : undefined;
570
+ if (value) {
571
+ DataConverter.setToStaticCache(entityId, value);
572
+ }
573
+ return value;
574
+ }
575
+ async getUserById(userId) {
576
+ let userOrg = undefined;
577
+ let count = 0;
578
+ let size = 0;
579
+ const entities = new sdk_1.Entities();
580
+ const getOptionsCriteria = {
581
+ entityName: 'user-org',
582
+ take: 1000
583
+ };
584
+ do {
585
+ const userBatch = await entities.get(getOptionsCriteria);
586
+ userOrg = userBatch.find(uo => uo?.user?.id === userId);
587
+ } while (!userOrg && size == getOptionsCriteria.take && count < 15);
588
+ return userOrg?.user;
589
+ }
590
+ }
591
+ exports.DataConverter = DataConverter;
592
+ DataConverter.staticUserCache = {};
@@ -0,0 +1 @@
1
+ export {};