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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (123) hide show
  1. package/.github/pull_request_template.md +31 -31
  2. package/.github/workflows/flexplm-lib.yml +27 -27
  3. package/CHANGELOG.md +1 -1
  4. package/lib/entity-processor/base-entity-processor.d.ts +42 -0
  5. package/lib/entity-processor/base-entity-processor.js +377 -0
  6. package/lib/entity-processor/base-entity-processor.spec.d.ts +1 -0
  7. package/lib/entity-processor/base-entity-processor.spec.js +426 -0
  8. package/lib/flexplm-request.d.ts +3 -0
  9. package/lib/flexplm-request.js +34 -0
  10. package/lib/flexplm-utils.d.ts +5 -0
  11. package/lib/flexplm-utils.js +33 -0
  12. package/lib/flexplm-utils.spec.d.ts +1 -0
  13. package/lib/flexplm-utils.spec.js +26 -0
  14. package/lib/index.d.ts +22 -0
  15. package/lib/index.js +38 -0
  16. package/lib/interfaces/interfaces.d.ts +105 -0
  17. package/lib/interfaces/interfaces.js +2 -0
  18. package/lib/interfaces/item-family-changes.d.ts +20 -0
  19. package/lib/interfaces/item-family-changes.js +56 -0
  20. package/lib/interfaces/publish-change-data.d.ts +19 -0
  21. package/lib/interfaces/publish-change-data.js +32 -0
  22. package/lib/publish/base-process-publish-assortment-callback.d.ts +9 -0
  23. package/lib/publish/base-process-publish-assortment-callback.js +38 -0
  24. package/lib/publish/base-process-publish-assortment.d.ts +93 -0
  25. package/lib/publish/base-process-publish-assortment.js +944 -0
  26. package/lib/publish/base-process-publish-assortment.spec.d.ts +1 -0
  27. package/lib/publish/base-process-publish-assortment.spec.js +1670 -0
  28. package/lib/publish/mockData.d.ts +1389 -0
  29. package/lib/publish/mockData.js +4519 -0
  30. package/lib/transform/identifier-conversion-spec-mockData.d.ts +0 -0
  31. package/lib/transform/identifier-conversion-spec-mockData.js +444 -0
  32. package/lib/transform/identifier-conversion.d.ts +15 -0
  33. package/lib/transform/identifier-conversion.js +212 -0
  34. package/lib/transform/identifier-conversion.spec.d.ts +1 -0
  35. package/lib/transform/identifier-conversion.spec.js +339 -0
  36. package/lib/util/config-defaults.d.ts +8 -0
  37. package/lib/util/config-defaults.js +85 -0
  38. package/lib/util/config-defaults.spec.d.ts +1 -0
  39. package/lib/util/config-defaults.spec.js +293 -0
  40. package/lib/util/data-converter-spec-mockData.d.ts +0 -0
  41. package/lib/util/data-converter-spec-mockData.js +205 -0
  42. package/lib/util/data-converter.d.ts +39 -0
  43. package/lib/util/data-converter.js +592 -0
  44. package/lib/util/data-converter.spec.d.ts +1 -0
  45. package/lib/util/data-converter.spec.js +904 -0
  46. package/lib/util/error-response-object.d.ts +4 -0
  47. package/lib/util/error-response-object.js +47 -0
  48. package/lib/util/error-response-object.spec.d.ts +1 -0
  49. package/lib/util/error-response-object.spec.js +99 -0
  50. package/lib/util/event-short-message-status.d.ts +18 -0
  51. package/lib/util/event-short-message-status.js +22 -0
  52. package/lib/util/federation.d.ts +15 -0
  53. package/lib/util/federation.js +149 -0
  54. package/lib/util/flexplm-connect.d.ts +22 -0
  55. package/lib/util/flexplm-connect.js +176 -0
  56. package/lib/util/flexplm-connect.spec.d.ts +1 -0
  57. package/lib/util/flexplm-connect.spec.js +88 -0
  58. package/lib/util/logger-config.d.ts +1 -0
  59. package/lib/util/logger-config.js +26 -0
  60. package/lib/util/map-util-spec-mockData.d.ts +0 -0
  61. package/lib/util/map-util-spec-mockData.js +205 -0
  62. package/lib/util/map-utils.d.ts +6 -0
  63. package/lib/util/map-utils.js +15 -0
  64. package/lib/util/map-utils.spec.d.ts +1 -0
  65. package/lib/util/map-utils.spec.js +89 -0
  66. package/lib/util/mockData.d.ts +79 -0
  67. package/lib/util/mockData.js +99 -0
  68. package/lib/util/thumbnail-util.d.ts +28 -0
  69. package/lib/util/thumbnail-util.js +202 -0
  70. package/lib/util/thumbnail-util.spec.d.ts +1 -0
  71. package/lib/util/thumbnail-util.spec.js +398 -0
  72. package/lib/util/type-conversion-utils-spec-mockData.d.ts +0 -0
  73. package/lib/util/type-conversion-utils-spec-mockData.js +259 -0
  74. package/lib/util/type-conversion-utils.d.ts +23 -0
  75. package/lib/util/type-conversion-utils.js +266 -0
  76. package/lib/util/type-conversion-utils.spec.d.ts +1 -0
  77. package/lib/util/type-conversion-utils.spec.js +868 -0
  78. package/lib/util/type-defaults.d.ts +16 -0
  79. package/lib/util/type-defaults.js +221 -0
  80. package/lib/util/type-defaults.spec.d.ts +1 -0
  81. package/lib/util/type-defaults.spec.js +516 -0
  82. package/lib/util/type-utils.d.ts +13 -0
  83. package/lib/util/type-utils.js +114 -0
  84. package/lib/util/type-utils.spec.d.ts +1 -0
  85. package/lib/util/type-utils.spec.js +190 -0
  86. package/package.json +1 -1
  87. package/publish.bat +4 -4
  88. package/publish.sh +4 -4
  89. package/src/entity-processor/base-entity-processor.spec.ts +157 -0
  90. package/src/entity-processor/base-entity-processor.ts +21 -2
  91. package/src/flexplm-request.ts +28 -28
  92. package/src/flexplm-utils.spec.ts +27 -27
  93. package/src/flexplm-utils.ts +29 -29
  94. package/src/index.ts +21 -21
  95. package/src/interfaces/item-family-changes.ts +66 -66
  96. package/src/interfaces/publish-change-data.ts +42 -42
  97. package/src/publish/base-process-publish-assortment-callback.ts +50 -50
  98. package/src/transform/identifier-conversion-spec-mockData.ts +495 -495
  99. package/src/transform/identifier-conversion.spec.ts +353 -353
  100. package/src/transform/identifier-conversion.ts +281 -281
  101. package/src/util/config-defaults.spec.ts +350 -350
  102. package/src/util/config-defaults.ts +92 -92
  103. package/src/util/data-converter-spec-mockData.ts +230 -230
  104. package/src/util/error-response-object.spec.ts +115 -115
  105. package/src/util/error-response-object.ts +49 -49
  106. package/src/util/federation.ts +172 -172
  107. package/src/util/logger-config.ts +19 -19
  108. package/src/util/map-util-spec-mockData.ts +230 -230
  109. package/src/util/map-utils.spec.ts +102 -102
  110. package/src/util/map-utils.ts +40 -40
  111. package/src/util/mockData.ts +97 -97
  112. package/src/util/thumbnail-util.spec.ts +190 -0
  113. package/src/util/thumbnail-util.ts +109 -1
  114. package/src/util/type-conversion-utils.spec.ts +25 -25
  115. package/src/util/type-conversion-utils.ts +10 -9
  116. package/src/util/type-defaults.spec.ts +668 -668
  117. package/src/util/type-defaults.ts +280 -280
  118. package/src/util/type-utils.spec.ts +227 -227
  119. package/src/util/type-utils.ts +144 -144
  120. package/tsconfig.json +28 -26
  121. package/tslint.json +57 -57
  122. package/scripts/output.png +0 -0
  123. package/scripts/test-get-request.ts +0 -35
@@ -3,6 +3,33 @@ import { ThumbnailUtil } from './thumbnail-util';
3
3
 
4
4
  import { empty_custom_sizes, four_custom_sizes, thumbnail_content_entity } from './mockData';
5
5
 
6
+ const mockEntitiesGet = jest.fn();
7
+ const mockEntitiesUpdate = jest.fn();
8
+ const mockEntitiesDelete = jest.fn();
9
+ const mockContentCreate = jest.fn();
10
+
11
+ jest.mock('@contrail/sdk', () => {
12
+ return {
13
+ Entities: jest.fn().mockImplementation(() => ({
14
+ get: mockEntitiesGet,
15
+ update: mockEntitiesUpdate,
16
+ delete: mockEntitiesDelete,
17
+ })),
18
+ Content: jest.fn().mockImplementation(() => ({
19
+ create: mockContentCreate,
20
+ })),
21
+ };
22
+ });
23
+
24
+ const mockGetRequest = jest.fn();
25
+ jest.mock('./flexplm-connect', () => {
26
+ return {
27
+ FlexPLMConnect: jest.fn().mockImplementation(() => ({
28
+ getRequest: mockGetRequest,
29
+ })),
30
+ };
31
+ });
32
+
6
33
  describe('ThumbnailUtil Tests', () =>{
7
34
  const config = {} as FCConfig;
8
35
  describe('setOutboundThumbnail()', () =>{
@@ -266,4 +293,167 @@ describe('ThumbnailUtil Tests', () =>{
266
293
  });
267
294
 
268
295
  });
296
+
297
+ describe('syncThumbnailToVibeIQ', () => {
298
+ let tu: ThumbnailUtil;
299
+
300
+ beforeEach(() => {
301
+ jest.clearAllMocks();
302
+ tu = new ThumbnailUtil(config);
303
+ mockEntitiesGet.mockImplementation((opts) => {
304
+ if (opts.entityName === 'content-custom-size') return Promise.resolve([]);
305
+ return Promise.resolve({});
306
+ });
307
+ mockEntitiesUpdate.mockImplementation((opts) => Promise.resolve({ id: opts.id }));
308
+ mockEntitiesDelete.mockImplementation((opts) => Promise.resolve({ id: opts.id }));
309
+ });
310
+
311
+ it('returns undefined when no thumbnail IDs in event data', async () => {
312
+ const event = { data: {} };
313
+ const result = await tu.syncThumbnailToVibeIQ({ entityId: 'entity1', event, entityName: 'color' });
314
+
315
+ expect(result).toBeUndefined();
316
+ expect(mockEntitiesUpdate).not.toHaveBeenCalled();
317
+ expect(mockEntitiesDelete).not.toHaveBeenCalled();
318
+ expect(mockContentCreate).not.toHaveBeenCalled();
319
+ });
320
+
321
+ it('returns undefined when event.data is undefined', async () => {
322
+ const event = {};
323
+ const result = await tu.syncThumbnailToVibeIQ({ entityId: 'entity1', event, entityName: 'color' });
324
+
325
+ expect(result).toBeUndefined();
326
+ expect(mockEntitiesUpdate).not.toHaveBeenCalled();
327
+ expect(mockEntitiesDelete).not.toHaveBeenCalled();
328
+ });
329
+
330
+ it('REMOVE_THUMBNAIL with existing primaryViewableId deletes content and returns clear updates', async () => {
331
+ const event = { data: { [ThumbnailUtil.NEW_THUMBNAIL_ID]: ThumbnailUtil.REMOVE_THUMBNAIL } };
332
+ const result = await tu.syncThumbnailToVibeIQ({ entityId: 'entity1', primaryViewableId: 'pv1', event, entityName: 'color' });
333
+
334
+ expect(mockEntitiesDelete).toHaveBeenCalledWith({ entityName: 'content', id: 'pv1' });
335
+ expect(result).toEqual(expect.objectContaining({ primaryViewableId: null, primaryFileUrl: null }));
336
+ });
337
+
338
+ it('REMOVE_THUMBNAIL with no primaryViewableId returns clear updates without deleting', async () => {
339
+ const event = { data: { [ThumbnailUtil.NEW_THUMBNAIL_ID]: ThumbnailUtil.REMOVE_THUMBNAIL } };
340
+ const result = await tu.syncThumbnailToVibeIQ({ entityId: 'entity1', event, entityName: 'item' });
341
+
342
+ expect(mockEntitiesDelete).not.toHaveBeenCalled();
343
+ expect(result).toEqual(expect.objectContaining({ primaryViewableId: null }));
344
+ });
345
+
346
+ it('creates new content when no primaryViewableId exists and returns primary viewable updates', async () => {
347
+ const mockResponse = {
348
+ arrayBuffer: jest.fn().mockResolvedValue(new ArrayBuffer(8)),
349
+ headers: { get: jest.fn().mockReturnValue('image/png') },
350
+ };
351
+ mockGetRequest.mockResolvedValue(mockResponse);
352
+
353
+ const createdContent = {
354
+ id: 'newContent1',
355
+ contentType: 'image/png',
356
+ fileName: 'thumb.png',
357
+ primaryFileUrl: 'https://files/primary.png',
358
+ largeViewableUrl: 'https://files/large.png',
359
+ mediumLargeViewableUrl: null,
360
+ mediumViewableUrl: null,
361
+ smallViewableUrl: null,
362
+ tinyViewableUrl: null,
363
+ };
364
+ mockContentCreate.mockResolvedValue(createdContent);
365
+
366
+ const event = { data: { [ThumbnailUtil.NEW_THUMBNAIL_ID]: '/rest/thumbnail/thumb.png' } };
367
+ const result = await tu.syncThumbnailToVibeIQ({ entityId: 'entity1', event, entityName: 'color' });
368
+
369
+ expect(mockGetRequest).toHaveBeenCalledWith({ urlPath: '/rest/thumbnail/thumb.png', includeUrlContext: false, returnFullResponse: true });
370
+ expect(mockContentCreate).toHaveBeenCalledWith(
371
+ expect.objectContaining({
372
+ fileName: 'thumb.png',
373
+ contentType: 'image/png',
374
+ contentHolderReference: 'color:entity1',
375
+ }),
376
+ );
377
+ // Updates content with flexplmThumbnailUrl
378
+ expect(mockEntitiesUpdate).toHaveBeenCalledWith(
379
+ expect.objectContaining({
380
+ entityName: 'content',
381
+ id: 'newContent1',
382
+ object: { flexplmThumbnailUrl: '/rest/thumbnail/thumb.png' },
383
+ }),
384
+ );
385
+ // Returns primary viewable updates for the entity
386
+ expect(result).toEqual(expect.objectContaining({
387
+ primaryViewableId: 'newContent1',
388
+ primaryFileUrl: 'https://files/primary.png',
389
+ largeViewableDownloadUrl: 'https://files/large.png',
390
+ }));
391
+ });
392
+
393
+ it('replaces content when primaryViewable.flexplmThumbnailUrl differs and returns updates', async () => {
394
+ mockEntitiesGet.mockImplementation((opts) => {
395
+ if (opts.entityName === 'content-custom-size') return Promise.resolve([]);
396
+ if (opts.entityName === 'content' && opts.id === 'oldPv') {
397
+ return Promise.resolve({ id: 'oldPv', flexplmThumbnailUrl: '/rest/thumbnail/old.png' });
398
+ }
399
+ return Promise.resolve({});
400
+ });
401
+
402
+ const mockResponse = {
403
+ arrayBuffer: jest.fn().mockResolvedValue(new ArrayBuffer(8)),
404
+ headers: { get: jest.fn().mockReturnValue('image/jpeg') },
405
+ };
406
+ mockGetRequest.mockResolvedValue(mockResponse);
407
+
408
+ const createdContent = {
409
+ id: 'newContent2',
410
+ contentType: 'image/jpeg',
411
+ fileName: 'new.jpg',
412
+ primaryFileUrl: 'https://files/new-primary.jpg',
413
+ largeViewableUrl: null,
414
+ mediumLargeViewableUrl: null,
415
+ mediumViewableUrl: null,
416
+ smallViewableUrl: null,
417
+ tinyViewableUrl: null,
418
+ };
419
+ mockContentCreate.mockResolvedValue(createdContent);
420
+
421
+ const event = { data: { [ThumbnailUtil.NEW_THUMBNAIL_ID]: '/rest/thumbnail/new.jpg' } };
422
+ const result = await tu.syncThumbnailToVibeIQ({ entityId: 'entity1', primaryViewableId: 'oldPv', event, entityName: 'item' });
423
+
424
+ // Creates new content
425
+ expect(mockContentCreate).toHaveBeenCalled();
426
+ // Updates new content with flexplmThumbnailUrl
427
+ expect(mockEntitiesUpdate).toHaveBeenCalledWith(
428
+ expect.objectContaining({
429
+ entityName: 'content',
430
+ id: 'newContent2',
431
+ object: { flexplmThumbnailUrl: '/rest/thumbnail/new.jpg' },
432
+ }),
433
+ );
434
+ // Returns primary viewable updates for the entity
435
+ expect(result).toEqual(expect.objectContaining({ primaryViewableId: 'newContent2' }));
436
+ // Deletes old content
437
+ expect(mockEntitiesDelete).toHaveBeenCalledWith({ entityName: 'content', id: 'oldPv' });
438
+ });
439
+
440
+ it('returns undefined when primaryViewable.flexplmThumbnailUrl matches', async () => {
441
+ const thumbnailUrl = '/rest/thumbnail/same.png';
442
+ mockEntitiesGet.mockImplementation((opts) => {
443
+ if (opts.entityName === 'content-custom-size') return Promise.resolve([]);
444
+ if (opts.entityName === 'content' && opts.id === 'pv1') {
445
+ return Promise.resolve({ id: 'pv1', flexplmThumbnailUrl: thumbnailUrl });
446
+ }
447
+ return Promise.resolve({});
448
+ });
449
+
450
+ const event = { data: { [ThumbnailUtil.EXISTING_THUMBNAIL_ID]: thumbnailUrl } };
451
+ const result = await tu.syncThumbnailToVibeIQ({ entityId: 'entity1', primaryViewableId: 'pv1', event, entityName: 'color' });
452
+
453
+ expect(result).toBeUndefined();
454
+ expect(mockContentCreate).not.toHaveBeenCalled();
455
+ expect(mockEntitiesUpdate).not.toHaveBeenCalled();
456
+ expect(mockEntitiesDelete).not.toHaveBeenCalled();
457
+ });
458
+ });
269
459
  });
@@ -1,6 +1,7 @@
1
1
  import { Logger } from '@contrail/app-framework';
2
- import { Entities } from '@contrail/sdk';
2
+ import { Content, Entities } from '@contrail/sdk';
3
3
  import { FCConfig } from '../interfaces/interfaces';
4
+ import { FlexPLMConnect } from './flexplm-connect';
4
5
 
5
6
  export class ThumbnailUtil {
6
7
  private max_thumbnail_size = 5 * 1_024 * 1_024;
@@ -134,4 +135,111 @@ export class ThumbnailUtil {
134
135
  }
135
136
  }
136
137
 
138
+ async syncThumbnailToVibeIQ({ entityId, primaryViewableId, event, entityName }: { entityId: string; primaryViewableId?: string; event: any; entityName: string }): Promise<any> {
139
+ const eventData = event.data || {};
140
+ const newThumbnailId = eventData[ThumbnailUtil.NEW_THUMBNAIL_ID];
141
+ const existingThumbnailId = eventData[ThumbnailUtil.EXISTING_THUMBNAIL_ID];
142
+ const thumbnailUrl = newThumbnailId || existingThumbnailId;
143
+
144
+ // Case 1: REMOVE_THUMBNAIL
145
+ if (newThumbnailId === ThumbnailUtil.REMOVE_THUMBNAIL) {
146
+ if (primaryViewableId) {
147
+ await this.entities.delete({ entityName: 'content', id: primaryViewableId });
148
+ }
149
+ return await this.getClearPrimaryViewableUpdates();
150
+ }
151
+
152
+ // Early return if no thumbnail URL
153
+ if (!thumbnailUrl) {
154
+ return undefined;
155
+ }
156
+
157
+ // Case 2: No existing primaryViewableId — create new content
158
+ if (!primaryViewableId) {
159
+ const content = await this.createContentFromFlexPLM(thumbnailUrl, entityId, entityName);
160
+ await this.entities.update({ entityName: 'content', id: content.id, object: { flexplmThumbnailUrl: thumbnailUrl } });
161
+ return await this.getPrimaryViewableUpdates(content);
162
+ }
163
+
164
+ // Case 3: Has primaryViewableId — check if thumbnail changed
165
+ const primaryViewable = await this.entities.get({ entityName: 'content', id: primaryViewableId });
166
+ if (primaryViewable?.flexplmThumbnailUrl === thumbnailUrl) {
167
+ return undefined; // Already synced
168
+ }
169
+
170
+ const content = await this.createContentFromFlexPLM(thumbnailUrl, entityId, entityName);
171
+ await this.entities.update({ entityName: 'content', id: content.id, object: { flexplmThumbnailUrl: thumbnailUrl } });
172
+ const primaryUpdates = await this.getPrimaryViewableUpdates(content);
173
+ await this.entities.delete({ entityName: 'content', id: primaryViewableId });
174
+ return primaryUpdates;
175
+ }
176
+
177
+ private async createContentFromFlexPLM(thumbnailUrl: string, entityId: string, entityName: string): Promise<any> {
178
+ const flexPLMConnect = new FlexPLMConnect(this.config);
179
+ const response = await flexPLMConnect.getRequest({
180
+ urlPath: thumbnailUrl,
181
+ includeUrlContext: false,
182
+ returnFullResponse: true,
183
+ }) as Response;
184
+
185
+ const fileBuffer = await response.arrayBuffer();
186
+ const buffer = Buffer.from(fileBuffer);
187
+ const contentTypeHeader = response.headers.get('content-type');
188
+ const contentType = contentTypeHeader ? contentTypeHeader.split(';')[0] : 'application/octet-stream';
189
+
190
+ const urlParts = thumbnailUrl.split('/');
191
+ const fileName = urlParts[urlParts.length - 1] || 'thumbnail';
192
+
193
+ const contentHolderReference = `${entityName}:${entityId}`;
194
+ const content = await new Content().create({
195
+ fileBuffer: buffer,
196
+ fileName,
197
+ contentType,
198
+ contentHolderReference,
199
+ });
200
+ return content;
201
+ }
202
+
203
+ private async getPrimaryViewableUpdates(content: any): Promise<any> {
204
+ const updates: any = {
205
+ primaryViewableId: content.id,
206
+ contentType: content.contentType,
207
+ fileName: content.fileName,
208
+ primaryFileUrl: content.primaryFileUrl,
209
+ largeViewableDownloadUrl: content.largeViewableUrl || content.primaryFileUrl,
210
+ mediumLargeViewableDownloadUrl: content.mediumLargeViewableUrl || content.primaryFileUrl,
211
+ mediumViewableDownloadUrl: content.mediumViewableUrl || content.primaryFileUrl,
212
+ smallViewableDownloadUrl: content.smallViewableUrl || content.primaryFileUrl,
213
+ tinyViewableDownloadUrl: content.tinyViewableUrl || content.primaryFileUrl,
214
+ };
215
+
216
+ const customSizes = await this.getCustomSizes();
217
+ for (const size of customSizes) {
218
+ updates[`${size.slug}DownloadUrl`] = content[`${size.slug}Url`] || content.primaryFileUrl;
219
+ }
220
+
221
+ return updates;
222
+ }
223
+
224
+ private async getClearPrimaryViewableUpdates(): Promise<any> {
225
+ const updates: any = {
226
+ primaryViewableId: null,
227
+ contentType: null,
228
+ fileName: null,
229
+ primaryFileUrl: null,
230
+ largeViewableDownloadUrl: null,
231
+ mediumLargeViewableDownloadUrl: null,
232
+ mediumViewableDownloadUrl: null,
233
+ smallViewableDownloadUrl: null,
234
+ tinyViewableDownloadUrl: null,
235
+ };
236
+
237
+ const customSizes = await this.getCustomSizes();
238
+ for (const size of customSizes) {
239
+ updates[`${size.slug}DownloadUrl`] = null;
240
+ }
241
+
242
+ return updates;
243
+ }
244
+
137
245
  }
@@ -785,18 +785,18 @@ describe('conversion-utils', () => {
785
785
  describe('syncInboundImages', () =>{
786
786
  const mapFileUtil = new MapFileUtil(new Entities());
787
787
 
788
- it('should return true for custom-entity:pack', async () =>{
788
+ it('should return true for Revisable Entity\\packaging (mapping entry true)', async () =>{
789
789
  const spy = jest.spyOn(mapFileUtil, 'getMapFile')
790
790
  .mockImplementation(async () =>{
791
791
  return mapping;
792
792
  });
793
- const entity = {
794
- entityType: 'custom-entity',
795
- typePath: 'custom-entity:pack'
793
+ const obj = {
794
+ flexPLMObjectClass: 'LCSRevisableEntity',
795
+ flexPLMTypePath: 'Revisable Entity\\packaging'
796
796
  }
797
797
 
798
798
  try{
799
- const results = await TypeConversionUtils.syncInboundImages(TRANSFORM_MAP_FILE, mapFileUtil, entity);
799
+ const results = await TypeConversionUtils.syncInboundImages(TRANSFORM_MAP_FILE, mapFileUtil, obj);
800
800
  expect(results).toBeTruthy();
801
801
 
802
802
  } finally {
@@ -804,18 +804,18 @@ describe('conversion-utils', () => {
804
804
  }
805
805
  });
806
806
 
807
- it('should return true for custom-entity:prefix', async () =>{
807
+ it('should return true for Revisable Entity\\prefix (mapping entry true)', async () =>{
808
808
  const spy = jest.spyOn(mapFileUtil, 'getMapFile')
809
809
  .mockImplementation(async () =>{
810
810
  return mapping;
811
811
  });
812
- const entity = {
813
- entityType: 'custom-entity',
814
- typePath: 'custom-entity:prefix'
812
+ const obj = {
813
+ flexPLMObjectClass: 'LCSRevisableEntity',
814
+ flexPLMTypePath: 'Revisable Entity\\prefix'
815
815
  }
816
816
 
817
817
  try{
818
- const results = await TypeConversionUtils.syncInboundImages(TRANSFORM_MAP_FILE, mapFileUtil, entity);
818
+ const results = await TypeConversionUtils.syncInboundImages(TRANSFORM_MAP_FILE, mapFileUtil, obj);
819
819
  expect(results).toBeTruthy();
820
820
 
821
821
  } finally {
@@ -828,14 +828,14 @@ describe('conversion-utils', () => {
828
828
  .mockImplementation(async () =>{
829
829
  return mapping;
830
830
  });
831
- const entity = {
832
- entityType: 'custom-entity',
833
- typePath: 'custom-entity:prefix'
831
+ const obj = {
832
+ flexPLMObjectClass: 'LCSRevisableEntity',
833
+ flexPLMTypePath: 'Revisable Entity\\prefix'
834
834
  }
835
835
  const context = { skipImages: true };
836
836
 
837
837
  try{
838
- const results = await TypeConversionUtils.syncInboundImages(TRANSFORM_MAP_FILE, mapFileUtil, entity, context);
838
+ const results = await TypeConversionUtils.syncInboundImages(TRANSFORM_MAP_FILE, mapFileUtil, obj, context);
839
839
  expect(results).toBeFalsy();
840
840
 
841
841
  } finally {
@@ -848,13 +848,13 @@ describe('conversion-utils', () => {
848
848
  .mockImplementation(async () =>{
849
849
  return mapping;
850
850
  });
851
- const entity = {
852
- entityType: 'custom-entity',
853
- typePath: 'custom-entity:catName'
851
+ const obj = {
852
+ flexPLMObjectClass: 'LCSRevisableEntity',
853
+ flexPLMTypePath: 'Revisable Entity\\catName'
854
854
  }
855
855
 
856
856
  try{
857
- const results = await TypeConversionUtils.syncInboundImages(TRANSFORM_MAP_FILE, mapFileUtil, entity);
857
+ const results = await TypeConversionUtils.syncInboundImages(TRANSFORM_MAP_FILE, mapFileUtil, obj);
858
858
  expect(results).toBeFalsy();
859
859
 
860
860
  } finally {
@@ -863,12 +863,12 @@ describe('conversion-utils', () => {
863
863
  });
864
864
 
865
865
  it('should default to false when no fileId', async () =>{
866
- const entity = {
867
- entityType: 'custom-entity',
868
- typePath: 'custom-entity:pack'
866
+ const obj = {
867
+ flexPLMObjectClass: 'LCSRevisableEntity',
868
+ flexPLMTypePath: 'Revisable Entity\\pack'
869
869
  }
870
870
 
871
- const results = await TypeConversionUtils.syncInboundImages(null, mapFileUtil, entity);
871
+ const results = await TypeConversionUtils.syncInboundImages('', mapFileUtil, obj);
872
872
  expect(results).toBeFalsy();
873
873
  });
874
874
 
@@ -877,7 +877,7 @@ describe('conversion-utils', () => {
877
877
  describe('syncOutboundImages', () =>{
878
878
  const mapFileUtil = new MapFileUtil(new Entities());
879
879
 
880
- it('should return false for custom-entity:pack', async () =>{
880
+ it('should return false for custom-entity:pack (mapping entry false)', async () =>{
881
881
  const spy = jest.spyOn(mapFileUtil, 'getMapFile')
882
882
  .mockImplementation(async () =>{
883
883
  return mapping;
@@ -896,7 +896,7 @@ describe('conversion-utils', () => {
896
896
  }
897
897
  });
898
898
 
899
- it('should return true for custom-entity:prefix', async () =>{
899
+ it('should return true for custom-entity:prefix (mapping entry true)', async () =>{
900
900
  const spy = jest.spyOn(mapFileUtil, 'getMapFile')
901
901
  .mockImplementation(async () =>{
902
902
  return mapping;
@@ -960,7 +960,7 @@ describe('conversion-utils', () => {
960
960
  typePath: 'custom-entity:pack'
961
961
  }
962
962
 
963
- const results = await TypeConversionUtils.syncOutboundImages(null, mapFileUtil, entity);
963
+ const results = await TypeConversionUtils.syncOutboundImages('', mapFileUtil, entity);
964
964
  expect(results).toBeTruthy();
965
965
  });
966
966
 
@@ -334,6 +334,7 @@ export class TypeConversionUtils {
334
334
  return type;
335
335
  }
336
336
  //TODO use TypeDefaults?
337
+ return '';
337
338
  }
338
339
 
339
340
  static async isInboundCreatableFromObject(fileId: string, mapFileUtil: MapFileUtil, object: any, context?: any): Promise<boolean> {
@@ -377,18 +378,18 @@ export class TypeConversionUtils {
377
378
  return isOutboundCreatable;
378
379
  }
379
380
 
380
- /** Takes in a VibeIQ entity object and determines whether inbound
381
- * images should be synced. The creation owning system is expected
382
- * to also control image syncing. Defaults to false if no mapping exists.
381
+ /** Takes in a FlexPLM object and determines whether inbound
382
+ * images should be synced. In most cases, the creation owning system
383
+ * will also control image syncing. Defaults to false if no mapping exists.
383
384
  * Map file entry in '<mapKey>:syncInboundImages()'
384
385
  *
385
386
  * @param fileId id for mapFile
386
387
  * @param mapFileUtil class to get mapfile
387
- * @param entity VibeIQ entity
388
+ * @param object FlexPLM object
388
389
  * @param context optional context object
389
390
  * @returns Promise<boolean>
390
391
  */
391
- static async syncInboundImages(fileId: string, mapFileUtil: MapFileUtil, entity: any, context?: any): Promise<boolean> {
392
+ static async syncInboundImages(fileId: string, mapFileUtil: MapFileUtil, object: any, context?: any): Promise<boolean> {
392
393
 
393
394
  let syncImages = false;
394
395
 
@@ -398,7 +399,7 @@ export class TypeConversionUtils {
398
399
 
399
400
  let mapKey: string | undefined;
400
401
  try {
401
- mapKey = await this.getMapKey(fileId, mapFileUtil, entity, TypeConversionUtils.VIBE2FLEX_DIRECTION);
402
+ mapKey = await this.getMapKeyFromObject(fileId, mapFileUtil, object, TypeConversionUtils.FLEX2VIBE_DIRECTION);
402
403
  } catch {
403
404
  return syncImages;
404
405
  }
@@ -409,14 +410,14 @@ export class TypeConversionUtils {
409
410
 
410
411
  const mapData = await MapUtil.getFullMapSection(fileId, mapFileUtil, mapKey);
411
412
  if (mapData && mapData['syncInboundImages']) {
412
- syncImages = await mapData['syncInboundImages'](entity, context);
413
+ syncImages = await mapData['syncInboundImages'](object, context);
413
414
  }
414
415
  return syncImages;
415
416
  }
416
417
 
417
418
  /** Takes in a VibeIQ entity object and determines whether outbound
418
- * images should be synced. The creation owning system is expected
419
- * to also control image syncing. Defaults to true if no mapping exists.
419
+ * images should be synced. In most cases, the creation owning system
420
+ * will also control image syncing. Defaults to true if no mapping exists.
420
421
  * Map file entry in '<mapKey>:syncOutboundImages()'
421
422
  *
422
423
  * @param fileId id for mapFile