@contrail/flexplm 1.1.58 → 1.1.60
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/entity-processor/base-entity-processor.d.ts +1 -0
- package/lib/entity-processor/base-entity-processor.js +16 -3
- package/lib/entity-processor/base-entity-processor.spec.js +56 -2
- package/lib/util/data-converter.js +1 -1
- package/lib/util/data-converter.spec.js +1 -1
- package/package.json +5 -4
- package/src/entity-processor/base-entity-processor.spec.ts +63 -3
- package/src/entity-processor/base-entity-processor.ts +28 -4
- package/src/util/data-converter.spec.ts +1 -1
- package/src/util/data-converter.ts +1 -1
|
@@ -20,6 +20,7 @@ export declare abstract class BaseEntityProcessor {
|
|
|
20
20
|
handleIncomingUpsert(event: EntityPayloadType): Promise<any>;
|
|
21
21
|
getInboundStatusMessage(statusObject: any): string;
|
|
22
22
|
queryEntityWithSubTypeCriteria(entityType: string, entityTypePath: string, propertyCriteria: any): Promise<any[]>;
|
|
23
|
+
getCriteriaForEntity(entityType: string, entityTypePath: string, propertyCriteria: any): Promise<any>;
|
|
23
24
|
getRootTypePropertyKeys(rootType: any, propertyCriteria?: any): string[];
|
|
24
25
|
handleIncomingDelete(event: any): Promise<void>;
|
|
25
26
|
getTransformedData(event: any): Promise<any>;
|
|
@@ -115,6 +115,17 @@ class BaseEntityProcessor {
|
|
|
115
115
|
+ ', orgSlug: ' + this.orgSlug;
|
|
116
116
|
}
|
|
117
117
|
async queryEntityWithSubTypeCriteria(entityType, entityTypePath, propertyCriteria) {
|
|
118
|
+
if (!entityType || !entityTypePath) {
|
|
119
|
+
throw new Error('type and entityTypePath must be defined');
|
|
120
|
+
}
|
|
121
|
+
if (!propertyCriteria || Object.getOwnPropertyNames(propertyCriteria).length == 0) {
|
|
122
|
+
throw new Error('propertyCriteria must be defined and have at least one property');
|
|
123
|
+
}
|
|
124
|
+
const { rootTypeCriteria, subTypeCriteria } = await this.getCriteriaForEntity(entityType, entityTypePath, propertyCriteria);
|
|
125
|
+
const returnedEntities = await this.dc.getAllObjectReferences(entityType, rootTypeCriteria, subTypeCriteria);
|
|
126
|
+
return returnedEntities;
|
|
127
|
+
}
|
|
128
|
+
async getCriteriaForEntity(entityType, entityTypePath, propertyCriteria) {
|
|
118
129
|
if (!entityType || !entityTypePath) {
|
|
119
130
|
throw new Error('type and entityTypePath must be defined');
|
|
120
131
|
}
|
|
@@ -123,8 +134,11 @@ class BaseEntityProcessor {
|
|
|
123
134
|
}
|
|
124
135
|
const rootType = await this.typeUtil.getByRootAndPath({ root: entityType });
|
|
125
136
|
const rootTypePropertyKeys = await this.getRootTypePropertyKeys(rootType, propertyCriteria);
|
|
126
|
-
const rootTypeCriteria = {
|
|
137
|
+
const rootTypeCriteria = {};
|
|
127
138
|
const subTypeCriteria = {};
|
|
139
|
+
if (entityType !== entityTypePath) {
|
|
140
|
+
subTypeCriteria['typePath'] = entityTypePath;
|
|
141
|
+
}
|
|
128
142
|
for (const key in propertyCriteria) {
|
|
129
143
|
if (rootTypePropertyKeys.includes(key)) {
|
|
130
144
|
rootTypeCriteria[key] = propertyCriteria[key];
|
|
@@ -133,8 +147,7 @@ class BaseEntityProcessor {
|
|
|
133
147
|
subTypeCriteria[key] = propertyCriteria[key];
|
|
134
148
|
}
|
|
135
149
|
}
|
|
136
|
-
|
|
137
|
-
return returnedEntities;
|
|
150
|
+
return { rootTypeCriteria, subTypeCriteria };
|
|
138
151
|
}
|
|
139
152
|
getRootTypePropertyKeys(rootType, propertyCriteria = null) {
|
|
140
153
|
const props = rootType['typeProperties'];
|
|
@@ -96,6 +96,7 @@ describe('BaseEntityProcessor', () => {
|
|
|
96
96
|
const config = {};
|
|
97
97
|
const mapFileUtil = new transform_data_1.MapFileUtil(new sdk_1.Entities());
|
|
98
98
|
beforeEach(() => {
|
|
99
|
+
jest.clearAllMocks();
|
|
99
100
|
});
|
|
100
101
|
it('entity parameter not set', async () => {
|
|
101
102
|
const btep = new TestBaseEntityProcessor({}, {}, {}, 'test');
|
|
@@ -127,10 +128,11 @@ describe('BaseEntityProcessor', () => {
|
|
|
127
128
|
rootText: 'root'
|
|
128
129
|
};
|
|
129
130
|
const subCriteria = {
|
|
130
|
-
sampleText: 'sample'
|
|
131
|
+
sampleText: 'sample',
|
|
132
|
+
typePath: entityTypePath
|
|
131
133
|
};
|
|
132
134
|
const propertyCriteria = Object.assign({}, rootCriteria, subCriteria);
|
|
133
|
-
const rootCriteriaResults = Object.assign({
|
|
135
|
+
const rootCriteriaResults = Object.assign({}, rootCriteria);
|
|
134
136
|
const mockGetByRootTypeProperties = jest.spyOn(btep, 'getRootTypePropertyKeys').mockReturnValue(['rootText']);
|
|
135
137
|
const mockDCgetAllObjectReferences = jest.spyOn(dc, 'getAllObjectReferences').mockReturnValue(Promise.resolve([]));
|
|
136
138
|
const results = await btep.queryEntityWithSubTypeCriteria(entityType, entityTypePath, propertyCriteria);
|
|
@@ -143,6 +145,58 @@ describe('BaseEntityProcessor', () => {
|
|
|
143
145
|
expect(mockDCgetAllObjectReferences).toBeCalledWith(entityType, rootCriteriaResults, subCriteria);
|
|
144
146
|
});
|
|
145
147
|
});
|
|
148
|
+
describe('getCriteriaForEntity', () => {
|
|
149
|
+
const config = {};
|
|
150
|
+
const mapFileUtil = new transform_data_1.MapFileUtil(new sdk_1.Entities());
|
|
151
|
+
beforeEach(() => {
|
|
152
|
+
jest.clearAllMocks();
|
|
153
|
+
});
|
|
154
|
+
it('entity parameter not set', async () => {
|
|
155
|
+
const btep = new TestBaseEntityProcessor({}, {}, {}, 'test');
|
|
156
|
+
const entity = '';
|
|
157
|
+
const subType = 'test';
|
|
158
|
+
const propertyCriteria = { a: 'val' };
|
|
159
|
+
expect(async () => { await btep.getCriteriaForEntity(entity, subType, propertyCriteria); }).rejects.toThrow();
|
|
160
|
+
});
|
|
161
|
+
it('entityTypePath not set', async () => {
|
|
162
|
+
const btep = new TestBaseEntityProcessor({}, {}, {}, 'test');
|
|
163
|
+
const entity = 'test';
|
|
164
|
+
const subType = '';
|
|
165
|
+
const propertyCriteria = {};
|
|
166
|
+
expect(async () => { await btep.getCriteriaForEntity(entity, subType, propertyCriteria); }).rejects.toThrow();
|
|
167
|
+
});
|
|
168
|
+
it('propertyCriteria not set', async () => {
|
|
169
|
+
const btep = new TestBaseEntityProcessor({}, {}, {}, 'test');
|
|
170
|
+
const entity = 'test';
|
|
171
|
+
const subType = 'test';
|
|
172
|
+
const propertyCriteria = {};
|
|
173
|
+
expect(async () => { await btep.getCriteriaForEntity(entity, subType, propertyCriteria); }).rejects.toThrow();
|
|
174
|
+
});
|
|
175
|
+
it('basic getCriteriaForEntity test', async () => {
|
|
176
|
+
const dc = new data_converter_1.DataConverter(config, mapFileUtil);
|
|
177
|
+
const btep = new TestBaseEntityProcessor(config, dc, mapFileUtil, 'test');
|
|
178
|
+
const entityType = 'custom-entity';
|
|
179
|
+
const entityTypePath = 'custom-entity:sample';
|
|
180
|
+
const rootCriteria = {
|
|
181
|
+
rootText: 'root'
|
|
182
|
+
};
|
|
183
|
+
const subCriteria = {
|
|
184
|
+
sampleText: 'sample',
|
|
185
|
+
typePath: entityTypePath
|
|
186
|
+
};
|
|
187
|
+
const propertyCriteria = Object.assign({}, rootCriteria, subCriteria);
|
|
188
|
+
const rootCriteriaResults = Object.assign({}, rootCriteria);
|
|
189
|
+
const subCriteriaResults = Object.assign({}, subCriteria);
|
|
190
|
+
const mockGetByRootTypeProperties = jest.spyOn(btep, 'getRootTypePropertyKeys').mockReturnValue(['rootText']);
|
|
191
|
+
const { rootTypeCriteria, subTypeCriteria } = await btep.getCriteriaForEntity(entityType, entityTypePath, propertyCriteria);
|
|
192
|
+
expect(mockTypeUtilGetByRootAndPath).toBeCalledTimes(1);
|
|
193
|
+
expect(mockTypeUtilGetByRootAndPath).toBeCalledWith({ root: entityType });
|
|
194
|
+
expect(mockGetByRootTypeProperties).toBeCalledTimes(1);
|
|
195
|
+
expect(mockGetByRootTypeProperties).toBeCalledWith(mockRootType, propertyCriteria);
|
|
196
|
+
expect(rootTypeCriteria).toEqual(rootCriteriaResults);
|
|
197
|
+
expect(subTypeCriteria).toEqual(subCriteriaResults);
|
|
198
|
+
});
|
|
199
|
+
});
|
|
146
200
|
describe('getRootTypePropertyKeys', () => {
|
|
147
201
|
it('rootType parameter not set', async () => {
|
|
148
202
|
const btep = new TestBaseEntityProcessor({}, {}, {}, 'test');
|
|
@@ -416,7 +416,7 @@ class DataConverter {
|
|
|
416
416
|
if (Object.keys(loadPage).includes('results')) {
|
|
417
417
|
usedV2 = true;
|
|
418
418
|
let postProcessedResults = loadPage.results;
|
|
419
|
-
if (postProcessCriteria && Object.keys(postProcessCriteria).length !== 0) {
|
|
419
|
+
if (postProcessedResults?.length > 0 && postProcessCriteria && Object.keys(postProcessCriteria).length !== 0) {
|
|
420
420
|
const subEntityTypePath = rootTypeCriteria.typePath || entityType;
|
|
421
421
|
postProcessedResults = this.checkKeysAndValues(postProcessCriteria, postProcessedResults, subEntityTypePath);
|
|
422
422
|
}
|
|
@@ -287,7 +287,7 @@ describe('getPersistableChanges', () => {
|
|
|
287
287
|
};
|
|
288
288
|
const diffs = dc.getPersistableChanges(entity, potentialChanges);
|
|
289
289
|
expect(Object.getOwnPropertyNames(diffs).length).toEqual(1);
|
|
290
|
-
expect(diffs['str']).
|
|
290
|
+
expect(diffs['str']).toBeNull();
|
|
291
291
|
});
|
|
292
292
|
});
|
|
293
293
|
describe('getObjectReferenceValue cache', () => {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@contrail/flexplm",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.60",
|
|
4
4
|
"description": "Library used for integration with flexplm.",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"types": "lib/index.d.ts",
|
|
@@ -40,9 +40,10 @@
|
|
|
40
40
|
"testEnvironment": "node"
|
|
41
41
|
},
|
|
42
42
|
"dependencies": {
|
|
43
|
-
"@contrail/app-framework": "^1.
|
|
44
|
-
"@contrail/sdk": "^1.3
|
|
45
|
-
"@contrail/transform-data": "^1.1.
|
|
43
|
+
"@contrail/app-framework": "^1.3.4",
|
|
44
|
+
"@contrail/sdk": "^1.4.3",
|
|
45
|
+
"@contrail/transform-data": "^1.1.3",
|
|
46
|
+
"@contrail/util": "^1.0.48",
|
|
46
47
|
"axios": "^1.4.0",
|
|
47
48
|
"p-limit": "^3.1.0"
|
|
48
49
|
}
|
|
@@ -104,7 +104,7 @@ describe('BaseEntityProcessor', () =>{
|
|
|
104
104
|
const config = {} as FCConfig;
|
|
105
105
|
const mapFileUtil = new MapFileUtil(new Entities());
|
|
106
106
|
beforeEach(() =>{
|
|
107
|
-
|
|
107
|
+
jest.clearAllMocks();
|
|
108
108
|
});
|
|
109
109
|
it('entity parameter not set', async () =>{
|
|
110
110
|
const btep = new TestBaseEntityProcessor({} as FCConfig, {} as DataConverter, {} as MapFileUtil, 'test');
|
|
@@ -138,10 +138,11 @@ describe('BaseEntityProcessor', () =>{
|
|
|
138
138
|
rootText: 'root'
|
|
139
139
|
};
|
|
140
140
|
const subCriteria = {
|
|
141
|
-
sampleText: 'sample'
|
|
141
|
+
sampleText: 'sample',
|
|
142
|
+
typePath: entityTypePath
|
|
142
143
|
};
|
|
143
144
|
const propertyCriteria = Object.assign({}, rootCriteria, subCriteria);
|
|
144
|
-
const rootCriteriaResults = Object.assign({
|
|
145
|
+
const rootCriteriaResults = Object.assign({}, rootCriteria);
|
|
145
146
|
|
|
146
147
|
const mockGetByRootTypeProperties = jest.spyOn(btep, 'getRootTypePropertyKeys').mockReturnValue(['rootText']);
|
|
147
148
|
const mockDCgetAllObjectReferences = jest.spyOn(dc, 'getAllObjectReferences').mockReturnValue(Promise.resolve([]));
|
|
@@ -159,6 +160,65 @@ describe('BaseEntityProcessor', () =>{
|
|
|
159
160
|
|
|
160
161
|
});
|
|
161
162
|
|
|
163
|
+
describe('getCriteriaForEntity', () =>{
|
|
164
|
+
const config = {} as FCConfig;
|
|
165
|
+
const mapFileUtil = new MapFileUtil(new Entities());
|
|
166
|
+
beforeEach(() =>{
|
|
167
|
+
jest.clearAllMocks();
|
|
168
|
+
});
|
|
169
|
+
it('entity parameter not set', async () =>{
|
|
170
|
+
const btep = new TestBaseEntityProcessor({} as FCConfig, {} as DataConverter, {} as MapFileUtil, 'test');
|
|
171
|
+
const entity = '';
|
|
172
|
+
const subType = 'test';
|
|
173
|
+
const propertyCriteria = {a:'val'};
|
|
174
|
+
expect(async () => {await btep.getCriteriaForEntity(entity, subType, propertyCriteria)}).rejects.toThrow();
|
|
175
|
+
});
|
|
176
|
+
it('entityTypePath not set', async () =>{
|
|
177
|
+
const btep = new TestBaseEntityProcessor({} as FCConfig, {} as DataConverter, {} as MapFileUtil, 'test');
|
|
178
|
+
const entity = 'test';
|
|
179
|
+
const subType = '';
|
|
180
|
+
const propertyCriteria = {};
|
|
181
|
+
expect(async () => {await btep.getCriteriaForEntity(entity, subType, propertyCriteria)}).rejects.toThrow();
|
|
182
|
+
|
|
183
|
+
});
|
|
184
|
+
it('propertyCriteria not set', async () =>{
|
|
185
|
+
const btep = new TestBaseEntityProcessor({} as FCConfig, {} as DataConverter, {} as MapFileUtil, 'test');
|
|
186
|
+
const entity = 'test';
|
|
187
|
+
const subType = 'test';
|
|
188
|
+
const propertyCriteria = {};
|
|
189
|
+
expect(async () => {await btep.getCriteriaForEntity(entity, subType, propertyCriteria)}).rejects.toThrow();
|
|
190
|
+
});
|
|
191
|
+
|
|
192
|
+
it('basic getCriteriaForEntity test', async () =>{
|
|
193
|
+
const dc = new DataConverter(config, mapFileUtil);
|
|
194
|
+
const btep = new TestBaseEntityProcessor(config, dc, mapFileUtil, 'test');
|
|
195
|
+
const entityType = 'custom-entity';
|
|
196
|
+
const entityTypePath = 'custom-entity:sample';
|
|
197
|
+
const rootCriteria = {
|
|
198
|
+
rootText: 'root'
|
|
199
|
+
};
|
|
200
|
+
const subCriteria = {
|
|
201
|
+
sampleText: 'sample',
|
|
202
|
+
typePath: entityTypePath
|
|
203
|
+
};
|
|
204
|
+
const propertyCriteria = Object.assign({}, rootCriteria, subCriteria);
|
|
205
|
+
const rootCriteriaResults = Object.assign({}, rootCriteria);
|
|
206
|
+
const subCriteriaResults = Object.assign({}, subCriteria);
|
|
207
|
+
|
|
208
|
+
const mockGetByRootTypeProperties = jest.spyOn(btep, 'getRootTypePropertyKeys').mockReturnValue(['rootText']);
|
|
209
|
+
// const mockDCgetAllObjectReferences = jest.spyOn(dc, 'getAllObjectReferences').mockReturnValue(Promise.resolve([]));
|
|
210
|
+
|
|
211
|
+
const {rootTypeCriteria, subTypeCriteria} = await btep.getCriteriaForEntity(entityType, entityTypePath, propertyCriteria);
|
|
212
|
+
expect(mockTypeUtilGetByRootAndPath).toBeCalledTimes(1);
|
|
213
|
+
expect(mockTypeUtilGetByRootAndPath).toBeCalledWith({ root: entityType});
|
|
214
|
+
expect(mockGetByRootTypeProperties).toBeCalledTimes(1);
|
|
215
|
+
expect(mockGetByRootTypeProperties).toBeCalledWith(mockRootType, propertyCriteria);
|
|
216
|
+
expect(rootTypeCriteria).toEqual(rootCriteriaResults);
|
|
217
|
+
expect(subTypeCriteria).toEqual(subCriteriaResults);
|
|
218
|
+
|
|
219
|
+
});
|
|
220
|
+
});
|
|
221
|
+
|
|
162
222
|
describe('getRootTypePropertyKeys', () =>{
|
|
163
223
|
it('rootType parameter not set', async () =>{
|
|
164
224
|
const btep = new TestBaseEntityProcessor({} as FCConfig, {} as DataConverter, {} as MapFileUtil, 'test');
|
|
@@ -153,11 +153,37 @@ export abstract class BaseEntityProcessor {
|
|
|
153
153
|
throw new Error('propertyCriteria must be defined and have at least one property');
|
|
154
154
|
}
|
|
155
155
|
|
|
156
|
+
const {rootTypeCriteria, subTypeCriteria} = await this.getCriteriaForEntity(entityType, entityTypePath, propertyCriteria);
|
|
157
|
+
|
|
158
|
+
const returnedEntities = await this.dc.getAllObjectReferences(entityType, rootTypeCriteria, subTypeCriteria);
|
|
159
|
+
|
|
160
|
+
return returnedEntities;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
/** This is to get the criteria for the entity that is being processed.
|
|
164
|
+
* This is to be overridden for item & project-item because of the need for
|
|
165
|
+
* setting the roles criteria.
|
|
166
|
+
*
|
|
167
|
+
* @param entityType: the root type of the entity
|
|
168
|
+
* @param entityTypePath: the full type path of the entity. Ex: custom-entity:sample
|
|
169
|
+
* @param propertyCriteria: all the criteria to search for the entity
|
|
170
|
+
* @returns the criteria for the entity
|
|
171
|
+
*/
|
|
172
|
+
async getCriteriaForEntity(entityType: string, entityTypePath: string, propertyCriteria: any): Promise<any>{
|
|
173
|
+
if(!entityType || !entityTypePath){
|
|
174
|
+
throw new Error('type and entityTypePath must be defined');
|
|
175
|
+
}
|
|
176
|
+
if(!propertyCriteria || Object.getOwnPropertyNames(propertyCriteria).length == 0){
|
|
177
|
+
throw new Error('propertyCriteria must be defined and have at least one property');
|
|
178
|
+
}
|
|
156
179
|
const rootType = await this.typeUtil.getByRootAndPath({root: entityType});
|
|
157
180
|
const rootTypePropertyKeys = await this.getRootTypePropertyKeys(rootType, propertyCriteria);
|
|
158
181
|
|
|
159
|
-
const rootTypeCriteria = {
|
|
182
|
+
const rootTypeCriteria = {};
|
|
160
183
|
const subTypeCriteria = {};
|
|
184
|
+
if(entityType !== entityTypePath){
|
|
185
|
+
subTypeCriteria['typePath'] = entityTypePath;
|
|
186
|
+
}
|
|
161
187
|
for(const key in propertyCriteria){
|
|
162
188
|
if(rootTypePropertyKeys.includes(key)){
|
|
163
189
|
rootTypeCriteria[key] = propertyCriteria[key];
|
|
@@ -166,9 +192,7 @@ export abstract class BaseEntityProcessor {
|
|
|
166
192
|
}
|
|
167
193
|
}
|
|
168
194
|
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
return returnedEntities;
|
|
195
|
+
return {rootTypeCriteria, subTypeCriteria};
|
|
172
196
|
}
|
|
173
197
|
|
|
174
198
|
/** This is to get the properties that are owned by the root type
|
|
@@ -321,7 +321,7 @@ describe('getPersistableChanges', () =>{
|
|
|
321
321
|
|
|
322
322
|
const diffs = dc.getPersistableChanges(entity, potentialChanges);
|
|
323
323
|
expect(Object.getOwnPropertyNames(diffs).length).toEqual(1);
|
|
324
|
-
expect(diffs['str']).
|
|
324
|
+
expect(diffs['str']).toBeNull();
|
|
325
325
|
});
|
|
326
326
|
|
|
327
327
|
});
|
|
@@ -513,7 +513,7 @@ export class DataConverter {
|
|
|
513
513
|
if (Object.keys(loadPage).includes('results')) {
|
|
514
514
|
usedV2 = true;
|
|
515
515
|
let postProcessedResults = loadPage.results;
|
|
516
|
-
if(postProcessCriteria && Object.keys(postProcessCriteria).length !== 0) {
|
|
516
|
+
if(postProcessedResults?.length > 0 && postProcessCriteria && Object.keys(postProcessCriteria).length !== 0) {
|
|
517
517
|
const subEntityTypePath = rootTypeCriteria.typePath || entityType;
|
|
518
518
|
postProcessedResults = this.checkKeysAndValues(postProcessCriteria, postProcessedResults, subEntityTypePath);
|
|
519
519
|
}
|