@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.
Files changed (113) hide show
  1. package/lib/cli/commands/compile.d.ts +4 -0
  2. package/lib/cli/commands/compile.js +73 -0
  3. package/lib/cli/commands/compile.spec.d.ts +1 -0
  4. package/lib/cli/commands/compile.spec.js +80 -0
  5. package/lib/cli/commands/create.d.ts +5 -0
  6. package/lib/cli/commands/create.js +77 -0
  7. package/lib/cli/commands/create.spec.d.ts +1 -0
  8. package/lib/cli/commands/create.spec.js +78 -0
  9. package/lib/cli/commands/upload.d.ts +17 -0
  10. package/lib/cli/commands/upload.js +228 -0
  11. package/lib/cli/commands/upload.spec.d.ts +1 -0
  12. package/lib/cli/commands/upload.spec.js +88 -0
  13. package/lib/cli/index.d.ts +5 -0
  14. package/lib/cli/index.js +70 -0
  15. package/lib/cli/index.spec.d.ts +1 -0
  16. package/lib/cli/index.spec.js +85 -0
  17. package/lib/cli/template/mapping-template.ts.template +62 -0
  18. package/lib/entity-processor/base-entity-processor.d.ts +47 -10
  19. package/lib/entity-processor/base-entity-processor.js +53 -34
  20. package/lib/entity-processor/base-entity-processor.spec.js +1 -191
  21. package/lib/index.d.ts +1 -0
  22. package/lib/index.js +1 -0
  23. package/lib/interfaces/mapping-file.d.ts +460 -0
  24. package/lib/interfaces/mapping-file.js +2 -0
  25. package/lib/publish/base-process-publish-assortment.d.ts +25 -0
  26. package/lib/publish/base-process-publish-assortment.js +60 -6
  27. package/lib/publish/base-process-publish-assortment.spec.js +22 -4
  28. package/lib/publish/mockData.js +5 -0
  29. package/lib/transform/identifier-conversion-spec-mockData.js +34 -6
  30. package/lib/transform/identifier-conversion.d.ts +36 -0
  31. package/lib/transform/identifier-conversion.js +36 -0
  32. package/lib/transform/identifier-conversion.spec.js +4 -0
  33. package/lib/util/config-defaults.d.ts +0 -1
  34. package/lib/util/config-defaults.js +3 -3
  35. package/lib/util/config-defaults.spec.js +9 -32
  36. package/lib/util/data-converter-spec-mockData.js +17 -3
  37. package/lib/util/data-converter.d.ts +97 -0
  38. package/lib/util/data-converter.js +133 -1
  39. package/lib/util/data-converter.spec.js +68 -0
  40. package/lib/util/error-response-object.d.ts +5 -0
  41. package/lib/util/error-response-object.js +7 -0
  42. package/lib/util/event-short-message-status.js +1 -0
  43. package/lib/util/federation.js +8 -0
  44. package/lib/util/flexplm-connect.d.ts +7 -0
  45. package/lib/util/flexplm-connect.js +14 -0
  46. package/lib/util/logger-config.js +1 -0
  47. package/lib/util/map-util-spec-mockData.js +17 -3
  48. package/lib/util/map-utils.d.ts +27 -0
  49. package/lib/util/map-utils.js +27 -0
  50. package/lib/util/thumbnail-util.d.ts +21 -0
  51. package/lib/util/thumbnail-util.js +28 -1
  52. package/lib/util/thumbnail-util.spec.js +6 -0
  53. package/lib/util/type-conversion-utils-spec-mockData.js +3 -4
  54. package/lib/util/type-conversion-utils.d.ts +140 -1
  55. package/lib/util/type-conversion-utils.js +143 -16
  56. package/lib/util/type-conversion-utils.spec.js +0 -59
  57. package/lib/util/type-defaults.d.ts +58 -0
  58. package/lib/util/type-defaults.js +58 -0
  59. package/lib/util/type-defaults.spec.js +5 -5
  60. package/lib/util/type-utils.d.ts +21 -0
  61. package/lib/util/type-utils.js +23 -0
  62. package/lib/util/type-utils.spec.js +2 -0
  63. package/package.json +21 -6
  64. package/scripts/copy-template.js +10 -0
  65. package/.github/pull_request_template.md +0 -31
  66. package/.github/workflows/flexplm-lib.yml +0 -27
  67. package/.github/workflows/publish-to-npm.yml +0 -121
  68. package/CHANGELOG.md +0 -36
  69. package/publish.bat +0 -5
  70. package/publish.sh +0 -5
  71. package/src/entity-processor/base-entity-processor.spec.ts +0 -689
  72. package/src/entity-processor/base-entity-processor.ts +0 -583
  73. package/src/flexplm-request.ts +0 -28
  74. package/src/flexplm-utils.spec.ts +0 -27
  75. package/src/flexplm-utils.ts +0 -29
  76. package/src/index.ts +0 -22
  77. package/src/interfaces/interfaces.ts +0 -122
  78. package/src/interfaces/item-family-changes.ts +0 -67
  79. package/src/interfaces/publish-change-data.ts +0 -43
  80. package/src/publish/base-process-publish-assortment-callback.ts +0 -50
  81. package/src/publish/base-process-publish-assortment.spec.ts +0 -1992
  82. package/src/publish/base-process-publish-assortment.ts +0 -1134
  83. package/src/publish/mockData.ts +0 -4561
  84. package/src/transform/identifier-conversion-spec-mockData.ts +0 -496
  85. package/src/transform/identifier-conversion.spec.ts +0 -354
  86. package/src/transform/identifier-conversion.ts +0 -282
  87. package/src/util/config-defaults.spec.ts +0 -392
  88. package/src/util/config-defaults.ts +0 -97
  89. package/src/util/data-converter-spec-mockData.ts +0 -231
  90. package/src/util/data-converter.spec.ts +0 -1041
  91. package/src/util/data-converter.ts +0 -762
  92. package/src/util/error-response-object.spec.ts +0 -116
  93. package/src/util/error-response-object.ts +0 -50
  94. package/src/util/event-short-message-status.ts +0 -22
  95. package/src/util/federation.ts +0 -172
  96. package/src/util/flexplm-connect.spec.ts +0 -132
  97. package/src/util/flexplm-connect.ts +0 -208
  98. package/src/util/logger-config.ts +0 -20
  99. package/src/util/map-util-spec-mockData.ts +0 -231
  100. package/src/util/map-utils.spec.ts +0 -103
  101. package/src/util/map-utils.ts +0 -41
  102. package/src/util/mockData.ts +0 -101
  103. package/src/util/thumbnail-util.spec.ts +0 -508
  104. package/src/util/thumbnail-util.ts +0 -272
  105. package/src/util/type-conversion-utils-spec-mockData.ts +0 -272
  106. package/src/util/type-conversion-utils.spec.ts +0 -1031
  107. package/src/util/type-conversion-utils.ts +0 -490
  108. package/src/util/type-defaults.spec.ts +0 -669
  109. package/src/util/type-defaults.ts +0 -281
  110. package/src/util/type-utils.spec.ts +0 -227
  111. package/src/util/type-utils.ts +0 -144
  112. package/tsconfig.json +0 -24
  113. package/tslint.json +0 -57
@@ -1,583 +0,0 @@
1
- import { FCConfig, EntityPayloadType } from '../interfaces/interfaces';
2
- import { DataConverter } from '../util/data-converter';
3
- import { TypeUtils } from '../util/type-utils';
4
- import { FlexPLMConnect,} from '../util/flexplm-connect';
5
- import { MapUtil } from '../util/map-utils';
6
- import { MapFileUtil } from '@contrail/transform-data';
7
- import { Entities } from '@contrail/sdk';
8
- import { TypeProperty } from '@contrail/types';
9
- import { TypeConversionUtils } from '../util/type-conversion-utils';
10
- import { ThumbnailUtil } from '../util/thumbnail-util';
11
- import { EventShortMessageStatus } from '../util/event-short-message-status';
12
-
13
- const UNSUPPORTED_TYPE = 'Unsupported eventType.';
14
- export class IncomingEntityResponse {
15
- entity: any
16
- earlyReturn: any
17
- }
18
-
19
- export abstract class BaseEntityProcessor {
20
-
21
- protected typeUtil: TypeUtils;
22
- protected transformMapFile: string;
23
- protected entities;
24
- protected orgSlug: string;
25
- constructor(
26
- protected config: FCConfig,
27
- protected dc: DataConverter,
28
- protected mapFileUtil: MapFileUtil,
29
- protected baseType: string
30
- ) {
31
- this.typeUtil = new TypeUtils();
32
- this.transformMapFile = this.config?.transformMapFile;
33
- this.entities = new Entities();
34
- this.orgSlug = this.config?.orgSlug || 'unset-orgSlug';
35
- }
36
-
37
- // inbound
38
- async inbound(event: EntityPayloadType) {
39
- const eventType = event.eventType;
40
- console.log(`inbound entity: ${eventType}:${event.objectClass}`);
41
-
42
- switch (eventType) {
43
- case 'PERSIST':
44
- return await this.handleIncomingUpsert(event);
45
- case 'DELETE':
46
- return await this.handleIncomingDelete(event);
47
- default:
48
- console.error(UNSUPPORTED_TYPE);
49
- return {
50
- status: 500,
51
- data: { UNSUPPORTED_TYPE }
52
- };
53
- }
54
- }
55
-
56
- async handleIncomingUpsert (event: EntityPayloadType) {
57
- const inboundData = await this.getTransformedData(event);
58
- const incomingEntityResponse = await this.getIncomingEntity(event, inboundData);
59
- // This case means there was an early return in the getIncomingEntity method
60
- if (incomingEntityResponse.earlyReturn) {
61
- const statusMsg = this.getInboundStatusMessage({
62
- status: EventShortMessageStatus.FAILURE,
63
- statusMessage: incomingEntityResponse.earlyReturn.shortStatusMessage || '',
64
- objectClass: event.objectClass,
65
- federatedId: event.federatedId
66
- });
67
- console.log(statusMsg);
68
- return incomingEntityResponse.earlyReturn;
69
- }
70
-
71
- const entity = incomingEntityResponse.entity;
72
- if (!entity) {
73
- const createEntityResponse = await this.getCreateEntity(inboundData);
74
- if (createEntityResponse.earlyReturn) {
75
- const status = (createEntityResponse.earlyReturn.shortStatusMessage === EventShortMessageStatus.NOT_CREATABLE)
76
- ? EventShortMessageStatus.SUCCESS
77
- : EventShortMessageStatus.FAILURE;
78
- const statusMsg = this.getInboundStatusMessage({
79
- status,
80
- statusMessage: createEntityResponse.earlyReturn.shortStatusMessage ||'',
81
- objectClass: event.objectClass,
82
- federatedId: event.federatedId
83
- });
84
- console.log(statusMsg);
85
- return createEntityResponse.earlyReturn;
86
- }
87
- let createdEntity = await this.createEntity(this.baseType, createEntityResponse.entity);
88
- const shouldSyncThumbnail = await TypeConversionUtils.syncInboundImages(
89
- this.transformMapFile, this.mapFileUtil, event.data
90
- );
91
- if (shouldSyncThumbnail) {
92
- createdEntity = await new ThumbnailUtil(this.config).syncThumbnailToVibeIQ({ entityId: createdEntity.id, primaryViewableId: createdEntity.primaryViewableId, event, entityName: this.baseType }) || createdEntity;
93
- }
94
- const statusMsg = this.getInboundStatusMessage({
95
- status: EventShortMessageStatus.SUCCESS,
96
- statusMessage: EventShortMessageStatus.CREATED,
97
- objectClass: event.objectClass,
98
- entityId: 'id',
99
- federatedId: event.federatedId
100
- });
101
- console.log(statusMsg);
102
- return createdEntity;
103
- }
104
-
105
- const diffs = await this.getUpdatesForEntity(entity, inboundData);
106
- const shouldSyncThumbnail = await TypeConversionUtils.syncInboundImages(
107
- this.transformMapFile, this.mapFileUtil, event.data
108
- );
109
- let thumbnailEntity;
110
- if (shouldSyncThumbnail) {
111
- thumbnailEntity = await new ThumbnailUtil(this.config).syncThumbnailToVibeIQ({ entityId: entity.id, primaryViewableId: entity.primaryViewableId, event, entityName: this.baseType });
112
- }
113
-
114
- const hasPropertyChanges = Object.getOwnPropertyNames(diffs).length > 0;
115
-
116
- if (!hasPropertyChanges && thumbnailEntity) {
117
- const statusMsg = this.getInboundStatusMessage({
118
- status: EventShortMessageStatus.SUCCESS,
119
- statusMessage: EventShortMessageStatus.PRIMARY_CONTENT_UPDATED,
120
- objectClass: event.objectClass,
121
- entityId: entity.id,
122
- federatedId: event.federatedId
123
- });
124
- console.log(statusMsg);
125
- return thumbnailEntity;
126
- }
127
-
128
- if (!hasPropertyChanges) {
129
- const statusMsg = this.getInboundStatusMessage({
130
- status: EventShortMessageStatus.SUCCESS,
131
- statusMessage: EventShortMessageStatus.NO_CHANGES,
132
- objectClass: event.objectClass,
133
- entityId: entity.id,
134
- federatedId: event.federatedId
135
- });
136
- console.log(statusMsg);
137
- const message = 'No Changes to persist for entity: ' + entity.id;
138
- return {
139
- status: 200,
140
- data: {message}
141
- };
142
- }
143
-
144
- const updatedEntity = await this.updateEntity(this.baseType, entity, diffs);
145
- const statusMsg = this.getInboundStatusMessage({
146
- status: EventShortMessageStatus.SUCCESS,
147
- statusMessage: EventShortMessageStatus.UPDATED,
148
- objectClass: event.objectClass,
149
- entityId: entity.id,
150
- federatedId: event.federatedId
151
- });
152
- console.log(statusMsg);
153
- return updatedEntity;
154
- }
155
-
156
- getInboundStatusMessage(statusObject){
157
- return 'BaseEntityProcessor: inbound: status: ' + statusObject.status
158
- + ', statusMessage: ' + statusObject.statusMessage
159
- + ', entityType: ' + this.baseType
160
- + ', entityId: ' + statusObject.entityId
161
- + ', objectClass: ' + statusObject.objectClass
162
- + ', federatedId: ' + statusObject.federatedId
163
- + ', orgSlug: ' + this.orgSlug;
164
- }
165
-
166
- /** Looks up an identity record from the identity service based on the passed in criteria.
167
- * If no identity record is found, returns undefined. If multiple are found, throws an error.
168
- *
169
- * @param params.poolKey the key to use for the identity service pool. This will be the subtype uniqueness is defined on, typically the root type. Ex: 'item' or 'item:material'
170
- * @param params.propertyName the name of the property to use for the criteria. Ex: 'itemNumber'
171
- * @param params.propertyValue the value of the property to use for the criteria. Ex: '12345'
172
- * @returns the identity entity, or undefined if no identity record is found
173
- * @throws error if multiple identity entities are found, or if required parameters are missing
174
- */
175
- async getIdentityEntity(params: {
176
- poolKey: string,
177
- propertyName: string,
178
- propertyValue: string
179
- }): Promise<any | undefined> {
180
- const {poolKey, propertyName, propertyValue} = params;
181
- if(!poolKey || !propertyName || !propertyValue){
182
- throw new Error('poolKey, propertyName, and propertyValue must be defined');
183
- }
184
-
185
- const identityEntities = await this.entities.get({
186
- entityName: 'identity',
187
- criteria: {
188
- poolKey,
189
- propertyName,
190
- propertyValue
191
- }
192
- });
193
-
194
- if(!identityEntities || (Array.isArray(identityEntities) && identityEntities.length === 0)){
195
- return undefined;
196
- }
197
-
198
- if(Array.isArray(identityEntities) && identityEntities.length > 1){
199
- throw new Error('Multiple identity entities found for poolKey: ' + poolKey + ', ' + propertyName + ': ' + propertyValue);
200
- }
201
-
202
- return Array.isArray(identityEntities) ? identityEntities[0] : identityEntities;
203
- }
204
-
205
- /** Looks up an entity via the identity service. Uses {@link getIdentityEntity} to find the identity record,
206
- * then resolves the entity reference to fetch and return the actual entity.
207
- *
208
- * @param params.poolKey the key to use for the identity service pool. This will be the subtype uniqueness is defined on, typically the root type. Ex: 'item' or 'item:material'
209
- * @param params.propertyName the name of the property to use for the criteria. Ex: 'itemNumber'
210
- * @param params.propertyValue the value of the property to use for the criteria. Ex: '12345'
211
- * @returns the resolved entity, or undefined if no identity record is found
212
- * @throws error if multiple identity entities are found, or if required parameters are missing
213
- */
214
- async getEntityUsingIdentityService(params: {
215
- poolKey: string,
216
- propertyName: string,
217
- propertyValue: string
218
- }): Promise<any | undefined> {
219
- const identityEntity = await this.getIdentityEntity(params);
220
- if(!identityEntity){
221
- return undefined;
222
- }
223
-
224
- const entityReference = identityEntity.entityReference;
225
- const [entityName, id] = entityReference.split(':');
226
-
227
- const entity = await this.entities.get({
228
- entityName,
229
- id
230
- });
231
-
232
- return entity;
233
- }
234
- /**This will query for the entity, and handle post-processing
235
- * of any critieria that is defined at the sub-type level.
236
- * Because sub-type criteria can't be used in the search done
237
- * on the server. This is expected to be called by getIncomingEntity().
238
- *
239
- * @param entityType: the root type of the entity
240
- * @param entityTypePath: the full type path of the entity. Ex: custom-entity:sample
241
- * @param propertyCriteria: all the criteria to search for the entity
242
- * @returns the entities that match the criteria
243
- */
244
- async queryEntityWithSubTypeCriteria(entityType: string, entityTypePath: string, propertyCriteria: any): Promise<any[]>{
245
- //allCriteria; identifierKeys; entityType; entityTypePath
246
- if(!entityType || !entityTypePath){
247
- throw new Error('type and entityTypePath must be defined');
248
- }
249
- if(!propertyCriteria || Object.getOwnPropertyNames(propertyCriteria).length == 0){
250
- throw new Error('propertyCriteria must be defined and have at least one property');
251
- }
252
-
253
- const {rootTypeCriteria, subTypeCriteria} = await this.getCriteriaForEntity(entityType, entityTypePath, propertyCriteria);
254
-
255
- const returnedEntities = await this.dc.getAllObjectReferences(entityType, rootTypeCriteria, subTypeCriteria);
256
-
257
- return returnedEntities;
258
- }
259
-
260
- /** This is to get the criteria for the entity that is being processed.
261
- * This is to be overridden for item & project-item because of the need for
262
- * setting the roles criteria.
263
- *
264
- * @param entityType: the root type of the entity
265
- * @param entityTypePath: the full type path of the entity. Ex: custom-entity:sample
266
- * @param propertyCriteria: all the criteria to search for the entity
267
- * @returns the criteria for the entity
268
- */
269
- async getCriteriaForEntity(entityType: string, entityTypePath: string, propertyCriteria: any): Promise<any>{
270
- if(!entityType || !entityTypePath){
271
- throw new Error('type and entityTypePath must be defined');
272
- }
273
- if(!propertyCriteria || Object.getOwnPropertyNames(propertyCriteria).length == 0){
274
- throw new Error('propertyCriteria must be defined and have at least one property');
275
- }
276
- const rootType = await this.typeUtil.getByRootAndPath({root: entityType});
277
- const rootTypePropertyKeys = await this.getRootTypePropertyKeys(rootType, propertyCriteria);
278
-
279
- const rootTypeCriteria = {};
280
- const subTypeCriteria = {};
281
- if(entityType !== entityTypePath){
282
- subTypeCriteria['typePath'] = entityTypePath;
283
- }
284
- for(const key in propertyCriteria){
285
- if(rootTypePropertyKeys.includes(key)){
286
- rootTypeCriteria[key] = propertyCriteria[key];
287
- }else{
288
- subTypeCriteria[key] = propertyCriteria[key];
289
- }
290
- }
291
-
292
- return {rootTypeCriteria, subTypeCriteria};
293
- }
294
-
295
- /** This is to get the properties that are owned by the root type
296
- * This needs to be overridded for multi-level types, such as item
297
- * and project-item. And for those types, the propertyCriteria
298
- * will be needed to determine the correct level.
299
- *
300
- * @param rootType: the full root type entity for the processed entity
301
- * @param propertyCriteria: the criteria to determine the correct level (unused for single level types)
302
- * @returns: string[] of the property keys
303
- */
304
- getRootTypePropertyKeys(rootType, propertyCriteria = null): string[] {
305
- const props: TypeProperty[] = rootType['typeProperties'];
306
- const rootTypePropertyKeys = props.map(prop => prop.slug);
307
-
308
- return rootTypePropertyKeys;
309
- }
310
-
311
-
312
- async handleIncomingDelete(event) {
313
- console.warn('delete is not configured', event);
314
- }
315
-
316
- async getTransformedData(event) {
317
- let inboundData = event.data;
318
- console.debug('inboundData: ' + JSON.stringify(inboundData));
319
-
320
- const mapKey = await TypeConversionUtils.getMapKeyFromObject(this.transformMapFile, this.mapFileUtil, inboundData, TypeConversionUtils.FLEX2VIBE_DIRECTION);
321
- inboundData = await MapUtil.applyTransformMap(this.transformMapFile, this.mapFileUtil, inboundData, mapKey, TypeConversionUtils.FLEX2VIBE_DIRECTION);
322
- console.debug('Transformed-inboundData: ' + JSON.stringify(inboundData));
323
-
324
-
325
-
326
- return inboundData;
327
- }
328
-
329
- async getUpdatesForEntity(entity, inboundData) {
330
- const vibeOwningKeys = await this.getVibeOwningKeys(entity);
331
- let updates = {
332
- typeId: entity.typeId,
333
- roles: entity.roles,
334
- id: entity.id,
335
- };
336
-
337
- updates = await this.dc.setEntityValues(updates, inboundData, vibeOwningKeys);
338
- for(const prop of ['typeId', 'roles', 'id']){
339
- delete updates[prop];
340
- }
341
-
342
- return this.dc.getPersistableChanges(entity, updates);
343
- }
344
-
345
- async getVibeOwningKeys(entity) {
346
- let vibeOwningKeys = [];
347
- if (this.transformMapFile && entity) {
348
- //Technically the transform is flex->vibe. But the vibe entity being updated was passed in,
349
- // so we use VIBE2FLEX_DIRECTION to get the mapKey
350
- const mapKey = await TypeConversionUtils.getMapKey(this.transformMapFile, this.mapFileUtil, entity, TypeConversionUtils.VIBE2FLEX_DIRECTION);
351
-
352
- const mapSection = await MapUtil.getFullMapSection(this.transformMapFile, this.mapFileUtil, mapKey);
353
- vibeOwningKeys = mapSection?.vibeOwningKeys || [];
354
- }
355
- console.debug('vibeOwningKeys: ' + vibeOwningKeys);
356
- return vibeOwningKeys;
357
- }
358
-
359
- async getVibeOwningKeysFromInbound(entity) {
360
- let vibeOwningKeys = [];
361
- if (this.transformMapFile && entity) {
362
- const mapKey = await TypeConversionUtils.getMapKeyFromObject(this.transformMapFile, this.mapFileUtil, entity, TypeConversionUtils.FLEX2VIBE_DIRECTION);
363
-
364
- const mapSection = await MapUtil.getFullMapSection(this.transformMapFile, this.mapFileUtil, mapKey);
365
- vibeOwningKeys = mapSection?.vibeOwningKeys || [];
366
- }
367
- console.debug('vibeOwningKeys: ' + vibeOwningKeys);
368
- return vibeOwningKeys;
369
- }
370
-
371
- async createEntity(entityName, changes) {
372
- const options = {
373
- entityName: entityName,
374
- object: changes,
375
- };
376
- console.log("createEntity: " + JSON.stringify(options));
377
-
378
- return await new Entities().create(options);
379
- }
380
-
381
- async updateEntity(entityName, entity, diffs) {
382
- const options = {
383
- entityName: entityName,
384
- id: entity['id'],
385
- object: diffs
386
- };
387
- console.log('updateEntity: ' + JSON.stringify(options));
388
-
389
- return await new Entities().update(options);
390
- }
391
-
392
- // This method must be implemented by derived classes
393
- protected abstract getIncomingEntity(event, inboundData): Promise<IncomingEntityResponse>;
394
- protected abstract getCreateEntity(inboundData): Promise<IncomingEntityResponse>;
395
-
396
- // outbound
397
-
398
- async outbound(event) {
399
- const entityType = event.entityType;
400
- const eventType = event.eventType;
401
- const entityId = event.id;
402
- console.log(`outbound: ${entityType}:${entityId}`);
403
-
404
- switch (eventType) {
405
- case 'update':
406
- case 'create':
407
- return await this.handleOutgoingUpsert(entityType, event);
408
- case 'delete':
409
- return await this.handleOutgoingDelete(entityType, event);
410
- case 'sendUpsertToFlexPLM':
411
- return await this.sendUpsertToFlexPLM(event);
412
- default:
413
- console.log(UNSUPPORTED_TYPE);
414
- return {
415
- status: 500,
416
- data: { UNSUPPORTED_TYPE }
417
- };
418
- }
419
- }
420
-
421
- async handleOutgoingUpsert(entityType, event) {
422
- const objectClass = await TypeConversionUtils.getObjectClass(this.transformMapFile, this.mapFileUtil, event.newData);
423
- if (!objectClass) {
424
- const message = 'ObjectClass must have a value.';
425
- console.log(message);
426
- return {
427
- status: 500,
428
- data: { message }
429
- };
430
- }
431
-
432
- try {
433
- const payload = await this.getOutgoingUpsertPayload(entityType, event);
434
- const flexResponse: any = await new FlexPLMConnect(this.config).sendToFlexPLM(payload);
435
-
436
- const outboundEntityUpdates = await this.getOutboundEntityUpdates(event, flexResponse);
437
- if(outboundEntityUpdates){
438
- flexResponse['outboundEntityUpdates'] = outboundEntityUpdates;
439
- }
440
-
441
- const statusMsg = 'BaseEntityProcessor: outbound: status: ' + EventShortMessageStatus.SUCCESS
442
- + ', statusMessage: '+ flexResponse.status
443
- + ', entityType: ' + this.baseType
444
- + ', entityId: ' + event.id
445
- + ', objectClass: ' + payload.objectClass
446
- + ', updateFromResponse: ' + (( outboundEntityUpdates &&Object.keys(outboundEntityUpdates).length > 0)? 'true' : 'false')
447
- + ', orgSlug: ' + this.orgSlug;
448
- console.log(statusMsg);
449
-
450
- return flexResponse;
451
-
452
- } catch(e){
453
- const statusMsg = 'BaseEntityProcessor: outbound: status: '+ EventShortMessageStatus.FAILURE
454
- + ', statusMessage: ' + e.httpResponseStatus
455
- + ', entityType: ' + this.baseType
456
- + ', entityId: ' + event.id
457
- + ', objectClass: ' + objectClass
458
- + ', updateFromResponse: ' + 'false'
459
- + ', orgSlug: ' + this.orgSlug;
460
- console.log(statusMsg);
461
- throw e;
462
- }
463
- }
464
-
465
- async getOutboundEntityUpdates(event, flexResponse): Promise<any> {
466
- const payload = flexResponse?.data?.payload;
467
- const flexPayload = (payload)? payload[0] : undefined;
468
- let outboundEntityUpdates = undefined;
469
- if(flexPayload && 'OK' === flexPayload.status) {
470
- if(flexPayload.data && !flexPayload.data?.flexPLMObjectClass){
471
- flexPayload.data.flexPLMObjectClass = flexPayload.objectClass;
472
- }
473
- const inboundData = await this.getTransformedData(flexPayload);
474
- outboundEntityUpdates = await this.getUpdatesForEntity(event.newData, inboundData)
475
- }
476
- return outboundEntityUpdates;
477
- }
478
-
479
- async handleOutgoingDelete(entityType, event) {
480
- console.warn('delete is not configured', entityType, event.oldData);
481
- }
482
-
483
- // This method must be implemented by derived classes
484
- protected abstract getOutgoingUpsertPayload(entityType, event): Promise<EntityPayloadType>;
485
-
486
- /** Create a new event-workflow-request to rerun sending the entity to FlexPLM
487
- * The event must contain any information needed to ensure it is put in the correct queue for the entity
488
- *
489
- * @param triggerKey Ex: event.entityType + '|sendUpsertToFlexPLM'
490
- * @param event
491
- * @returns
492
- */
493
-
494
- protected async triggerNewEvent(triggerKey: string, event: any) {
495
- const newEvent = {
496
- entityName: 'event-workflow-request',
497
- object: {
498
- triggerKey,
499
- event
500
- }
501
- };
502
- const response = await this.entities.create(newEvent);
503
-
504
- return response;
505
- }
506
-
507
- /** Sends the current state of the entity to FlexPLM.
508
- * So any changes made in Vibe between the event being generated and the event being processed are sent to FlexPLM.
509
- *
510
- * @param event must contain entityType, id; which are used to query for the entity
511
- * @returns results of sending the entity to FlexPLM
512
- */
513
- protected async sendUpsertToFlexPLM(event) {
514
- const payload = await this.getEntityCurrentStateUpsertPayload(event);
515
- if(!payload){
516
- const message = 'No payload to send to FlexPLM';
517
- console.log(message);
518
- return {
519
- status: 500,
520
- data: {message}
521
- };
522
- };
523
- let objectClass = payload.objectClass;
524
- try {
525
- const flexResponse: any = await new FlexPLMConnect(this.config).sendToFlexPLM(payload);
526
-
527
- const outboundEntityUpdates = await this.getOutboundEntityUpdates(event, flexResponse);
528
- if(outboundEntityUpdates){
529
- flexResponse['outboundEntityUpdates'] = outboundEntityUpdates;
530
- }
531
-
532
- const statusMsg = 'BaseEntityProcessor: outbound: status: ' + EventShortMessageStatus.SUCCESS
533
- + ', statusMessage: ' + flexResponse.status
534
- + ', entityType: ' + this.baseType
535
- + ', entityId: ' + event.id
536
- + ', objectClass: ' + objectClass
537
- + ', updateFromResponse: ' + ((outboundEntityUpdates &&Object.keys(outboundEntityUpdates).length > 0)? 'true' : 'false')
538
- + ', orgSlug: ' + this.orgSlug;
539
- console.log(statusMsg);
540
- return flexResponse;
541
- }catch(e){
542
- const statusMsg = 'BaseEntityProcessor: outbound: status: '+ EventShortMessageStatus.FAILURE
543
- + ', statusMessage: ' + e.httpResponseStatus
544
- + ', entityType: ' + this.baseType
545
- + ', entityId: ' + event.id
546
- + ', objectClass: ' + objectClass
547
- + ', updateFromResponse: ' + 'false'
548
- + ', orgSlug: ' + this.orgSlug;
549
- console.log(statusMsg);
550
- throw e;
551
- }
552
- }
553
-
554
- /** Generates the payload to send to FlexPLM, based on the current state of the entity.
555
- * The current state of the entity are used as the newData and oldData; which is passed
556
- * to getOutgoingUpsertPayload to generate the payload.
557
- * @param event information about the item to send to FlexPLM
558
- * @returns The payload to send to FlexPLM
559
- */
560
- protected async getEntityCurrentStateUpsertPayload(event: any): Promise<EntityPayloadType> {
561
-
562
- const id = event.id;
563
- if(!id){
564
- return undefined;
565
- }
566
-
567
- const entity = await this.entities.get({
568
- entityName: this.baseType,
569
- id
570
- });
571
-
572
- if(!entity){
573
- return undefined;
574
- }
575
-
576
- event.newData = entity;
577
- event.oldData = entity;
578
-
579
- const payload = await this.getOutgoingUpsertPayload(this.baseType, event);
580
-
581
- return payload;
582
- }
583
- }
@@ -1,28 +0,0 @@
1
- import axios, { AxiosRequestConfig } from 'axios';
2
-
3
- const BASE_URL: string = 'https://PP-2006031951wo.portal.ptc.io/Windchill/servlet/rest/cdee';
4
- const BASE_CONFIG: AxiosRequestConfig = {
5
- method: 'POST',
6
- headers: {
7
- 'Accept': 'application/json',
8
- 'Content-Type': 'application/json',
9
- 'CSRF_NONCE': '2OaLp+0dWNBtrkTwtdDC491zaacu6Hykvqi/lpl6bZgJ/QXBrK/B1J5FErMkmAmktr/I3thcbO1Xn3HJ7Ne/l9kpaedUmn7H75Xey4ZbNLsenW+anM3vxIZ7ELosk3k=',
10
- 'Authorization': 'Basic d2NhZG1pbjpSZXRhaWwyMDIwLQ==',
11
- 'Cookie': 'JSESSIONID=36D5B3C74C1F963C6C73E9AF5B6BDA78.tomcat1; JSESSIONID=B8090C802D8548EA773C97F5886FAB79.tomcat1',
12
- },
13
- };
14
-
15
- export class FlexPLMRequest {
16
- static async request(path: string, data: any){
17
- const config = Object.assign({}, BASE_CONFIG);
18
- config.url = BASE_URL + path;
19
- config.data = data;
20
- try {
21
- const resp = await axios(config);
22
- return Promise.resolve(resp.data);
23
- } catch (error) {
24
- console.error(`${FlexPLMRequest} error: ${error.message}`);
25
- return Promise.resolve(null);
26
- }
27
- }
28
- }
@@ -1,27 +0,0 @@
1
- import { FlexPLMUtils } from './flexplm-utils';
2
-
3
- describe('Types Controller', () => {
4
-
5
- beforeEach(async () => {
6
- });
7
-
8
- it('should convert a type path', () => {
9
- expect(FlexPLMUtils.convertTypePath('Product')).toEqual('product');
10
- expect(FlexPLMUtils.convertTypePath('Product\\Apparel')).toEqual('product:apparel');
11
- expect(FlexPLMUtils.convertTypePath('Product\\Skin Care')).toEqual('product:skin_care');
12
- expect(FlexPLMUtils.convertTypePath('Product\\Apparel\\Shirt')).toEqual('product:apparel:shirt');
13
- expect(FlexPLMUtils.convertTypePath('Product\\Apparel\\[Shirt]')).toEqual('product:apparel:*shirt*');
14
- expect(FlexPLMUtils.convertTypePath('')).toBeNull();
15
- });
16
- it('should compute level in tree', () => {
17
- expect(FlexPLMUtils.computeLevelFromPath('product')).toEqual(1);
18
- expect(FlexPLMUtils.computeLevelFromPath('product:apparel')).toEqual(2);
19
- expect(FlexPLMUtils.computeLevelFromPath('product:apparel:dress:mini')).toEqual(4);
20
- });
21
- it('should get a parent type path', () => {
22
- expect(FlexPLMUtils.getParentTypePath('product')).toBeNull();
23
- expect(FlexPLMUtils.getParentTypePath('product:apparel')).toEqual('product');
24
- expect(FlexPLMUtils.getParentTypePath('product:apparel:stuff')).toEqual('product:apparel');
25
- expect(FlexPLMUtils.getParentTypePath('Product\\Apparel')).toEqual('product');
26
- });
27
- });
@@ -1,29 +0,0 @@
1
- export class FlexPLMUtils {
2
- static convertTypePath = (path: string): string => {
3
- if (!path) { return null; }
4
- let newPath = path;
5
- while (newPath.indexOf('\\') > 1) {
6
- newPath = newPath.replace('\\', ':');
7
- }
8
- while (newPath.indexOf('[') > 1) {
9
- newPath = newPath.replace('[', '*');
10
- }
11
- while (newPath.indexOf(']') > 1) {
12
- newPath = newPath.replace(']', '*');
13
- }
14
- while (newPath.indexOf(' ') > 1) {
15
- newPath = newPath.replace(' ', '_');
16
- }
17
- newPath = newPath.toLowerCase();
18
- return newPath;
19
- }
20
-
21
- static getParentTypePath = (path: string): string => {
22
- const newPath = FlexPLMUtils.convertTypePath(path);
23
- return (!newPath || newPath.indexOf(':') < 0) ? null : newPath.substring(0, newPath.lastIndexOf(':'));
24
- }
25
-
26
- static computeLevelFromPath(path: string) {
27
- return (path.match(/:/g) || []).length + 1;
28
- }
29
- }
package/src/index.ts DELETED
@@ -1,22 +0,0 @@
1
- export * from './flexplm-request';
2
- export * from './flexplm-utils';
3
- export * from './util/config-defaults';
4
- export * from './util/data-converter';
5
- export * from './util/error-response-object';
6
- export * from './util/event-short-message-status';
7
- export * from './util/federation';
8
- export * from './util/flexplm-connect';
9
- export * from './interfaces/interfaces';
10
- export * from './util/logger-config';
11
- export * from './util/thumbnail-util';
12
- export * from './util/type-conversion-utils';
13
- export * from './util/type-defaults';
14
- export * from './util/type-utils';
15
- export * from './util/map-utils';
16
- export * from './interfaces/interfaces';
17
- export * from './interfaces/item-family-changes';
18
- export * from './interfaces/publish-change-data';
19
- export * from './publish/base-process-publish-assortment';
20
- export * from './publish/base-process-publish-assortment-callback';
21
- export * from './entity-processor/base-entity-processor';
22
- export * from './transform/identifier-conversion';