@contrail/flexplm 1.3.0 → 1.3.1-alpha.3e8dbdd
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/cli/commands/compile.d.ts +1 -0
- package/lib/cli/commands/compile.js +71 -0
- package/lib/cli/commands/compile.spec.d.ts +1 -0
- package/lib/cli/commands/compile.spec.js +80 -0
- package/lib/cli/commands/create.d.ts +1 -0
- package/lib/cli/commands/create.js +75 -0
- package/lib/cli/commands/create.spec.d.ts +1 -0
- package/lib/cli/commands/create.spec.js +78 -0
- package/lib/cli/commands/upload.d.ts +10 -0
- package/lib/cli/commands/upload.js +226 -0
- package/lib/cli/commands/upload.spec.d.ts +1 -0
- package/lib/cli/commands/upload.spec.js +88 -0
- package/lib/cli/index.d.ts +2 -0
- package/lib/cli/index.js +64 -0
- package/lib/cli/index.spec.d.ts +1 -0
- package/lib/cli/index.spec.js +79 -0
- package/lib/cli/template/mapping-template.ts.template +62 -0
- package/lib/entity-processor/base-entity-processor.d.ts +89 -42
- package/lib/entity-processor/base-entity-processor.js +438 -385
- package/lib/entity-processor/base-entity-processor.spec.d.ts +1 -1
- package/lib/entity-processor/base-entity-processor.spec.js +398 -397
- package/lib/flexplm-request.d.ts +3 -3
- package/lib/flexplm-request.js +34 -34
- package/lib/flexplm-utils.d.ts +5 -5
- package/lib/flexplm-utils.js +33 -33
- package/lib/flexplm-utils.spec.d.ts +1 -1
- package/lib/flexplm-utils.spec.js +26 -26
- package/lib/index.d.ts +23 -22
- package/lib/index.js +39 -38
- package/lib/interfaces/interfaces.d.ts +105 -105
- package/lib/interfaces/interfaces.js +2 -2
- package/lib/interfaces/item-family-changes.d.ts +20 -20
- package/lib/interfaces/item-family-changes.js +56 -56
- package/lib/interfaces/mapping-file.d.ts +460 -0
- package/lib/interfaces/mapping-file.js +2 -0
- package/lib/interfaces/publish-change-data.d.ts +19 -19
- package/lib/interfaces/publish-change-data.js +32 -32
- package/lib/publish/base-process-publish-assortment-callback.d.ts +9 -9
- package/lib/publish/base-process-publish-assortment-callback.js +38 -38
- package/lib/publish/base-process-publish-assortment.d.ts +118 -93
- package/lib/publish/base-process-publish-assortment.js +998 -944
- package/lib/publish/base-process-publish-assortment.spec.d.ts +1 -1
- package/lib/publish/base-process-publish-assortment.spec.js +1688 -1670
- package/lib/publish/mockData.d.ts +1389 -1389
- package/lib/publish/mockData.js +4524 -4519
- package/lib/transform/identifier-conversion-spec-mockData.js +472 -444
- package/lib/transform/identifier-conversion.d.ts +51 -15
- package/lib/transform/identifier-conversion.js +248 -212
- package/lib/transform/identifier-conversion.spec.d.ts +1 -1
- package/lib/transform/identifier-conversion.spec.js +343 -339
- package/lib/util/config-defaults.d.ts +8 -8
- package/lib/util/config-defaults.js +88 -85
- package/lib/util/config-defaults.spec.d.ts +1 -1
- package/lib/util/config-defaults.spec.js +302 -293
- package/lib/util/data-converter-spec-mockData.js +219 -205
- package/lib/util/data-converter.d.ts +136 -39
- package/lib/util/data-converter.js +718 -592
- package/lib/util/data-converter.spec.d.ts +1 -1
- package/lib/util/data-converter.spec.js +906 -904
- package/lib/util/error-response-object.d.ts +9 -4
- package/lib/util/error-response-object.js +54 -47
- package/lib/util/error-response-object.spec.d.ts +1 -1
- package/lib/util/error-response-object.spec.js +99 -99
- package/lib/util/event-short-message-status.d.ts +19 -19
- package/lib/util/event-short-message-status.js +24 -23
- package/lib/util/federation.d.ts +15 -15
- package/lib/util/federation.js +157 -149
- package/lib/util/flexplm-connect.d.ts +29 -22
- package/lib/util/flexplm-connect.js +190 -176
- package/lib/util/flexplm-connect.spec.d.ts +1 -1
- package/lib/util/flexplm-connect.spec.js +88 -88
- package/lib/util/logger-config.d.ts +1 -1
- package/lib/util/logger-config.js +27 -26
- package/lib/util/map-util-spec-mockData.js +219 -205
- package/lib/util/map-utils.d.ts +33 -6
- package/lib/util/map-utils.js +42 -15
- package/lib/util/map-utils.spec.d.ts +1 -1
- package/lib/util/map-utils.spec.js +89 -89
- package/lib/util/mockData.d.ts +80 -80
- package/lib/util/mockData.js +103 -103
- package/lib/util/thumbnail-util.d.ts +55 -34
- package/lib/util/thumbnail-util.js +242 -215
- package/lib/util/thumbnail-util.spec.d.ts +1 -1
- package/lib/util/thumbnail-util.spec.js +440 -434
- package/lib/util/type-conversion-utils-spec-mockData.js +259 -259
- package/lib/util/type-conversion-utils.d.ts +163 -23
- package/lib/util/type-conversion-utils.js +408 -265
- package/lib/util/type-conversion-utils.spec.d.ts +1 -1
- package/lib/util/type-conversion-utils.spec.js +868 -868
- package/lib/util/type-defaults.d.ts +74 -16
- package/lib/util/type-defaults.js +279 -221
- package/lib/util/type-defaults.spec.d.ts +1 -1
- package/lib/util/type-defaults.spec.js +516 -516
- package/lib/util/type-utils.d.ts +34 -13
- package/lib/util/type-utils.js +137 -114
- package/lib/util/type-utils.spec.d.ts +1 -1
- package/lib/util/type-utils.spec.js +192 -190
- package/package.json +21 -6
- package/scripts/copy-template.js +10 -0
- package/.claude/settings.local.json +0 -8
- package/.github/pull_request_template.md +0 -31
- package/.github/workflows/flexplm-lib.yml +0 -27
- package/.github/workflows/publish-to-npm.yml +0 -124
- package/CHANGELOG.md +0 -32
- package/publish.bat +0 -5
- package/publish.sh +0 -5
- package/src/entity-processor/base-entity-processor.spec.ts +0 -460
- package/src/entity-processor/base-entity-processor.ts +0 -515
- package/src/flexplm-request.ts +0 -28
- package/src/flexplm-utils.spec.ts +0 -27
- package/src/flexplm-utils.ts +0 -29
- package/src/index.ts +0 -22
- package/src/interfaces/interfaces.ts +0 -122
- package/src/interfaces/item-family-changes.ts +0 -67
- package/src/interfaces/publish-change-data.ts +0 -43
- package/src/publish/base-process-publish-assortment-callback.ts +0 -50
- package/src/publish/base-process-publish-assortment.spec.ts +0 -1992
- package/src/publish/base-process-publish-assortment.ts +0 -1134
- package/src/publish/mockData.ts +0 -4561
- package/src/transform/identifier-conversion-spec-mockData.ts +0 -496
- package/src/transform/identifier-conversion.spec.ts +0 -354
- package/src/transform/identifier-conversion.ts +0 -282
- package/src/util/config-defaults.spec.ts +0 -350
- package/src/util/config-defaults.ts +0 -93
- package/src/util/data-converter-spec-mockData.ts +0 -231
- package/src/util/data-converter.spec.ts +0 -1041
- package/src/util/data-converter.ts +0 -762
- package/src/util/error-response-object.spec.ts +0 -116
- package/src/util/error-response-object.ts +0 -50
- package/src/util/event-short-message-status.ts +0 -22
- package/src/util/federation.ts +0 -172
- package/src/util/flexplm-connect.spec.ts +0 -132
- package/src/util/flexplm-connect.ts +0 -208
- package/src/util/logger-config.ts +0 -20
- package/src/util/map-util-spec-mockData.ts +0 -231
- package/src/util/map-utils.spec.ts +0 -103
- package/src/util/map-utils.ts +0 -41
- package/src/util/mockData.ts +0 -101
- package/src/util/thumbnail-util.spec.ts +0 -508
- package/src/util/thumbnail-util.ts +0 -272
- package/src/util/type-conversion-utils-spec-mockData.ts +0 -271
- package/src/util/type-conversion-utils.spec.ts +0 -968
- package/src/util/type-conversion-utils.ts +0 -460
- package/src/util/type-defaults.spec.ts +0 -669
- package/src/util/type-defaults.ts +0 -281
- package/src/util/type-utils.spec.ts +0 -227
- package/src/util/type-utils.ts +0 -144
- package/tsconfig.json +0 -29
- package/tslint.json +0 -57
|
@@ -1,56 +1,56 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.ItemFamilyChanges = void 0;
|
|
4
|
-
class ItemFamilyChanges {
|
|
5
|
-
get itemFamilyId() { return this._itemFamilyId; }
|
|
6
|
-
get sinceDate() { return this._sinceDate; }
|
|
7
|
-
constructor(itemFamilyId, sinceDate) {
|
|
8
|
-
this.familyAdd = false;
|
|
9
|
-
this.familyDelete = false;
|
|
10
|
-
this.familyUpdate = false;
|
|
11
|
-
this.familyItemRemoved = false;
|
|
12
|
-
this.itemFamilyObject = undefined;
|
|
13
|
-
this.colorAdds = [];
|
|
14
|
-
this.colorDeletes = [];
|
|
15
|
-
this.colorUpdates = [];
|
|
16
|
-
this.colorUnchanged = [];
|
|
17
|
-
this.assortmentItemFullChangeMap = new Map();
|
|
18
|
-
this.assortmentItemDeleteMap = new Map();
|
|
19
|
-
this.itemToFederatedIdMapping = new Map();
|
|
20
|
-
this._itemFamilyId = itemFamilyId;
|
|
21
|
-
this._sinceDate = sinceDate;
|
|
22
|
-
}
|
|
23
|
-
toString() {
|
|
24
|
-
let s = 'ItemFamilyChanges\n'
|
|
25
|
-
+ ' itemFamilyId: ' + this._itemFamilyId + '\n'
|
|
26
|
-
+ ' sinceDate: ' + this._sinceDate + '\n'
|
|
27
|
-
+ ' familyAdd: ' + this.familyAdd + '\n'
|
|
28
|
-
+ ' familyDelete: ' + this.familyDelete + '\n'
|
|
29
|
-
+ ' familyUpdate: ' + this.familyUpdate + '\n'
|
|
30
|
-
+ ' familyItemRemoved: ' + this.familyItemRemoved + '\n';
|
|
31
|
-
s += ' colorAdds: [' + this.colorAdds + ']\n';
|
|
32
|
-
s += ' colorDeletes: [' + this.colorDeletes + ']\n';
|
|
33
|
-
s += ' colorUpdates: [' + this.colorUpdates + ']\n';
|
|
34
|
-
s += ' colorUnchanged: [' + this.colorUnchanged + ']\n';
|
|
35
|
-
s += 'assortmentItemFullChangeMap:\n';
|
|
36
|
-
s += 'size: ' + this.assortmentItemFullChangeMap.size + '\n[';
|
|
37
|
-
for (const key of this.assortmentItemFullChangeMap.keys()) {
|
|
38
|
-
s += key + ', ';
|
|
39
|
-
}
|
|
40
|
-
s += ']\n';
|
|
41
|
-
s += 'assortmentItemDeleteMap:\n';
|
|
42
|
-
s += 'size: ' + this.assortmentItemDeleteMap.size + '\n[';
|
|
43
|
-
for (const key of this.assortmentItemDeleteMap.keys()) {
|
|
44
|
-
s += key + ', ';
|
|
45
|
-
}
|
|
46
|
-
s += ']\n';
|
|
47
|
-
s += 'itemToFederatedIdMapping:\n';
|
|
48
|
-
s += 'size: ' + this.itemToFederatedIdMapping.size + '\n[';
|
|
49
|
-
for (const key of this.itemToFederatedIdMapping.keys()) {
|
|
50
|
-
s += key + ', ';
|
|
51
|
-
}
|
|
52
|
-
s += ']\n';
|
|
53
|
-
return s;
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
exports.ItemFamilyChanges = ItemFamilyChanges;
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ItemFamilyChanges = void 0;
|
|
4
|
+
class ItemFamilyChanges {
|
|
5
|
+
get itemFamilyId() { return this._itemFamilyId; }
|
|
6
|
+
get sinceDate() { return this._sinceDate; }
|
|
7
|
+
constructor(itemFamilyId, sinceDate) {
|
|
8
|
+
this.familyAdd = false;
|
|
9
|
+
this.familyDelete = false;
|
|
10
|
+
this.familyUpdate = false;
|
|
11
|
+
this.familyItemRemoved = false;
|
|
12
|
+
this.itemFamilyObject = undefined;
|
|
13
|
+
this.colorAdds = [];
|
|
14
|
+
this.colorDeletes = [];
|
|
15
|
+
this.colorUpdates = [];
|
|
16
|
+
this.colorUnchanged = [];
|
|
17
|
+
this.assortmentItemFullChangeMap = new Map();
|
|
18
|
+
this.assortmentItemDeleteMap = new Map();
|
|
19
|
+
this.itemToFederatedIdMapping = new Map();
|
|
20
|
+
this._itemFamilyId = itemFamilyId;
|
|
21
|
+
this._sinceDate = sinceDate;
|
|
22
|
+
}
|
|
23
|
+
toString() {
|
|
24
|
+
let s = 'ItemFamilyChanges\n'
|
|
25
|
+
+ ' itemFamilyId: ' + this._itemFamilyId + '\n'
|
|
26
|
+
+ ' sinceDate: ' + this._sinceDate + '\n'
|
|
27
|
+
+ ' familyAdd: ' + this.familyAdd + '\n'
|
|
28
|
+
+ ' familyDelete: ' + this.familyDelete + '\n'
|
|
29
|
+
+ ' familyUpdate: ' + this.familyUpdate + '\n'
|
|
30
|
+
+ ' familyItemRemoved: ' + this.familyItemRemoved + '\n';
|
|
31
|
+
s += ' colorAdds: [' + this.colorAdds + ']\n';
|
|
32
|
+
s += ' colorDeletes: [' + this.colorDeletes + ']\n';
|
|
33
|
+
s += ' colorUpdates: [' + this.colorUpdates + ']\n';
|
|
34
|
+
s += ' colorUnchanged: [' + this.colorUnchanged + ']\n';
|
|
35
|
+
s += 'assortmentItemFullChangeMap:\n';
|
|
36
|
+
s += 'size: ' + this.assortmentItemFullChangeMap.size + '\n[';
|
|
37
|
+
for (const key of this.assortmentItemFullChangeMap.keys()) {
|
|
38
|
+
s += key + ', ';
|
|
39
|
+
}
|
|
40
|
+
s += ']\n';
|
|
41
|
+
s += 'assortmentItemDeleteMap:\n';
|
|
42
|
+
s += 'size: ' + this.assortmentItemDeleteMap.size + '\n[';
|
|
43
|
+
for (const key of this.assortmentItemDeleteMap.keys()) {
|
|
44
|
+
s += key + ', ';
|
|
45
|
+
}
|
|
46
|
+
s += ']\n';
|
|
47
|
+
s += 'itemToFederatedIdMapping:\n';
|
|
48
|
+
s += 'size: ' + this.itemToFederatedIdMapping.size + '\n[';
|
|
49
|
+
for (const key of this.itemToFederatedIdMapping.keys()) {
|
|
50
|
+
s += key + ', ';
|
|
51
|
+
}
|
|
52
|
+
s += ']\n';
|
|
53
|
+
return s;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
exports.ItemFamilyChanges = ItemFamilyChanges;
|
|
@@ -0,0 +1,460 @@
|
|
|
1
|
+
import { FunctionTransformers, RekeyTransformers, TransformDefinition, TransformTask } from "@contrail/transform-data";
|
|
2
|
+
/**
|
|
3
|
+
* One direction of a {@link MappingSection} (either `vibe2flex` or `flex2vibe`).
|
|
4
|
+
*
|
|
5
|
+
* Holds the per-direction transform pipeline plus the named lookup tables
|
|
6
|
+
* (`rekey`, `removeKey`, `valueTransform`) that the tasks in
|
|
7
|
+
* {@link DirectionalSection.transformOrder} reference by key. A REKEY task
|
|
8
|
+
* configured with `rekeyTransformersKey: 'rekey'` resolves to
|
|
9
|
+
* {@link DirectionalSection.rekey} on the same directional section.
|
|
10
|
+
*
|
|
11
|
+
* The named members below cover the conventional shape, but the section
|
|
12
|
+
* is open: each task in a pipeline resolves its config by reading the
|
|
13
|
+
* sibling property whose name is supplied by the matching `*Key` pointer
|
|
14
|
+
* on the task. That means a directional section can hold:
|
|
15
|
+
* - additional `TransformTask[]` pipelines under names other than
|
|
16
|
+
* `transformOrder` (selected by passing a non-default `orderKey` to
|
|
17
|
+
* `MapFileUtil.getTransformTasks`)
|
|
18
|
+
* - additional REKEY / REMOVE / MORPH / VALUE_TRANSFORM / CONDITIONAL
|
|
19
|
+
* lookup tables under arbitrary names referenced by the task's
|
|
20
|
+
* `rekeyTransformersKey`, `removeKeysKey`, `functionTransformersKey`,
|
|
21
|
+
* or `conditionalTransformDefinitionsKey`.
|
|
22
|
+
*
|
|
23
|
+
* @example
|
|
24
|
+
* vibe2flex: {
|
|
25
|
+
* transformOrder: [
|
|
26
|
+
* { processor: 'VALUE_TRANSFORM', functionTransformersKey: 'valueTransform' },
|
|
27
|
+
* { processor: 'REKEY', rekeyDelete: true, rekeyKeepEmptyValues: true, rekeyTransformersKey: 'rekey' },
|
|
28
|
+
* { processor: 'REMOVE', removeKeysKey: 'removeKey' },
|
|
29
|
+
* ],
|
|
30
|
+
* rekey: { productName: 'name', custBrand: 'brand' },
|
|
31
|
+
* valueTransform: {
|
|
32
|
+
* itemNumber: (row) => '' + row['itemNumber'],
|
|
33
|
+
* },
|
|
34
|
+
* removeKey: ['patternReference', 'vibeOnlyProp'],
|
|
35
|
+
* }
|
|
36
|
+
*/
|
|
37
|
+
export interface DirectionalSection {
|
|
38
|
+
/**
|
|
39
|
+
* Ordered pipeline of transforms applied to each row in this direction.
|
|
40
|
+
*
|
|
41
|
+
* Each task is dispatched by its `processor` discriminator
|
|
42
|
+
* (REKEY, REMOVE, VALUE_TRANSFORM, MORPH, CONDITIONAL) and reads its
|
|
43
|
+
* configuration from the corresponding sibling property on this section
|
|
44
|
+
* (e.g. a REKEY task with `rekeyTransformersKey: 'rekey'` reads
|
|
45
|
+
* {@link DirectionalSection.rekey}).
|
|
46
|
+
*
|
|
47
|
+
* @example
|
|
48
|
+
* transformOrder: [
|
|
49
|
+
* { processor: 'REKEY', rekeyDelete: true, rekeyKeepEmptyValues: true, rekeyTransformersKey: 'rekey' },
|
|
50
|
+
* { processor: 'REMOVE', removeKeysKey: 'removeKey' },
|
|
51
|
+
* ]
|
|
52
|
+
*/
|
|
53
|
+
transformOrder?: TransformTask[];
|
|
54
|
+
/**
|
|
55
|
+
* Resolves the FlexPLM object class (vibe2flex) or VibeIQ entity class
|
|
56
|
+
* (flex2vibe) for a row when it cannot be derived from the row itself.
|
|
57
|
+
*
|
|
58
|
+
* Consulted by `TypeConversionUtils.getObjectClass` /
|
|
59
|
+
* `getEntityClassFromObject` after the explicit `flexPLMObjectClass` /
|
|
60
|
+
* `vibeIQEntityClass` property and before the `TypeDefaults` fallback.
|
|
61
|
+
*
|
|
62
|
+
* @example
|
|
63
|
+
* // vibe2flex
|
|
64
|
+
* getClass: () => 'LCSRevisableEntity'
|
|
65
|
+
* // flex2vibe
|
|
66
|
+
* getClass: () => 'custom-entity'
|
|
67
|
+
*/
|
|
68
|
+
getClass?: (entity: Record<string, unknown>) => string;
|
|
69
|
+
/**
|
|
70
|
+
* Resolves the FlexPLM type path (vibe2flex) or VibeIQ type path
|
|
71
|
+
* (flex2vibe) for a row when it cannot be derived from the row itself.
|
|
72
|
+
*
|
|
73
|
+
* Consulted by `TypeConversionUtils.getObjectTypePath` /
|
|
74
|
+
* `getEntityTypePathFromObject` after the explicit `flexPLMTypePath` /
|
|
75
|
+
* `vibeIQTypePath` property and before the `TypeDefaults` fallback.
|
|
76
|
+
*
|
|
77
|
+
* @example
|
|
78
|
+
* // vibe2flex
|
|
79
|
+
* getSoftType: () => 'Revisable Entity\\Product Concept'
|
|
80
|
+
* // flex2vibe
|
|
81
|
+
* getSoftType: () => 'custom-entity:styleConcept'
|
|
82
|
+
*/
|
|
83
|
+
getSoftType?: (entity: Record<string, unknown>) => string;
|
|
84
|
+
/**
|
|
85
|
+
* Lookup table consumed by REKEY tasks in {@link DirectionalSection.transformOrder}.
|
|
86
|
+
*
|
|
87
|
+
* **Read each entry as `destination: 'source'`** — the property name (left)
|
|
88
|
+
* is the key written onto the row, the string value (right) is the
|
|
89
|
+
* existing key whose value is read. Each entry copies (or moves, when the
|
|
90
|
+
* task sets `rekeyDelete: true`) the value at the source key onto the
|
|
91
|
+
* destination key. Referenced by `rekeyTransformersKey` on the REKEY task.
|
|
92
|
+
*
|
|
93
|
+
* Because REKEY runs on the row in its **input** shape, the source side
|
|
94
|
+
* matches the direction's input system and the destination side matches
|
|
95
|
+
* its output system:
|
|
96
|
+
* - Inside `vibe2flex.rekey`: `flexKey: 'vibeKey'` (vibe in → flex out).
|
|
97
|
+
* - Inside `flex2vibe.rekey`: `vibeKey: 'flexKey'` (flex in → vibe out).
|
|
98
|
+
*
|
|
99
|
+
* @example
|
|
100
|
+
* // vibe2flex — left side is the FlexPLM key, right side is the VibeIQ key
|
|
101
|
+
* rekey: {
|
|
102
|
+
* productName: 'name', // flex 'productName' ← vibe 'name'
|
|
103
|
+
* custBrand: 'brand', // flex 'custBrand' ← vibe 'brand'
|
|
104
|
+
* custStyleNumber: 'styleNumber', // flex 'custStyleNumber' ← vibe 'styleNumber'
|
|
105
|
+
* }
|
|
106
|
+
*
|
|
107
|
+
* @example
|
|
108
|
+
* // flex2vibe — left side is the VibeIQ key, right side is the FlexPLM key
|
|
109
|
+
* rekey: {
|
|
110
|
+
* name: 'productName', // vibe 'name' ← flex 'productName'
|
|
111
|
+
* brand: 'custBrand', // vibe 'brand' ← flex 'custBrand'
|
|
112
|
+
* styleNumber: 'custStyleNumber', // vibe 'styleNumber' ← flex 'custStyleNumber'
|
|
113
|
+
* }
|
|
114
|
+
*/
|
|
115
|
+
rekey?: RekeyTransformers;
|
|
116
|
+
/**
|
|
117
|
+
* Lookup table consumed by REMOVE tasks in {@link DirectionalSection.transformOrder}.
|
|
118
|
+
*
|
|
119
|
+
* Names of keys to delete from each row. Referenced by `removeKeysKey`
|
|
120
|
+
* on the REMOVE task.
|
|
121
|
+
*
|
|
122
|
+
* @example
|
|
123
|
+
* removeKey: ['patternReference', 'vibeOnlyProp']
|
|
124
|
+
*/
|
|
125
|
+
removeKey?: string[];
|
|
126
|
+
/**
|
|
127
|
+
* Lookup table consumed by VALUE_TRANSFORM tasks in
|
|
128
|
+
* {@link DirectionalSection.transformOrder}.
|
|
129
|
+
*
|
|
130
|
+
* Each entry's key is the property the function's return value is written
|
|
131
|
+
* to on the row; the function receives the full row plus optional
|
|
132
|
+
* dependencies. Referenced by `functionTransformersKey` on the
|
|
133
|
+
* VALUE_TRANSFORM task.
|
|
134
|
+
*
|
|
135
|
+
* @example
|
|
136
|
+
* valueTransform: {
|
|
137
|
+
* itemNumber: (row) => {
|
|
138
|
+
* const numValue = parseInt(row['itemNumber'], 10);
|
|
139
|
+
* return isNaN(numValue) ? row['itemNumber'] : numValue;
|
|
140
|
+
* },
|
|
141
|
+
* }
|
|
142
|
+
*/
|
|
143
|
+
valueTransform?: Record<string, (row: Record<string, unknown>, dependencies?: unknown) => unknown>;
|
|
144
|
+
/**
|
|
145
|
+
* Lookup table consumed by MORPH tasks in {@link DirectionalSection.transformOrder}.
|
|
146
|
+
*
|
|
147
|
+
* Each entry's function receives the full row plus optional dependencies
|
|
148
|
+
* and may rewrite/augment it in place; unlike {@link DirectionalSection.valueTransform},
|
|
149
|
+
* the function key is just an identifier and is not the destination
|
|
150
|
+
* property. Referenced by `functionTransformersKey` on the MORPH task.
|
|
151
|
+
*
|
|
152
|
+
* @example
|
|
153
|
+
* morphTransform: {
|
|
154
|
+
* morph1: (row) => {
|
|
155
|
+
* const val = row['productStatus'];
|
|
156
|
+
* if (val && Object.keys(val).length === 0) {
|
|
157
|
+
* delete row['productStatus'];
|
|
158
|
+
* }
|
|
159
|
+
* },
|
|
160
|
+
* }
|
|
161
|
+
*/
|
|
162
|
+
morphTransform?: Record<string, (row: Record<string, unknown>, dependencies?: unknown) => unknown>;
|
|
163
|
+
/**
|
|
164
|
+
* Catch-all for additional pipelines and per-processor lookup tables
|
|
165
|
+
* referenced by sibling `*Key` pointers on tasks. Each entry should be
|
|
166
|
+
* one of:
|
|
167
|
+
* - {@link TransformTask}[] — alternate pipeline (read it by passing
|
|
168
|
+
* its property name as `orderKey` to `MapFileUtil.getTransformTasks`)
|
|
169
|
+
* - {@link RekeyTransformers} — `newKey` → `existingKey` map for REKEY
|
|
170
|
+
* - `string[]` — keys to delete for REMOVE
|
|
171
|
+
* - {@link FunctionTransformers} — Record<string, Function> for MORPH or VALUE_TRANSFORM
|
|
172
|
+
* - {@link TransformDefinition}[] — conditional rules for CONDITIONAL
|
|
173
|
+
*/
|
|
174
|
+
[key: string]: TransformTask[] | TransformDefinition[] | RekeyTransformers | FunctionTransformers | Record<string, unknown> | string[] | ((entity: Record<string, unknown>) => string) | ((entity: Record<string, unknown>) => string[]) | ((row: Record<string, unknown>, dependencies?: unknown) => unknown) | undefined;
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* Per-entity-type configuration block, keyed in the {@link MappingFile}
|
|
178
|
+
* by the section key returned from
|
|
179
|
+
* {@link TypeConversionEntry.getMapKey} (e.g. `LCSProduct`,
|
|
180
|
+
* `'Exchange Rate'`).
|
|
181
|
+
*
|
|
182
|
+
* Holds direction-agnostic settings (ownership, identifier/informational
|
|
183
|
+
* properties, creation and image-sync gates) plus the two
|
|
184
|
+
* {@link DirectionalSection}s that drive the actual data transforms.
|
|
185
|
+
*
|
|
186
|
+
* @example
|
|
187
|
+
* LCSProduct: {
|
|
188
|
+
* vibeOwningKeys: ['itemNumber', 'lifecycleStage'],
|
|
189
|
+
* getIdentifierProperties: () => ['styleNumber'],
|
|
190
|
+
* vibe2flex: {
|
|
191
|
+
* transformOrder: [
|
|
192
|
+
* { processor: 'REKEY', rekeyDelete: true, rekeyKeepEmptyValues: true, rekeyTransformersKey: 'rekey' },
|
|
193
|
+
* ],
|
|
194
|
+
* // destination: source -> flexKey: 'vibeKey'
|
|
195
|
+
* rekey: { productName: 'name' },
|
|
196
|
+
* },
|
|
197
|
+
* flex2vibe: {
|
|
198
|
+
* transformOrder: [
|
|
199
|
+
* { processor: 'REKEY', rekeyDelete: true, rekeyKeepEmptyValues: true, rekeyTransformersKey: 'rekey' },
|
|
200
|
+
* ],
|
|
201
|
+
* // destination: source -> vibeKey: 'flexKey'
|
|
202
|
+
* rekey: { name: 'productName' },
|
|
203
|
+
* },
|
|
204
|
+
* }
|
|
205
|
+
*/
|
|
206
|
+
export interface MappingSection {
|
|
207
|
+
/**
|
|
208
|
+
* These are the slugs of the properties that the VibeIQ system owns. So
|
|
209
|
+
* even if data comes in from an external source, it is ignored and the
|
|
210
|
+
* values are not overwritten.
|
|
211
|
+
*
|
|
212
|
+
* @example
|
|
213
|
+
* vibeOwningKeys: ['itemNumber', 'lifecycleStage']
|
|
214
|
+
*/
|
|
215
|
+
vibeOwningKeys?: string[];
|
|
216
|
+
/**
|
|
217
|
+
* Tag identifying which identity service uniqueness pool this entity participates in.
|
|
218
|
+
* There can only be one entity with a given value for the property(defined by `getIdentifierProperties`) within the same uniqueness pool.
|
|
219
|
+
*
|
|
220
|
+
* @example
|
|
221
|
+
* uniquenessPool: 'item'
|
|
222
|
+
*/
|
|
223
|
+
uniquenessPool?: string;
|
|
224
|
+
/**
|
|
225
|
+
* Gate controlling whether an inbound FlexPLM object is allowed to
|
|
226
|
+
* create a new VibeIQ entity. When the function returns `false`, the
|
|
227
|
+
* inbound row may still update an existing entity but will not create
|
|
228
|
+
* one. Consulted by `TypeConversionUtils.isInboundCreatableFromObject`;
|
|
229
|
+
* defaults to `false` when the function is absent.
|
|
230
|
+
*
|
|
231
|
+
* @example
|
|
232
|
+
* isInboundCreatable: () => true
|
|
233
|
+
*/
|
|
234
|
+
isInboundCreatable?: (entity: Record<string, unknown>, context?: unknown) => boolean;
|
|
235
|
+
/**
|
|
236
|
+
* Gate controlling whether an outbound VibeIQ entity is allowed to
|
|
237
|
+
* create a new FlexPLM object. When the function returns `false`, the
|
|
238
|
+
* outbound publish becomes an update-only operation. Consulted by
|
|
239
|
+
* `TypeConversionUtils.isOutboundCreatableFromEntity`; defaults to
|
|
240
|
+
* `true` when the function is absent.
|
|
241
|
+
*
|
|
242
|
+
* @example
|
|
243
|
+
* isOutboundCreatable: () => false
|
|
244
|
+
*/
|
|
245
|
+
isOutboundCreatable?: (entity: Record<string, unknown>, context?: unknown) => boolean;
|
|
246
|
+
/**
|
|
247
|
+
* Gate controlling whether image/thumbnail content should be synced
|
|
248
|
+
* from FlexPLM into VibeIQ for this entity type. Consulted by
|
|
249
|
+
* `TypeConversionUtils.syncInboundImages`; defaults to `false` when
|
|
250
|
+
* the function is absent. Typically aligned with whichever system
|
|
251
|
+
* owns creation of the entity.
|
|
252
|
+
*
|
|
253
|
+
* @example
|
|
254
|
+
* syncInboundImages: () => true
|
|
255
|
+
*/
|
|
256
|
+
syncInboundImages?: (entity: Record<string, unknown>, context?: unknown) => boolean;
|
|
257
|
+
/**
|
|
258
|
+
* Gate controlling whether image/thumbnail content should be synced
|
|
259
|
+
* from VibeIQ out to FlexPLM for this entity type. Consulted by
|
|
260
|
+
* `TypeConversionUtils.syncOutboundImages`; defaults to `true` when
|
|
261
|
+
* the function is absent. Typically aligned with whichever system
|
|
262
|
+
* owns creation of the entity.
|
|
263
|
+
*
|
|
264
|
+
* @example
|
|
265
|
+
* syncOutboundImages: () => false
|
|
266
|
+
*/
|
|
267
|
+
syncOutboundImages?: (entity: Record<string, unknown>, context?: unknown) => boolean;
|
|
268
|
+
/**
|
|
269
|
+
* Returns the property names that uniquely identify this entity. Used
|
|
270
|
+
* by `TypeConversionUtils.getIdentifierProperties` to drive lookup and
|
|
271
|
+
* matching when an explicit `flexPLMIdentifierProperties` /
|
|
272
|
+
* `vibeIQIdentifierProperties` is not present on the row, falling
|
|
273
|
+
* back to `TypeDefaults` when this is absent.
|
|
274
|
+
*
|
|
275
|
+
* @example
|
|
276
|
+
* getIdentifierProperties: () => ['itemNumber']
|
|
277
|
+
*/
|
|
278
|
+
getIdentifierProperties?: (entity: Record<string, unknown>) => string[];
|
|
279
|
+
/**
|
|
280
|
+
* Returns supplemental property names that should be carried alongside
|
|
281
|
+
* identifiers (e.g. display names) but do not participate in identity.
|
|
282
|
+
* Consulted by `TypeConversionUtils.getInformationalProperties` with
|
|
283
|
+
* the same lookup precedence as {@link MappingSection.getIdentifierProperties}.
|
|
284
|
+
*
|
|
285
|
+
* @example
|
|
286
|
+
* getInformationalProperties: () => ['longName']
|
|
287
|
+
*/
|
|
288
|
+
getInformationalProperties?: (entity: Record<string, unknown>) => string[];
|
|
289
|
+
/**
|
|
290
|
+
* Transform configuration applied when sending data from VibeIQ to FlexPLM.
|
|
291
|
+
* Pipeline runs on rows in their VibeIQ shape and produces rows in their
|
|
292
|
+
* FlexPLM shape, so inside `rekey` the destination (left) is the FlexPLM
|
|
293
|
+
* key and the source (right) is the VibeIQ key — see
|
|
294
|
+
* {@link DirectionalSection.rekey}.
|
|
295
|
+
*/
|
|
296
|
+
vibe2flex?: DirectionalSection;
|
|
297
|
+
/**
|
|
298
|
+
* Transform configuration applied when receiving data from FlexPLM into VibeIQ.
|
|
299
|
+
* Pipeline runs on rows in their FlexPLM shape and produces rows in their
|
|
300
|
+
* VibeIQ shape, so inside `rekey` the destination (left) is the VibeIQ
|
|
301
|
+
* key and the source (right) is the FlexPLM key — see
|
|
302
|
+
* {@link DirectionalSection.rekey}.
|
|
303
|
+
*/
|
|
304
|
+
flex2vibe?: DirectionalSection;
|
|
305
|
+
}
|
|
306
|
+
/**
|
|
307
|
+
* Entry in the {@link TypeConversionSection} that maps a single source
|
|
308
|
+
* type onto the {@link MappingSection} key that should handle it.
|
|
309
|
+
*
|
|
310
|
+
* Useful for fanning a single VibeIQ `entityType` (e.g. `'custom-entity'`)
|
|
311
|
+
* out to multiple sections based on the row's `typePath`.
|
|
312
|
+
*/
|
|
313
|
+
export interface TypeConversionEntry {
|
|
314
|
+
/**
|
|
315
|
+
* Returns the {@link MappingFile} key whose {@link MappingSection}
|
|
316
|
+
* should be used to transform `entity`. Returning an empty string
|
|
317
|
+
* signals that no section applies and the row should be skipped.
|
|
318
|
+
*
|
|
319
|
+
* @example
|
|
320
|
+
* getMapKey: (entity) => {
|
|
321
|
+
* switch (entity['typePath']) {
|
|
322
|
+
* case 'custom-entity:exchangeRate': return 'Exchange Rate';
|
|
323
|
+
* case 'custom-entity:styleConcept': return 'Style Concept Master';
|
|
324
|
+
* default: return '';
|
|
325
|
+
* }
|
|
326
|
+
* }
|
|
327
|
+
*/
|
|
328
|
+
getMapKey: (entity: Record<string, unknown>) => string;
|
|
329
|
+
}
|
|
330
|
+
/**
|
|
331
|
+
* One direction of {@link TypeConversion}, keyed by the source-system
|
|
332
|
+
* type:
|
|
333
|
+
* - In `vibe2flex`, keys are VibeIQ entity types (e.g. `'custom-entity'`,
|
|
334
|
+
* `'size-range-template'`) — see `TypeConversionUtils.getEntityType`.
|
|
335
|
+
* - In `flex2vibe`, keys are FlexPLM object classes (e.g. `LCSProduct`) —
|
|
336
|
+
* see `TypeConversionUtils.getObjectType`.
|
|
337
|
+
*/
|
|
338
|
+
export interface TypeConversionSection {
|
|
339
|
+
[type: string]: TypeConversionEntry;
|
|
340
|
+
}
|
|
341
|
+
/**
|
|
342
|
+
* Top-level routing table that resolves a row to its
|
|
343
|
+
* {@link MappingSection} key for each direction.
|
|
344
|
+
*
|
|
345
|
+
* `TypeConversionUtils.getMapKey` / `getMapKeyFromObject` look up the
|
|
346
|
+
* row's type in the appropriate side, invoke
|
|
347
|
+
* {@link TypeConversionEntry.getMapKey}, and use the returned string
|
|
348
|
+
* as the key into the rest of the {@link MappingFile}.
|
|
349
|
+
*
|
|
350
|
+
* @example
|
|
351
|
+
* typeConversion: {
|
|
352
|
+
* vibe2flex: {
|
|
353
|
+
* 'custom-entity': {
|
|
354
|
+
* getMapKey: (entity) => {
|
|
355
|
+
* switch (entity['typePath']) {
|
|
356
|
+
* case 'custom-entity:exchangeRate': return 'Exchange Rate';
|
|
357
|
+
* default: return '';
|
|
358
|
+
* }
|
|
359
|
+
* },
|
|
360
|
+
* },
|
|
361
|
+
* 'size-range-template': {
|
|
362
|
+
* getMapKey: () => 'size-range-template',
|
|
363
|
+
* },
|
|
364
|
+
* },
|
|
365
|
+
* flex2vibe: {
|
|
366
|
+
* LCSRevisableEntity: {
|
|
367
|
+
* getMapKey: (object) => {
|
|
368
|
+
* switch (object['flexPLMTypePath']) {
|
|
369
|
+
* case 'Revisable Entity\\Exchange Rate': return 'Exchange Rate';
|
|
370
|
+
* default: return '';
|
|
371
|
+
* }
|
|
372
|
+
* },
|
|
373
|
+
* },
|
|
374
|
+
* },
|
|
375
|
+
* }
|
|
376
|
+
*/
|
|
377
|
+
export interface TypeConversion {
|
|
378
|
+
/** Routes outbound VibeIQ entities to their FlexPLM mapping sections. */
|
|
379
|
+
vibe2flex: TypeConversionSection;
|
|
380
|
+
/** Routes inbound FlexPLM objects to their VibeIQ mapping sections. */
|
|
381
|
+
flex2vibe: TypeConversionSection;
|
|
382
|
+
}
|
|
383
|
+
/** Identifies the application and tenant that owns a {@link MappingFile}. */
|
|
384
|
+
export interface OrgInfo {
|
|
385
|
+
/** This is the identifier for the application, and is used to set the owner of the mapping file */
|
|
386
|
+
appIdentifier: '@vibeiq/flexplm-connector';
|
|
387
|
+
/** The name of the organization using the mapping file. */
|
|
388
|
+
orgName: string;
|
|
389
|
+
}
|
|
390
|
+
interface MappingFileBase {
|
|
391
|
+
/** The information about the organization using the mapping file */
|
|
392
|
+
orgInfo: OrgInfo;
|
|
393
|
+
/** The type conversion information for the mapping file. */
|
|
394
|
+
typeConversion: TypeConversion;
|
|
395
|
+
}
|
|
396
|
+
/**
|
|
397
|
+
* Full mapping file driving bidirectional sync between VibeIQ and FlexPLM
|
|
398
|
+
* for a single tenant.
|
|
399
|
+
*
|
|
400
|
+
* Combines the fixed {@link MappingFileBase} fields (`orgInfo`,
|
|
401
|
+
* `typeConversion`) with an open set of {@link MappingSection} entries
|
|
402
|
+
* keyed by the strings returned from
|
|
403
|
+
* {@link TypeConversionEntry.getMapKey} (e.g. `LCSProduct`, `LCSSKU`,
|
|
404
|
+
* `'Exchange Rate'`).
|
|
405
|
+
*
|
|
406
|
+
* @example
|
|
407
|
+
* export const mapping: MappingFile = {
|
|
408
|
+
* orgInfo: {
|
|
409
|
+
* appIdentifier: '@vibeiq/flexplm-connector',
|
|
410
|
+
* orgName: 'acme',
|
|
411
|
+
* },
|
|
412
|
+
* typeConversion: {
|
|
413
|
+
* vibe2flex: {
|
|
414
|
+
* 'custom-entity': {
|
|
415
|
+
* getMapKey: (entity) => {
|
|
416
|
+
* switch (entity['typePath']) {
|
|
417
|
+
* case 'custom-entity:exchangeRate': return 'Exchange Rate';
|
|
418
|
+
* default: return '';
|
|
419
|
+
* }
|
|
420
|
+
* },
|
|
421
|
+
* },
|
|
422
|
+
* 'size-range-template': {
|
|
423
|
+
* getMapKey: () => 'size-range-template',
|
|
424
|
+
* },
|
|
425
|
+
* },
|
|
426
|
+
* flex2vibe: {
|
|
427
|
+
* LCSRevisableEntity: {
|
|
428
|
+
* getMapKey: (object) => {
|
|
429
|
+
* switch (object['flexPLMTypePath']) {
|
|
430
|
+
* case 'Revisable Entity\\Exchange Rate': return 'Exchange Rate';
|
|
431
|
+
* default: return '';
|
|
432
|
+
* }
|
|
433
|
+
* },
|
|
434
|
+
* },
|
|
435
|
+
* },
|
|
436
|
+
* },
|
|
437
|
+
* 'Exchange Rate': {
|
|
438
|
+
* vibe2flex: {
|
|
439
|
+
* transformOrder: [
|
|
440
|
+
* { processor: 'REKEY', rekeyDelete: true, rekeyKeepEmptyValues: true, rekeyTransformersKey: 'rekey' },
|
|
441
|
+
* ],
|
|
442
|
+
* rekey: { exchangeRateDescription: 'name' },
|
|
443
|
+
* getClass: () => 'LCSRevisableEntity',
|
|
444
|
+
* getSoftType: () => 'Revisable Entity\\Exchange Rate',
|
|
445
|
+
* },
|
|
446
|
+
* flex2vibe: {
|
|
447
|
+
* transformOrder: [
|
|
448
|
+
* { processor: 'REKEY', rekeyDelete: true, rekeyKeepEmptyValues: true, rekeyTransformersKey: 'rekey' },
|
|
449
|
+
* ],
|
|
450
|
+
* rekey: { name: 'exchangeRateDescription' },
|
|
451
|
+
* getClass: () => 'custom-entity',
|
|
452
|
+
* getSoftType: () => 'custom-entity:exchangeRate',
|
|
453
|
+
* },
|
|
454
|
+
* },
|
|
455
|
+
* };
|
|
456
|
+
*/
|
|
457
|
+
export type MappingFile = MappingFileBase & {
|
|
458
|
+
[mapKey: string]: MappingSection | MappingFileBase[keyof MappingFileBase];
|
|
459
|
+
};
|
|
460
|
+
export {};
|
|
@@ -1,19 +1,19 @@
|
|
|
1
|
-
import { SeasonFederation } from './interfaces';
|
|
2
|
-
import { ItemFamilyChanges } from './item-family-changes';
|
|
3
|
-
export declare class PublishChangeData {
|
|
4
|
-
private _assortmentId;
|
|
5
|
-
get assortmentId(): string;
|
|
6
|
-
private _seasonFed;
|
|
7
|
-
get seasonFed(): SeasonFederation;
|
|
8
|
-
private _assortmentPublishChangeId;
|
|
9
|
-
get assortmentPublishChangeId(): string;
|
|
10
|
-
private _sinceDate;
|
|
11
|
-
get sinceDate(): Date;
|
|
12
|
-
private _publisher;
|
|
13
|
-
get publisher(): object;
|
|
14
|
-
itemToFederatedIdMapping: Map<string, string>;
|
|
15
|
-
releasedForDevelopmentItemIds: string[];
|
|
16
|
-
itemFamilyChanges: Map<string, ItemFamilyChanges>;
|
|
17
|
-
constructor(_assortmentId: string, _seasonFed: SeasonFederation, _assortmentPublishChangeId: string, _sinceDate: Date, _publisher?: {});
|
|
18
|
-
toString(): string;
|
|
19
|
-
}
|
|
1
|
+
import { SeasonFederation } from './interfaces';
|
|
2
|
+
import { ItemFamilyChanges } from './item-family-changes';
|
|
3
|
+
export declare class PublishChangeData {
|
|
4
|
+
private _assortmentId;
|
|
5
|
+
get assortmentId(): string;
|
|
6
|
+
private _seasonFed;
|
|
7
|
+
get seasonFed(): SeasonFederation;
|
|
8
|
+
private _assortmentPublishChangeId;
|
|
9
|
+
get assortmentPublishChangeId(): string;
|
|
10
|
+
private _sinceDate;
|
|
11
|
+
get sinceDate(): Date;
|
|
12
|
+
private _publisher;
|
|
13
|
+
get publisher(): object;
|
|
14
|
+
itemToFederatedIdMapping: Map<string, string>;
|
|
15
|
+
releasedForDevelopmentItemIds: string[];
|
|
16
|
+
itemFamilyChanges: Map<string, ItemFamilyChanges>;
|
|
17
|
+
constructor(_assortmentId: string, _seasonFed: SeasonFederation, _assortmentPublishChangeId: string, _sinceDate: Date, _publisher?: {});
|
|
18
|
+
toString(): string;
|
|
19
|
+
}
|