@contrail/cli 3.5.2 → 3.5.3-alpha.317fe63
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/README.md +10 -28
- package/dist/api/types.d.ts +0 -5
- package/dist/api/types.js +1 -36
- package/dist/commands/projects/export.d.ts +1 -0
- package/dist/commands/projects/export.js +19 -5
- package/dist/commands/types/getAll.js +0 -18
- package/dist/commands/types/loadAll.js +0 -2
- package/dist/commands/types/mergeTypeProperties.js +0 -5
- package/dist/commands/types/uploadOptionSetHierarchies.js +0 -117
- package/dist/commands/types/uploadOptionSets.js +1 -1
- package/dist/commands/types/uploadRuleSets.js +2 -85
- package/dist/commands/types/uploadTypeOverrides.js +10 -2
- package/dist/commands/types/uploadTypePolicies.js +2 -86
- package/dist/commands/types/uploadTypePropertyPolicies.d.ts +0 -1
- package/dist/commands/types/uploadTypePropertyPolicies.js +3 -139
- package/dist/helpers/projects/helpers.d.ts +2 -1
- package/dist/helpers/projects/helpers.js +37 -2
- package/dist/helpers/projects/post-processor.d.ts +131 -0
- package/dist/helpers/projects/post-processor.js +519 -0
- package/dist/helpers/types/type-uploader.js +1 -1
- package/dist/interfaces.d.ts +0 -25
- package/dist/templates/typescript/tsup.config.ts +0 -0
- package/node_modules/@contrail/org-config-migration/.github/workflows/publish-to-npm.yml +117 -0
- package/node_modules/@contrail/org-config-migration/.husky/pre-commit +0 -0
- package/node_modules/@contrail/org-config-migration/lib/index.d.ts +3 -3
- package/node_modules/@contrail/org-config-migration/lib/index.js +19 -19
- package/node_modules/@contrail/org-config-migration/lib/interfaces.d.ts +87 -97
- package/node_modules/@contrail/org-config-migration/lib/interfaces.js +2 -2
- package/node_modules/@contrail/org-config-migration/lib/services/index.d.ts +1 -1
- package/node_modules/@contrail/org-config-migration/lib/services/index.js +17 -17
- package/node_modules/@contrail/org-config-migration/lib/services/types.d.ts +12 -17
- package/node_modules/@contrail/org-config-migration/lib/services/types.js +115 -155
- package/node_modules/@contrail/org-config-migration/lib/types/exportAll.d.ts +2 -2
- package/node_modules/@contrail/org-config-migration/lib/types/exportAll.js +34 -40
- package/node_modules/@contrail/org-config-migration/lib/types/exportOptionSet.d.ts +2 -2
- package/node_modules/@contrail/org-config-migration/lib/types/exportOptionSet.js +20 -20
- package/node_modules/@contrail/org-config-migration/lib/types/exportOptionSetHierarchies.d.ts +2 -3
- package/node_modules/@contrail/org-config-migration/lib/types/exportOptionSetHierarchies.js +16 -47
- package/node_modules/@contrail/org-config-migration/lib/types/exportOverrides.d.ts +2 -2
- package/node_modules/@contrail/org-config-migration/lib/types/exportOverrides.js +8 -8
- package/node_modules/@contrail/org-config-migration/lib/types/exportRuleSets.d.ts +2 -3
- package/node_modules/@contrail/org-config-migration/lib/types/exportRuleSets.js +14 -39
- package/node_modules/@contrail/org-config-migration/lib/types/exportTypePolicies.d.ts +2 -3
- package/node_modules/@contrail/org-config-migration/lib/types/exportTypePolicies.js +44 -56
- package/node_modules/@contrail/org-config-migration/lib/types/exportTypePropertyPolicies.d.ts +2 -3
- package/node_modules/@contrail/org-config-migration/lib/types/exportTypePropertyPolicies.js +44 -71
- package/node_modules/@contrail/org-config-migration/lib/types/exportTypes.d.ts +2 -2
- package/node_modules/@contrail/org-config-migration/lib/types/exportTypes.js +85 -85
- package/node_modules/@contrail/org-config-migration/lib/types/importAll.d.ts +2 -2
- package/node_modules/@contrail/org-config-migration/lib/types/importAll.js +386 -451
- package/node_modules/@contrail/org-config-migration/lib/types/index.d.ts +8 -9
- package/node_modules/@contrail/org-config-migration/lib/types/index.js +24 -25
- package/node_modules/@contrail/org-config-migration/lib/types/parseOptionSetHierarchy.d.ts +3 -3
- package/node_modules/@contrail/org-config-migration/lib/types/parseOptionSetHierarchy.js +210 -210
- package/node_modules/@contrail/org-config-migration/lib/users/export.d.ts +2 -2
- package/node_modules/@contrail/org-config-migration/lib/users/export.js +40 -40
- package/node_modules/@contrail/org-config-migration/lib/users/import.d.ts +2 -2
- package/node_modules/@contrail/org-config-migration/lib/users/import.js +41 -41
- package/node_modules/@contrail/org-config-migration/lib/users/index.d.ts +2 -2
- package/node_modules/@contrail/org-config-migration/lib/users/index.js +18 -18
- package/node_modules/@contrail/org-config-migration/package.json +1 -1
- package/oclif.manifest.json +11 -55
- package/package.json +2 -2
- package/dist/commands/types/uploadUsageInfo.d.ts +0 -15
- package/dist/commands/types/uploadUsageInfo.js +0 -180
- package/dist/commands/types/uploadUsageInfo.spec.d.ts +0 -1
- package/dist/commands/types/uploadUsageInfo.spec.js +0 -249
- package/node_modules/@contrail/org-config-migration/lib/types/exportUsageInfo.d.ts +0 -2
- package/node_modules/@contrail/org-config-migration/lib/types/exportUsageInfo.js +0 -39
|
@@ -0,0 +1,519 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ProjectPostProcessor = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
const logger_1 = tslib_1.__importDefault(require("../../logger"));
|
|
6
|
+
/**
|
|
7
|
+
* Main class for processing project YAML data
|
|
8
|
+
*/
|
|
9
|
+
class ProjectPostProcessor {
|
|
10
|
+
stats;
|
|
11
|
+
options;
|
|
12
|
+
projectId = null;
|
|
13
|
+
constructor(options = {}) {
|
|
14
|
+
this.options = {
|
|
15
|
+
removeBackings: true,
|
|
16
|
+
fixMissingIdentifiers: true,
|
|
17
|
+
cleanProperties: true,
|
|
18
|
+
analyzeOnly: false,
|
|
19
|
+
verbose: false,
|
|
20
|
+
...options,
|
|
21
|
+
};
|
|
22
|
+
this.stats = this.initializeStats();
|
|
23
|
+
}
|
|
24
|
+
initializeStats() {
|
|
25
|
+
return {
|
|
26
|
+
itemTypeConverted: 0,
|
|
27
|
+
nbFXRatesRemoved: 0,
|
|
28
|
+
createdByRemoved: 0,
|
|
29
|
+
updatedByRemoved: 0,
|
|
30
|
+
emptyAssortmentAttsRemoved: 0,
|
|
31
|
+
identifiersCreated: 0,
|
|
32
|
+
planIdentifiers: 0,
|
|
33
|
+
backingIdentifiers: 0,
|
|
34
|
+
folderIdentifiers: 0,
|
|
35
|
+
viewsIdentifiers: 0,
|
|
36
|
+
assortmentIdentifiers: 0,
|
|
37
|
+
backingsRemoved: 0,
|
|
38
|
+
removedBackingNames: [],
|
|
39
|
+
totalObjects: 0,
|
|
40
|
+
totalAssortments: 0,
|
|
41
|
+
totalPlans: 0,
|
|
42
|
+
totalBackings: 0,
|
|
43
|
+
totalFolders: 0,
|
|
44
|
+
duplicateIdentifiers: 0,
|
|
45
|
+
emptyIdentifiers: 0,
|
|
46
|
+
missingIdentifiers: 0,
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Main processing method for project data
|
|
51
|
+
*/
|
|
52
|
+
processProjectData(projectData) {
|
|
53
|
+
try {
|
|
54
|
+
if (this.options.verbose) {
|
|
55
|
+
logger_1.default.info('Starting project data processing...');
|
|
56
|
+
}
|
|
57
|
+
// Extract project ID
|
|
58
|
+
this.extractProjectId(projectData);
|
|
59
|
+
// Analysis phase
|
|
60
|
+
const analysisResults = this.analyzeProjectData(projectData);
|
|
61
|
+
if (this.options.analyzeOnly) {
|
|
62
|
+
return { data: projectData, results: analysisResults };
|
|
63
|
+
}
|
|
64
|
+
let processedData = projectData;
|
|
65
|
+
// Processing phase
|
|
66
|
+
if (this.options.cleanProperties) {
|
|
67
|
+
if (this.options.verbose)
|
|
68
|
+
logger_1.default.info('Cleaning properties...');
|
|
69
|
+
processedData = this.cleanProperties(processedData);
|
|
70
|
+
}
|
|
71
|
+
if (this.options.fixMissingIdentifiers) {
|
|
72
|
+
if (this.options.verbose)
|
|
73
|
+
logger_1.default.info('Fixing missing identifiers...');
|
|
74
|
+
processedData = this.fixMissingIdentifiers(processedData);
|
|
75
|
+
}
|
|
76
|
+
if (this.options.removeBackings) {
|
|
77
|
+
if (this.options.verbose)
|
|
78
|
+
logger_1.default.info('Removing backing assortments...');
|
|
79
|
+
processedData = this.removeBackings(processedData);
|
|
80
|
+
}
|
|
81
|
+
// Final analysis after processing
|
|
82
|
+
const finalAnalysis = this.analyzeProjectData(processedData);
|
|
83
|
+
if (this.options.verbose) {
|
|
84
|
+
this.logProcessingSummary();
|
|
85
|
+
}
|
|
86
|
+
return { data: processedData, results: finalAnalysis };
|
|
87
|
+
}
|
|
88
|
+
catch (error) {
|
|
89
|
+
logger_1.default.error('Error processing project data:', error);
|
|
90
|
+
throw error;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Extract project ID from project data
|
|
95
|
+
*/
|
|
96
|
+
extractProjectId(projectData) {
|
|
97
|
+
if (projectData.projectConfiguration?.projectName) {
|
|
98
|
+
this.projectId = projectData.projectConfiguration.projectName;
|
|
99
|
+
}
|
|
100
|
+
else if (projectData.name?.match(/^S\d-\d+/)) {
|
|
101
|
+
const match = projectData.name.match(/^(S\d-\d+)/);
|
|
102
|
+
this.projectId = match ? match[1] : null;
|
|
103
|
+
}
|
|
104
|
+
if (this.options.verbose && this.projectId) {
|
|
105
|
+
logger_1.default.info(`Project ID identified: ${this.projectId}`);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Analyze project data for identifiers, types, and structure
|
|
110
|
+
*/
|
|
111
|
+
analyzeProjectData(projectData) {
|
|
112
|
+
const identifiers = {};
|
|
113
|
+
const duplicates = {};
|
|
114
|
+
const emptyIdentifierObjects = [];
|
|
115
|
+
const missingIdentifierObjects = {
|
|
116
|
+
assortments: [],
|
|
117
|
+
plans: [],
|
|
118
|
+
folders: [],
|
|
119
|
+
};
|
|
120
|
+
const analyzeObject = (obj, path = []) => {
|
|
121
|
+
if (!obj || typeof obj !== 'object')
|
|
122
|
+
return;
|
|
123
|
+
if (Array.isArray(obj)) {
|
|
124
|
+
obj.forEach((item, index) => {
|
|
125
|
+
analyzeObject(item, [...path, index.toString()]);
|
|
126
|
+
});
|
|
127
|
+
return;
|
|
128
|
+
}
|
|
129
|
+
this.stats.totalObjects++;
|
|
130
|
+
// Analyze object with name
|
|
131
|
+
if (obj.name) {
|
|
132
|
+
// Determine object type
|
|
133
|
+
let objType = 'unknown';
|
|
134
|
+
if (obj.subFolders) {
|
|
135
|
+
objType = 'folder';
|
|
136
|
+
this.stats.totalFolders++;
|
|
137
|
+
}
|
|
138
|
+
if (obj.type) {
|
|
139
|
+
objType = obj.type.toLowerCase();
|
|
140
|
+
if (objType === 'plan')
|
|
141
|
+
this.stats.totalPlans++;
|
|
142
|
+
if (objType === 'assortment')
|
|
143
|
+
this.stats.totalAssortments++;
|
|
144
|
+
if (objType === 'backing')
|
|
145
|
+
this.stats.totalBackings++;
|
|
146
|
+
}
|
|
147
|
+
// Check identifier
|
|
148
|
+
if (obj.identifier !== undefined) {
|
|
149
|
+
const id = obj.identifier;
|
|
150
|
+
if (!id || id.trim() === '') {
|
|
151
|
+
this.stats.emptyIdentifiers++;
|
|
152
|
+
emptyIdentifierObjects.push({
|
|
153
|
+
name: obj.name,
|
|
154
|
+
path: path.join('.'),
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
else {
|
|
158
|
+
if (identifiers[id]) {
|
|
159
|
+
identifiers[id].count++;
|
|
160
|
+
identifiers[id].names.push(obj.name);
|
|
161
|
+
identifiers[id].paths.push(path.join('.'));
|
|
162
|
+
}
|
|
163
|
+
else {
|
|
164
|
+
identifiers[id] = {
|
|
165
|
+
count: 1,
|
|
166
|
+
names: [obj.name],
|
|
167
|
+
paths: [path.join('.')],
|
|
168
|
+
};
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
else if (this.shouldHaveIdentifier(obj)) {
|
|
173
|
+
this.stats.missingIdentifiers++;
|
|
174
|
+
if (objType === 'assortment') {
|
|
175
|
+
missingIdentifierObjects.assortments.push({
|
|
176
|
+
name: obj.name,
|
|
177
|
+
path: path.join('.'),
|
|
178
|
+
});
|
|
179
|
+
}
|
|
180
|
+
else if (objType === 'plan') {
|
|
181
|
+
missingIdentifierObjects.plans.push({
|
|
182
|
+
name: obj.name,
|
|
183
|
+
path: path.join('.'),
|
|
184
|
+
});
|
|
185
|
+
}
|
|
186
|
+
else if (objType === 'folder') {
|
|
187
|
+
missingIdentifierObjects.folders.push({
|
|
188
|
+
name: obj.name,
|
|
189
|
+
path: path.join('.'),
|
|
190
|
+
});
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
// Recursively analyze nested objects
|
|
195
|
+
for (const key in obj) {
|
|
196
|
+
if (typeof obj[key] === 'object' && obj[key] !== null) {
|
|
197
|
+
analyzeObject(obj[key], [...path, key]);
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
};
|
|
201
|
+
analyzeObject(projectData);
|
|
202
|
+
// Find duplicates
|
|
203
|
+
for (const [id, info] of Object.entries(identifiers)) {
|
|
204
|
+
if (info.count > 1) {
|
|
205
|
+
duplicates[id] = info;
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
this.stats.duplicateIdentifiers = Object.keys(duplicates).length;
|
|
209
|
+
return {
|
|
210
|
+
stats: { ...this.stats },
|
|
211
|
+
duplicates,
|
|
212
|
+
emptyIdentifierObjects,
|
|
213
|
+
missingIdentifierObjects,
|
|
214
|
+
};
|
|
215
|
+
}
|
|
216
|
+
/**
|
|
217
|
+
* Clean properties from project data
|
|
218
|
+
*/
|
|
219
|
+
cleanProperties(projectData) {
|
|
220
|
+
const processObject = (obj) => {
|
|
221
|
+
if (!obj || typeof obj !== 'object')
|
|
222
|
+
return obj;
|
|
223
|
+
if (Array.isArray(obj)) {
|
|
224
|
+
return obj.map((item) => processObject(item));
|
|
225
|
+
}
|
|
226
|
+
const newObj = {};
|
|
227
|
+
for (const key in obj) {
|
|
228
|
+
if (!Object.prototype.hasOwnProperty.call(obj, key))
|
|
229
|
+
continue;
|
|
230
|
+
if (key === 'itemType') {
|
|
231
|
+
// Handle itemType conversion
|
|
232
|
+
if (typeof obj[key] === 'object' && obj[key]?.typePath) {
|
|
233
|
+
newObj[key] = obj[key].typePath;
|
|
234
|
+
this.stats.itemTypeConverted++;
|
|
235
|
+
}
|
|
236
|
+
else {
|
|
237
|
+
newObj[key] = obj[key];
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
else if (key === 'nbFXRates') {
|
|
241
|
+
// Remove nbFXRates
|
|
242
|
+
this.stats.nbFXRatesRemoved++;
|
|
243
|
+
if (this.options.verbose) {
|
|
244
|
+
logger_1.default.debug(`Removed nbFXRates from object: ${obj.name || 'unnamed'}`);
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
else if (key === 'updatedBy') {
|
|
248
|
+
// Remove updatedBy
|
|
249
|
+
this.stats.updatedByRemoved++;
|
|
250
|
+
}
|
|
251
|
+
else if (key === 'createdBy') {
|
|
252
|
+
// Remove createdBy
|
|
253
|
+
this.stats.createdByRemoved++;
|
|
254
|
+
}
|
|
255
|
+
else if (key === 'assortmentAtts' && typeof obj[key] === 'object') {
|
|
256
|
+
// Process assortmentAtts
|
|
257
|
+
const processedAtts = this.processAssortmentAtts(obj[key]);
|
|
258
|
+
if (Object.keys(processedAtts).length > 0) {
|
|
259
|
+
newObj[key] = processedAtts;
|
|
260
|
+
}
|
|
261
|
+
else {
|
|
262
|
+
this.stats.emptyAssortmentAttsRemoved++;
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
else if (obj[key] === null) {
|
|
266
|
+
// Skip null values
|
|
267
|
+
}
|
|
268
|
+
else if (typeof obj[key] === 'object') {
|
|
269
|
+
newObj[key] = processObject(obj[key]);
|
|
270
|
+
}
|
|
271
|
+
else {
|
|
272
|
+
newObj[key] = obj[key];
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
return newObj;
|
|
276
|
+
};
|
|
277
|
+
return processObject(projectData);
|
|
278
|
+
}
|
|
279
|
+
/**
|
|
280
|
+
* Process assortmentAtts object
|
|
281
|
+
*/
|
|
282
|
+
processAssortmentAtts(assortmentAtts) {
|
|
283
|
+
const processed = {};
|
|
284
|
+
for (const key in assortmentAtts) {
|
|
285
|
+
if (key === 'updatedBy' || key === 'createdBy') {
|
|
286
|
+
// Skip these properties
|
|
287
|
+
if (key === 'updatedBy')
|
|
288
|
+
this.stats.updatedByRemoved++;
|
|
289
|
+
if (key === 'createdBy')
|
|
290
|
+
this.stats.createdByRemoved++;
|
|
291
|
+
}
|
|
292
|
+
else if (key === 'nbFXRates') {
|
|
293
|
+
// Skip nbFXRates
|
|
294
|
+
this.stats.nbFXRatesRemoved++;
|
|
295
|
+
}
|
|
296
|
+
else if (key === 'itemTypeId') {
|
|
297
|
+
// Skip itemTypeId
|
|
298
|
+
this.stats.itemTypeIdRemoved++;
|
|
299
|
+
}
|
|
300
|
+
else if (key === 'itemType' &&
|
|
301
|
+
typeof assortmentAtts[key] === 'object' &&
|
|
302
|
+
assortmentAtts[key]?.typePath) {
|
|
303
|
+
// Convert itemType object to string
|
|
304
|
+
processed[key] = assortmentAtts[key].typePath;
|
|
305
|
+
this.stats.itemTypeConverted++;
|
|
306
|
+
}
|
|
307
|
+
else if (assortmentAtts[key] !== null && assortmentAtts[key] !== undefined) {
|
|
308
|
+
// Keep other properties
|
|
309
|
+
processed[key] = assortmentAtts[key];
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
return processed;
|
|
313
|
+
}
|
|
314
|
+
/**
|
|
315
|
+
* Fix missing identifiers
|
|
316
|
+
*/
|
|
317
|
+
fixMissingIdentifiers(projectData) {
|
|
318
|
+
const processObject = (obj, path = [], parentIdentifier = '') => {
|
|
319
|
+
if (!obj || typeof obj !== 'object')
|
|
320
|
+
return obj;
|
|
321
|
+
if (Array.isArray(obj)) {
|
|
322
|
+
return obj.map((item, index) => processObject(item, [...path, index.toString()], parentIdentifier));
|
|
323
|
+
}
|
|
324
|
+
const newObj = { ...obj };
|
|
325
|
+
// Generate identifier if missing
|
|
326
|
+
if (newObj.name && !newObj.identifier && this.shouldHaveIdentifier(newObj)) {
|
|
327
|
+
const identifier = this.generateIdentifier(newObj, parentIdentifier);
|
|
328
|
+
if (identifier) {
|
|
329
|
+
newObj.identifier = identifier;
|
|
330
|
+
this.stats.identifiersCreated++;
|
|
331
|
+
const objType = this.getObjectType(newObj);
|
|
332
|
+
if (objType === 'plan')
|
|
333
|
+
this.stats.planIdentifiers++;
|
|
334
|
+
else if (objType === 'assortment')
|
|
335
|
+
this.stats.assortmentIdentifiers++;
|
|
336
|
+
else if (objType === 'backing')
|
|
337
|
+
this.stats.backingIdentifiers++;
|
|
338
|
+
else if (objType === 'folder')
|
|
339
|
+
this.stats.folderIdentifiers++;
|
|
340
|
+
if (newObj.name.toLowerCase().includes('views')) {
|
|
341
|
+
this.stats.viewsIdentifiers++;
|
|
342
|
+
}
|
|
343
|
+
if (this.options.verbose) {
|
|
344
|
+
logger_1.default.debug(`Generated identifier "${identifier}" for "${newObj.name}"`);
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
else if (newObj.identifier) {
|
|
349
|
+
parentIdentifier = newObj.identifier;
|
|
350
|
+
}
|
|
351
|
+
// Process nested objects
|
|
352
|
+
for (const key in newObj) {
|
|
353
|
+
if (typeof newObj[key] === 'object' && newObj[key] !== null && key !== 'identifier') {
|
|
354
|
+
newObj[key] = processObject(newObj[key], [...path, key], parentIdentifier);
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
return newObj;
|
|
358
|
+
};
|
|
359
|
+
return processObject(projectData);
|
|
360
|
+
}
|
|
361
|
+
/**
|
|
362
|
+
* Remove backing assortments
|
|
363
|
+
*/
|
|
364
|
+
removeBackings(projectData) {
|
|
365
|
+
const processObject = (obj) => {
|
|
366
|
+
if (!obj || typeof obj !== 'object')
|
|
367
|
+
return obj;
|
|
368
|
+
if (Array.isArray(obj)) {
|
|
369
|
+
const filtered = obj.filter((item) => {
|
|
370
|
+
if (item && item.type === 'BACKING') {
|
|
371
|
+
this.stats.backingsRemoved++;
|
|
372
|
+
if (item.name) {
|
|
373
|
+
this.stats.removedBackingNames.push(item.name);
|
|
374
|
+
}
|
|
375
|
+
if (this.options.verbose) {
|
|
376
|
+
logger_1.default.debug(`Removed backing: ${item.name || 'unnamed'}`);
|
|
377
|
+
}
|
|
378
|
+
return false;
|
|
379
|
+
}
|
|
380
|
+
return true;
|
|
381
|
+
});
|
|
382
|
+
return filtered.map((item) => processObject(item));
|
|
383
|
+
}
|
|
384
|
+
const newObj = {};
|
|
385
|
+
for (const key in obj) {
|
|
386
|
+
if (Object.prototype.hasOwnProperty.call(obj, key)) {
|
|
387
|
+
newObj[key] = processObject(obj[key]);
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
return newObj;
|
|
391
|
+
};
|
|
392
|
+
return processObject(projectData);
|
|
393
|
+
}
|
|
394
|
+
/**
|
|
395
|
+
* Generate identifier for an object
|
|
396
|
+
*/
|
|
397
|
+
generateIdentifier(obj, parentIdentifier) {
|
|
398
|
+
const objType = this.getObjectType(obj);
|
|
399
|
+
let typeSuffix = 'folder';
|
|
400
|
+
if (objType === 'plan')
|
|
401
|
+
typeSuffix = 'product.plan';
|
|
402
|
+
else if (objType === 'assortment')
|
|
403
|
+
typeSuffix = 'product.assortment';
|
|
404
|
+
else if (objType === 'backing')
|
|
405
|
+
typeSuffix = 'backing';
|
|
406
|
+
const sanitizeName = (name) => {
|
|
407
|
+
return name
|
|
408
|
+
.toLowerCase()
|
|
409
|
+
.replace(/'/g, '')
|
|
410
|
+
.replace(/&/g, 'and')
|
|
411
|
+
.replace(/\s+/g, '')
|
|
412
|
+
.replace(/[^\w]/g, '');
|
|
413
|
+
};
|
|
414
|
+
// Strategy 1: Extract from name pattern
|
|
415
|
+
const nameMatch = obj.name.match(/^(S\d-\d+)\s+(.+)$/);
|
|
416
|
+
if (nameMatch) {
|
|
417
|
+
const projectId = nameMatch[1];
|
|
418
|
+
const sanitizedName = sanitizeName(nameMatch[2]);
|
|
419
|
+
return `${projectId}:${sanitizedName}:${typeSuffix}`;
|
|
420
|
+
}
|
|
421
|
+
// Strategy 2: Views objects
|
|
422
|
+
if (obj.name.toLowerCase().includes('views')) {
|
|
423
|
+
let sanitizedName = 'main';
|
|
424
|
+
if (obj.name.startsWith('Views -')) {
|
|
425
|
+
sanitizedName = sanitizeName(obj.name.substring(8).trim());
|
|
426
|
+
}
|
|
427
|
+
else if (obj.name.toLowerCase() !== 'views') {
|
|
428
|
+
sanitizedName = sanitizeName(obj.name);
|
|
429
|
+
}
|
|
430
|
+
const baseId = this.projectId || parentIdentifier;
|
|
431
|
+
return `${baseId}:views:${sanitizedName}:${typeSuffix}`;
|
|
432
|
+
}
|
|
433
|
+
// Strategy 3: Training objects
|
|
434
|
+
if (obj.name.toLowerCase().includes('training')) {
|
|
435
|
+
let sanitizedName;
|
|
436
|
+
if (obj.name.startsWith('(Training)')) {
|
|
437
|
+
sanitizedName = sanitizeName(obj.name.substring(10).trim());
|
|
438
|
+
}
|
|
439
|
+
else {
|
|
440
|
+
sanitizedName = sanitizeName(obj.name);
|
|
441
|
+
}
|
|
442
|
+
const baseId = this.projectId || parentIdentifier;
|
|
443
|
+
return `${baseId}:training:${sanitizedName}:${typeSuffix}`;
|
|
444
|
+
}
|
|
445
|
+
// Strategy 4: Seasonal/Regional patterns
|
|
446
|
+
if (obj.name.match(/^(SS|FW|SU|FA)\d{2}/i) || obj.name.match(/^(APAC|NA|EMEA|LATAM|ANZ)/i)) {
|
|
447
|
+
const sanitizedName = sanitizeName(obj.name);
|
|
448
|
+
const baseId = this.projectId || parentIdentifier;
|
|
449
|
+
if (obj.name.match(/^(SS|FW|SU|FA)\d{2}/i)) {
|
|
450
|
+
return `${baseId}:seasons:${sanitizedName}:${typeSuffix}`;
|
|
451
|
+
}
|
|
452
|
+
else {
|
|
453
|
+
return `${baseId}:regions:${sanitizedName}:${typeSuffix}`;
|
|
454
|
+
}
|
|
455
|
+
}
|
|
456
|
+
// Strategy 5: Use parent identifier
|
|
457
|
+
if (parentIdentifier) {
|
|
458
|
+
const sanitizedName = sanitizeName(obj.name);
|
|
459
|
+
return `${parentIdentifier}:${sanitizedName}:${typeSuffix}`;
|
|
460
|
+
}
|
|
461
|
+
// Strategy 6: Use project ID
|
|
462
|
+
if (this.projectId) {
|
|
463
|
+
const sanitizedName = sanitizeName(obj.name);
|
|
464
|
+
return `${this.projectId}:${sanitizedName}:${typeSuffix}`;
|
|
465
|
+
}
|
|
466
|
+
return null;
|
|
467
|
+
}
|
|
468
|
+
/**
|
|
469
|
+
* Determine object type
|
|
470
|
+
*/
|
|
471
|
+
getObjectType(obj) {
|
|
472
|
+
if (obj.subFolders)
|
|
473
|
+
return 'folder';
|
|
474
|
+
if (obj.type)
|
|
475
|
+
return obj.type.toLowerCase();
|
|
476
|
+
return 'unknown';
|
|
477
|
+
}
|
|
478
|
+
/**
|
|
479
|
+
* Check if object should have an identifier
|
|
480
|
+
*/
|
|
481
|
+
shouldHaveIdentifier(obj) {
|
|
482
|
+
return (obj.name &&
|
|
483
|
+
(obj.type === 'ASSORTMENT' || obj.type === 'PLAN' || obj.type === 'BACKING' || obj.subFolders));
|
|
484
|
+
}
|
|
485
|
+
/**
|
|
486
|
+
* Log processing summary
|
|
487
|
+
*/
|
|
488
|
+
logProcessingSummary() {
|
|
489
|
+
logger_1.default.info('========== PROCESSING SUMMARY ==========');
|
|
490
|
+
if (this.options.cleanProperties) {
|
|
491
|
+
logger_1.default.info('PROPERTY CLEANING:');
|
|
492
|
+
logger_1.default.info(`- ItemType objects converted: ${this.stats.itemTypeConverted}`);
|
|
493
|
+
logger_1.default.info(`- nbFXRates properties removed: ${this.stats.nbFXRatesRemoved}`);
|
|
494
|
+
logger_1.default.info(`- updatedBy properties removed: ${this.stats.updatedByRemoved}`);
|
|
495
|
+
logger_1.default.info(`- createdBy properties removed: ${this.stats.createdByRemoved}`);
|
|
496
|
+
logger_1.default.info(`- Empty assortmentAtts removed: ${this.stats.emptyAssortmentAttsRemoved}`);
|
|
497
|
+
}
|
|
498
|
+
if (this.options.fixMissingIdentifiers) {
|
|
499
|
+
logger_1.default.info('IDENTIFIER GENERATION:');
|
|
500
|
+
logger_1.default.info(`- Total identifiers created: ${this.stats.identifiersCreated}`);
|
|
501
|
+
logger_1.default.info(` - Assortments: ${this.stats.assortmentIdentifiers}`);
|
|
502
|
+
logger_1.default.info(` - Plans: ${this.stats.planIdentifiers}`);
|
|
503
|
+
logger_1.default.info(` - Backings: ${this.stats.backingIdentifiers}`);
|
|
504
|
+
logger_1.default.info(` - Folders: ${this.stats.folderIdentifiers}`);
|
|
505
|
+
logger_1.default.info(` - Views: ${this.stats.viewsIdentifiers}`);
|
|
506
|
+
}
|
|
507
|
+
if (this.options.removeBackings) {
|
|
508
|
+
logger_1.default.info('BACKING REMOVAL:');
|
|
509
|
+
logger_1.default.info(`- Backing assortments removed: ${this.stats.backingsRemoved}`);
|
|
510
|
+
}
|
|
511
|
+
}
|
|
512
|
+
/**
|
|
513
|
+
* Get processing statistics
|
|
514
|
+
*/
|
|
515
|
+
getStats() {
|
|
516
|
+
return { ...this.stats };
|
|
517
|
+
}
|
|
518
|
+
}
|
|
519
|
+
exports.ProjectPostProcessor = ProjectPostProcessor;
|
|
@@ -303,7 +303,7 @@ async function uploadReducedTypeProperties(type, currentPropertyTypes, newProper
|
|
|
303
303
|
}
|
|
304
304
|
}
|
|
305
305
|
catch (err) {
|
|
306
|
-
|
|
306
|
+
logger_1.default.error(`Error Deleting Type-Property ${currentPropertyType.slug}: ${err}`);
|
|
307
307
|
}
|
|
308
308
|
}
|
|
309
309
|
}
|
package/dist/interfaces.d.ts
CHANGED
|
@@ -370,31 +370,6 @@ export interface ReducedOptionSet {
|
|
|
370
370
|
isArchived: boolean;
|
|
371
371
|
optionSet: any[];
|
|
372
372
|
}
|
|
373
|
-
export interface ReducedUsageInfo {
|
|
374
|
-
typeId: string;
|
|
375
|
-
typePropertyId: string;
|
|
376
|
-
typePath: string;
|
|
377
|
-
typePropertySlug: string;
|
|
378
|
-
editable: boolean;
|
|
379
|
-
used: boolean;
|
|
380
|
-
formulaFunction?: string;
|
|
381
|
-
validationFunction?: string;
|
|
382
|
-
numberFormat?: any;
|
|
383
|
-
defaultValue?: string;
|
|
384
|
-
label?: string;
|
|
385
|
-
required?: boolean;
|
|
386
|
-
searchable?: boolean;
|
|
387
|
-
isUniqueProperty?: boolean;
|
|
388
|
-
isUniquePropertyInFamily?: boolean;
|
|
389
|
-
copyBehavior?: string;
|
|
390
|
-
copyDefault?: string;
|
|
391
|
-
propertyLevel?: string;
|
|
392
|
-
isArchived: boolean;
|
|
393
|
-
isFederationProperty?: boolean;
|
|
394
|
-
carryOverBehavior?: string;
|
|
395
|
-
carryOverDefault?: string;
|
|
396
|
-
}
|
|
397
|
-
export type PersistReducedUsageInfo = Omit<ReducedUsageInfo, 'typePath' | 'typePropertySlug'>;
|
|
398
373
|
export declare enum PropertyType {
|
|
399
374
|
Text = "text",
|
|
400
375
|
String = "string",
|
|
File without changes
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
name: Publish to NPM
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [master]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: ['**']
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
check-version:
|
|
11
|
+
name: Verify version is available on npm
|
|
12
|
+
if: github.event_name == 'pull_request'
|
|
13
|
+
runs-on: ubuntu-latest
|
|
14
|
+
steps:
|
|
15
|
+
- uses: actions/checkout@v4
|
|
16
|
+
|
|
17
|
+
- name: Check version not already published
|
|
18
|
+
run: |
|
|
19
|
+
PACKAGE_NAME=$(node -p "require('./package.json').name")
|
|
20
|
+
VERSION=$(node -p "require('./package.json').version")
|
|
21
|
+
echo "Checking if ${PACKAGE_NAME}@${VERSION} exists on npm..."
|
|
22
|
+
if npm view "${PACKAGE_NAME}@${VERSION}" version 2>/dev/null; then
|
|
23
|
+
echo "::error::Version ${VERSION} is already published on npm. Bump the version in package.json before merging."
|
|
24
|
+
exit 1
|
|
25
|
+
else
|
|
26
|
+
echo "Version ${VERSION} is available."
|
|
27
|
+
fi
|
|
28
|
+
|
|
29
|
+
check-dependencies:
|
|
30
|
+
name: Verify no private dependencies
|
|
31
|
+
runs-on: ubuntu-latest
|
|
32
|
+
steps:
|
|
33
|
+
- uses: actions/checkout@v4
|
|
34
|
+
|
|
35
|
+
- name: Verify no private dependencies
|
|
36
|
+
run: |
|
|
37
|
+
node -e "
|
|
38
|
+
const deps = require('./package.json').dependencies || {};
|
|
39
|
+
const { execSync } = require('child_process');
|
|
40
|
+
let failed = false;
|
|
41
|
+
for (const pkg of Object.keys(deps)) {
|
|
42
|
+
try {
|
|
43
|
+
execSync('npm view ' + pkg, { stdio: 'pipe' });
|
|
44
|
+
} catch {
|
|
45
|
+
console.error('::error::Dependency ' + pkg + ' is not publicly accessible on npm');
|
|
46
|
+
failed = true;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
if (failed) process.exit(1);
|
|
50
|
+
console.log('All ' + Object.keys(deps).length + ' dependencies are public.');
|
|
51
|
+
"
|
|
52
|
+
|
|
53
|
+
publish-alpha:
|
|
54
|
+
name: Publish alpha
|
|
55
|
+
needs: check-dependencies
|
|
56
|
+
if: github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository
|
|
57
|
+
runs-on: ubuntu-latest
|
|
58
|
+
permissions:
|
|
59
|
+
id-token: write
|
|
60
|
+
contents: read
|
|
61
|
+
outputs:
|
|
62
|
+
version: ${{ steps.publish.outputs.version }}
|
|
63
|
+
steps:
|
|
64
|
+
- uses: actions/checkout@v4
|
|
65
|
+
|
|
66
|
+
- uses: actions/setup-node@v4
|
|
67
|
+
with:
|
|
68
|
+
node-version: '24'
|
|
69
|
+
registry-url: 'https://registry.npmjs.org'
|
|
70
|
+
|
|
71
|
+
- name: Install and build
|
|
72
|
+
run: npm ci && npm run build
|
|
73
|
+
|
|
74
|
+
- name: Publish alpha
|
|
75
|
+
id: publish
|
|
76
|
+
run: |
|
|
77
|
+
SHORT_SHA=$(echo ${{ github.event.pull_request.head.sha }} | cut -c1-7)
|
|
78
|
+
VERSION=$(node -p "require('./package.json').version")-alpha.${SHORT_SHA}
|
|
79
|
+
npm version $VERSION --no-git-tag-version
|
|
80
|
+
OUTPUT=$(npm publish --tag alpha 2>&1) && {
|
|
81
|
+
echo "version=$VERSION" >> $GITHUB_OUTPUT
|
|
82
|
+
} || {
|
|
83
|
+
if echo "$OUTPUT" | grep -q "You cannot publish over the previously published versions"; then
|
|
84
|
+
echo "::warning::Alpha ${VERSION} already published, skipping."
|
|
85
|
+
else
|
|
86
|
+
echo "::error::Failed to publish alpha ${VERSION}"
|
|
87
|
+
echo "$OUTPUT"
|
|
88
|
+
exit 1
|
|
89
|
+
fi
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
publish-release:
|
|
93
|
+
name: Publish release
|
|
94
|
+
needs: check-dependencies
|
|
95
|
+
if: github.event_name == 'push'
|
|
96
|
+
runs-on: ubuntu-latest
|
|
97
|
+
permissions:
|
|
98
|
+
id-token: write
|
|
99
|
+
contents: read
|
|
100
|
+
outputs:
|
|
101
|
+
version: ${{ steps.publish.outputs.version }}
|
|
102
|
+
steps:
|
|
103
|
+
- uses: actions/checkout@v4
|
|
104
|
+
|
|
105
|
+
- uses: actions/setup-node@v4
|
|
106
|
+
with:
|
|
107
|
+
node-version: '24'
|
|
108
|
+
registry-url: 'https://registry.npmjs.org'
|
|
109
|
+
|
|
110
|
+
- name: Install and build
|
|
111
|
+
run: npm ci && npm run build
|
|
112
|
+
|
|
113
|
+
- name: Publish release
|
|
114
|
+
id: publish
|
|
115
|
+
run: |
|
|
116
|
+
npm publish
|
|
117
|
+
echo "version=$(node -p "require('./package.json').version")" >> $GITHUB_OUTPUT
|
|
File without changes
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export * from './types';
|
|
2
|
-
export * from './services';
|
|
3
|
-
export * from './users';
|
|
1
|
+
export * from './types';
|
|
2
|
+
export * from './services';
|
|
3
|
+
export * from './users';
|