@contrail/flexplm 1.3.0-alpha.ccc03be → 1.3.1-alpha.3e8dbdd
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/cli/commands/compile.d.ts +1 -0
- package/lib/cli/commands/compile.js +71 -0
- package/lib/cli/commands/compile.spec.d.ts +1 -0
- package/lib/cli/commands/compile.spec.js +80 -0
- package/lib/cli/commands/create.d.ts +1 -0
- package/lib/cli/commands/create.js +75 -0
- package/lib/cli/commands/create.spec.d.ts +1 -0
- package/lib/cli/commands/create.spec.js +78 -0
- package/lib/cli/commands/upload.d.ts +10 -0
- package/lib/cli/commands/upload.js +226 -0
- package/lib/cli/commands/upload.spec.d.ts +1 -0
- package/lib/cli/commands/upload.spec.js +88 -0
- package/lib/cli/index.d.ts +2 -0
- package/lib/cli/index.js +64 -0
- package/lib/cli/index.spec.d.ts +1 -0
- package/lib/cli/index.spec.js +79 -0
- package/lib/cli/template/mapping-template.ts.template +62 -0
- package/lib/entity-processor/base-entity-processor.d.ts +47 -0
- package/lib/entity-processor/base-entity-processor.js +53 -0
- package/lib/entity-processor/base-entity-processor.spec.js +1 -0
- package/lib/index.d.ts +1 -0
- package/lib/index.js +1 -0
- package/lib/interfaces/mapping-file.d.ts +460 -0
- package/lib/interfaces/mapping-file.js +2 -0
- package/lib/publish/base-process-publish-assortment.d.ts +25 -0
- package/lib/publish/base-process-publish-assortment.js +60 -6
- package/lib/publish/base-process-publish-assortment.spec.js +22 -4
- package/lib/publish/mockData.js +5 -0
- package/lib/transform/identifier-conversion-spec-mockData.js +34 -6
- package/lib/transform/identifier-conversion.d.ts +36 -0
- package/lib/transform/identifier-conversion.js +36 -0
- package/lib/transform/identifier-conversion.spec.js +4 -0
- package/lib/util/config-defaults.js +3 -0
- package/lib/util/config-defaults.spec.js +9 -0
- package/lib/util/data-converter-spec-mockData.js +17 -3
- package/lib/util/data-converter.d.ts +97 -0
- package/lib/util/data-converter.js +127 -1
- package/lib/util/data-converter.spec.js +2 -0
- package/lib/util/error-response-object.d.ts +5 -0
- package/lib/util/error-response-object.js +7 -0
- package/lib/util/event-short-message-status.js +1 -0
- package/lib/util/federation.js +8 -0
- package/lib/util/flexplm-connect.d.ts +7 -0
- package/lib/util/flexplm-connect.js +14 -0
- package/lib/util/logger-config.js +1 -0
- package/lib/util/map-util-spec-mockData.js +17 -3
- package/lib/util/map-utils.d.ts +27 -0
- package/lib/util/map-utils.js +27 -0
- package/lib/util/thumbnail-util.d.ts +21 -0
- package/lib/util/thumbnail-util.js +28 -1
- package/lib/util/thumbnail-util.spec.js +6 -0
- package/lib/util/type-conversion-utils-spec-mockData.js +3 -3
- package/lib/util/type-conversion-utils.d.ts +140 -0
- package/lib/util/type-conversion-utils.js +143 -0
- package/lib/util/type-defaults.d.ts +58 -0
- package/lib/util/type-defaults.js +58 -0
- package/lib/util/type-defaults.spec.js +5 -5
- package/lib/util/type-utils.d.ts +21 -0
- package/lib/util/type-utils.js +23 -0
- package/lib/util/type-utils.spec.js +2 -0
- package/package.json +21 -6
- package/scripts/copy-template.js +10 -0
- package/.github/pull_request_template.md +0 -31
- package/.github/workflows/flexplm-lib.yml +0 -27
- package/.github/workflows/publish-to-npm.yml +0 -121
- package/CHANGELOG.md +0 -32
- package/publish.bat +0 -5
- package/publish.sh +0 -5
- package/src/entity-processor/base-entity-processor.spec.ts +0 -460
- package/src/entity-processor/base-entity-processor.ts +0 -515
- package/src/flexplm-request.ts +0 -28
- package/src/flexplm-utils.spec.ts +0 -27
- package/src/flexplm-utils.ts +0 -29
- package/src/index.ts +0 -22
- package/src/interfaces/interfaces.ts +0 -122
- package/src/interfaces/item-family-changes.ts +0 -67
- package/src/interfaces/publish-change-data.ts +0 -43
- package/src/publish/base-process-publish-assortment-callback.ts +0 -50
- package/src/publish/base-process-publish-assortment.spec.ts +0 -1992
- package/src/publish/base-process-publish-assortment.ts +0 -1134
- package/src/publish/mockData.ts +0 -4561
- package/src/transform/identifier-conversion-spec-mockData.ts +0 -496
- package/src/transform/identifier-conversion.spec.ts +0 -354
- package/src/transform/identifier-conversion.ts +0 -282
- package/src/util/config-defaults.spec.ts +0 -350
- package/src/util/config-defaults.ts +0 -93
- package/src/util/data-converter-spec-mockData.ts +0 -231
- package/src/util/data-converter.spec.ts +0 -1041
- package/src/util/data-converter.ts +0 -762
- package/src/util/error-response-object.spec.ts +0 -116
- package/src/util/error-response-object.ts +0 -50
- package/src/util/event-short-message-status.ts +0 -22
- package/src/util/federation.ts +0 -172
- package/src/util/flexplm-connect.spec.ts +0 -132
- package/src/util/flexplm-connect.ts +0 -208
- package/src/util/logger-config.ts +0 -20
- package/src/util/map-util-spec-mockData.ts +0 -231
- package/src/util/map-utils.spec.ts +0 -103
- package/src/util/map-utils.ts +0 -41
- package/src/util/mockData.ts +0 -101
- package/src/util/thumbnail-util.spec.ts +0 -508
- package/src/util/thumbnail-util.ts +0 -272
- package/src/util/type-conversion-utils-spec-mockData.ts +0 -271
- package/src/util/type-conversion-utils.spec.ts +0 -968
- package/src/util/type-conversion-utils.ts +0 -460
- package/src/util/type-defaults.spec.ts +0 -669
- package/src/util/type-defaults.ts +0 -281
- package/src/util/type-utils.spec.ts +0 -227
- package/src/util/type-utils.ts +0 -144
- package/tsconfig.json +0 -24
- package/tslint.json +0 -57
|
@@ -44,16 +44,22 @@ class DataConverter {
|
|
|
44
44
|
if (this.isVerboseDebugOn()) {
|
|
45
45
|
console.debug('newData: ' + JSON.stringify(newData));
|
|
46
46
|
}
|
|
47
|
+
//Using event to get propertyDiffs to find emptied values
|
|
48
|
+
//Add standard atts to skip
|
|
47
49
|
dataToSkip = dataToSkip.concat(['updatedOn', 'updatedById', 'createdOn', 'createdById', 'modifiedAt', 'orgId', 'createdAt', 'id', 'typeId', 'workspaceId']);
|
|
50
|
+
// const oldData = event.oldData;
|
|
48
51
|
const data = {};
|
|
49
52
|
const typeId = newData?.typeId;
|
|
50
53
|
if (!typeId) {
|
|
51
|
-
return;
|
|
54
|
+
return; // Don't have a type; so can't process
|
|
52
55
|
}
|
|
53
56
|
data['typePath'] = newData['typePath'];
|
|
54
57
|
const type = await this.typeUtils.getTypeById(typeId);
|
|
55
58
|
const typeProps = this.typeUtils.filterTypeProperties(type, newData);
|
|
56
59
|
for (const prop of typeProps) {
|
|
60
|
+
// if(this.logger.isTraceOn()){
|
|
61
|
+
// this.logger.log('prop: ' + JSON.stringify(prop));
|
|
62
|
+
// }
|
|
57
63
|
const slug = prop['slug'];
|
|
58
64
|
if (dataToSkip.includes(slug)) {
|
|
59
65
|
continue;
|
|
@@ -69,6 +75,7 @@ class DataConverter {
|
|
|
69
75
|
const propertyType = prop['propertyType'];
|
|
70
76
|
const slug = prop['slug'];
|
|
71
77
|
const nd = newData[slug];
|
|
78
|
+
// console.log('getFlexPLMValue: ' + propertyType + ', ' +slug + ', ' + nd + ', ' + od);
|
|
72
79
|
let value;
|
|
73
80
|
if (['string', 'text'].includes(propertyType)) {
|
|
74
81
|
value = nd || '';
|
|
@@ -79,6 +86,10 @@ class DataConverter {
|
|
|
79
86
|
else if ('date' === propertyType) {
|
|
80
87
|
if (nd) {
|
|
81
88
|
value = nd;
|
|
89
|
+
// const d = new Date(nd);
|
|
90
|
+
// console.log('Date.getTimezoneOffset(): ' + d.getTimezoneOffset());
|
|
91
|
+
// value = d.toISOString();
|
|
92
|
+
// console.log('date: ' + nd + ' -- ' + value);
|
|
82
93
|
}
|
|
83
94
|
else {
|
|
84
95
|
value = null;
|
|
@@ -100,11 +111,13 @@ class DataConverter {
|
|
|
100
111
|
}
|
|
101
112
|
}
|
|
102
113
|
else if ('image' === propertyType) {
|
|
114
|
+
// console.log('image-TODO');
|
|
103
115
|
}
|
|
104
116
|
else if ('formula' === propertyType) {
|
|
105
117
|
value = nd;
|
|
106
118
|
}
|
|
107
119
|
else if ('json' === propertyType) {
|
|
120
|
+
// console.log('json-TODO');
|
|
108
121
|
value = nd;
|
|
109
122
|
}
|
|
110
123
|
else if ('userList' === propertyType) {
|
|
@@ -112,6 +125,12 @@ class DataConverter {
|
|
|
112
125
|
}
|
|
113
126
|
return value;
|
|
114
127
|
}
|
|
128
|
+
/** Returns the display values for list properties (choice & multi_select)
|
|
129
|
+
*
|
|
130
|
+
* @param prop
|
|
131
|
+
* @param newData
|
|
132
|
+
* @returns
|
|
133
|
+
*/
|
|
115
134
|
getEnumerationValue(prop, nd) {
|
|
116
135
|
const propertyType = prop['propertyType'];
|
|
117
136
|
let value;
|
|
@@ -195,6 +214,14 @@ class DataConverter {
|
|
|
195
214
|
this.objRefCache[entityId] = value;
|
|
196
215
|
return value;
|
|
197
216
|
}
|
|
217
|
+
/** (Deprecated) Use TypeConversionUtils.getMapKey()
|
|
218
|
+
* Will return the class to use to get mapping.
|
|
219
|
+
* This is needed because mappings will be different for different sub types
|
|
220
|
+
* of custom-entity
|
|
221
|
+
*
|
|
222
|
+
* @param obj: Entity being checked
|
|
223
|
+
* @param mapping: The whole mapping file
|
|
224
|
+
*/
|
|
198
225
|
getMappingClass(entity, mapping) {
|
|
199
226
|
const entityTypePath = entity['typePath'];
|
|
200
227
|
const typeMapKey = mapping['typeMapKey'];
|
|
@@ -208,11 +235,22 @@ class DataConverter {
|
|
|
208
235
|
}
|
|
209
236
|
return objClass;
|
|
210
237
|
}
|
|
238
|
+
/** Sets entity values from FlexPLM data passed in
|
|
239
|
+
* Assumes the entity has a VibeIQ typeId and 'roles' value to filter if necessary.
|
|
240
|
+
* @param entity the entity to update
|
|
241
|
+
* @param data the FlexPLM data
|
|
242
|
+
* @param keysToSkip properties to skip
|
|
243
|
+
* @returns the modified entity with VibeIQ values
|
|
244
|
+
*/
|
|
211
245
|
async setEntityValues(entity, data, keysToSkip = []) {
|
|
246
|
+
// this.logger.log('setEntityValues: ' + JSON.stringify(entity));
|
|
247
|
+
// this.logger.log('data: ' + JSON.stringify(data));
|
|
212
248
|
const type = await this.typeUtils.getTypeById(entity.typeId);
|
|
213
249
|
keysToSkip = keysToSkip.concat(['updatedOn', 'updatedById', 'createdOn', 'createdById', 'modifiedAt', 'orgId', 'createdAt', 'id', 'typeId', 'typePath', 'workspaceId']);
|
|
214
250
|
let typeProps = this.typeUtils.filterTypeProperties(type, entity);
|
|
215
251
|
typeProps = typeProps.filter(prop => !keysToSkip.includes(prop['slug']));
|
|
252
|
+
//Only process properties that had a value sent; to not accidentally clear out values
|
|
253
|
+
//for properties that weren't sent.
|
|
216
254
|
const dataKeys = Object.getOwnPropertyNames(data);
|
|
217
255
|
typeProps = typeProps.filter(prop => dataKeys.includes(prop['slug']));
|
|
218
256
|
for (const prop of typeProps) {
|
|
@@ -223,9 +261,17 @@ class DataConverter {
|
|
|
223
261
|
keyName = slug + 'Id';
|
|
224
262
|
}
|
|
225
263
|
entity[keyName] = await this.getEntityValue(prop, data);
|
|
264
|
+
// console.log('entity[slug]: ' + entity[slug]);
|
|
226
265
|
}
|
|
227
266
|
return entity;
|
|
228
267
|
}
|
|
268
|
+
/** Gets the entity values from FlexPLM data
|
|
269
|
+
* Assumes there isn't a VibeIQ typeId, so uses FlexPLM data to determine type
|
|
270
|
+
* @param objectClass FlexPLM object class
|
|
271
|
+
* @param data object data
|
|
272
|
+
* @param keysToSkip type properties to not process
|
|
273
|
+
* @returns object with VibeIQ values
|
|
274
|
+
*/
|
|
229
275
|
async getEntityValues(objectClass, data, keysToSkip = []) {
|
|
230
276
|
const entityValues = {};
|
|
231
277
|
const tco = await this.typeUtils.getEntityTypeClientOptionsUsingMapping(this.transformMapFile, this.mapFileUtil, data);
|
|
@@ -250,10 +296,17 @@ class DataConverter {
|
|
|
250
296
|
}
|
|
251
297
|
return entityValues;
|
|
252
298
|
}
|
|
299
|
+
/** Gets the VibeIQ value for the property from data
|
|
300
|
+
*
|
|
301
|
+
* @param prop the VibeIQ property
|
|
302
|
+
* @param data the FlexPLM data
|
|
303
|
+
* @returns value to be set in VibeIQ
|
|
304
|
+
*/
|
|
253
305
|
async getEntityValue(prop, data) {
|
|
254
306
|
const propertyType = prop['propertyType'];
|
|
255
307
|
const slug = prop['slug'];
|
|
256
308
|
const nd = data[slug];
|
|
309
|
+
// this.logger.log('getValue: ' + propertyType + ', ' +slug + ', ' + nd);
|
|
257
310
|
let value;
|
|
258
311
|
if (['string', 'text'].includes(propertyType)) {
|
|
259
312
|
value = nd;
|
|
@@ -263,6 +316,11 @@ class DataConverter {
|
|
|
263
316
|
}
|
|
264
317
|
else if ('date' === propertyType) {
|
|
265
318
|
if (nd) {
|
|
319
|
+
// const offset = new Date(nd).getTimezoneOffset() * 60 * 1_000;
|
|
320
|
+
// this.logger.log('nd: ' + nd);
|
|
321
|
+
// this.logger.log(offset);
|
|
322
|
+
// this.logger.log('No Offset: ' + new Date(nd).toISOString());
|
|
323
|
+
// const d = new Date(nd + offset);// Take system Timezone into account.
|
|
266
324
|
const d = new Date(nd);
|
|
267
325
|
value = d.toISOString();
|
|
268
326
|
}
|
|
@@ -283,20 +341,25 @@ class DataConverter {
|
|
|
283
341
|
value = await this.setObjectReferenceValue(prop, nd);
|
|
284
342
|
}
|
|
285
343
|
else if ('image' === propertyType) {
|
|
344
|
+
// console.log('TODO-image');
|
|
286
345
|
}
|
|
287
346
|
else if ('formula' === propertyType) {
|
|
347
|
+
// console.log('TODO-formula');
|
|
288
348
|
}
|
|
289
349
|
else if ('json' === propertyType) {
|
|
350
|
+
// console.log('TODO-json');
|
|
290
351
|
}
|
|
291
352
|
else if ('userList' === propertyType) {
|
|
292
353
|
value = await this.setUserListValue(prop, nd);
|
|
293
354
|
}
|
|
355
|
+
// console.log(value);
|
|
294
356
|
return value;
|
|
295
357
|
}
|
|
296
358
|
setEnumerationKeys(prop, nd, matchByDisplay) {
|
|
297
359
|
const propertyType = prop['propertyType'];
|
|
298
360
|
let value;
|
|
299
361
|
if (['choice', 'multi_select'].includes(propertyType)) {
|
|
362
|
+
//If there are no options, use empty array to not error out and don't set anything
|
|
300
363
|
const options = prop['options'] || [];
|
|
301
364
|
if ('choice' === propertyType) {
|
|
302
365
|
if (nd) {
|
|
@@ -326,6 +389,12 @@ class DataConverter {
|
|
|
326
389
|
}
|
|
327
390
|
return value;
|
|
328
391
|
}
|
|
392
|
+
/** Compares the potential changes to the entity and returns only the actual differences.
|
|
393
|
+
*
|
|
394
|
+
* @param entity the full entity
|
|
395
|
+
* @param changes the potential changes
|
|
396
|
+
* @returns only the change values that are different from the entity's value
|
|
397
|
+
*/
|
|
329
398
|
getPersistableChanges(entity, changes) {
|
|
330
399
|
const entityCompareValues = {};
|
|
331
400
|
for (const key of (Object.getOwnPropertyNames(changes))) {
|
|
@@ -340,6 +409,12 @@ class DataConverter {
|
|
|
340
409
|
}
|
|
341
410
|
return diffValues;
|
|
342
411
|
}
|
|
412
|
+
/** Sets object reference value from FlexPLM data passed in
|
|
413
|
+
*
|
|
414
|
+
* @param prop the VibeIQ property
|
|
415
|
+
* @param nd the VibeIQ data
|
|
416
|
+
* @returns the object reference id from VibeIQ
|
|
417
|
+
*/
|
|
343
418
|
async setObjectReferenceValue(prop, nd) {
|
|
344
419
|
let objectReferenceId = "";
|
|
345
420
|
if (!nd) {
|
|
@@ -398,6 +473,13 @@ class DataConverter {
|
|
|
398
473
|
this.objRefCache[cacheKey] = objectReferenceId;
|
|
399
474
|
return objectReferenceId;
|
|
400
475
|
}
|
|
476
|
+
/**
|
|
477
|
+
* Retrieves all object references of a specified entity type based on the provided criteria.
|
|
478
|
+
* This function handles pagination and asynchronously fetches object references until there are no more pages.
|
|
479
|
+
* @param {string} entityType - The type of entity for which object references are to be retrieved.
|
|
480
|
+
* @param {object} rootTypeCriteria - The criteria used to filter object references.
|
|
481
|
+
* @returns {Promise<Array>} A Promise that resolves to an array containing all object references.
|
|
482
|
+
*/
|
|
401
483
|
async getAllObjectReferences(entityType, rootTypeCriteria, postProcessCriteria = null) {
|
|
402
484
|
const entities = new sdk_1.Entities();
|
|
403
485
|
let loads = [];
|
|
@@ -453,6 +535,14 @@ class DataConverter {
|
|
|
453
535
|
}
|
|
454
536
|
return loads;
|
|
455
537
|
}
|
|
538
|
+
/**
|
|
539
|
+
* Checks if all keys and values of a given object are present in an array of objects.
|
|
540
|
+
* @param {Object} criteria - The object whose keys and values are to be checked in the array of objects.
|
|
541
|
+
* @param {Array<Object>} arrayOfObjects - The array of objects to be searched for matching keys and values.
|
|
542
|
+
* @param {string} entityTypePath - The type / subtype for the property; objects must be this type or a sub type of it.
|
|
543
|
+
* @returns {(Object|boolean)} Returns the array of objects that matches all keys and values of the provided object.
|
|
544
|
+
* If no match is found, returns empty array.
|
|
545
|
+
*/
|
|
456
546
|
checkKeysAndValues(criteria, arrayOfObjects, entityTypePath) {
|
|
457
547
|
let arrOfMatchObjects = [];
|
|
458
548
|
for (let i = 0; i < arrayOfObjects.length; i++) {
|
|
@@ -476,6 +566,11 @@ class DataConverter {
|
|
|
476
566
|
}
|
|
477
567
|
return arrOfMatchObjects;
|
|
478
568
|
}
|
|
569
|
+
/** Filters out archived and trashed entities from the provided array of entities.
|
|
570
|
+
*
|
|
571
|
+
* @param entities
|
|
572
|
+
* @returns
|
|
573
|
+
*/
|
|
479
574
|
filterOutArchivedAndTrashedEntities(entities) {
|
|
480
575
|
if (!entities || !Array.isArray(entities) || entities.length === 0) {
|
|
481
576
|
return [];
|
|
@@ -486,6 +581,12 @@ class DataConverter {
|
|
|
486
581
|
return !isArchived && !isTrashed;
|
|
487
582
|
});
|
|
488
583
|
}
|
|
584
|
+
/** Sets userListId value from FlexPLM data passed in
|
|
585
|
+
*
|
|
586
|
+
* @param prop the VibeIQ property
|
|
587
|
+
* @param nd the VibeIQ data
|
|
588
|
+
* @returns the modified entity with FlexPLM values
|
|
589
|
+
*/
|
|
489
590
|
async setUserListValue(prop, nd) {
|
|
490
591
|
if (!nd?.email) {
|
|
491
592
|
return "";
|
|
@@ -506,6 +607,13 @@ class DataConverter {
|
|
|
506
607
|
}
|
|
507
608
|
return userId;
|
|
508
609
|
}
|
|
610
|
+
/** Makes batch calls of 1000 of user-org entities until
|
|
611
|
+
* it find one with userEmail of passed in nd.email.
|
|
612
|
+
* Maxes out after querying for 15,000 user-org entities
|
|
613
|
+
*
|
|
614
|
+
* @param nd
|
|
615
|
+
* @returns
|
|
616
|
+
*/
|
|
509
617
|
async getUserByEmail(nd) {
|
|
510
618
|
let userOrg = undefined;
|
|
511
619
|
let count = 0;
|
|
@@ -522,6 +630,11 @@ class DataConverter {
|
|
|
522
630
|
} while (!userOrg && size == getOptionsCriteria.take && count < 15);
|
|
523
631
|
return userOrg?.user;
|
|
524
632
|
}
|
|
633
|
+
/** Shows warning if user email address not present in group associated to property
|
|
634
|
+
*
|
|
635
|
+
* @param prop the VibeIQ property
|
|
636
|
+
* @param userEmail user email address
|
|
637
|
+
*/
|
|
525
638
|
async processGroupMemberCheck(prop, userEmail) {
|
|
526
639
|
let arrUserList = [];
|
|
527
640
|
if (this.userRefCache[prop.typePropertyUserListId]) {
|
|
@@ -544,6 +657,12 @@ class DataConverter {
|
|
|
544
657
|
}
|
|
545
658
|
}
|
|
546
659
|
}
|
|
660
|
+
/** Gets the VibeIQ value for the userList property from data
|
|
661
|
+
*
|
|
662
|
+
* @param prop the VibeIQ property
|
|
663
|
+
* @param newData the FlexPLM data
|
|
664
|
+
* @returns value to be set in VibeIQ
|
|
665
|
+
*/
|
|
547
666
|
async getUserListValue(prop, newData) {
|
|
548
667
|
const slug = prop['slug'];
|
|
549
668
|
if (app_framework_1.Logger.isDebugOn()) {
|
|
@@ -572,6 +691,13 @@ class DataConverter {
|
|
|
572
691
|
}
|
|
573
692
|
return value;
|
|
574
693
|
}
|
|
694
|
+
/** Makes batch calls of 1000 of user-org entities until
|
|
695
|
+
* it find one with user.id of passed in userId.
|
|
696
|
+
* Maxes out after querying for 15,000 user-org entities
|
|
697
|
+
*
|
|
698
|
+
* @param userId
|
|
699
|
+
* @returns
|
|
700
|
+
*/
|
|
575
701
|
async getUserById(userId) {
|
|
576
702
|
let userOrg = undefined;
|
|
577
703
|
let count = 0;
|
|
@@ -609,6 +609,7 @@ describe('checkKeysAndValues', () => {
|
|
|
609
609
|
{ name: 'Group 4', typePath: 'custom-entity:grouping:sub' },
|
|
610
610
|
{ name: 'Group 5', typePath: 'custom-entity:grouping:sub' }
|
|
611
611
|
];
|
|
612
|
+
//item:product:newBalance:accessories, item:product:newBalance:apparel
|
|
612
613
|
it('Group 1', () => {
|
|
613
614
|
const criteria = {
|
|
614
615
|
name: 'Group 1'
|
|
@@ -830,6 +831,7 @@ describe('getUserListValue', () => {
|
|
|
830
831
|
];
|
|
831
832
|
const mapFileUtil = new transform_data_1.MapFileUtil(new sdk_1.Entities());
|
|
832
833
|
const dc = new data_converter_1.DataConverter(config, mapFileUtil);
|
|
834
|
+
//getUserById
|
|
833
835
|
let spyGetUserById = jest.spyOn(dc, 'getUserById')
|
|
834
836
|
.mockImplementation(async (nd) => {
|
|
835
837
|
return userEmailMapping.find((user) => user.id === nd);
|
|
@@ -1,4 +1,9 @@
|
|
|
1
1
|
import { AppActionCallBack } from "@contrail/app-framework";
|
|
2
2
|
export declare class ErrorResponseObject {
|
|
3
|
+
/** Returns a response, checking for multiple possible error details
|
|
4
|
+
*
|
|
5
|
+
* @param e
|
|
6
|
+
* @returns
|
|
7
|
+
*/
|
|
3
8
|
static getResponse(e: any): AppActionCallBack;
|
|
4
9
|
}
|
|
@@ -3,6 +3,11 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.ErrorResponseObject = void 0;
|
|
4
4
|
const app_framework_1 = require("@contrail/app-framework");
|
|
5
5
|
class ErrorResponseObject {
|
|
6
|
+
/** Returns a response, checking for multiple possible error details
|
|
7
|
+
*
|
|
8
|
+
* @param e
|
|
9
|
+
* @returns
|
|
10
|
+
*/
|
|
6
11
|
static getResponse(e) {
|
|
7
12
|
if (!e) {
|
|
8
13
|
const response = {
|
|
@@ -20,6 +25,7 @@ class ErrorResponseObject {
|
|
|
20
25
|
}
|
|
21
26
|
};
|
|
22
27
|
const output = response.output;
|
|
28
|
+
//Errors when persisting in VibeIQ
|
|
23
29
|
if (e.details)
|
|
24
30
|
output.errorDetails = e.details;
|
|
25
31
|
if (e.code)
|
|
@@ -30,6 +36,7 @@ class ErrorResponseObject {
|
|
|
30
36
|
output.type = e.type;
|
|
31
37
|
if (e.name)
|
|
32
38
|
output.errorName = e.name;
|
|
39
|
+
//Has original cause
|
|
33
40
|
if (e.cause) {
|
|
34
41
|
output.cause = {};
|
|
35
42
|
const cause = output.cause;
|
|
@@ -16,6 +16,7 @@ var EventShortMessageStatus;
|
|
|
16
16
|
EventShortMessageStatus["PRIMARY_CONTENT_UPDATED"] = "Primary_Content_Updated";
|
|
17
17
|
EventShortMessageStatus["TOO_MANY_ENTITIES_FOUND"] = "Too_Many_Entities_Found";
|
|
18
18
|
EventShortMessageStatus["UPDATED"] = "Updated";
|
|
19
|
+
//Publish
|
|
19
20
|
EventShortMessageStatus["NOT_PUBLISHABLE"] = "Not_Publishable";
|
|
20
21
|
EventShortMessageStatus["NO_FEDERATION_INFO"] = "No_Federation_Information";
|
|
21
22
|
EventShortMessageStatus["NO_EVENTS_TO_SEND"] = "No_Events_to_Send";
|
package/lib/util/federation.js
CHANGED
|
@@ -43,9 +43,11 @@ class Federation {
|
|
|
43
43
|
mappedReference: itemResults[i].federatedId,
|
|
44
44
|
federationSchema: FED_CONFIG.federationSchema
|
|
45
45
|
};
|
|
46
|
+
// console.log('createFederatedRecord: ' + JSON.stringify(payload));
|
|
46
47
|
try {
|
|
47
48
|
const results = await new sdk_1.Entities().create({ entityName: 'federation', object: payload });
|
|
48
49
|
return results;
|
|
50
|
+
// console.log(JSON.stringify(results));
|
|
49
51
|
}
|
|
50
52
|
catch (error) {
|
|
51
53
|
console.log('createFederatedRecord-error: ', error);
|
|
@@ -79,13 +81,16 @@ class Federation {
|
|
|
79
81
|
return { entityType, entityId };
|
|
80
82
|
}
|
|
81
83
|
async getEntityFromMappedRefId(mappedRefId) {
|
|
84
|
+
// console.log('!---getEntityFromMappedRefId: ' + mappedRefId);
|
|
82
85
|
const fedRecord = await this.getFederationRecordFromMappedRefId(mappedRefId);
|
|
83
86
|
console.log('fedRecord: ' + JSON.stringify(fedRecord));
|
|
84
87
|
if (!fedRecord) {
|
|
88
|
+
//Not creating from FlexPLM at this time.
|
|
85
89
|
console.log('Federation Record doesnt exist. Cant get entity!');
|
|
86
90
|
return;
|
|
87
91
|
}
|
|
88
92
|
const { entityType, entityId } = Federation.getEntityId(fedRecord);
|
|
93
|
+
// console.log(entityType + ':' + entityId);
|
|
89
94
|
const criteria = {
|
|
90
95
|
id: entityId
|
|
91
96
|
};
|
|
@@ -94,6 +99,7 @@ class Federation {
|
|
|
94
99
|
criteria
|
|
95
100
|
});
|
|
96
101
|
const entity = (entities && entities[0]) ? entities[0] : undefined;
|
|
102
|
+
// console.log(' entities: ' +JSON.stringify(entities));
|
|
97
103
|
return entity;
|
|
98
104
|
}
|
|
99
105
|
async getFederationRecordsFromIds(ids) {
|
|
@@ -104,6 +110,7 @@ class Federation {
|
|
|
104
110
|
appIdentifier: FED_CONFIG.appIdentifier,
|
|
105
111
|
federationSchema: FED_CONFIG.federationSchema
|
|
106
112
|
};
|
|
113
|
+
// this.logger.log('getFederatedMappedRefId: ' + JSON.stringify(criteria));
|
|
107
114
|
const recs = await new sdk_1.Entities().get({
|
|
108
115
|
entityName: 'federation',
|
|
109
116
|
criteria
|
|
@@ -126,6 +133,7 @@ class Federation {
|
|
|
126
133
|
appIdentifier: FED_CONFIG.appIdentifier,
|
|
127
134
|
federationSchema: FED_CONFIG.federationSchema
|
|
128
135
|
};
|
|
136
|
+
// this.logger.log('getFederatedMappedRefId: ' + JSON.stringify(criteria));
|
|
129
137
|
const records = await entities.get({
|
|
130
138
|
entityName: 'federation',
|
|
131
139
|
criteria
|
|
@@ -14,6 +14,13 @@ export declare class FlexPLMConnect {
|
|
|
14
14
|
protected processRequest(payload: any): Promise<FlexPLMResponseData>;
|
|
15
15
|
sendToFlexPLM(payload: PayloadType): Promise<FlexPLMResponseData>;
|
|
16
16
|
sendMultipleToFlexPLM(payload: PayloadType[]): Promise<FlexPLMResponseData>;
|
|
17
|
+
/** Runs a GET request to FlexPLM.
|
|
18
|
+
* @param params - Optional configuration for the request.
|
|
19
|
+
* @param params.urlPath - Custom URL path to use instead of the default `/servlet/rest` + endpoint.
|
|
20
|
+
* @param params.includeUrlContext - Whether to include the urlContext in the URL. Defaults to `true`.
|
|
21
|
+
* @param params.returnFullResponse - If `true`, returns the raw `Response` object instead of parsed JSON. Defaults to `false`.
|
|
22
|
+
* @returns The parsed JSON response body, or the raw `Response` object if `returnFullResponse` is `true`.
|
|
23
|
+
*/
|
|
17
24
|
getRequest(params?: {
|
|
18
25
|
urlPath?: string;
|
|
19
26
|
includeUrlContext?: boolean;
|
|
@@ -18,6 +18,9 @@ class FlexPLMConnect {
|
|
|
18
18
|
this.staticHeaders = this.config?.flexplmConnect?.staticHeaders;
|
|
19
19
|
}
|
|
20
20
|
}
|
|
21
|
+
/////////////////////////////////////////////////////////////////////////////
|
|
22
|
+
///////// Custom getRequestOptions: start
|
|
23
|
+
/////////////////////////////////////////////////////////////////////////////
|
|
21
24
|
getRequestOptions(method) {
|
|
22
25
|
const csrfOptions = {
|
|
23
26
|
method,
|
|
@@ -37,6 +40,9 @@ class FlexPLMConnect {
|
|
|
37
40
|
}
|
|
38
41
|
return csrfOptions;
|
|
39
42
|
}
|
|
43
|
+
/////////////////////////////////////////////////////////////////////////////
|
|
44
|
+
///////// Custom getRequestOptions: end
|
|
45
|
+
/////////////////////////////////////////////////////////////////////////////
|
|
40
46
|
async getCSRF() {
|
|
41
47
|
const urlContext = this.config.urlContext;
|
|
42
48
|
const csrfEndpoint = this.config.csrfEndpoint;
|
|
@@ -130,6 +136,7 @@ class FlexPLMConnect {
|
|
|
130
136
|
}
|
|
131
137
|
}
|
|
132
138
|
console.log('eventResponse.status: ' + status);
|
|
139
|
+
// console.log('eventBody: ', JSON.stringify(data));
|
|
133
140
|
return res;
|
|
134
141
|
}
|
|
135
142
|
catch (e) {
|
|
@@ -145,6 +152,13 @@ class FlexPLMConnect {
|
|
|
145
152
|
async sendMultipleToFlexPLM(payload) {
|
|
146
153
|
return await this.processRequest(payload);
|
|
147
154
|
}
|
|
155
|
+
/** Runs a GET request to FlexPLM.
|
|
156
|
+
* @param params - Optional configuration for the request.
|
|
157
|
+
* @param params.urlPath - Custom URL path to use instead of the default `/servlet/rest` + endpoint.
|
|
158
|
+
* @param params.includeUrlContext - Whether to include the urlContext in the URL. Defaults to `true`.
|
|
159
|
+
* @param params.returnFullResponse - If `true`, returns the raw `Response` object instead of parsed JSON. Defaults to `false`.
|
|
160
|
+
* @returns The parsed JSON response body, or the raw `Response` object if `returnFullResponse` is `true`.
|
|
161
|
+
*/
|
|
148
162
|
async getRequest(params) {
|
|
149
163
|
const { urlPath, includeUrlContext = true, returnFullResponse = false } = params || {};
|
|
150
164
|
const urlContext = includeUrlContext ? this.config.urlContext : '';
|
|
@@ -5,6 +5,7 @@ const app_framework_1 = require("@contrail/app-framework");
|
|
|
5
5
|
async function setLoggerConfig(appConfig) {
|
|
6
6
|
let logLevel = app_framework_1.LogLevel.INFO;
|
|
7
7
|
if (!appConfig.logLevel) {
|
|
8
|
+
//pass
|
|
8
9
|
}
|
|
9
10
|
else if (appConfig.logLevel === 'error') {
|
|
10
11
|
logLevel = app_framework_1.LogLevel.ERROR;
|
|
@@ -31,12 +31,26 @@ exports.mapping = {
|
|
|
31
31
|
}
|
|
32
32
|
}
|
|
33
33
|
}
|
|
34
|
+
// flex2vibe: {
|
|
35
|
+
// LCSRevisableEntity: {
|
|
36
|
+
// getMapKey: (object) =>{ return object;}
|
|
37
|
+
// },
|
|
38
|
+
// LCSLast: {
|
|
39
|
+
// getMapKey: (object) => {return object;}
|
|
40
|
+
// },
|
|
41
|
+
// LCSMaterial: {
|
|
42
|
+
// getMapKey: (object) =>{ return object;}
|
|
43
|
+
// },
|
|
44
|
+
// LCSBusinessObject: {
|
|
45
|
+
// getMapKey: (object) => {return object;}
|
|
46
|
+
// }
|
|
47
|
+
// },
|
|
34
48
|
},
|
|
35
49
|
LCSProduct: {
|
|
36
50
|
vibeOwningKeys: ['itemNumber', 'lifecycleStage'],
|
|
37
51
|
vibe2flex: {
|
|
38
52
|
getClass: () => 'LCSProduct',
|
|
39
|
-
getSoftType: (entity) => {
|
|
53
|
+
getSoftType: (entity /*, dependencies*/) => {
|
|
40
54
|
const prodType = entity['prodType'];
|
|
41
55
|
let val = '';
|
|
42
56
|
switch (prodType) {
|
|
@@ -61,7 +75,7 @@ exports.mapping = {
|
|
|
61
75
|
vibeIQIdentifier: 'itemNumber'
|
|
62
76
|
},
|
|
63
77
|
valueTransform: {
|
|
64
|
-
transformEx: (row) => {
|
|
78
|
+
transformEx: (row /*, dependencies*/) => {
|
|
65
79
|
return row['otherProp'] + 'xxx';
|
|
66
80
|
}
|
|
67
81
|
}
|
|
@@ -79,7 +93,7 @@ exports.mapping = {
|
|
|
79
93
|
vibeOwningKeys: ['itemNumber', 'lifecycleStage'],
|
|
80
94
|
vibe2flex: {
|
|
81
95
|
getClass: () => 'LCSSKU',
|
|
82
|
-
getSoftType: (entity) => {
|
|
96
|
+
getSoftType: (entity /*, dependencies*/) => {
|
|
83
97
|
const prodType = entity['prodType'];
|
|
84
98
|
let val = '';
|
|
85
99
|
switch (prodType) {
|
package/lib/util/map-utils.d.ts
CHANGED
|
@@ -1,6 +1,33 @@
|
|
|
1
1
|
import { MapFileUtil } from '@contrail/transform-data';
|
|
2
2
|
export declare class MapUtil {
|
|
3
|
+
/** Transforms the data, assumes mapSectionKey has been correctly determined.
|
|
4
|
+
*
|
|
5
|
+
* @param transformMapFile id of map file
|
|
6
|
+
* @param mapFileUtil
|
|
7
|
+
* @param data
|
|
8
|
+
* @param mapSectionKey key for section of map file
|
|
9
|
+
* @param direction vibe2flex or flex2vibe
|
|
10
|
+
* @param transformTaskOrderKey key for the list of tasks to be processed. default is 'transformOrder'
|
|
11
|
+
* @returns The converted data
|
|
12
|
+
*/
|
|
3
13
|
static applyTransformMap(transformMapFile: any, mapFileUtil: any, data: any, mapSectionKey: string, direction: string, transformTaskOrderKey?: string): Promise<any>;
|
|
14
|
+
/** Returns the mapKey based on the 'typeConversion' section of the map file.
|
|
15
|
+
* If the map file doesn't have a section for the type in question, 'undefined' is returned.
|
|
16
|
+
*
|
|
17
|
+
* @param fileId
|
|
18
|
+
* @param mapFileUtil
|
|
19
|
+
* @param data The full object
|
|
20
|
+
* @param type The entity or object class of the object. The functions are keyed based on this.
|
|
21
|
+
* @param direction
|
|
22
|
+
* @returns
|
|
23
|
+
*/
|
|
4
24
|
static getMapKey(transformMapFile: any, mapFileUtil: MapFileUtil, data: any, type: string, direction: string): Promise<string>;
|
|
25
|
+
/** Returns the full map section with both directions; identifier and informational properties; etc.
|
|
26
|
+
*
|
|
27
|
+
* @param transformMapFile id if map file
|
|
28
|
+
* @param mapFileUtil
|
|
29
|
+
* @param mapSectionKey key of the map section
|
|
30
|
+
* @returns
|
|
31
|
+
*/
|
|
5
32
|
static getFullMapSection(transformMapFile: string, mapFileUtil: MapFileUtil, mapSectionKey: string): Promise<any>;
|
|
6
33
|
}
|
package/lib/util/map-utils.js
CHANGED
|
@@ -2,12 +2,39 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.MapUtil = void 0;
|
|
4
4
|
class MapUtil {
|
|
5
|
+
/** Transforms the data, assumes mapSectionKey has been correctly determined.
|
|
6
|
+
*
|
|
7
|
+
* @param transformMapFile id of map file
|
|
8
|
+
* @param mapFileUtil
|
|
9
|
+
* @param data
|
|
10
|
+
* @param mapSectionKey key for section of map file
|
|
11
|
+
* @param direction vibe2flex or flex2vibe
|
|
12
|
+
* @param transformTaskOrderKey key for the list of tasks to be processed. default is 'transformOrder'
|
|
13
|
+
* @returns The converted data
|
|
14
|
+
*/
|
|
5
15
|
static async applyTransformMap(transformMapFile, mapFileUtil, data, mapSectionKey, direction, transformTaskOrderKey = 'transformOrder') {
|
|
6
16
|
return await mapFileUtil.applyTransformMap(transformMapFile, data, mapSectionKey, direction, transformTaskOrderKey);
|
|
7
17
|
}
|
|
18
|
+
/** Returns the mapKey based on the 'typeConversion' section of the map file.
|
|
19
|
+
* If the map file doesn't have a section for the type in question, 'undefined' is returned.
|
|
20
|
+
*
|
|
21
|
+
* @param fileId
|
|
22
|
+
* @param mapFileUtil
|
|
23
|
+
* @param data The full object
|
|
24
|
+
* @param type The entity or object class of the object. The functions are keyed based on this.
|
|
25
|
+
* @param direction
|
|
26
|
+
* @returns
|
|
27
|
+
*/
|
|
8
28
|
static async getMapKey(transformMapFile, mapFileUtil, data, type, direction) {
|
|
9
29
|
return await mapFileUtil.getMapKey(transformMapFile, data, type, direction);
|
|
10
30
|
}
|
|
31
|
+
/** Returns the full map section with both directions; identifier and informational properties; etc.
|
|
32
|
+
*
|
|
33
|
+
* @param transformMapFile id if map file
|
|
34
|
+
* @param mapFileUtil
|
|
35
|
+
* @param mapSectionKey key of the map section
|
|
36
|
+
* @returns
|
|
37
|
+
*/
|
|
11
38
|
static async getFullMapSection(transformMapFile, mapFileUtil, mapSectionKey) {
|
|
12
39
|
return await mapFileUtil.getFullMapSection(transformMapFile, mapSectionKey);
|
|
13
40
|
}
|
|
@@ -6,6 +6,7 @@ interface ContentCustomSize {
|
|
|
6
6
|
}
|
|
7
7
|
export declare class ThumbnailUtil {
|
|
8
8
|
private config;
|
|
9
|
+
/** The max_thumbnail_size is for limiting the size of the thumbnail being sent to FlexPLM. It is used when checking the size of the auto generated thumbnails (smallViewable, tinyViewable, etc.). */
|
|
9
10
|
private max_thumbnail_size;
|
|
10
11
|
private entities;
|
|
11
12
|
static NEW_THUMBNAIL_ID: string;
|
|
@@ -16,11 +17,31 @@ export declare class ThumbnailUtil {
|
|
|
16
17
|
}[];
|
|
17
18
|
constructor(config: FCConfig);
|
|
18
19
|
setOutboundThumbnail(data: any, event: any): Promise<any>;
|
|
20
|
+
/** Determines if a new image has been generated. If any viewable is new, there might be a better
|
|
21
|
+
* sized image. So send the fileId as new.
|
|
22
|
+
*/
|
|
19
23
|
isThumbnailNew(event: any, customSizes: any[]): boolean;
|
|
20
24
|
getFileId(primaryViewableId: string): Promise<string | undefined>;
|
|
21
25
|
getCustomSizes(): Promise<ContentCustomSize[]>;
|
|
22
26
|
getContentEntity(primaryViewableId: any, sizes: ContentCustomSize[]): Promise<any>;
|
|
27
|
+
/** This outputs the content entity, without the inflated file entities.
|
|
28
|
+
* To help debugging issues with sending the thumbnail info.
|
|
29
|
+
* The inflated entities are removed, because are large and cause
|
|
30
|
+
* problems with log file size limits.
|
|
31
|
+
*
|
|
32
|
+
* @param content: the content with inflated objects
|
|
33
|
+
* @param relations: string[] of the slugs for inflated objects
|
|
34
|
+
*/
|
|
23
35
|
logContentResults(content: any, relations: string[]): void;
|
|
36
|
+
/** Syncs the thumbnail from FlexPLM to VibeIQ. Handles creating, replacing, or removing
|
|
37
|
+
* the primary viewable content and persists the updates directly to the entity.
|
|
38
|
+
*
|
|
39
|
+
* @param entityId - The ID of the entity to update with thumbnail properties.
|
|
40
|
+
* @param primaryViewableId - The existing primary viewable content ID, if any.
|
|
41
|
+
* @param event - The inbound event containing thumbnail data (NEW_THUMBNAIL_ID / EXISTING_THUMBNAIL_ID).
|
|
42
|
+
* @param entityName - The entity type name (e.g. 'item', 'color') used for API calls.
|
|
43
|
+
* @returns The updated entity, or undefined if no thumbnail changes were needed.
|
|
44
|
+
*/
|
|
24
45
|
syncThumbnailToVibeIQ({ entityId, primaryViewableId, event, entityName }: {
|
|
25
46
|
entityId: string;
|
|
26
47
|
primaryViewableId?: string;
|