@contrail/flexplm 1.3.2-alpha.30ca8bf → 1.3.2-alpha.3ffe557
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 +4 -0
- package/lib/cli/commands/compile.js +73 -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 +5 -0
- package/lib/cli/commands/create.js +77 -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 +17 -0
- package/lib/cli/commands/upload.js +228 -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 +5 -0
- package/lib/cli/index.js +70 -0
- package/lib/cli/index.spec.d.ts +1 -0
- package/lib/cli/index.spec.js +85 -0
- package/lib/cli/template/mapping-template.ts.template +62 -0
- package/lib/entity-processor/base-entity-processor.d.ts +47 -10
- package/lib/entity-processor/base-entity-processor.js +53 -34
- package/lib/entity-processor/base-entity-processor.spec.js +1 -191
- 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.d.ts +0 -1
- package/lib/util/config-defaults.js +3 -3
- package/lib/util/config-defaults.spec.js +9 -32
- 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 +133 -1
- package/lib/util/data-converter.spec.js +68 -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 -4
- package/lib/util/type-conversion-utils.d.ts +140 -1
- package/lib/util/type-conversion-utils.js +143 -16
- package/lib/util/type-conversion-utils.spec.js +0 -59
- 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 -36
- package/publish.bat +0 -5
- package/publish.sh +0 -5
- package/src/entity-processor/base-entity-processor.spec.ts +0 -689
- package/src/entity-processor/base-entity-processor.ts +0 -583
- 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 -392
- package/src/util/config-defaults.ts +0 -97
- 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 -272
- package/src/util/type-conversion-utils.spec.ts +0 -1031
- package/src/util/type-conversion-utils.ts +0 -490
- 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
|
@@ -19,21 +19,118 @@ export declare class DataConverter {
|
|
|
19
19
|
getFlexPLMObjectDataFromEvent(event: any, dataToSkip: string[]): Promise<{}>;
|
|
20
20
|
getFlexPLMObjectData(newData: any, dataToSkip: string[], inflateObjRef: boolean): Promise<{}>;
|
|
21
21
|
getFlexPLMValue(prop: any, newData: any, inflateObjRef: boolean): Promise<any>;
|
|
22
|
+
/** Returns the display values for list properties (choice & multi_select)
|
|
23
|
+
*
|
|
24
|
+
* @param prop
|
|
25
|
+
* @param newData
|
|
26
|
+
* @returns
|
|
27
|
+
*/
|
|
22
28
|
getEnumerationValue(prop: any, nd: any): any;
|
|
23
29
|
getObjectReferenceValue(prop: any, newData: any, inflateObjRef?: boolean): Promise<any>;
|
|
30
|
+
/** (Deprecated) Use TypeConversionUtils.getMapKey()
|
|
31
|
+
* Will return the class to use to get mapping.
|
|
32
|
+
* This is needed because mappings will be different for different sub types
|
|
33
|
+
* of custom-entity
|
|
34
|
+
*
|
|
35
|
+
* @param obj: Entity being checked
|
|
36
|
+
* @param mapping: The whole mapping file
|
|
37
|
+
*/
|
|
24
38
|
getMappingClass(entity: object, mapping: any): string;
|
|
39
|
+
/** Sets entity values from FlexPLM data passed in
|
|
40
|
+
* Assumes the entity has a VibeIQ typeId and 'roles' value to filter if necessary.
|
|
41
|
+
* @param entity the entity to update
|
|
42
|
+
* @param data the FlexPLM data
|
|
43
|
+
* @param keysToSkip properties to skip
|
|
44
|
+
* @returns the modified entity with VibeIQ values
|
|
45
|
+
*/
|
|
25
46
|
setEntityValues(entity: any, data: any, keysToSkip?: string[]): Promise<any>;
|
|
47
|
+
/** Gets the entity values from FlexPLM data
|
|
48
|
+
* Assumes there isn't a VibeIQ typeId, so uses FlexPLM data to determine type
|
|
49
|
+
* @param objectClass FlexPLM object class
|
|
50
|
+
* @param data object data
|
|
51
|
+
* @param keysToSkip type properties to not process
|
|
52
|
+
* @returns object with VibeIQ values
|
|
53
|
+
*/
|
|
26
54
|
getEntityValues(objectClass: string, data: any, keysToSkip?: string[]): Promise<{}>;
|
|
55
|
+
/** Gets the VibeIQ value for the property from data
|
|
56
|
+
*
|
|
57
|
+
* @param prop the VibeIQ property
|
|
58
|
+
* @param data the FlexPLM data
|
|
59
|
+
* @returns value to be set in VibeIQ
|
|
60
|
+
*/
|
|
27
61
|
getEntityValue(prop: any, data: any): Promise<any>;
|
|
28
62
|
setEnumerationKeys(prop: any, nd: any, matchByDisplay: any): any;
|
|
63
|
+
/** Compares the potential changes to the entity and returns only the actual differences.
|
|
64
|
+
*
|
|
65
|
+
* @param entity the full entity
|
|
66
|
+
* @param changes the potential changes
|
|
67
|
+
* @returns only the change values that are different from the entity's value
|
|
68
|
+
*/
|
|
29
69
|
getPersistableChanges(entity: object, changes: object): object;
|
|
70
|
+
/** Sets object reference value from FlexPLM data passed in
|
|
71
|
+
*
|
|
72
|
+
* @param prop the VibeIQ property
|
|
73
|
+
* @param nd the VibeIQ data
|
|
74
|
+
* @returns the object reference id from VibeIQ
|
|
75
|
+
*/
|
|
30
76
|
setObjectReferenceValue(prop: any, nd: any): Promise<any>;
|
|
77
|
+
/**
|
|
78
|
+
* Retrieves all object references of a specified entity type based on the provided criteria.
|
|
79
|
+
* This function handles pagination and asynchronously fetches object references until there are no more pages.
|
|
80
|
+
* @param {string} entityType - The type of entity for which object references are to be retrieved.
|
|
81
|
+
* @param {object} rootTypeCriteria - The criteria used to filter object references.
|
|
82
|
+
* @returns {Promise<Array>} A Promise that resolves to an array containing all object references.
|
|
83
|
+
*/
|
|
31
84
|
getAllObjectReferences(entityType: string, rootTypeCriteria: any, postProcessCriteria?: any): Promise<any[]>;
|
|
85
|
+
/**
|
|
86
|
+
* Checks if all keys and values of a given object are present in an array of objects.
|
|
87
|
+
* @param {Object} criteria - The object whose keys and values are to be checked in the array of objects.
|
|
88
|
+
* @param {Array<Object>} arrayOfObjects - The array of objects to be searched for matching keys and values.
|
|
89
|
+
* @param {string} entityTypePath - The type / subtype for the property; objects must be this type or a sub type of it.
|
|
90
|
+
* @returns {(Object|boolean)} Returns the array of objects that matches all keys and values of the provided object.
|
|
91
|
+
* If no match is found, returns empty array.
|
|
92
|
+
*/
|
|
32
93
|
checkKeysAndValues(criteria: any, arrayOfObjects: any, entityTypePath: any): any[];
|
|
94
|
+
/** Filters out archived and trashed entities from the provided array of entities.
|
|
95
|
+
*
|
|
96
|
+
* @param entities
|
|
97
|
+
* @returns
|
|
98
|
+
*/
|
|
33
99
|
filterOutArchivedAndTrashedEntities(entities: any[]): any[];
|
|
100
|
+
/** Sets userListId value from FlexPLM data passed in
|
|
101
|
+
*
|
|
102
|
+
* @param prop the VibeIQ property
|
|
103
|
+
* @param nd the VibeIQ data
|
|
104
|
+
* @returns the modified entity with FlexPLM values
|
|
105
|
+
*/
|
|
34
106
|
setUserListValue(prop: any, nd: any): Promise<any>;
|
|
107
|
+
/** Makes batch calls of 1000 of user-org entities until
|
|
108
|
+
* it find one with userEmail of passed in nd.email.
|
|
109
|
+
* Maxes out after querying for 15,000 user-org entities
|
|
110
|
+
*
|
|
111
|
+
* @param nd
|
|
112
|
+
* @returns
|
|
113
|
+
*/
|
|
35
114
|
getUserByEmail(nd: any): Promise<any>;
|
|
115
|
+
/** Shows warning if user email address not present in group associated to property
|
|
116
|
+
*
|
|
117
|
+
* @param prop the VibeIQ property
|
|
118
|
+
* @param userEmail user email address
|
|
119
|
+
*/
|
|
36
120
|
processGroupMemberCheck(prop: any, userEmail: any): Promise<void>;
|
|
121
|
+
/** Gets the VibeIQ value for the userList property from data
|
|
122
|
+
*
|
|
123
|
+
* @param prop the VibeIQ property
|
|
124
|
+
* @param newData the FlexPLM data
|
|
125
|
+
* @returns value to be set in VibeIQ
|
|
126
|
+
*/
|
|
37
127
|
getUserListValue(prop: any, newData: any): Promise<any>;
|
|
128
|
+
/** Makes batch calls of 1000 of user-org entities until
|
|
129
|
+
* it find one with user.id of passed in userId.
|
|
130
|
+
* Maxes out after querying for 15,000 user-org entities
|
|
131
|
+
*
|
|
132
|
+
* @param userId
|
|
133
|
+
* @returns
|
|
134
|
+
*/
|
|
38
135
|
getUserById(userId: any): Promise<any>;
|
|
39
136
|
}
|
|
@@ -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,18 +111,29 @@ 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) {
|
|
111
124
|
value = await this.getUserListValue(prop, newData);
|
|
112
125
|
}
|
|
126
|
+
else if ('size_range' === propertyType) {
|
|
127
|
+
value = nd;
|
|
128
|
+
}
|
|
113
129
|
return value;
|
|
114
130
|
}
|
|
131
|
+
/** Returns the display values for list properties (choice & multi_select)
|
|
132
|
+
*
|
|
133
|
+
* @param prop
|
|
134
|
+
* @param newData
|
|
135
|
+
* @returns
|
|
136
|
+
*/
|
|
115
137
|
getEnumerationValue(prop, nd) {
|
|
116
138
|
const propertyType = prop['propertyType'];
|
|
117
139
|
let value;
|
|
@@ -195,6 +217,14 @@ class DataConverter {
|
|
|
195
217
|
this.objRefCache[entityId] = value;
|
|
196
218
|
return value;
|
|
197
219
|
}
|
|
220
|
+
/** (Deprecated) Use TypeConversionUtils.getMapKey()
|
|
221
|
+
* Will return the class to use to get mapping.
|
|
222
|
+
* This is needed because mappings will be different for different sub types
|
|
223
|
+
* of custom-entity
|
|
224
|
+
*
|
|
225
|
+
* @param obj: Entity being checked
|
|
226
|
+
* @param mapping: The whole mapping file
|
|
227
|
+
*/
|
|
198
228
|
getMappingClass(entity, mapping) {
|
|
199
229
|
const entityTypePath = entity['typePath'];
|
|
200
230
|
const typeMapKey = mapping['typeMapKey'];
|
|
@@ -208,11 +238,22 @@ class DataConverter {
|
|
|
208
238
|
}
|
|
209
239
|
return objClass;
|
|
210
240
|
}
|
|
241
|
+
/** Sets entity values from FlexPLM data passed in
|
|
242
|
+
* Assumes the entity has a VibeIQ typeId and 'roles' value to filter if necessary.
|
|
243
|
+
* @param entity the entity to update
|
|
244
|
+
* @param data the FlexPLM data
|
|
245
|
+
* @param keysToSkip properties to skip
|
|
246
|
+
* @returns the modified entity with VibeIQ values
|
|
247
|
+
*/
|
|
211
248
|
async setEntityValues(entity, data, keysToSkip = []) {
|
|
249
|
+
// this.logger.log('setEntityValues: ' + JSON.stringify(entity));
|
|
250
|
+
// this.logger.log('data: ' + JSON.stringify(data));
|
|
212
251
|
const type = await this.typeUtils.getTypeById(entity.typeId);
|
|
213
252
|
keysToSkip = keysToSkip.concat(['updatedOn', 'updatedById', 'createdOn', 'createdById', 'modifiedAt', 'orgId', 'createdAt', 'id', 'typeId', 'typePath', 'workspaceId']);
|
|
214
253
|
let typeProps = this.typeUtils.filterTypeProperties(type, entity);
|
|
215
254
|
typeProps = typeProps.filter(prop => !keysToSkip.includes(prop['slug']));
|
|
255
|
+
//Only process properties that had a value sent; to not accidentally clear out values
|
|
256
|
+
//for properties that weren't sent.
|
|
216
257
|
const dataKeys = Object.getOwnPropertyNames(data);
|
|
217
258
|
typeProps = typeProps.filter(prop => dataKeys.includes(prop['slug']));
|
|
218
259
|
for (const prop of typeProps) {
|
|
@@ -223,9 +264,17 @@ class DataConverter {
|
|
|
223
264
|
keyName = slug + 'Id';
|
|
224
265
|
}
|
|
225
266
|
entity[keyName] = await this.getEntityValue(prop, data);
|
|
267
|
+
// console.log('entity[slug]: ' + entity[slug]);
|
|
226
268
|
}
|
|
227
269
|
return entity;
|
|
228
270
|
}
|
|
271
|
+
/** Gets the entity values from FlexPLM data
|
|
272
|
+
* Assumes there isn't a VibeIQ typeId, so uses FlexPLM data to determine type
|
|
273
|
+
* @param objectClass FlexPLM object class
|
|
274
|
+
* @param data object data
|
|
275
|
+
* @param keysToSkip type properties to not process
|
|
276
|
+
* @returns object with VibeIQ values
|
|
277
|
+
*/
|
|
229
278
|
async getEntityValues(objectClass, data, keysToSkip = []) {
|
|
230
279
|
const entityValues = {};
|
|
231
280
|
const tco = await this.typeUtils.getEntityTypeClientOptionsUsingMapping(this.transformMapFile, this.mapFileUtil, data);
|
|
@@ -250,10 +299,17 @@ class DataConverter {
|
|
|
250
299
|
}
|
|
251
300
|
return entityValues;
|
|
252
301
|
}
|
|
302
|
+
/** Gets the VibeIQ value for the property from data
|
|
303
|
+
*
|
|
304
|
+
* @param prop the VibeIQ property
|
|
305
|
+
* @param data the FlexPLM data
|
|
306
|
+
* @returns value to be set in VibeIQ
|
|
307
|
+
*/
|
|
253
308
|
async getEntityValue(prop, data) {
|
|
254
309
|
const propertyType = prop['propertyType'];
|
|
255
310
|
const slug = prop['slug'];
|
|
256
311
|
const nd = data[slug];
|
|
312
|
+
// this.logger.log('getValue: ' + propertyType + ', ' +slug + ', ' + nd);
|
|
257
313
|
let value;
|
|
258
314
|
if (['string', 'text'].includes(propertyType)) {
|
|
259
315
|
value = nd;
|
|
@@ -263,6 +319,11 @@ class DataConverter {
|
|
|
263
319
|
}
|
|
264
320
|
else if ('date' === propertyType) {
|
|
265
321
|
if (nd) {
|
|
322
|
+
// const offset = new Date(nd).getTimezoneOffset() * 60 * 1_000;
|
|
323
|
+
// this.logger.log('nd: ' + nd);
|
|
324
|
+
// this.logger.log(offset);
|
|
325
|
+
// this.logger.log('No Offset: ' + new Date(nd).toISOString());
|
|
326
|
+
// const d = new Date(nd + offset);// Take system Timezone into account.
|
|
266
327
|
const d = new Date(nd);
|
|
267
328
|
value = d.toISOString();
|
|
268
329
|
}
|
|
@@ -283,20 +344,28 @@ class DataConverter {
|
|
|
283
344
|
value = await this.setObjectReferenceValue(prop, nd);
|
|
284
345
|
}
|
|
285
346
|
else if ('image' === propertyType) {
|
|
347
|
+
// console.log('TODO-image');
|
|
286
348
|
}
|
|
287
349
|
else if ('formula' === propertyType) {
|
|
350
|
+
// console.log('TODO-formula');
|
|
288
351
|
}
|
|
289
352
|
else if ('json' === propertyType) {
|
|
353
|
+
// console.log('TODO-json');
|
|
290
354
|
}
|
|
291
355
|
else if ('userList' === propertyType) {
|
|
292
356
|
value = await this.setUserListValue(prop, nd);
|
|
293
357
|
}
|
|
358
|
+
else if ('size_range' === propertyType) {
|
|
359
|
+
value = nd;
|
|
360
|
+
}
|
|
361
|
+
// console.log(value);
|
|
294
362
|
return value;
|
|
295
363
|
}
|
|
296
364
|
setEnumerationKeys(prop, nd, matchByDisplay) {
|
|
297
365
|
const propertyType = prop['propertyType'];
|
|
298
366
|
let value;
|
|
299
367
|
if (['choice', 'multi_select'].includes(propertyType)) {
|
|
368
|
+
//If there are no options, use empty array to not error out and don't set anything
|
|
300
369
|
const options = prop['options'] || [];
|
|
301
370
|
if ('choice' === propertyType) {
|
|
302
371
|
if (nd) {
|
|
@@ -326,6 +395,12 @@ class DataConverter {
|
|
|
326
395
|
}
|
|
327
396
|
return value;
|
|
328
397
|
}
|
|
398
|
+
/** Compares the potential changes to the entity and returns only the actual differences.
|
|
399
|
+
*
|
|
400
|
+
* @param entity the full entity
|
|
401
|
+
* @param changes the potential changes
|
|
402
|
+
* @returns only the change values that are different from the entity's value
|
|
403
|
+
*/
|
|
329
404
|
getPersistableChanges(entity, changes) {
|
|
330
405
|
const entityCompareValues = {};
|
|
331
406
|
for (const key of (Object.getOwnPropertyNames(changes))) {
|
|
@@ -340,6 +415,12 @@ class DataConverter {
|
|
|
340
415
|
}
|
|
341
416
|
return diffValues;
|
|
342
417
|
}
|
|
418
|
+
/** Sets object reference value from FlexPLM data passed in
|
|
419
|
+
*
|
|
420
|
+
* @param prop the VibeIQ property
|
|
421
|
+
* @param nd the VibeIQ data
|
|
422
|
+
* @returns the object reference id from VibeIQ
|
|
423
|
+
*/
|
|
343
424
|
async setObjectReferenceValue(prop, nd) {
|
|
344
425
|
let objectReferenceId = "";
|
|
345
426
|
if (!nd) {
|
|
@@ -398,6 +479,13 @@ class DataConverter {
|
|
|
398
479
|
this.objRefCache[cacheKey] = objectReferenceId;
|
|
399
480
|
return objectReferenceId;
|
|
400
481
|
}
|
|
482
|
+
/**
|
|
483
|
+
* Retrieves all object references of a specified entity type based on the provided criteria.
|
|
484
|
+
* This function handles pagination and asynchronously fetches object references until there are no more pages.
|
|
485
|
+
* @param {string} entityType - The type of entity for which object references are to be retrieved.
|
|
486
|
+
* @param {object} rootTypeCriteria - The criteria used to filter object references.
|
|
487
|
+
* @returns {Promise<Array>} A Promise that resolves to an array containing all object references.
|
|
488
|
+
*/
|
|
401
489
|
async getAllObjectReferences(entityType, rootTypeCriteria, postProcessCriteria = null) {
|
|
402
490
|
const entities = new sdk_1.Entities();
|
|
403
491
|
let loads = [];
|
|
@@ -453,6 +541,14 @@ class DataConverter {
|
|
|
453
541
|
}
|
|
454
542
|
return loads;
|
|
455
543
|
}
|
|
544
|
+
/**
|
|
545
|
+
* Checks if all keys and values of a given object are present in an array of objects.
|
|
546
|
+
* @param {Object} criteria - The object whose keys and values are to be checked in the array of objects.
|
|
547
|
+
* @param {Array<Object>} arrayOfObjects - The array of objects to be searched for matching keys and values.
|
|
548
|
+
* @param {string} entityTypePath - The type / subtype for the property; objects must be this type or a sub type of it.
|
|
549
|
+
* @returns {(Object|boolean)} Returns the array of objects that matches all keys and values of the provided object.
|
|
550
|
+
* If no match is found, returns empty array.
|
|
551
|
+
*/
|
|
456
552
|
checkKeysAndValues(criteria, arrayOfObjects, entityTypePath) {
|
|
457
553
|
let arrOfMatchObjects = [];
|
|
458
554
|
for (let i = 0; i < arrayOfObjects.length; i++) {
|
|
@@ -476,6 +572,11 @@ class DataConverter {
|
|
|
476
572
|
}
|
|
477
573
|
return arrOfMatchObjects;
|
|
478
574
|
}
|
|
575
|
+
/** Filters out archived and trashed entities from the provided array of entities.
|
|
576
|
+
*
|
|
577
|
+
* @param entities
|
|
578
|
+
* @returns
|
|
579
|
+
*/
|
|
479
580
|
filterOutArchivedAndTrashedEntities(entities) {
|
|
480
581
|
if (!entities || !Array.isArray(entities) || entities.length === 0) {
|
|
481
582
|
return [];
|
|
@@ -486,6 +587,12 @@ class DataConverter {
|
|
|
486
587
|
return !isArchived && !isTrashed;
|
|
487
588
|
});
|
|
488
589
|
}
|
|
590
|
+
/** Sets userListId value from FlexPLM data passed in
|
|
591
|
+
*
|
|
592
|
+
* @param prop the VibeIQ property
|
|
593
|
+
* @param nd the VibeIQ data
|
|
594
|
+
* @returns the modified entity with FlexPLM values
|
|
595
|
+
*/
|
|
489
596
|
async setUserListValue(prop, nd) {
|
|
490
597
|
if (!nd?.email) {
|
|
491
598
|
return "";
|
|
@@ -506,6 +613,13 @@ class DataConverter {
|
|
|
506
613
|
}
|
|
507
614
|
return userId;
|
|
508
615
|
}
|
|
616
|
+
/** Makes batch calls of 1000 of user-org entities until
|
|
617
|
+
* it find one with userEmail of passed in nd.email.
|
|
618
|
+
* Maxes out after querying for 15,000 user-org entities
|
|
619
|
+
*
|
|
620
|
+
* @param nd
|
|
621
|
+
* @returns
|
|
622
|
+
*/
|
|
509
623
|
async getUserByEmail(nd) {
|
|
510
624
|
let userOrg = undefined;
|
|
511
625
|
let count = 0;
|
|
@@ -522,6 +636,11 @@ class DataConverter {
|
|
|
522
636
|
} while (!userOrg && size == getOptionsCriteria.take && count < 15);
|
|
523
637
|
return userOrg?.user;
|
|
524
638
|
}
|
|
639
|
+
/** Shows warning if user email address not present in group associated to property
|
|
640
|
+
*
|
|
641
|
+
* @param prop the VibeIQ property
|
|
642
|
+
* @param userEmail user email address
|
|
643
|
+
*/
|
|
525
644
|
async processGroupMemberCheck(prop, userEmail) {
|
|
526
645
|
let arrUserList = [];
|
|
527
646
|
if (this.userRefCache[prop.typePropertyUserListId]) {
|
|
@@ -544,6 +663,12 @@ class DataConverter {
|
|
|
544
663
|
}
|
|
545
664
|
}
|
|
546
665
|
}
|
|
666
|
+
/** Gets the VibeIQ value for the userList property from data
|
|
667
|
+
*
|
|
668
|
+
* @param prop the VibeIQ property
|
|
669
|
+
* @param newData the FlexPLM data
|
|
670
|
+
* @returns value to be set in VibeIQ
|
|
671
|
+
*/
|
|
547
672
|
async getUserListValue(prop, newData) {
|
|
548
673
|
const slug = prop['slug'];
|
|
549
674
|
if (app_framework_1.Logger.isDebugOn()) {
|
|
@@ -572,6 +697,13 @@ class DataConverter {
|
|
|
572
697
|
}
|
|
573
698
|
return value;
|
|
574
699
|
}
|
|
700
|
+
/** Makes batch calls of 1000 of user-org entities until
|
|
701
|
+
* it find one with user.id of passed in userId.
|
|
702
|
+
* Maxes out after querying for 15,000 user-org entities
|
|
703
|
+
*
|
|
704
|
+
* @param userId
|
|
705
|
+
* @returns
|
|
706
|
+
*/
|
|
575
707
|
async getUserById(userId) {
|
|
576
708
|
let userOrg = undefined;
|
|
577
709
|
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);
|
|
@@ -902,3 +904,69 @@ describe('getUserListValue', () => {
|
|
|
902
904
|
expect(returnValue.lastName).toEqual('Smith');
|
|
903
905
|
});
|
|
904
906
|
});
|
|
907
|
+
describe('getFlexPLMValue size_range', () => {
|
|
908
|
+
const config = {
|
|
909
|
+
apiHost: 'host',
|
|
910
|
+
userName: () => 'user',
|
|
911
|
+
password: () => 'pass',
|
|
912
|
+
urlContext: 'xxx',
|
|
913
|
+
vibeEventEndpoint: '/rfa/vibeiq/vibeEvents',
|
|
914
|
+
csrfEndpoint: '/servlet/rest/security/csrf',
|
|
915
|
+
itemPreDevelopmentLifecycleStages: ['concept']
|
|
916
|
+
};
|
|
917
|
+
const mapFileUtil = new transform_data_1.MapFileUtil(new sdk_1.Entities());
|
|
918
|
+
const dc = new data_converter_1.DataConverter(config, mapFileUtil);
|
|
919
|
+
const sizeRangeProp = {
|
|
920
|
+
propertyType: 'size_range',
|
|
921
|
+
slug: 'sizeRange',
|
|
922
|
+
label: 'Size Range',
|
|
923
|
+
};
|
|
924
|
+
it('returns sizeRange object when value is present', async () => {
|
|
925
|
+
const newData = { sizeRange: { sizes: ['PRE', 'NB'] } };
|
|
926
|
+
const returnValue = await dc.getFlexPLMValue(sizeRangeProp, newData, true);
|
|
927
|
+
expect(returnValue).toEqual({ sizes: ['PRE', 'NB'] });
|
|
928
|
+
});
|
|
929
|
+
it('returns null when sizeRange is null', async () => {
|
|
930
|
+
const newData = { sizeRange: null };
|
|
931
|
+
const returnValue = await dc.getFlexPLMValue(sizeRangeProp, newData, true);
|
|
932
|
+
expect(returnValue).toBeNull();
|
|
933
|
+
});
|
|
934
|
+
it('returns undefined when sizeRange is missing', async () => {
|
|
935
|
+
const newData = {};
|
|
936
|
+
const returnValue = await dc.getFlexPLMValue(sizeRangeProp, newData, true);
|
|
937
|
+
expect(returnValue).toBeUndefined();
|
|
938
|
+
});
|
|
939
|
+
});
|
|
940
|
+
describe('getEntityValue size_range', () => {
|
|
941
|
+
const config = {
|
|
942
|
+
apiHost: 'host',
|
|
943
|
+
userName: () => 'user',
|
|
944
|
+
password: () => 'pass',
|
|
945
|
+
urlContext: 'xxx',
|
|
946
|
+
vibeEventEndpoint: '/rfa/vibeiq/vibeEvents',
|
|
947
|
+
csrfEndpoint: '/servlet/rest/security/csrf',
|
|
948
|
+
itemPreDevelopmentLifecycleStages: ['concept']
|
|
949
|
+
};
|
|
950
|
+
const mapFileUtil = new transform_data_1.MapFileUtil(new sdk_1.Entities());
|
|
951
|
+
const dc = new data_converter_1.DataConverter(config, mapFileUtil);
|
|
952
|
+
const sizeRangeProp = {
|
|
953
|
+
propertyType: 'size_range',
|
|
954
|
+
slug: 'sizeRange',
|
|
955
|
+
label: 'Size Range',
|
|
956
|
+
};
|
|
957
|
+
it('returns sizeRange object when value is present', async () => {
|
|
958
|
+
const data = { sizeRange: { sizes: ['PRE', 'NB'] } };
|
|
959
|
+
const returnValue = await dc.getEntityValue(sizeRangeProp, data);
|
|
960
|
+
expect(returnValue).toEqual({ sizes: ['PRE', 'NB'] });
|
|
961
|
+
});
|
|
962
|
+
it('returns null when sizeRange is null', async () => {
|
|
963
|
+
const data = { sizeRange: null };
|
|
964
|
+
const returnValue = await dc.getEntityValue(sizeRangeProp, data);
|
|
965
|
+
expect(returnValue).toBeNull();
|
|
966
|
+
});
|
|
967
|
+
it('returns undefined when sizeRange is missing', async () => {
|
|
968
|
+
const data = {};
|
|
969
|
+
const returnValue = await dc.getEntityValue(sizeRangeProp, data);
|
|
970
|
+
expect(returnValue).toBeUndefined();
|
|
971
|
+
});
|
|
972
|
+
});
|
|
@@ -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 : '';
|