@contrail/flexplm 1.1.12 → 1.1.14
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/.github/pull_request_template.md +30 -0
- package/.github/workflows/flexplm-lib.yml +27 -0
- package/lib/flexplm-utils.spec.d.ts +1 -0
- package/lib/flexplm-utils.spec.js +26 -0
- package/lib/publish/base-process-publish-assortment.js +2 -4
- package/lib/publish/base-process-publish-assortment.spec.d.ts +1 -0
- package/lib/publish/base-process-publish-assortment.spec.js +1053 -0
- package/lib/util/config-defaults.spec.d.ts +1 -0
- package/lib/util/config-defaults.spec.js +264 -0
- package/lib/util/data-converter.spec.d.ts +1 -0
- package/lib/util/data-converter.spec.js +591 -0
- package/lib/util/map-utils.d.ts +2 -2
- package/lib/util/map-utils.js +5 -28
- package/lib/util/map-utils.spec.d.ts +1 -0
- package/lib/util/map-utils.spec.js +89 -0
- package/lib/util/thumbnail-util.spec.d.ts +1 -0
- package/lib/util/thumbnail-util.spec.js +132 -0
- package/lib/util/type-conversion-utils-spec-mockData.js +21 -0
- package/lib/util/type-conversion-utils.d.ts +7 -0
- package/lib/util/type-conversion-utils.js +88 -4
- package/lib/util/type-conversion-utils.spec.d.ts +1 -0
- package/lib/util/type-conversion-utils.spec.js +547 -0
- package/lib/util/type-defaults.d.ts +5 -0
- package/lib/util/type-defaults.js +66 -0
- package/lib/util/type-defaults.spec.d.ts +1 -0
- package/lib/util/type-defaults.spec.js +460 -0
- package/lib/util/type-utils.spec.d.ts +1 -0
- package/lib/util/type-utils.spec.js +190 -0
- package/package.json +2 -2
- package/publish.bat +5 -0
- package/publish.sh +5 -0
- package/src/entity-processor/base-entity-processor.ts +183 -0
- package/src/flexplm-request.ts +28 -0
- package/src/flexplm-utils.spec.ts +27 -0
- package/src/flexplm-utils.ts +29 -0
- package/src/index.ts +20 -0
- package/src/interfaces/interfaces.ts +120 -0
- package/src/interfaces/item-family-changes.ts +67 -0
- package/src/interfaces/publish-change-data.ts +43 -0
- package/src/publish/base-process-publish-assortment-callback.ts +23 -0
- package/src/publish/base-process-publish-assortment.spec.ts +1239 -0
- package/src/publish/base-process-publish-assortment.ts +1024 -0
- package/src/publish/mockData.ts +4561 -0
- package/src/transform/identifier-conversion.ts +226 -0
- package/src/util/config-defaults.spec.ts +315 -0
- package/src/util/config-defaults.ts +79 -0
- package/src/util/data-converter-spec-mockData.ts +231 -0
- package/src/util/data-converter.spec.ts +872 -0
- package/src/util/data-converter.ts +389 -0
- package/src/util/federation.ts +172 -0
- package/src/util/flexplm-connect.ts +169 -0
- package/src/util/logger-config.ts +20 -0
- package/src/util/map-util-spec-mockData.ts +231 -0
- package/src/util/map-utils.spec.ts +103 -0
- package/src/util/map-utils.ts +40 -0
- package/src/util/mockData.ts +98 -0
- package/src/util/thumbnail-util.spec.ts +152 -0
- package/src/util/thumbnail-util.ts +128 -0
- package/src/util/type-conversion-utils-spec-mockData.ts +238 -0
- package/src/util/type-conversion-utils.spec.ts +601 -0
- package/src/util/type-conversion-utils.ts +345 -0
- package/src/util/type-defaults.spec.ts +592 -0
- package/src/util/type-defaults.ts +261 -0
- package/src/util/type-utils.spec.ts +227 -0
- package/src/util/type-utils.ts +124 -0
- package/tsconfig.json +27 -0
- package/tslint.json +57 -0
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
import { MapFileUtil } from "@contrail/transform-data";
|
|
2
|
+
import { ProductFederation, SeasonFederation, SeasonGroupFederation, SkuFederation } from "../interfaces/interfaces";
|
|
3
|
+
import { MapUtil } from "../util/map-utils";
|
|
4
|
+
import { TypeConversionUtils } from "../util/type-conversion-utils";
|
|
5
|
+
import { DataConverter } from "../util/data-converter";
|
|
6
|
+
|
|
7
|
+
export class IdentifierConversion {
|
|
8
|
+
|
|
9
|
+
/** Takes in an assortment and returns an object to query for an LCSSeason
|
|
10
|
+
* This will only return the identifier properties, and information properties if specified.
|
|
11
|
+
* @param transformMapFile
|
|
12
|
+
* @param mapFileUtil
|
|
13
|
+
* @param dc
|
|
14
|
+
* @param assortment
|
|
15
|
+
* @param includeInformationKeys defaults true
|
|
16
|
+
* @returns
|
|
17
|
+
*/
|
|
18
|
+
static async getSeasonIdentityObject(transformMapFile: string, mapFileUtil: MapFileUtil, dc: DataConverter, assortment, includeInformationKeys = true): Promise<SeasonFederation>{
|
|
19
|
+
if(!assortment){
|
|
20
|
+
throw new Error('IdentifierConversion.getSeasonIdentityObject(): assortment must be provided.');
|
|
21
|
+
}
|
|
22
|
+
assortment['flex2vibeMapKeyRoot'] = 'LCSSeason';
|
|
23
|
+
const flexPLMTypePath = await TypeConversionUtils.getObjectTypePath(transformMapFile, mapFileUtil, assortment);
|
|
24
|
+
|
|
25
|
+
let seasonObj: any = {
|
|
26
|
+
entityReference: 'assortment:' + assortment?.id,
|
|
27
|
+
objectClass: 'LCSSeason' as const,
|
|
28
|
+
flexPLMTypePath
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
try{
|
|
32
|
+
const assortmentObj = await dc.getFlexPLMObjectData(assortment, [], true);
|
|
33
|
+
const identifierKeys: string[] = await TypeConversionUtils.getIdentifierProperties(transformMapFile, mapFileUtil, assortment);
|
|
34
|
+
for(const key of identifierKeys){
|
|
35
|
+
if(assortmentObj[key]){
|
|
36
|
+
seasonObj[key] = assortmentObj[key];
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
if(includeInformationKeys){
|
|
40
|
+
const informationKeys: string[] = await TypeConversionUtils
|
|
41
|
+
.getInformationalProperties(transformMapFile, mapFileUtil, assortment);
|
|
42
|
+
for(const key of informationKeys){
|
|
43
|
+
if(assortmentObj[key]){
|
|
44
|
+
seasonObj[key] = assortmentObj[key];
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
const objectKeys = Object.keys(seasonObj);
|
|
50
|
+
const hasAllIdentifiers = identifierKeys.every(key => objectKeys.includes(key));
|
|
51
|
+
if(!hasAllIdentifiers){
|
|
52
|
+
console.error('IdentifierConversion.getSeasonIdentityObject(): doesnt have all identifier properties - '+ identifierKeys);
|
|
53
|
+
console.error('assortment: ' + JSON.stringify(assortment));
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
const mapKey:string = await TypeConversionUtils
|
|
57
|
+
.getMapKey(transformMapFile, mapFileUtil, assortment, TypeConversionUtils.VIBE2FLEX_DIRECTION);
|
|
58
|
+
seasonObj = await MapUtil
|
|
59
|
+
.applyTransformMap(transformMapFile, mapFileUtil, seasonObj, mapKey, TypeConversionUtils.VIBE2FLEX_DIRECTION);
|
|
60
|
+
} finally {
|
|
61
|
+
delete assortment['flex2vibeMapKeyRoot'];
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
return seasonObj as SeasonFederation;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/** Takes in an assortment and returns an object to query for an SeasonGroup
|
|
68
|
+
* This will only return the identifier properties, and information properties if specified.
|
|
69
|
+
* @param transformMapFile
|
|
70
|
+
* @param mapFileUtil
|
|
71
|
+
* @param dc
|
|
72
|
+
* @param assortment
|
|
73
|
+
* @param includeInformationKeys defaults true
|
|
74
|
+
* @returns
|
|
75
|
+
*/
|
|
76
|
+
static async getSeasonGroupIdentityObject(transformMapFile: string, mapFileUtil: MapFileUtil, dc: DataConverter, assortment, includeInformationKeys = true): Promise<SeasonGroupFederation> {
|
|
77
|
+
if(!assortment){
|
|
78
|
+
throw new Error('IdentifierConversion.getSeasonGroupIdentityObject(): assortment must be provided.');
|
|
79
|
+
}
|
|
80
|
+
assortment['flex2vibeMapKeyRoot'] = 'SeasonGroup';
|
|
81
|
+
const flexPLMTypePath = await TypeConversionUtils.getObjectTypePath(transformMapFile, mapFileUtil, assortment);
|
|
82
|
+
|
|
83
|
+
let seasonGroupObj = {
|
|
84
|
+
entityReference: 'assortment:' + assortment?.id,
|
|
85
|
+
objectClass: 'SeasonGroup' as const,
|
|
86
|
+
flexPLMTypePath
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
try {
|
|
90
|
+
const assortmentObj = await dc.getFlexPLMObjectData(assortment, [], true);
|
|
91
|
+
|
|
92
|
+
const identifierKeys: string[] = await TypeConversionUtils
|
|
93
|
+
.getIdentifierProperties(transformMapFile, mapFileUtil, assortment);
|
|
94
|
+
for (const key of identifierKeys) {
|
|
95
|
+
if (assortmentObj[key]) {
|
|
96
|
+
seasonGroupObj[key] = assortmentObj[key];
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
if(includeInformationKeys){
|
|
101
|
+
const informationKeys: string[] = await TypeConversionUtils
|
|
102
|
+
.getInformationalProperties(transformMapFile, mapFileUtil, assortment);
|
|
103
|
+
for (const key of informationKeys) {
|
|
104
|
+
if (assortmentObj[key]) {
|
|
105
|
+
seasonGroupObj[key] = assortmentObj[key];
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
}
|
|
110
|
+
const objectKeys = Object.keys(seasonGroupObj);
|
|
111
|
+
const hasAllIdentifiers = identifierKeys.every(key => objectKeys.includes(key));
|
|
112
|
+
|
|
113
|
+
if (!hasAllIdentifiers) {
|
|
114
|
+
console.error('IdentifierConversion.getSeasonGroupIdentityObject(): doesnt have all identifier properties - '+ identifierKeys);
|
|
115
|
+
console.error('assortment: ' + JSON.stringify(assortment));
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
const mapKey: string = await TypeConversionUtils.getMapKey(transformMapFile, mapFileUtil, assortment, TypeConversionUtils.VIBE2FLEX_DIRECTION);
|
|
119
|
+
seasonGroupObj = await MapUtil.applyTransformMap(transformMapFile, mapFileUtil, seasonGroupObj, mapKey, TypeConversionUtils.VIBE2FLEX_DIRECTION);
|
|
120
|
+
|
|
121
|
+
} finally {
|
|
122
|
+
delete assortment['flex2vibeMapKeyRoot'];
|
|
123
|
+
}
|
|
124
|
+
return seasonGroupObj;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
/** Takes in an item and returns an object to query for an LCSProduct
|
|
128
|
+
* This will only return the identifier properties, and information properties if specified.
|
|
129
|
+
* @param transformMapFile
|
|
130
|
+
* @param mapFileUtil
|
|
131
|
+
* @param dc
|
|
132
|
+
* @param assortment
|
|
133
|
+
* @param includeInformationKeys defaults true
|
|
134
|
+
* @returns
|
|
135
|
+
*/
|
|
136
|
+
static async getProductIdentityObject(transformMapFile: string, mapFileUtil: MapFileUtil, dc: DataConverter, itemFamilyObject, includeInformationKeys = true): Promise<ProductFederation> {
|
|
137
|
+
if(!itemFamilyObject){
|
|
138
|
+
throw new Error('IdentifierConversion.getProductIdentityObject(): itemFamilyObject must be provided.');
|
|
139
|
+
}
|
|
140
|
+
const itemObj = await dc.getFlexPLMObjectData(itemFamilyObject, [], true);
|
|
141
|
+
const flexPLMTypePath = await TypeConversionUtils.getObjectTypePath(transformMapFile, mapFileUtil, itemFamilyObject);
|
|
142
|
+
let prodObj: ProductFederation = {
|
|
143
|
+
entityReference: 'item:' + itemFamilyObject?.id,
|
|
144
|
+
objectClass: 'LCSProduct' as const,
|
|
145
|
+
flexPLMTypePath
|
|
146
|
+
};
|
|
147
|
+
|
|
148
|
+
const identifierKeys: string[] = await TypeConversionUtils
|
|
149
|
+
.getIdentifierProperties(transformMapFile, mapFileUtil, itemFamilyObject);
|
|
150
|
+
for (const key of identifierKeys) {
|
|
151
|
+
if (itemObj[key]) {
|
|
152
|
+
prodObj[key] = itemObj[key];
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
if(includeInformationKeys){
|
|
157
|
+
const informationKeys: string[] = await TypeConversionUtils
|
|
158
|
+
.getInformationalProperties(transformMapFile, mapFileUtil, itemFamilyObject);
|
|
159
|
+
for (const key of informationKeys) {
|
|
160
|
+
if (itemObj[key]) {
|
|
161
|
+
prodObj[key] = itemObj[key];
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
const vibeIQIdentifier = 'vibeIQIdentifier';
|
|
167
|
+
if (!prodObj[vibeIQIdentifier]) {
|
|
168
|
+
prodObj['vibeIQIdentifier'] = itemFamilyObject['identifier'] || itemFamilyObject['itemNumber'];
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
const mapKey: string = await TypeConversionUtils
|
|
172
|
+
.getMapKey(transformMapFile, mapFileUtil, itemFamilyObject, TypeConversionUtils.VIBE2FLEX_DIRECTION);
|
|
173
|
+
prodObj = await MapUtil
|
|
174
|
+
.applyTransformMap(transformMapFile, mapFileUtil, prodObj, mapKey, TypeConversionUtils.VIBE2FLEX_DIRECTION);
|
|
175
|
+
|
|
176
|
+
return prodObj as ProductFederation;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
/** Takes in an item and returns an object to query for an LCSSKU
|
|
180
|
+
* This will only return the identifier properties, and information properties if specified.
|
|
181
|
+
* @param transformMapFile
|
|
182
|
+
* @param mapFileUtil
|
|
183
|
+
* @param dc
|
|
184
|
+
* @param assortment
|
|
185
|
+
* @param includeInformationKeys defaults true
|
|
186
|
+
* @returns
|
|
187
|
+
*/
|
|
188
|
+
static async getSKUIdentityObject(transformMapFile: string, mapFileUtil: MapFileUtil, dc: DataConverter, itemObject, includeInformationKeys = true): Promise<SkuFederation> {
|
|
189
|
+
if(!itemObject){
|
|
190
|
+
throw new Error('IdentifierConversion.getSKUIdentityObject(): itemObject must be provided.');
|
|
191
|
+
}
|
|
192
|
+
const itemObj = await dc.getFlexPLMObjectData(itemObject, [], true);
|
|
193
|
+
const flexPLMTypePath = await TypeConversionUtils.getObjectTypePath(transformMapFile, mapFileUtil, itemObject);
|
|
194
|
+
let skuObj: SkuFederation = {
|
|
195
|
+
entityReference: 'item:' + itemObject?.id,
|
|
196
|
+
objectClass: 'LCSSKU' as const,
|
|
197
|
+
flexPLMTypePath
|
|
198
|
+
};
|
|
199
|
+
|
|
200
|
+
const identifierKeys: string[] = await TypeConversionUtils.getIdentifierProperties(transformMapFile, mapFileUtil, itemObject);
|
|
201
|
+
for (const key of identifierKeys) {
|
|
202
|
+
if (itemObj[key]) {
|
|
203
|
+
skuObj[key] = itemObj[key];
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
if(includeInformationKeys){
|
|
208
|
+
const informationKeys: string[] = await TypeConversionUtils.getInformationalProperties(transformMapFile, mapFileUtil, itemObject);
|
|
209
|
+
for (const key of informationKeys) {
|
|
210
|
+
if (itemObj[key]) {
|
|
211
|
+
skuObj[key] = itemObj[key];
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
const vibeIQIdentifier = 'vibeIQIdentifier';
|
|
217
|
+
if (!skuObj[vibeIQIdentifier]) {
|
|
218
|
+
skuObj['vibeIQIdentifier'] = itemObject['identifier'] || itemObject['itemNumber'];
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
const mapKey: string = await TypeConversionUtils.getMapKey(transformMapFile, mapFileUtil, itemObject, TypeConversionUtils.VIBE2FLEX_DIRECTION);
|
|
222
|
+
skuObj = await MapUtil.applyTransformMap(transformMapFile, mapFileUtil, skuObj, mapKey, TypeConversionUtils.VIBE2FLEX_DIRECTION);
|
|
223
|
+
|
|
224
|
+
return skuObj as SkuFederation;
|
|
225
|
+
}
|
|
226
|
+
}
|
|
@@ -0,0 +1,315 @@
|
|
|
1
|
+
import { ConfigDefaults } from './config-defaults';
|
|
2
|
+
import { FCConfig } from '../interfaces/interfaces';
|
|
3
|
+
|
|
4
|
+
let entityObject = {};
|
|
5
|
+
jest.mock('@contrail/sdk', () => {
|
|
6
|
+
return {
|
|
7
|
+
Entities: class {
|
|
8
|
+
get() {
|
|
9
|
+
return entityObject;
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
};
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
let fetchJson = {};
|
|
16
|
+
global.fetch = jest.fn().mockImplementation(() => {
|
|
17
|
+
return Promise.resolve({
|
|
18
|
+
json: () => Promise.resolve(fetchJson)
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
describe('all tests', () => {
|
|
24
|
+
describe('setConfigDefaults - required values', () => {
|
|
25
|
+
it('missing apiHost', async () => {
|
|
26
|
+
const config = {
|
|
27
|
+
//apiHost: 'http://test.com',
|
|
28
|
+
userName: 'vibeiq',
|
|
29
|
+
password: 'vibeiq',
|
|
30
|
+
plmEnviornment: 'SB'
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
try {
|
|
34
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars, unused-imports/no-unused-vars
|
|
35
|
+
const fcConfig: FCConfig = await ConfigDefaults.setConfigDefaults(config);
|
|
36
|
+
|
|
37
|
+
} catch (e) {
|
|
38
|
+
expect(e.message).toEqual(ConfigDefaults.NEED_CONFIG_VALUES);
|
|
39
|
+
}
|
|
40
|
+
});
|
|
41
|
+
it('missing userName', async () => {
|
|
42
|
+
const config = {
|
|
43
|
+
apiHost: 'http://test.com',
|
|
44
|
+
//userName: 'vibeiq',
|
|
45
|
+
password: 'vibeiq',
|
|
46
|
+
plmEnviornment: 'SB'
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
try {
|
|
50
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars, unused-imports/no-unused-vars
|
|
51
|
+
const fcConfig: FCConfig = await ConfigDefaults.setConfigDefaults(config);
|
|
52
|
+
|
|
53
|
+
} catch (e) {
|
|
54
|
+
expect(e.message).toEqual(ConfigDefaults.NEED_CONFIG_VALUES);
|
|
55
|
+
}
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
it('missing password', async () => {
|
|
59
|
+
const config = {
|
|
60
|
+
apiHost: 'http://test.com',
|
|
61
|
+
userName: 'vibeiq',
|
|
62
|
+
//password: 'vibeiq',
|
|
63
|
+
plmEnviornment: 'SB'
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
try {
|
|
67
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars, unused-imports/no-unused-vars
|
|
68
|
+
const fcConfig: FCConfig = await ConfigDefaults.setConfigDefaults(config);
|
|
69
|
+
|
|
70
|
+
} catch (e) {
|
|
71
|
+
expect(e.message).toEqual(ConfigDefaults.NEED_CONFIG_VALUES);
|
|
72
|
+
}
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
it('missing plmEnviornment', async () => {
|
|
76
|
+
const config = {
|
|
77
|
+
apiHost: 'http://test.com',
|
|
78
|
+
userName: 'vibeiq',
|
|
79
|
+
password: 'vibeiq',
|
|
80
|
+
//plmEnviornment: 'SB'
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
try {
|
|
84
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars, unused-imports/no-unused-vars
|
|
85
|
+
const fcConfig: FCConfig = await ConfigDefaults.setConfigDefaults(config);
|
|
86
|
+
|
|
87
|
+
} catch (e) {
|
|
88
|
+
expect(e.message).toEqual(ConfigDefaults.NEED_CONFIG_VALUES);
|
|
89
|
+
}
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
describe('userName & password as functions', () =>{
|
|
95
|
+
const config = {
|
|
96
|
+
apiHost: 'http://test.com',
|
|
97
|
+
userName: 'vibeiq',
|
|
98
|
+
password: 'vibeiq',
|
|
99
|
+
plmEnviornment: 'SB'
|
|
100
|
+
};
|
|
101
|
+
it('userName as function', async () =>{
|
|
102
|
+
const startConfig = Object.assign({}, config, { userName: 'newName' });
|
|
103
|
+
const fcConfig = await ConfigDefaults.setConfigDefaults(startConfig);
|
|
104
|
+
expect(fcConfig.userName()).toEqual('newName');
|
|
105
|
+
|
|
106
|
+
});
|
|
107
|
+
it('password as function', async () =>{
|
|
108
|
+
const startConfig = Object.assign({}, config, { password: 'strange' });
|
|
109
|
+
const fcConfig = await ConfigDefaults.setConfigDefaults(startConfig);
|
|
110
|
+
expect(fcConfig.password()).toEqual('strange');
|
|
111
|
+
|
|
112
|
+
});
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
describe('setConfigDefaults-setting defaults', () => {
|
|
116
|
+
const config = {
|
|
117
|
+
apiHost: 'http://test.com',
|
|
118
|
+
userName: 'vibeiq',
|
|
119
|
+
password: 'vibeiq',
|
|
120
|
+
plmEnviornment: 'SB'
|
|
121
|
+
};
|
|
122
|
+
it('urlContext-get default', async () => {
|
|
123
|
+
const startConfig = Object.assign({}, config);
|
|
124
|
+
const fcConfig = await ConfigDefaults.setConfigDefaults(startConfig);
|
|
125
|
+
expect(fcConfig.urlContext).toEqual('/Windchill');
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
it('urlContext-set value', async () => {
|
|
129
|
+
const startConfig = Object.assign({}, config);
|
|
130
|
+
startConfig['urlContext'] = '/FlexPLM';
|
|
131
|
+
const fcConfig = await ConfigDefaults.setConfigDefaults(startConfig);
|
|
132
|
+
expect(fcConfig.urlContext).toEqual('/FlexPLM');
|
|
133
|
+
});
|
|
134
|
+
|
|
135
|
+
it('sendMode-ASYNC_PUBLISH_SEASON-get default', async () => {
|
|
136
|
+
const startConfig = Object.assign({}, config);
|
|
137
|
+
const fcConfig: FCConfig = await ConfigDefaults.setConfigDefaults(startConfig);
|
|
138
|
+
expect(fcConfig['sendMode']['ASYNC_PUBLISH_SEASON']).toEqual('vibeiqfile');
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
it('sendMode-ASYNC_PUBLISH_SEASON-set value', async () => {
|
|
142
|
+
const startConfig = Object.assign({}, config);
|
|
143
|
+
startConfig['sendMode'] = { ASYNC_PUBLISH_SEASON: 'vibeiqfile-dontsendtoflexplm' };
|
|
144
|
+
const fcConfig: FCConfig = await ConfigDefaults.setConfigDefaults(startConfig);
|
|
145
|
+
expect(fcConfig['sendMode']['ASYNC_PUBLISH_SEASON']).toEqual('vibeiqfile-dontsendtoflexplm');
|
|
146
|
+
});
|
|
147
|
+
|
|
148
|
+
it('sendMode-NO_DEFAULT-get default', async () => {
|
|
149
|
+
const startConfig = Object.assign({}, config);
|
|
150
|
+
const fcConfig: FCConfig = await ConfigDefaults.setConfigDefaults(startConfig);
|
|
151
|
+
expect(fcConfig['sendMode']['NO_DEFAULT']).toBeUndefined();
|
|
152
|
+
});
|
|
153
|
+
|
|
154
|
+
it('sendMode-NO_DEFAULT-set value', async () => {
|
|
155
|
+
const startConfig = Object.assign({}, config);
|
|
156
|
+
startConfig['sendMode'] = { NO_DEFAULT: 'vibeiqfile-dontsendtoflexplm' };
|
|
157
|
+
const fcConfig: FCConfig = await ConfigDefaults.setConfigDefaults(startConfig);
|
|
158
|
+
expect(fcConfig['sendMode']['NO_DEFAULT']).toEqual('vibeiqfile-dontsendtoflexplm');
|
|
159
|
+
});
|
|
160
|
+
|
|
161
|
+
it('itemPreDevelopmentLifecycleStages-get default', async () => {
|
|
162
|
+
const startConfig = Object.assign({}, config);
|
|
163
|
+
const fcConfig: FCConfig = await ConfigDefaults.setConfigDefaults(startConfig);
|
|
164
|
+
expect(fcConfig['itemPreDevelopmentLifecycleStages']).toEqual(['concept']);
|
|
165
|
+
});
|
|
166
|
+
|
|
167
|
+
it('itemPreDevelopmentLifecycleStages-set value', async () => {
|
|
168
|
+
const startConfig = Object.assign({}, config);
|
|
169
|
+
const concept = 'concept';
|
|
170
|
+
const development = 'development';
|
|
171
|
+
startConfig['itemPreDevelopmentLifecycleStages'] = concept + ',' + development;
|
|
172
|
+
const fcConfig: FCConfig = await ConfigDefaults.setConfigDefaults(startConfig);
|
|
173
|
+
const itemPreDevelopmentLifecycleStages = fcConfig['itemPreDevelopmentLifecycleStages'];
|
|
174
|
+
expect(itemPreDevelopmentLifecycleStages instanceof Array).toBeTruthy();
|
|
175
|
+
expect(itemPreDevelopmentLifecycleStages.length).toBe(2);
|
|
176
|
+
expect(itemPreDevelopmentLifecycleStages.includes(concept));
|
|
177
|
+
expect(itemPreDevelopmentLifecycleStages.includes(development));
|
|
178
|
+
});
|
|
179
|
+
|
|
180
|
+
it('itemPreDevelopmentLifecycleStages-set value with space', async () => {
|
|
181
|
+
const startConfig = Object.assign({}, config);
|
|
182
|
+
const concept = 'concept';
|
|
183
|
+
const development = 'development';
|
|
184
|
+
startConfig['itemPreDevelopmentLifecycleStages'] = concept + ', ' + development;
|
|
185
|
+
const fcConfig: FCConfig = await ConfigDefaults.setConfigDefaults(startConfig);
|
|
186
|
+
const itemPreDevelopmentLifecycleStages = fcConfig['itemPreDevelopmentLifecycleStages'];
|
|
187
|
+
expect(itemPreDevelopmentLifecycleStages instanceof Array).toBeTruthy();
|
|
188
|
+
expect(itemPreDevelopmentLifecycleStages.length).toBe(2);
|
|
189
|
+
expect(itemPreDevelopmentLifecycleStages.includes(concept));
|
|
190
|
+
expect(itemPreDevelopmentLifecycleStages.includes(development));
|
|
191
|
+
});
|
|
192
|
+
|
|
193
|
+
it('identifierAtts-LCSProduct-get default', async () => {
|
|
194
|
+
const startConfig = Object.assign({}, config);
|
|
195
|
+
const objectClass = 'LCSProduct';
|
|
196
|
+
const expectedAtts = ['name'];
|
|
197
|
+
|
|
198
|
+
const fcConfig = await ConfigDefaults.setConfigDefaults(startConfig);
|
|
199
|
+
const identifierAtts = fcConfig.identifierAtts[objectClass];
|
|
200
|
+
expect(identifierAtts instanceof Array).toBeTruthy();
|
|
201
|
+
expect(identifierAtts.length).toBe(expectedAtts.length);
|
|
202
|
+
for (const att of expectedAtts) {
|
|
203
|
+
expect(identifierAtts.includes(att));
|
|
204
|
+
}
|
|
205
|
+
});
|
|
206
|
+
|
|
207
|
+
it('identifierAtts-LCSProduct-set value', async () => {
|
|
208
|
+
const startConfig = Object.assign({}, config);
|
|
209
|
+
const objectClass = 'LCSProduct';
|
|
210
|
+
const expectedAtts = ['val1', 'val2'];
|
|
211
|
+
startConfig['identifierAtts'] = {};
|
|
212
|
+
startConfig['identifierAtts'][objectClass] = expectedAtts;
|
|
213
|
+
|
|
214
|
+
const fcConfig = await ConfigDefaults.setConfigDefaults(startConfig);
|
|
215
|
+
const identifierAtts = fcConfig.identifierAtts[objectClass];
|
|
216
|
+
expect(identifierAtts instanceof Array).toBeTruthy();
|
|
217
|
+
expect(identifierAtts.length).toBe(expectedAtts.length);
|
|
218
|
+
for (const att of expectedAtts) {
|
|
219
|
+
expect(identifierAtts.includes(att));
|
|
220
|
+
}
|
|
221
|
+
});
|
|
222
|
+
|
|
223
|
+
it('identifierAtts-LCSSeason-get default', async () => {
|
|
224
|
+
const startConfig = Object.assign({}, config);
|
|
225
|
+
const objectClass = 'LCSSeason';
|
|
226
|
+
const expectedAtts = ['flexPLMSeasonName'];
|
|
227
|
+
// const expectedAtts =['seasonType', 'seasonYear'];
|
|
228
|
+
|
|
229
|
+
const fcConfig = await ConfigDefaults.setConfigDefaults(startConfig);
|
|
230
|
+
const identifierAtts = fcConfig.identifierAtts[objectClass];
|
|
231
|
+
expect(identifierAtts instanceof Array).toBeTruthy();
|
|
232
|
+
expect(identifierAtts.length).toBe(expectedAtts.length);
|
|
233
|
+
for (const att of expectedAtts) {
|
|
234
|
+
expect(identifierAtts.includes(att));
|
|
235
|
+
}
|
|
236
|
+
});
|
|
237
|
+
|
|
238
|
+
it('identifierAtts-LCSSeason-set value', async () => {
|
|
239
|
+
const startConfig = Object.assign({}, config);
|
|
240
|
+
const objectClass = 'LCSSeason';
|
|
241
|
+
const expectedAtts = ['val1', 'val2'];
|
|
242
|
+
startConfig['identifierAtts'] = {};
|
|
243
|
+
startConfig['identifierAtts'][objectClass] = expectedAtts;
|
|
244
|
+
|
|
245
|
+
const fcConfig = await ConfigDefaults.setConfigDefaults(startConfig);
|
|
246
|
+
const identifierAtts = fcConfig.identifierAtts[objectClass];
|
|
247
|
+
expect(identifierAtts instanceof Array).toBeTruthy();
|
|
248
|
+
expect(identifierAtts.length).toBe(expectedAtts.length);
|
|
249
|
+
for (const att of expectedAtts) {
|
|
250
|
+
expect(identifierAtts.includes(att));
|
|
251
|
+
}
|
|
252
|
+
});
|
|
253
|
+
|
|
254
|
+
it('identifierAtts-LCSSKU-get default', async () => {
|
|
255
|
+
const startConfig = Object.assign({}, config);
|
|
256
|
+
const objectClass = 'LCSSKU';
|
|
257
|
+
const expectedAtts = ['optionName'];
|
|
258
|
+
|
|
259
|
+
const fcConfig = await ConfigDefaults.setConfigDefaults(startConfig);
|
|
260
|
+
const identifierAtts = fcConfig.identifierAtts[objectClass];
|
|
261
|
+
expect(identifierAtts instanceof Array).toBeTruthy();
|
|
262
|
+
expect(identifierAtts.length).toBe(expectedAtts.length);
|
|
263
|
+
for (const att of expectedAtts) {
|
|
264
|
+
expect(identifierAtts.includes(att));
|
|
265
|
+
}
|
|
266
|
+
});
|
|
267
|
+
|
|
268
|
+
it('identifierAtts-LCSSKU-set value', async () => {
|
|
269
|
+
const startConfig = Object.assign({}, config);
|
|
270
|
+
const objectClass = 'LCSSKU';
|
|
271
|
+
const expectedAtts = ['val1', 'val2'];
|
|
272
|
+
startConfig['identifierAtts'] = {};
|
|
273
|
+
startConfig['identifierAtts'][objectClass] = expectedAtts;
|
|
274
|
+
|
|
275
|
+
const fcConfig = await ConfigDefaults.setConfigDefaults(startConfig);
|
|
276
|
+
const identifierAtts = fcConfig.identifierAtts[objectClass];
|
|
277
|
+
expect(identifierAtts instanceof Array).toBeTruthy();
|
|
278
|
+
expect(identifierAtts.length).toBe(expectedAtts.length);
|
|
279
|
+
for (const att of expectedAtts) {
|
|
280
|
+
expect(identifierAtts.includes(att));
|
|
281
|
+
}
|
|
282
|
+
});
|
|
283
|
+
|
|
284
|
+
});
|
|
285
|
+
|
|
286
|
+
describe('getConfigFile', () => {
|
|
287
|
+
it('response has test var', async () => {
|
|
288
|
+
fetchJson = { testVar: true };
|
|
289
|
+
entityObject = { downloadUrl: 'http://sss.com' };
|
|
290
|
+
|
|
291
|
+
const config = await ConfigDefaults.getConfigFile('id-1');
|
|
292
|
+
expect(config).toBeDefined();
|
|
293
|
+
expect(config['testVar']).toBeTruthy();
|
|
294
|
+
});
|
|
295
|
+
|
|
296
|
+
it('undefined file object', async () => {
|
|
297
|
+
fetchJson = { testVar: true };
|
|
298
|
+
entityObject = undefined;
|
|
299
|
+
|
|
300
|
+
const config = await ConfigDefaults.getConfigFile('id-1');
|
|
301
|
+
expect(config).toBeDefined();
|
|
302
|
+
expect(Object.keys(config).length).toEqual(0);
|
|
303
|
+
});
|
|
304
|
+
|
|
305
|
+
it('response no downloadUrl', async () => {
|
|
306
|
+
fetchJson = { testVar: true };
|
|
307
|
+
entityObject = { };
|
|
308
|
+
|
|
309
|
+
const config = await ConfigDefaults.getConfigFile('id-1');
|
|
310
|
+
expect(config).toBeDefined();
|
|
311
|
+
expect(Object.keys(config).length).toEqual(0);
|
|
312
|
+
});
|
|
313
|
+
|
|
314
|
+
});
|
|
315
|
+
});
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { Entities } from '@contrail/sdk';
|
|
2
|
+
import { FCConfig } from '../interfaces/interfaces';
|
|
3
|
+
import { ObjectUtil } from '@contrail/util';
|
|
4
|
+
|
|
5
|
+
export class ConfigDefaults {
|
|
6
|
+
static NEED_CONFIG_VALUES = 'To connect to FlexPLM all these APP values need to be set apiHost, userName, and password';
|
|
7
|
+
static async setConfigDefaults(config): Promise<FCConfig> {
|
|
8
|
+
//Validate config
|
|
9
|
+
if (!config.apiHost || !config.userName || !config.password) {
|
|
10
|
+
throw new Error(ConfigDefaults.NEED_CONFIG_VALUES);
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
//List will be comma separated list in UI, so convert to array
|
|
14
|
+
if(config?.itemPreDevelopmentLifecycleStages && !(config?.itemPreDevelopmentLifecycleStages instanceof Array)){
|
|
15
|
+
config.itemPreDevelopmentLifecycleStages = config.itemPreDevelopmentLifecycleStages.split(',');
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
const defaultConfig = {
|
|
19
|
+
urlContext: '/Windchill',
|
|
20
|
+
sendMode: {
|
|
21
|
+
ASYNC_PUBLISH_SEASON: 'vibeiqfile'
|
|
22
|
+
},
|
|
23
|
+
itemPreDevelopmentLifecycleStages: ['concept'],
|
|
24
|
+
identifierAtts: {
|
|
25
|
+
LCSProduct: ['itemNumber'],
|
|
26
|
+
LCSSeason: ['flexPLMSeasonName'],
|
|
27
|
+
LCSSKU: ['itemNumber']
|
|
28
|
+
},
|
|
29
|
+
csrfEndpoint: '/servlet/rest/security/csrf',
|
|
30
|
+
vibeEventEndpoint: '/rfa/vibeiq/vibeEvents',
|
|
31
|
+
payloadDefaultAsArray: true
|
|
32
|
+
};
|
|
33
|
+
const configArr = [defaultConfig];
|
|
34
|
+
|
|
35
|
+
if(config.configFile){
|
|
36
|
+
const fileConfig = await ConfigDefaults.getConfigFile(config.configFile);
|
|
37
|
+
configArr.push(fileConfig);
|
|
38
|
+
}
|
|
39
|
+
configArr.push(config);
|
|
40
|
+
const outputConfig = ObjectUtil.mergeDeep({}, ...configArr);
|
|
41
|
+
const uName = outputConfig.userName;
|
|
42
|
+
const pass = outputConfig.password;
|
|
43
|
+
outputConfig.userName = () => uName;
|
|
44
|
+
outputConfig.password = () => pass;
|
|
45
|
+
|
|
46
|
+
//Don't allow overwriting this.
|
|
47
|
+
outputConfig['OOBvibeEventEndpoint'] = '/rfa/vibeiq/vibeEvents';
|
|
48
|
+
|
|
49
|
+
console.log('outputConfig: ' + JSON.stringify(outputConfig));
|
|
50
|
+
return outputConfig as FCConfig;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
static async getConfigFile(fileId: string) {
|
|
54
|
+
try {
|
|
55
|
+
|
|
56
|
+
const options = {
|
|
57
|
+
entityName: 'file',
|
|
58
|
+
id: fileId,
|
|
59
|
+
};
|
|
60
|
+
const file = await new Entities().get(options);
|
|
61
|
+
if (!file){
|
|
62
|
+
console.log('failed to find file with id: ' + fileId);
|
|
63
|
+
return {};
|
|
64
|
+
}
|
|
65
|
+
const downloadUrl = file['downloadUrl'];
|
|
66
|
+
|
|
67
|
+
if(!downloadUrl){
|
|
68
|
+
console.log('file didnt have downloadUrl. fileId: ' + fileId);
|
|
69
|
+
return {};
|
|
70
|
+
}
|
|
71
|
+
const response = await fetch(downloadUrl);
|
|
72
|
+
const config = await response.json();
|
|
73
|
+
return config ? config: {};
|
|
74
|
+
}catch(e){
|
|
75
|
+
console.log('Error getting config file: ' + fileId + '- ' +e.message);
|
|
76
|
+
return {};
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|