@contrail/flexplm 1.8.1 → 2.0.0-alpha.9af4b96
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/__tests__/telemetry-test-utils.d.ts +8 -0
- package/lib/__tests__/telemetry-test-utils.js +30 -0
- package/lib/cli/commands/compile.js +17 -7
- package/lib/cli/commands/compile.spec.js +17 -7
- package/lib/cli/commands/create.js +17 -7
- package/lib/cli/commands/create.spec.js +17 -7
- package/lib/cli/commands/upload.js +17 -7
- package/lib/cli/index.js +2 -2
- package/lib/entity-processor/base-entity-processor.d.ts +29 -0
- package/lib/entity-processor/base-entity-processor.js +238 -143
- package/lib/entity-processor/base-entity-processor.spec.js +212 -0
- package/lib/index.d.ts +1 -0
- package/lib/index.js +1 -0
- package/lib/interfaces/interfaces.d.ts +1 -1
- package/lib/publish/base-process-publish-assortment-callback.js +30 -0
- package/lib/publish/base-process-publish-assortment-callback.spec.d.ts +1 -0
- package/lib/publish/base-process-publish-assortment-callback.spec.js +62 -0
- package/lib/publish/base-process-publish-assortment.d.ts +24 -0
- package/lib/publish/base-process-publish-assortment.js +243 -132
- package/lib/publish/base-process-publish-assortment.spec.js +188 -0
- package/lib/util/config-defaults.js +2 -0
- package/lib/util/error-response-object.js +2 -0
- package/lib/util/event-short-message-status.js +1 -1
- package/lib/util/flexplm-connect.d.ts +4 -0
- package/lib/util/flexplm-connect.js +210 -145
- package/lib/util/flexplm-connect.telemetry.spec.d.ts +1 -0
- package/lib/util/flexplm-connect.telemetry.spec.js +212 -0
- package/lib/util/logger-config.js +1 -2
- package/lib/util/telemetry-attributes.d.ts +68 -0
- package/lib/util/telemetry-attributes.js +73 -0
- package/lib/util/telemetry-utils.d.ts +3 -0
- package/lib/util/telemetry-utils.js +10 -0
- package/lib/util/thumbnail-util.d.ts +2 -1
- package/lib/util/thumbnail-util.js +35 -7
- package/lib/util/thumbnail-util.spec.js +42 -0
- package/package.json +10 -3
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/** Span and log attribute names emitted by this library. Connectors should reuse these instead of defining their own. */
|
|
2
|
+
/** Which FlexPLM call a span covers: 'csrf' | 'send' | 'get'. */
|
|
3
|
+
export declare const ATTR_FLEXPLM_REQUEST_KIND: "contrail.flexplm.request.kind";
|
|
4
|
+
/** True when the cached session was rejected and the request was retried with a new session. */
|
|
5
|
+
export declare const ATTR_FLEXPLM_REQUEST_RETRIED: "contrail.flexplm.request.retried";
|
|
6
|
+
/** Number of events in the payload sent to FlexPLM. */
|
|
7
|
+
export declare const ATTR_FLEXPLM_PAYLOAD_COUNT: "contrail.flexplm.payload.count";
|
|
8
|
+
export declare const ATTR_FLEXPLM_EVENT_OBJECT_CLASS: "contrail.flexplm.event.object_class";
|
|
9
|
+
/** The event type: inbound 'PERSIST' | 'DELETE'; outbound 'create' | 'update' | 'delete' | 'sendUpsertToFlexPLM'. */
|
|
10
|
+
export declare const ATTR_FLEXPLM_EVENT_TYPE: "contrail.flexplm.event.type";
|
|
11
|
+
/** Where the FlexPLM session for a request came from: 'cached' | 'new' | 'disabled' (session reuse off). */
|
|
12
|
+
export declare const ATTR_FLEXPLM_SESSION_SOURCE: "contrail.flexplm.session.source";
|
|
13
|
+
/** True when the request waited for another request's session acquisition before running. */
|
|
14
|
+
export declare const ATTR_FLEXPLM_SESSION_WAITED: "contrail.flexplm.session.waited";
|
|
15
|
+
/** Number of properties written to the VibeIQ entity by a create or update. */
|
|
16
|
+
export declare const ATTR_FLEXPLM_CHANGED_PROPERTY_COUNT: "contrail.flexplm.entity.changed_property_count";
|
|
17
|
+
/** Whether a lookup found the entity. */
|
|
18
|
+
export declare const ATTR_FLEXPLM_ENTITY_FOUND: "contrail.flexplm.entity.found";
|
|
19
|
+
/** Number of entities a criteria query returned. */
|
|
20
|
+
export declare const ATTR_FLEXPLM_ENTITY_RESULT_COUNT: "contrail.flexplm.entity.result_count";
|
|
21
|
+
/** Result of syncing a FlexPLM thumbnail: 'removed' | 'created' | 'replaced' | 'already_synced' | 'no_thumbnail'. */
|
|
22
|
+
export declare const ATTR_FLEXPLM_THUMBNAIL_OUTCOME: "contrail.flexplm.thumbnail.outcome";
|
|
23
|
+
/** FlexPLM's per-item result counts for a publish, reported to the publish callback. */
|
|
24
|
+
export declare const ATTR_FLEXPLM_PUBLISH_FAILURE_COUNT: "contrail.flexplm.publish.failure_count";
|
|
25
|
+
export declare const ATTR_FLEXPLM_PUBLISH_INVALID_COUNT: "contrail.flexplm.publish.invalid_count";
|
|
26
|
+
/** True when the publish callback dispatched a failure notification. */
|
|
27
|
+
export declare const ATTR_FLEXPLM_PUBLISH_NOTIFICATION_SENT: "contrail.flexplm.publish.notification_sent";
|
|
28
|
+
export declare const ATTR_FLEXPLM_ENTITY_TYPE: "contrail.flexplm.entity.type";
|
|
29
|
+
export declare const ATTR_FLEXPLM_PUBLISH_ADDED_COUNT: "contrail.flexplm.publish.added_count";
|
|
30
|
+
export declare const ATTR_FLEXPLM_PUBLISH_REMOVED_COUNT: "contrail.flexplm.publish.removed_count";
|
|
31
|
+
export declare const ATTR_FLEXPLM_PUBLISH_CHANGED_COUNT: "contrail.flexplm.publish.changed_count";
|
|
32
|
+
/** Result of processing one entity event: EventShortMessageStatus 'Success' | 'Failure'. */
|
|
33
|
+
export declare const ATTR_FLEXPLM_STATUS: "contrail.flexplm.status";
|
|
34
|
+
/** Short status message for one inbound entity event, e.g. 'Created', 'Updated', 'No_Changes'. */
|
|
35
|
+
export declare const ATTR_FLEXPLM_OUTCOME: "contrail.flexplm.outcome";
|
|
36
|
+
export declare const ATTR_FLEXPLM_ENTITY_ID: "contrail.flexplm.entity.id";
|
|
37
|
+
export declare const ATTR_FLEXPLM_FEDERATED_ID: "contrail.flexplm.federated_id";
|
|
38
|
+
export declare const ATTR_FLEXPLM_ASSORTMENT_ID: "contrail.flexplm.assortment.id";
|
|
39
|
+
export declare const ATTR_FLEXPLM_PUBLISH_CHANGE_ID: "contrail.flexplm.publish.change_id";
|
|
40
|
+
/** LCSProductSeasonLink events sent for one assortment publish. */
|
|
41
|
+
export declare const ATTR_FLEXPLM_PUBLISH_PRODUCT_SEASON_COUNT: "contrail.flexplm.publish.product_season_count";
|
|
42
|
+
/** LCSSKUSeasonLink events sent for one assortment publish. */
|
|
43
|
+
export declare const ATTR_FLEXPLM_PUBLISH_COLORWAY_SEASON_COUNT: "contrail.flexplm.publish.colorway_season_count";
|
|
44
|
+
/** True when FlexPLM's response produced updates that were applied back to the VibeIQ entity. */
|
|
45
|
+
export declare const ATTR_FLEXPLM_UPDATED_FROM_RESPONSE: "contrail.flexplm.outbound.updated_from_response";
|
|
46
|
+
/** FlexPLM's per-item status in a send response ('OK' | 'FAIL'); FlexPLM can answer HTTP 200 and still reject the item. */
|
|
47
|
+
export declare const ATTR_FLEXPLM_RESPONSE_ITEM_STATUS: "contrail.flexplm.response.item_status";
|
|
48
|
+
/** Which publish file a download span covers: 'hydrated_detail' | 'baseline'. */
|
|
49
|
+
export declare const ATTR_FLEXPLM_PUBLISH_FILE: "contrail.flexplm.publish.file";
|
|
50
|
+
/** Publish files that could not be downloaded; the publish continues without them. */
|
|
51
|
+
export declare const ATTR_FLEXPLM_PUBLISH_FAILED_DOWNLOADS: "contrail.flexplm.publish.failed_downloads";
|
|
52
|
+
/** Number of publish-change records in the assortment's history. */
|
|
53
|
+
export declare const ATTR_FLEXPLM_PUBLISH_HISTORY_COUNT: "contrail.flexplm.publish.history_count";
|
|
54
|
+
/** Number of delete changes being published, including ones carried over from earlier publishes. */
|
|
55
|
+
export declare const ATTR_FLEXPLM_PUBLISH_DELETE_CHANGE_COUNT: "contrail.flexplm.publish.delete_change_count";
|
|
56
|
+
/** Delete changes carried over from earlier publishes that had not been sent yet. */
|
|
57
|
+
export declare const ATTR_FLEXPLM_PUBLISH_HISTORICAL_DELETE_COUNT: "contrail.flexplm.publish.historical_delete_count";
|
|
58
|
+
/** Deleted items in scope that were skipped because their item entity was missing. */
|
|
59
|
+
export declare const ATTR_FLEXPLM_PUBLISH_SKIPPED_DELETE_COUNT: "contrail.flexplm.publish.skipped_delete_count";
|
|
60
|
+
/** Number of item families with changes in a publish. */
|
|
61
|
+
export declare const ATTR_FLEXPLM_PUBLISH_ITEM_FAMILY_COUNT: "contrail.flexplm.publish.item_family_count";
|
|
62
|
+
/** The configured sendMode for ASYNC_PUBLISH_SEASON, e.g. 'sendtoflexplm', 'vibeiqfile', 'localfile'. */
|
|
63
|
+
export declare const ATTR_FLEXPLM_PUBLISH_SEND_MODE: "contrail.flexplm.publish.send_mode";
|
|
64
|
+
/** True when FlexPLM accepted the publish but the external-event that records it could not be created. */
|
|
65
|
+
export declare const ATTR_FLEXPLM_PUBLISH_SENT_UNRECORDED: "contrail.flexplm.publish.sent_unrecorded";
|
|
66
|
+
export declare const ATTR_HTTP_REQUEST_METHOD = "http.request.method";
|
|
67
|
+
export declare const ATTR_HTTP_RESPONSE_STATUS_CODE = "http.response.status_code";
|
|
68
|
+
export declare const ATTR_URL_PATH = "url.path";
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ATTR_URL_PATH = exports.ATTR_HTTP_RESPONSE_STATUS_CODE = exports.ATTR_HTTP_REQUEST_METHOD = exports.ATTR_FLEXPLM_PUBLISH_SENT_UNRECORDED = exports.ATTR_FLEXPLM_PUBLISH_SEND_MODE = exports.ATTR_FLEXPLM_PUBLISH_ITEM_FAMILY_COUNT = exports.ATTR_FLEXPLM_PUBLISH_SKIPPED_DELETE_COUNT = exports.ATTR_FLEXPLM_PUBLISH_HISTORICAL_DELETE_COUNT = exports.ATTR_FLEXPLM_PUBLISH_DELETE_CHANGE_COUNT = exports.ATTR_FLEXPLM_PUBLISH_HISTORY_COUNT = exports.ATTR_FLEXPLM_PUBLISH_FAILED_DOWNLOADS = exports.ATTR_FLEXPLM_PUBLISH_FILE = exports.ATTR_FLEXPLM_RESPONSE_ITEM_STATUS = exports.ATTR_FLEXPLM_UPDATED_FROM_RESPONSE = exports.ATTR_FLEXPLM_PUBLISH_COLORWAY_SEASON_COUNT = exports.ATTR_FLEXPLM_PUBLISH_PRODUCT_SEASON_COUNT = exports.ATTR_FLEXPLM_PUBLISH_CHANGE_ID = exports.ATTR_FLEXPLM_ASSORTMENT_ID = exports.ATTR_FLEXPLM_FEDERATED_ID = exports.ATTR_FLEXPLM_ENTITY_ID = exports.ATTR_FLEXPLM_OUTCOME = exports.ATTR_FLEXPLM_STATUS = exports.ATTR_FLEXPLM_PUBLISH_CHANGED_COUNT = exports.ATTR_FLEXPLM_PUBLISH_REMOVED_COUNT = exports.ATTR_FLEXPLM_PUBLISH_ADDED_COUNT = exports.ATTR_FLEXPLM_ENTITY_TYPE = exports.ATTR_FLEXPLM_PUBLISH_NOTIFICATION_SENT = exports.ATTR_FLEXPLM_PUBLISH_INVALID_COUNT = exports.ATTR_FLEXPLM_PUBLISH_FAILURE_COUNT = exports.ATTR_FLEXPLM_THUMBNAIL_OUTCOME = exports.ATTR_FLEXPLM_ENTITY_RESULT_COUNT = exports.ATTR_FLEXPLM_ENTITY_FOUND = exports.ATTR_FLEXPLM_CHANGED_PROPERTY_COUNT = exports.ATTR_FLEXPLM_SESSION_WAITED = exports.ATTR_FLEXPLM_SESSION_SOURCE = exports.ATTR_FLEXPLM_EVENT_TYPE = exports.ATTR_FLEXPLM_EVENT_OBJECT_CLASS = exports.ATTR_FLEXPLM_PAYLOAD_COUNT = exports.ATTR_FLEXPLM_REQUEST_RETRIED = exports.ATTR_FLEXPLM_REQUEST_KIND = void 0;
|
|
4
|
+
const telemetry_1 = require("@contrail/telemetry");
|
|
5
|
+
/** Span and log attribute names emitted by this library. Connectors should reuse these instead of defining their own. */
|
|
6
|
+
/** Which FlexPLM call a span covers: 'csrf' | 'send' | 'get'. */
|
|
7
|
+
exports.ATTR_FLEXPLM_REQUEST_KIND = (0, telemetry_1.buildContrailAttributeName)('flexplm.request.kind');
|
|
8
|
+
/** True when the cached session was rejected and the request was retried with a new session. */
|
|
9
|
+
exports.ATTR_FLEXPLM_REQUEST_RETRIED = (0, telemetry_1.buildContrailAttributeName)('flexplm.request.retried');
|
|
10
|
+
/** Number of events in the payload sent to FlexPLM. */
|
|
11
|
+
exports.ATTR_FLEXPLM_PAYLOAD_COUNT = (0, telemetry_1.buildContrailAttributeName)('flexplm.payload.count');
|
|
12
|
+
exports.ATTR_FLEXPLM_EVENT_OBJECT_CLASS = (0, telemetry_1.buildContrailAttributeName)('flexplm.event.object_class');
|
|
13
|
+
/** The event type: inbound 'PERSIST' | 'DELETE'; outbound 'create' | 'update' | 'delete' | 'sendUpsertToFlexPLM'. */
|
|
14
|
+
exports.ATTR_FLEXPLM_EVENT_TYPE = (0, telemetry_1.buildContrailAttributeName)('flexplm.event.type');
|
|
15
|
+
/** Where the FlexPLM session for a request came from: 'cached' | 'new' | 'disabled' (session reuse off). */
|
|
16
|
+
exports.ATTR_FLEXPLM_SESSION_SOURCE = (0, telemetry_1.buildContrailAttributeName)('flexplm.session.source');
|
|
17
|
+
/** True when the request waited for another request's session acquisition before running. */
|
|
18
|
+
exports.ATTR_FLEXPLM_SESSION_WAITED = (0, telemetry_1.buildContrailAttributeName)('flexplm.session.waited');
|
|
19
|
+
/** Number of properties written to the VibeIQ entity by a create or update. */
|
|
20
|
+
exports.ATTR_FLEXPLM_CHANGED_PROPERTY_COUNT = (0, telemetry_1.buildContrailAttributeName)('flexplm.entity.changed_property_count');
|
|
21
|
+
/** Whether a lookup found the entity. */
|
|
22
|
+
exports.ATTR_FLEXPLM_ENTITY_FOUND = (0, telemetry_1.buildContrailAttributeName)('flexplm.entity.found');
|
|
23
|
+
/** Number of entities a criteria query returned. */
|
|
24
|
+
exports.ATTR_FLEXPLM_ENTITY_RESULT_COUNT = (0, telemetry_1.buildContrailAttributeName)('flexplm.entity.result_count');
|
|
25
|
+
/** Result of syncing a FlexPLM thumbnail: 'removed' | 'created' | 'replaced' | 'already_synced' | 'no_thumbnail'. */
|
|
26
|
+
exports.ATTR_FLEXPLM_THUMBNAIL_OUTCOME = (0, telemetry_1.buildContrailAttributeName)('flexplm.thumbnail.outcome');
|
|
27
|
+
/** FlexPLM's per-item result counts for a publish, reported to the publish callback. */
|
|
28
|
+
exports.ATTR_FLEXPLM_PUBLISH_FAILURE_COUNT = (0, telemetry_1.buildContrailAttributeName)('flexplm.publish.failure_count');
|
|
29
|
+
exports.ATTR_FLEXPLM_PUBLISH_INVALID_COUNT = (0, telemetry_1.buildContrailAttributeName)('flexplm.publish.invalid_count');
|
|
30
|
+
/** True when the publish callback dispatched a failure notification. */
|
|
31
|
+
exports.ATTR_FLEXPLM_PUBLISH_NOTIFICATION_SENT = (0, telemetry_1.buildContrailAttributeName)('flexplm.publish.notification_sent');
|
|
32
|
+
exports.ATTR_FLEXPLM_ENTITY_TYPE = (0, telemetry_1.buildContrailAttributeName)('flexplm.entity.type');
|
|
33
|
+
exports.ATTR_FLEXPLM_PUBLISH_ADDED_COUNT = (0, telemetry_1.buildContrailAttributeName)('flexplm.publish.added_count');
|
|
34
|
+
exports.ATTR_FLEXPLM_PUBLISH_REMOVED_COUNT = (0, telemetry_1.buildContrailAttributeName)('flexplm.publish.removed_count');
|
|
35
|
+
exports.ATTR_FLEXPLM_PUBLISH_CHANGED_COUNT = (0, telemetry_1.buildContrailAttributeName)('flexplm.publish.changed_count');
|
|
36
|
+
/** Result of processing one entity event: EventShortMessageStatus 'Success' | 'Failure'. */
|
|
37
|
+
exports.ATTR_FLEXPLM_STATUS = (0, telemetry_1.buildContrailAttributeName)('flexplm.status');
|
|
38
|
+
/** Short status message for one inbound entity event, e.g. 'Created', 'Updated', 'No_Changes'. */
|
|
39
|
+
exports.ATTR_FLEXPLM_OUTCOME = (0, telemetry_1.buildContrailAttributeName)('flexplm.outcome');
|
|
40
|
+
exports.ATTR_FLEXPLM_ENTITY_ID = (0, telemetry_1.buildContrailAttributeName)('flexplm.entity.id');
|
|
41
|
+
exports.ATTR_FLEXPLM_FEDERATED_ID = (0, telemetry_1.buildContrailAttributeName)('flexplm.federated_id');
|
|
42
|
+
exports.ATTR_FLEXPLM_ASSORTMENT_ID = (0, telemetry_1.buildContrailAttributeName)('flexplm.assortment.id');
|
|
43
|
+
exports.ATTR_FLEXPLM_PUBLISH_CHANGE_ID = (0, telemetry_1.buildContrailAttributeName)('flexplm.publish.change_id');
|
|
44
|
+
/** LCSProductSeasonLink events sent for one assortment publish. */
|
|
45
|
+
exports.ATTR_FLEXPLM_PUBLISH_PRODUCT_SEASON_COUNT = (0, telemetry_1.buildContrailAttributeName)('flexplm.publish.product_season_count');
|
|
46
|
+
/** LCSSKUSeasonLink events sent for one assortment publish. */
|
|
47
|
+
exports.ATTR_FLEXPLM_PUBLISH_COLORWAY_SEASON_COUNT = (0, telemetry_1.buildContrailAttributeName)('flexplm.publish.colorway_season_count');
|
|
48
|
+
/** True when FlexPLM's response produced updates that were applied back to the VibeIQ entity. */
|
|
49
|
+
exports.ATTR_FLEXPLM_UPDATED_FROM_RESPONSE = (0, telemetry_1.buildContrailAttributeName)('flexplm.outbound.updated_from_response');
|
|
50
|
+
/** FlexPLM's per-item status in a send response ('OK' | 'FAIL'); FlexPLM can answer HTTP 200 and still reject the item. */
|
|
51
|
+
exports.ATTR_FLEXPLM_RESPONSE_ITEM_STATUS = (0, telemetry_1.buildContrailAttributeName)('flexplm.response.item_status');
|
|
52
|
+
/** Which publish file a download span covers: 'hydrated_detail' | 'baseline'. */
|
|
53
|
+
exports.ATTR_FLEXPLM_PUBLISH_FILE = (0, telemetry_1.buildContrailAttributeName)('flexplm.publish.file');
|
|
54
|
+
/** Publish files that could not be downloaded; the publish continues without them. */
|
|
55
|
+
exports.ATTR_FLEXPLM_PUBLISH_FAILED_DOWNLOADS = (0, telemetry_1.buildContrailAttributeName)('flexplm.publish.failed_downloads');
|
|
56
|
+
/** Number of publish-change records in the assortment's history. */
|
|
57
|
+
exports.ATTR_FLEXPLM_PUBLISH_HISTORY_COUNT = (0, telemetry_1.buildContrailAttributeName)('flexplm.publish.history_count');
|
|
58
|
+
/** Number of delete changes being published, including ones carried over from earlier publishes. */
|
|
59
|
+
exports.ATTR_FLEXPLM_PUBLISH_DELETE_CHANGE_COUNT = (0, telemetry_1.buildContrailAttributeName)('flexplm.publish.delete_change_count');
|
|
60
|
+
/** Delete changes carried over from earlier publishes that had not been sent yet. */
|
|
61
|
+
exports.ATTR_FLEXPLM_PUBLISH_HISTORICAL_DELETE_COUNT = (0, telemetry_1.buildContrailAttributeName)('flexplm.publish.historical_delete_count');
|
|
62
|
+
/** Deleted items in scope that were skipped because their item entity was missing. */
|
|
63
|
+
exports.ATTR_FLEXPLM_PUBLISH_SKIPPED_DELETE_COUNT = (0, telemetry_1.buildContrailAttributeName)('flexplm.publish.skipped_delete_count');
|
|
64
|
+
/** Number of item families with changes in a publish. */
|
|
65
|
+
exports.ATTR_FLEXPLM_PUBLISH_ITEM_FAMILY_COUNT = (0, telemetry_1.buildContrailAttributeName)('flexplm.publish.item_family_count');
|
|
66
|
+
/** The configured sendMode for ASYNC_PUBLISH_SEASON, e.g. 'sendtoflexplm', 'vibeiqfile', 'localfile'. */
|
|
67
|
+
exports.ATTR_FLEXPLM_PUBLISH_SEND_MODE = (0, telemetry_1.buildContrailAttributeName)('flexplm.publish.send_mode');
|
|
68
|
+
/** True when FlexPLM accepted the publish but the external-event that records it could not be created. */
|
|
69
|
+
exports.ATTR_FLEXPLM_PUBLISH_SENT_UNRECORDED = (0, telemetry_1.buildContrailAttributeName)('flexplm.publish.sent_unrecorded');
|
|
70
|
+
// Standard OpenTelemetry HTTP attributes. Only the path is recorded, never the host, headers or body.
|
|
71
|
+
exports.ATTR_HTTP_REQUEST_METHOD = 'http.request.method';
|
|
72
|
+
exports.ATTR_HTTP_RESPONSE_STATUS_CODE = 'http.response.status_code';
|
|
73
|
+
exports.ATTR_URL_PATH = 'url.path';
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.setActiveSpanAttributes = void 0;
|
|
4
|
+
const api_1 = require("@opentelemetry/api");
|
|
5
|
+
/** Sets the defined values on the active span; a no-op when no span is active. */
|
|
6
|
+
const setActiveSpanAttributes = (attributes) => {
|
|
7
|
+
const defined = Object.fromEntries(Object.entries(attributes).filter(([, value]) => value !== undefined && value !== null));
|
|
8
|
+
api_1.trace.getActiveSpan()?.setAttributes(defined);
|
|
9
|
+
};
|
|
10
|
+
exports.setActiveSpanAttributes = setActiveSpanAttributes;
|
|
@@ -43,12 +43,13 @@ export declare class ThumbnailUtil {
|
|
|
43
43
|
* @param entityName - The entity type name (e.g. 'item', 'color') used for API calls.
|
|
44
44
|
* @returns The updated entity, or undefined if no thumbnail changes were needed.
|
|
45
45
|
*/
|
|
46
|
-
syncThumbnailToVibeIQ(
|
|
46
|
+
syncThumbnailToVibeIQ(params: {
|
|
47
47
|
entityId: string;
|
|
48
48
|
primaryViewableId?: string;
|
|
49
49
|
event: any;
|
|
50
50
|
entityName: string;
|
|
51
51
|
}): Promise<any>;
|
|
52
|
+
private syncThumbnail;
|
|
52
53
|
private createContentFromFlexPLM;
|
|
53
54
|
private getPrimaryViewableUpdates;
|
|
54
55
|
private getClearPrimaryViewableUpdates;
|
|
@@ -1,9 +1,20 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
|
+
};
|
|
2
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
12
|
exports.ThumbnailUtil = void 0;
|
|
4
13
|
const app_framework_1 = require("@contrail/app-framework");
|
|
5
14
|
const sdk_1 = require("@contrail/sdk");
|
|
6
15
|
const flexplm_connect_1 = require("./flexplm-connect");
|
|
16
|
+
const telemetry_1 = require("@contrail/telemetry");
|
|
17
|
+
const telemetry_attributes_1 = require("./telemetry-attributes");
|
|
7
18
|
;
|
|
8
19
|
class ThumbnailUtil {
|
|
9
20
|
constructor(config) {
|
|
@@ -131,7 +142,17 @@ class ThumbnailUtil {
|
|
|
131
142
|
* @param entityName - The entity type name (e.g. 'item', 'color') used for API calls.
|
|
132
143
|
* @returns The updated entity, or undefined if no thumbnail changes were needed.
|
|
133
144
|
*/
|
|
134
|
-
async syncThumbnailToVibeIQ(
|
|
145
|
+
async syncThumbnailToVibeIQ(params) {
|
|
146
|
+
return (0, telemetry_1.traceSection)('sync_thumbnail_to_vibeiq', {
|
|
147
|
+
[telemetry_attributes_1.ATTR_FLEXPLM_ENTITY_TYPE]: params.entityName,
|
|
148
|
+
[telemetry_attributes_1.ATTR_FLEXPLM_ENTITY_ID]: params.entityId,
|
|
149
|
+
}, async (span) => {
|
|
150
|
+
const { outcome, result } = await this.syncThumbnail(params);
|
|
151
|
+
span.setAttribute(telemetry_attributes_1.ATTR_FLEXPLM_THUMBNAIL_OUTCOME, outcome);
|
|
152
|
+
return result;
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
async syncThumbnail({ entityId, primaryViewableId, event, entityName }) {
|
|
135
156
|
console.debug(`syncThumbnailToVibeIQ: entityId=${entityId}, primaryViewableId=${primaryViewableId}, entityName=${entityName}`);
|
|
136
157
|
const eventData = event.data || {};
|
|
137
158
|
const newThumbnailId = eventData[ThumbnailUtil.NEW_THUMBNAIL_ID];
|
|
@@ -146,12 +167,12 @@ class ThumbnailUtil {
|
|
|
146
167
|
const clearUpdates = await this.getClearPrimaryViewableUpdates();
|
|
147
168
|
const updatedEntity = await this.entities.update({ entityName, id: entityId, object: clearUpdates });
|
|
148
169
|
console.debug(`syncThumbnailToVibeIQ: applied clear updates for entityId=${entityId}`);
|
|
149
|
-
return updatedEntity;
|
|
170
|
+
return { outcome: 'removed', result: updatedEntity };
|
|
150
171
|
}
|
|
151
172
|
// Early return if no thumbnail URL
|
|
152
173
|
if (!thumbnailUrl) {
|
|
153
174
|
console.debug(`syncThumbnailToVibeIQ: no thumbnail URL for entityId=${entityId}`);
|
|
154
|
-
return undefined;
|
|
175
|
+
return { outcome: 'no_thumbnail', result: undefined };
|
|
155
176
|
}
|
|
156
177
|
// Case 2: No existing primaryViewableId — create new content
|
|
157
178
|
if (!primaryViewableId) {
|
|
@@ -160,13 +181,13 @@ class ThumbnailUtil {
|
|
|
160
181
|
const primaryUpdates = await this.getPrimaryViewableUpdates(content);
|
|
161
182
|
const updatedEntity = await this.entities.update({ entityName, id: entityId, object: primaryUpdates });
|
|
162
183
|
console.debug(`syncThumbnailToVibeIQ: created new content ${content.id} for entityId=${entityId}`);
|
|
163
|
-
return updatedEntity;
|
|
184
|
+
return { outcome: 'created', result: updatedEntity };
|
|
164
185
|
}
|
|
165
186
|
// Case 3: Has primaryViewableId — check if thumbnail changed
|
|
166
187
|
const primaryViewable = await this.entities.get({ entityName: 'content', id: primaryViewableId });
|
|
167
188
|
if (primaryViewable?.flexplmThumbnailUrl === thumbnailUrl) {
|
|
168
189
|
console.debug(`syncThumbnailToVibeIQ: thumbnail already synced for entityId=${entityId}`);
|
|
169
|
-
return
|
|
190
|
+
return { outcome: 'already_synced', result: undefined };
|
|
170
191
|
}
|
|
171
192
|
const content = await this.createContentFromFlexPLM(thumbnailUrl, entityId, entityName);
|
|
172
193
|
await this.entities.update({ entityName: 'content', id: content.id, object: { flexplmThumbnailUrl: thumbnailUrl } });
|
|
@@ -174,8 +195,9 @@ class ThumbnailUtil {
|
|
|
174
195
|
const updatedEntity = await this.entities.update({ entityName, id: entityId, object: primaryUpdates });
|
|
175
196
|
await this.entities.delete({ entityName: 'content', id: primaryViewableId });
|
|
176
197
|
console.debug(`syncThumbnailToVibeIQ: replaced content ${primaryViewableId} with ${content.id} for entityId=${entityId}`);
|
|
177
|
-
return updatedEntity;
|
|
198
|
+
return { outcome: 'replaced', result: updatedEntity };
|
|
178
199
|
}
|
|
200
|
+
// Downloads the image from FlexPLM and stores it as VibeIQ content.
|
|
179
201
|
async createContentFromFlexPLM(thumbnailUrl, entityId, entityName) {
|
|
180
202
|
const urlParts = thumbnailUrl.split('/');
|
|
181
203
|
const fileName = urlParts[urlParts.length - 1] || 'thumbnail';
|
|
@@ -189,7 +211,7 @@ class ThumbnailUtil {
|
|
|
189
211
|
const urlPath = '/servlet/rest' + imageEndpoint + '?path=' + encodeURIComponent(thumbnailUrl);
|
|
190
212
|
response = await flexPLMConnect.getRequest({
|
|
191
213
|
urlPath,
|
|
192
|
-
includeUrlContext: true,
|
|
214
|
+
includeUrlContext: true, // apiHost + /Windchill + /servlet/rest/rfa/vibeiq/image?path=...
|
|
193
215
|
returnFullResponse: true,
|
|
194
216
|
});
|
|
195
217
|
}
|
|
@@ -262,3 +284,9 @@ ThumbnailUtil.NEW_THUMBNAIL_ID = 'NEW_THUMBNAIL_ID';
|
|
|
262
284
|
ThumbnailUtil.EXISTING_THUMBNAIL_ID = 'EXISTING_THUMBNAIL_ID';
|
|
263
285
|
ThumbnailUtil.REMOVE_THUMBNAIL = 'REMOVE_THUMBNAIL';
|
|
264
286
|
ThumbnailUtil.OOB_SIZES = [{ slug: 'largeViewable' }, { slug: 'mediumLargeViewable' }, { slug: 'mediumViewable' }, { slug: 'smallViewable' }, { slug: 'tinyViewable' }];
|
|
287
|
+
__decorate([
|
|
288
|
+
(0, telemetry_1.Traced)('copy_thumbnail_from_flexplm'),
|
|
289
|
+
__metadata("design:type", Function),
|
|
290
|
+
__metadata("design:paramtypes", [String, String, String]),
|
|
291
|
+
__metadata("design:returntype", Promise)
|
|
292
|
+
], ThumbnailUtil.prototype, "createContentFromFlexPLM", null);
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
const thumbnail_util_1 = require("./thumbnail-util");
|
|
4
|
+
const telemetry_test_utils_1 = require("../__tests__/telemetry-test-utils");
|
|
5
|
+
const telemetry_attributes_1 = require("./telemetry-attributes");
|
|
4
6
|
const mockData_1 = require("./mockData");
|
|
5
7
|
const mockEntitiesGet = jest.fn();
|
|
6
8
|
const mockEntitiesUpdate = jest.fn();
|
|
@@ -563,3 +565,43 @@ describe('ThumbnailUtil Tests', () => {
|
|
|
563
565
|
});
|
|
564
566
|
});
|
|
565
567
|
});
|
|
568
|
+
describe('syncThumbnailToVibeIQ telemetry', () => {
|
|
569
|
+
const exporter = (0, telemetry_test_utils_1.registerInMemoryTracing)();
|
|
570
|
+
const image = { arrayBuffer: jest.fn().mockResolvedValue(new ArrayBuffer(8)), headers: { get: jest.fn().mockReturnValue('image/png') } };
|
|
571
|
+
let tu;
|
|
572
|
+
const outcomeOf = async (params) => {
|
|
573
|
+
exporter.reset();
|
|
574
|
+
await tu.syncThumbnailToVibeIQ({ entityId: 'entity1', primaryViewableId: params.primaryViewableId, event: { data: params.data }, entityName: 'color' });
|
|
575
|
+
const [span] = (0, telemetry_test_utils_1.findSpans)(exporter, 'sync_thumbnail_to_vibeiq');
|
|
576
|
+
expect(span.attributes[telemetry_attributes_1.ATTR_FLEXPLM_ENTITY_ID]).toBe('entity1');
|
|
577
|
+
return span.attributes[telemetry_attributes_1.ATTR_FLEXPLM_THUMBNAIL_OUTCOME];
|
|
578
|
+
};
|
|
579
|
+
beforeEach(() => {
|
|
580
|
+
jest.clearAllMocks();
|
|
581
|
+
tu = new thumbnail_util_1.ThumbnailUtil({});
|
|
582
|
+
mockGetRequest.mockResolvedValue(image);
|
|
583
|
+
mockContentCreate.mockResolvedValue({ id: 'newContent' });
|
|
584
|
+
mockEntitiesUpdate.mockImplementation((opts) => Promise.resolve({ id: opts.id }));
|
|
585
|
+
mockEntitiesGet.mockImplementation((opts) => {
|
|
586
|
+
if (opts.entityName === 'content-custom-size')
|
|
587
|
+
return Promise.resolve([]);
|
|
588
|
+
if (opts.entityName === 'content')
|
|
589
|
+
return Promise.resolve({ id: opts.id, flexplmThumbnailUrl: '/rest/thumbnail/same.png' });
|
|
590
|
+
return Promise.resolve({});
|
|
591
|
+
});
|
|
592
|
+
});
|
|
593
|
+
it('should record each sync outcome on the span', async () => {
|
|
594
|
+
expect(await outcomeOf({ data: {} })).toBe('no_thumbnail');
|
|
595
|
+
expect(await outcomeOf({ primaryViewableId: 'pv1', data: { [thumbnail_util_1.ThumbnailUtil.NEW_THUMBNAIL_ID]: thumbnail_util_1.ThumbnailUtil.REMOVE_THUMBNAIL } })).toBe('removed');
|
|
596
|
+
expect(await outcomeOf({ data: { [thumbnail_util_1.ThumbnailUtil.NEW_THUMBNAIL_ID]: '/rest/thumbnail/new.png' } })).toBe('created');
|
|
597
|
+
expect(await outcomeOf({ primaryViewableId: 'pv1', data: { [thumbnail_util_1.ThumbnailUtil.EXISTING_THUMBNAIL_ID]: '/rest/thumbnail/same.png' } })).toBe('already_synced');
|
|
598
|
+
expect(await outcomeOf({ primaryViewableId: 'pv1', data: { [thumbnail_util_1.ThumbnailUtil.NEW_THUMBNAIL_ID]: '/rest/thumbnail/new.png' } })).toBe('replaced');
|
|
599
|
+
});
|
|
600
|
+
it('should nest the thumbnail download under the sync span', async () => {
|
|
601
|
+
exporter.reset();
|
|
602
|
+
await tu.syncThumbnailToVibeIQ({ entityId: 'entity1', event: { data: { [thumbnail_util_1.ThumbnailUtil.NEW_THUMBNAIL_ID]: '/rest/thumbnail/new.png' } }, entityName: 'color' });
|
|
603
|
+
const [sync] = (0, telemetry_test_utils_1.findSpans)(exporter, 'sync_thumbnail_to_vibeiq');
|
|
604
|
+
const [copy] = (0, telemetry_test_utils_1.findSpans)(exporter, 'copy_thumbnail_from_flexplm');
|
|
605
|
+
expect(copy.parentSpanContext?.spanId).toBe(sync.spanContext().spanId);
|
|
606
|
+
});
|
|
607
|
+
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@contrail/flexplm",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.0-alpha.9af4b96",
|
|
4
4
|
"description": "Library used for integration with flexplm.",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"types": "lib/index.d.ts",
|
|
@@ -25,15 +25,23 @@
|
|
|
25
25
|
"author": "VibeIQ",
|
|
26
26
|
"license": "ISC",
|
|
27
27
|
"devDependencies": {
|
|
28
|
+
"@contrail/app-framework": "2.1.1",
|
|
29
|
+
"@contrail/telemetry": "^2.3.1",
|
|
30
|
+
"@opentelemetry/api": "^1.9.1",
|
|
31
|
+
"@opentelemetry/context-async-hooks": "^2.12.0",
|
|
32
|
+
"@opentelemetry/sdk-trace-base": "^2.12.0",
|
|
28
33
|
"@types/jest": "^29.5.2",
|
|
29
34
|
"jest": "^29.5.0",
|
|
30
35
|
"prettier": "^1.19.1",
|
|
31
36
|
"ts-jest": "^29.1.1",
|
|
32
37
|
"tslint": "^5.11.0",
|
|
33
38
|
"tslint-config-prettier": "^1.18.0",
|
|
34
|
-
"typescript": "^
|
|
39
|
+
"typescript": "^5.9.3"
|
|
35
40
|
},
|
|
36
41
|
"peerDependencies": {
|
|
42
|
+
"@contrail/app-framework": "^2.1.1",
|
|
43
|
+
"@contrail/telemetry": "^2.3.1",
|
|
44
|
+
"@opentelemetry/api": "^1.9.0",
|
|
37
45
|
"typescript": ">=4.0.0"
|
|
38
46
|
},
|
|
39
47
|
"peerDependenciesMeta": {
|
|
@@ -56,7 +64,6 @@
|
|
|
56
64
|
"testEnvironment": "node"
|
|
57
65
|
},
|
|
58
66
|
"dependencies": {
|
|
59
|
-
"@contrail/app-framework": "^1.4.3",
|
|
60
67
|
"@contrail/sdk": "^1.6.1",
|
|
61
68
|
"@contrail/transform-data": "^1.3.2",
|
|
62
69
|
"@contrail/util": "^1.3.1",
|