@contrail/cli 2.3.3 → 2.3.5

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 CHANGED
@@ -17,7 +17,7 @@ $ npm install -g @contrail/cli
17
17
  $ contrail COMMAND
18
18
  running command...
19
19
  $ contrail (--version)
20
- @contrail/cli/2.3.3 darwin-arm64 node-v18.13.0
20
+ @contrail/cli/2.3.5 darwin-arm64 node-v22.3.0
21
21
  $ contrail --help [COMMAND]
22
22
  USAGE
23
23
  $ contrail COMMAND
@@ -876,11 +876,14 @@ Configure a project from a yml file.
876
876
 
877
877
  ```
878
878
  USAGE
879
- $ contrail projects load TEMPLATEFILELOCATION
879
+ $ contrail projects load TEMPLATEFILELOCATION [--dumpTransformedFile]
880
880
 
881
881
  ARGUMENTS
882
882
  TEMPLATEFILELOCATION The location to the template file
883
883
 
884
+ FLAGS
885
+ --dumpTransformedFile If set to true, stores a transformed version of the template file
886
+
884
887
  DESCRIPTION
885
888
  Configure a project from a yml file.
886
889
 
@@ -5,6 +5,9 @@ export default class LoadProject extends BaseCommand {
5
5
  static args: {
6
6
  templateFileLocation: import("@oclif/core/lib/interfaces/parser").Arg<string, Record<string, unknown>>;
7
7
  };
8
+ static flags: {
9
+ dumpTransformedFile: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
10
+ };
8
11
  run(): Promise<void>;
9
12
  }
10
13
  interface CheckerFunction {
@@ -9,6 +9,8 @@ const login_1 = require("../../auth/login");
9
9
  const basecommand_1 = require("../../basecommand");
10
10
  const helpers_1 = require("../../helpers/projects/helpers");
11
11
  const logger_1 = tslib_1.__importDefault(require("../../logger"));
12
+ const pLimit = require('p-limit');
13
+ const limit = pLimit(30);
12
14
  class LoadProject extends basecommand_1.BaseCommand {
13
15
  static description = 'Configure a project from a yml file.';
14
16
  static examples = [
@@ -21,18 +23,26 @@ class LoadProject extends basecommand_1.BaseCommand {
21
23
  required: true,
22
24
  }),
23
25
  };
26
+ static flags = {
27
+ ...basecommand_1.BaseCommand.flags,
28
+ dumpTransformedFile: core_1.Flags.boolean({
29
+ description: 'If set to true, stores a transformed version of the template file',
30
+ default: false,
31
+ }),
32
+ };
24
33
  async run() {
25
- const { args } = await this.parse(LoadProject);
34
+ const { args, flags } = await this.parse(LoadProject);
26
35
  try {
27
36
  await (0, login_1.authUser)();
28
37
  this.log('%s Parsing Template.', chalk_1.default.blue.bold('START'));
29
38
  this.log('%s Uploading', chalk_1.default.yellow.bold('PROJECT'));
30
39
  const templateFileLocation = args.templateFileLocation;
31
40
  this.log('Using Template File Location: ', args.templateFileLocation);
32
- await uploadProject(templateFileLocation);
41
+ await uploadProject(templateFileLocation, flags);
33
42
  this.log('%s Uploaded', chalk_1.default.yellow.bold('PROJECT'));
34
43
  }
35
44
  catch (e) {
45
+ console.error(e);
36
46
  this.log(`%s Project Upload Failed. ${e}`, chalk_1.default.red.bold('FAIL'));
37
47
  return;
38
48
  }
@@ -40,11 +50,16 @@ class LoadProject extends basecommand_1.BaseCommand {
40
50
  }
41
51
  }
42
52
  exports.default = LoadProject;
43
- async function uploadProject(templateFileLocation) {
53
+ async function uploadProject(templateFileLocation, flags) {
44
54
  const projectConfigurationFromFile = (0, helpers_1.getProjectFile)(templateFileLocation);
45
55
  const projectConfiguration = getProjectConfiguration(projectConfigurationFromFile);
46
56
  logger_1.default.info('Checking for object and type references');
47
57
  await transformProject(projectConfiguration);
58
+ if (flags.dumpTransformedFile) {
59
+ logger_1.default.info('Dumping transformed project file');
60
+ const fs = require('fs');
61
+ fs.writeFileSync(templateFileLocation + '.transformed', JSON.stringify(projectConfiguration, null, 2));
62
+ }
48
63
  logger_1.default.info('Configuring Project.');
49
64
  await sdk_1.Request.request('/project-configurator', {
50
65
  method: 'POST',
@@ -155,43 +170,47 @@ async function transformAssortmentObjectReferences(_, assortments) {
155
170
  relations: ['typeProperties'],
156
171
  });
157
172
  const assortmentProperties = assortmentType.typeProperties;
173
+ const promises = [];
158
174
  for (const assortment of assortments ?? []) {
159
- const attributes = JSON.parse(JSON.stringify(assortment?.assortmentAtts ?? {}));
160
- if (!Object.keys(attributes)?.length) {
161
- continue;
162
- }
163
- for (const [attributeKey, attributeValue] of Object.entries(attributes)) {
164
- const property = assortmentProperties.find((x) => x.slug === attributeKey);
165
- // if not a reference
166
- if (!property || !property.referencedTypePath) {
167
- continue;
175
+ promises.push(limit(async () => {
176
+ const attributes = JSON.parse(JSON.stringify(assortment?.assortmentAtts ?? {}));
177
+ if (!Object.keys(attributes)?.length) {
178
+ return;
168
179
  }
169
- if (property.propertyType === types_1.PropertyType.TypeReference) {
170
- logger_1.default.debug(`found type reference!${attributeKey}${attributeValue}`);
171
- // special case: handle type references
172
- const type = (await new sdk_1.Types().getType({ path: attributeValue }))?.id;
173
- logger_1.default.debug(`found type ${type}`);
174
- logger_1.default.info(`replacing ${attributeKey}:${attributeValue} with ${attributeKey}Id:${type}`);
175
- assortment.assortmentAtts[`${attributeKey}Id`] = type;
176
- }
177
- else if (property.propertyType === types_1.PropertyType.ObjectReference) {
178
- logger_1.default.debug(`found object reference!${attributeKey}${attributeValue}`);
179
- let allEntities = [];
180
- if (property.referencedTypePath.startsWith('custom-entity')) {
181
- allEntities = await new sdk_1.Entities().get({
182
- entityName: 'custom-entity',
183
- criteria: { typePath: property.referencedTypePath },
184
- });
180
+ for (const [attributeKey, attributeValue] of Object.entries(attributes)) {
181
+ const property = assortmentProperties.find((x) => x.slug === attributeKey);
182
+ // if not a reference
183
+ if (!property || !property.referencedTypePath) {
184
+ continue;
185
+ }
186
+ if (property.propertyType === types_1.PropertyType.TypeReference) {
187
+ logger_1.default.debug(`found type reference!${attributeKey}${attributeValue}`);
188
+ // special case: handle type references
189
+ const type = (await new sdk_1.Types().getType({ path: attributeValue }))?.id;
190
+ logger_1.default.debug(`found type ${type}`);
191
+ logger_1.default.info(`replacing ${attributeKey}:${attributeValue} with ${attributeKey}Id:${type}`);
192
+ assortment.assortmentAtts[`${attributeKey}Id`] = type;
185
193
  }
186
- else {
187
- allEntities = await new sdk_1.Entities().get({ entityName: property.referencedTypePath });
194
+ else if (property.propertyType === types_1.PropertyType.ObjectReference) {
195
+ logger_1.default.debug(`found object reference!${attributeKey}${attributeValue}`);
196
+ let allEntities = [];
197
+ if (property.referencedTypePath.startsWith('custom-entity')) {
198
+ allEntities = await new sdk_1.Entities().get({
199
+ entityName: 'custom-entity',
200
+ criteria: { typePath: property.referencedTypePath },
201
+ });
202
+ }
203
+ else {
204
+ allEntities = await new sdk_1.Entities().get({ entityName: property.referencedTypePath });
205
+ }
206
+ // special case: handle type references
207
+ const foundAttribute = allEntities.find((x) => x.name === attributeValue)?.id ?? attributeKey;
208
+ logger_1.default.debug(`found attribute ${foundAttribute}`);
209
+ logger_1.default.info(`replacing ${attributeKey}:${attributeValue} with ${attributeKey}Id:${foundAttribute}`);
210
+ assortment.assortmentAtts[`${attributeKey}Id`] = foundAttribute;
188
211
  }
189
- // special case: handle type references
190
- const foundAttribute = allEntities.find((x) => x.name === attributeValue)?.id ?? attributeKey;
191
- logger_1.default.debug(`found attribute ${foundAttribute}`);
192
- logger_1.default.info(`replacing ${attributeKey}:${attributeValue} with ${attributeKey}Id:${foundAttribute}`);
193
- assortment.assortmentAtts[`${attributeKey}Id`] = foundAttribute;
194
212
  }
195
- }
213
+ }));
214
+ await Promise.all(promises);
196
215
  }
197
216
  }
@@ -312,6 +312,9 @@ function reduceTypes(dataHolder) {
312
312
  for (const type of dataHolder.types) {
313
313
  const reducedTypeProperties = [];
314
314
  for (const typeProperty of type.typeProperties) {
315
+ if (typeProperty.inherited) {
316
+ continue;
317
+ }
315
318
  const reducedTypeProperty = {
316
319
  slug: typeProperty.slug,
317
320
  id: typeProperty.id,
@@ -325,10 +328,14 @@ function reduceTypes(dataHolder) {
325
328
  formula: typeProperty.formula,
326
329
  referencedTypePath: typeProperty.referencedTypePath,
327
330
  referencedTypeRootSlug: typeProperty.referencedTypeRootSlug,
331
+ typePropertyUserListId: typeProperty.typePropertyUserListId,
332
+ referencedTypeRole: typeProperty.referencedTypeRole,
328
333
  defaultValue: typeProperty.defaultValue,
329
334
  propertyLevel: typeProperty.propertyLevel,
330
335
  carryOverBehavior: typeProperty.carryOverBehavior,
331
336
  carryOverDefault: typeProperty.carryOverDefault,
337
+ isUniqueProperty: typeProperty.isUniqueProperty,
338
+ isUniquePropertyInFamily: typeProperty.isUniquePropertyInFamily,
332
339
  inherited: typeProperty.inherited,
333
340
  formulaFunction: typeProperty.formulaFunction,
334
341
  validationFunction: typeProperty.validationFunction,
@@ -55,6 +55,7 @@ async function mergeOptionSets(fileLocation) {
55
55
  const currentOptionSets = currentOptionSetsFull.map((os) => Object.assign({}, {
56
56
  name: os.name,
57
57
  isArchived: os.isArchived,
58
+ slug: os.slug,
58
59
  optionSet: os.optionSet,
59
60
  }));
60
61
  const currentOptionSetsByName = {};
@@ -101,9 +102,10 @@ function mergeOptionSet(existingOptionSet, uploadedOptionSet) {
101
102
  for (const keyVal of existingOptionSet.optionSet) {
102
103
  const value = keyVal.value;
103
104
  const display = keyVal.display;
105
+ const disabled = keyVal?.disabled;
104
106
  const found = merged.optionSet.find((keyVal) => keyVal.value === value);
105
107
  if (!found) {
106
- merged.optionSet.push({ value, display });
108
+ merged.optionSet.push({ value, display, disabled });
107
109
  }
108
110
  }
109
111
  }
@@ -18,18 +18,20 @@ export declare function ParseOptionSetsToFolderStructure(args: any): Promise<voi
18
18
  */
19
19
  export declare function parseLabelsInColumn(uploadedOptionData: any): any[];
20
20
  /**
21
- * Expects a CSV file with an ignored header file and 3 columns:
21
+ * Expects a CSV file with an ignored header file and 4 columns:
22
22
  * The first column contains the option set name (e.g. Gender)
23
23
  * The second column contains the option keys (e.g. ge_men)
24
- * The second column contains the option display label (e.g. Men)
24
+ * The third column contains the option display label (e.g. Men)
25
+ * The fourth column contains the disabled value (e.g. true / false)
25
26
  *
26
27
  * Sample file
27
- * ignored header 1, ignored header 2, ignored header 3
28
- * Gender, ge_men, Men
29
- * Gender, ge_women, Women
30
- * Brand, b_prada, Prada
31
- * Brand, b_coach, Coach
28
+ * ignored header 1, ignored header 2, ignored header 3, ignored header 4
29
+ * Gender, ge_men, Men, true
30
+ * Gender, ge_women, Women, false
31
+ * Brand, b_prada, Prada, true
32
+ * Brand, b_coach, Coach, true
32
33
  * @param uploadedOptionData
33
34
  * @returns
34
35
  */
35
36
  export declare function parseNameAndLabelAndKey(uploadedOptionData: any[]): any[];
37
+ export declare function parseDisabledValue(stringValue: string): boolean;
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.parseNameAndLabelAndKey = exports.parseLabelsInColumn = exports.ParseOptionSetsToFolderStructure = void 0;
3
+ exports.parseDisabledValue = exports.parseNameAndLabelAndKey = exports.parseLabelsInColumn = exports.ParseOptionSetsToFolderStructure = void 0;
4
4
  const tslib_1 = require("tslib");
5
5
  const path = tslib_1.__importStar(require("path"));
6
6
  const fs_1 = tslib_1.__importDefault(require("fs"));
@@ -154,7 +154,7 @@ function parseLabelsInColumn(uploadedOptionData) {
154
154
  const uniqueOptionSetValues = new Set();
155
155
  for (const data of uploadedOptionData) {
156
156
  const label = data[optionSetName];
157
- uniqueOptionSetValues.add(label);
157
+ uniqueOptionSetValues.add(label.toString()); // Parse the value to string
158
158
  }
159
159
  const optionSet = [];
160
160
  if (uniqueOptionSetValues) {
@@ -180,17 +180,18 @@ function parseLabelsInColumn(uploadedOptionData) {
180
180
  }
181
181
  exports.parseLabelsInColumn = parseLabelsInColumn;
182
182
  /**
183
- * Expects a CSV file with an ignored header file and 3 columns:
183
+ * Expects a CSV file with an ignored header file and 4 columns:
184
184
  * The first column contains the option set name (e.g. Gender)
185
185
  * The second column contains the option keys (e.g. ge_men)
186
- * The second column contains the option display label (e.g. Men)
186
+ * The third column contains the option display label (e.g. Men)
187
+ * The fourth column contains the disabled value (e.g. true / false)
187
188
  *
188
189
  * Sample file
189
- * ignored header 1, ignored header 2, ignored header 3
190
- * Gender, ge_men, Men
191
- * Gender, ge_women, Women
192
- * Brand, b_prada, Prada
193
- * Brand, b_coach, Coach
190
+ * ignored header 1, ignored header 2, ignored header 3, ignored header 4
191
+ * Gender, ge_men, Men, true
192
+ * Gender, ge_women, Women, false
193
+ * Brand, b_prada, Prada, true
194
+ * Brand, b_coach, Coach, true
194
195
  * @param uploadedOptionData
195
196
  * @returns
196
197
  */
@@ -198,7 +199,7 @@ function parseNameAndLabelAndKey(uploadedOptionData) {
198
199
  const optionSets = {};
199
200
  for (const csvRow of uploadedOptionData) {
200
201
  const row = Object.values(csvRow);
201
- if (row.length !== 3 || row.some((x) => !x)) {
202
+ if (!(row.length === 4 || row.length === 3) || row.some((x) => !x)) {
202
203
  console.log('skipping bad row', JSON.stringify(row, null, 2));
203
204
  continue;
204
205
  }
@@ -208,15 +209,23 @@ function parseNameAndLabelAndKey(uploadedOptionData) {
208
209
  }
209
210
  const key = row[1];
210
211
  const label = row[2];
211
- optionSets[optionSetName][key] = label;
212
+ let disabled = false;
213
+ if (row.length === 4) {
214
+ // as bad row is skipped above, testString is always a string
215
+ const testString = row[3];
216
+ disabled = parseDisabledValue(testString);
217
+ }
218
+ optionSets[optionSetName][key] = { label, disabled };
212
219
  }
213
220
  const result = [];
214
221
  for (const optionSetName of Object.keys(optionSets)) {
215
222
  const optionSet = [];
216
- for (const [key, value] of Object.entries(optionSets[optionSetName])) {
223
+ for (const [key, obj] of Object.entries(optionSets[optionSetName])) {
224
+ const optionObj = obj; // Add type annotation
217
225
  optionSet.push({
218
- value: key,
219
- display: value,
226
+ value: key.toString(),
227
+ display: optionObj?.label,
228
+ disabled: optionObj?.disabled, // Use the type annotated variable
220
229
  });
221
230
  }
222
231
  const reducedOptionSet = {
@@ -230,3 +239,13 @@ function parseNameAndLabelAndKey(uploadedOptionData) {
230
239
  return result;
231
240
  }
232
241
  exports.parseNameAndLabelAndKey = parseNameAndLabelAndKey;
242
+ function parseDisabledValue(stringValue) {
243
+ const testString = /^true$/i.test(stringValue?.trim());
244
+ const isDisabledFalse = testString === false;
245
+ const isDisabledTrue = testString === true;
246
+ if (!isDisabledFalse && !isDisabledTrue) {
247
+ console.warn(`Invalid value (${stringValue}) for disabled attribute. Must be either "true" or "false"`);
248
+ }
249
+ return isDisabledTrue;
250
+ }
251
+ exports.parseDisabledValue = parseDisabledValue;
@@ -8,3 +8,4 @@ export default class UploadOptionSets extends BaseCommand {
8
8
  run(): Promise<void>;
9
9
  }
10
10
  export declare function uploadOptionSets(dir: string): Promise<void>;
11
+ export declare function parseOptionSetValuesToString(optionSet: any): any;
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.uploadOptionSets = void 0;
3
+ exports.parseOptionSetValuesToString = exports.uploadOptionSets = void 0;
4
4
  const tslib_1 = require("tslib");
5
5
  const sdk_1 = require("@contrail/sdk");
6
6
  const fs_1 = tslib_1.__importDefault(require("fs"));
@@ -11,6 +11,7 @@ const core_1 = require("@oclif/core");
11
11
  const basecommand_1 = require("../../basecommand");
12
12
  const logger_1 = tslib_1.__importDefault(require("../../logger"));
13
13
  const js_yaml_1 = tslib_1.__importDefault(require("js-yaml"));
14
+ const lodash_1 = require("lodash");
14
15
  class UploadOptionSets extends basecommand_1.BaseCommand {
15
16
  static description = 'Upload OptionSets for your Org. OptionSets are loaded from .yml files in the option-sets directory.';
16
17
  static examples = [
@@ -34,7 +35,7 @@ exports.default = UploadOptionSets;
34
35
  async function uploadOptionSets(dir) {
35
36
  try {
36
37
  const userConfig = await (0, login_1.authUser)();
37
- logger_1.default.info(`${chalk_1.default.blue.bold('START')} Getting all types for orgId: ${userConfig.orgId}`);
38
+ logger_1.default.info(`${chalk_1.default.blue.bold('START')} Getting all types for org ${userConfig.orgSlug}`);
38
39
  logger_1.default.info(`${chalk_1.default.yellow.bold('OPTION SETS')} Uploading`);
39
40
  await uploadOS(dir);
40
41
  logger_1.default.info(`${chalk_1.default.yellow.bold('OPTION SETS')} Uploaded`);
@@ -60,6 +61,17 @@ function loadOptionSets(fromDir) {
60
61
  throw new Error(`ERROR PARSING YAML: ${e}`);
61
62
  }
62
63
  }
64
+ function parseOptionSetValuesToString(optionSet) {
65
+ return (0, lodash_1.cloneDeepWith)(optionSet, (value) => {
66
+ // If the value is an object or array, let cloneDeepWith handle it
67
+ if ((0, lodash_1.isObject)(value) || (0, lodash_1.isArray)(value)) {
68
+ return undefined;
69
+ }
70
+ // Otherwise, convert the value to string
71
+ return String(value);
72
+ });
73
+ }
74
+ exports.parseOptionSetValuesToString = parseOptionSetValuesToString;
63
75
  async function uploadOS(dir) {
64
76
  const optionSets = loadOptionSets(dir);
65
77
  const currentOptionSets = await new sdk_1.Entities().get({
@@ -83,18 +95,20 @@ async function uploadOS(dir) {
83
95
  logger_1.default.info(`No OptionSet for: ${optionSet.slug}`);
84
96
  continue;
85
97
  }
86
- logger_1.default.info(`Creating: ${JSON.stringify(optionSet, null, 2)}`);
98
+ const parsedOptionSet = parseOptionSetValuesToString(optionSet.optionSet);
99
+ logger_1.default.info(`Creating: ${JSON.stringify(parsedOptionSet, null, 2)}`);
87
100
  await new sdk_1.Entities().create({
88
101
  entityName: 'type-property-option-set',
89
102
  object: {
90
103
  name: optionSet.name,
91
104
  slug: optionSet.slug,
92
- optionSet: optionSet.optionSet,
105
+ optionSet: parsedOptionSet,
93
106
  isArchived: optionSet.isArchived,
94
107
  },
95
108
  });
96
109
  }
97
110
  else {
111
+ const parsedOptionSet = parseOptionSetValuesToString(optionSet.optionSet);
98
112
  logger_1.default.info(`Updating: ${optionSet.slug}`);
99
113
  await new sdk_1.Entities().update({
100
114
  entityName: 'type-property-option-set',
@@ -102,7 +116,7 @@ async function uploadOS(dir) {
102
116
  object: {
103
117
  name: optionSet.name,
104
118
  slug: optionSet.slug,
105
- optionSet: optionSet.optionSet,
119
+ optionSet: parsedOptionSet,
106
120
  isArchived: optionSet.isArchived,
107
121
  },
108
122
  });
@@ -112,19 +126,18 @@ async function uploadOS(dir) {
112
126
  logger_1.default.error(`Error Uploading OptionSets: ${err}`);
113
127
  }
114
128
  }
115
- for (const currentOptionSet of currentOptionSets) {
116
- try {
117
- const found = newOptionSetsBySlug[currentOptionSet.slug];
118
- if (!found) {
119
- logger_1.default.info(`Deleting: ${currentOptionSet.slug}`);
120
- await new sdk_1.Entities().delete({
121
- entityName: 'type-property-option-set',
122
- id: currentOptionSet.id,
123
- });
124
- }
125
- }
126
- catch (err) {
127
- logger_1.default.error(`Error Deleting OptionSets: ${err}`);
128
- }
129
- }
129
+ // for (const currentOptionSet of currentOptionSets) {
130
+ // try {
131
+ // const found = newOptionSetsBySlug[currentOptionSet.slug];
132
+ // if (!found) {
133
+ // logger.info(`Deleting: ${currentOptionSet.slug}`);
134
+ // await new Entities().delete({
135
+ // entityName: 'type-property-option-set',
136
+ // id: currentOptionSet.id,
137
+ // });
138
+ // }
139
+ // } catch (err) {
140
+ // logger.error(`Error Deleting OptionSets: ${err}`);
141
+ // }
142
+ // }
130
143
  }
@@ -8,6 +8,9 @@ const fs_1 = tslib_1.__importDefault(require("fs"));
8
8
  const sdk_1 = require("@contrail/sdk");
9
9
  const util_1 = require("@contrail/util");
10
10
  const logger_1 = tslib_1.__importDefault(require("../../logger"));
11
+ const uuid_1 = require("uuid");
12
+ const pLimit = require('p-limit');
13
+ const limit = pLimit(30);
11
14
  function getProjectFile(fileName) {
12
15
  const CURRENT_DIR = process.cwd();
13
16
  try {
@@ -52,7 +55,7 @@ async function getAssortmentsAndSubFolders(parentId, assortments, subFolders, al
52
55
  workspaceId: parentId,
53
56
  },
54
57
  });
55
- const integrationAssortments = workspaceAssortments; //?.filter(a => a.assortmentType === 'INTEGRATION');
58
+ const integrationAssortments = workspaceAssortments.filter((x) => x.assortmentType !== 'BACKING'); //?.filter(a => a.assortmentType === 'INTEGRATION');
56
59
  if (integrationAssortments?.length > 0) {
57
60
  allAssortments.push(...integrationAssortments);
58
61
  for (const a of integrationAssortments) {
@@ -60,7 +63,7 @@ async function getAssortmentsAndSubFolders(parentId, assortments, subFolders, al
60
63
  deleteNonUserKeys(integrationAssortmentsCopy);
61
64
  const assortmentType = a.assortmentType === 'INTEGRATION' ? 'ASSORTMENT' : a.assortmentType;
62
65
  const converted = {
63
- identifier: a.identifier,
66
+ identifier: a.identifier ?? `${a.name}_${(0, uuid_1.v4)()}.assortment`,
64
67
  name: a.name,
65
68
  type: assortmentType,
66
69
  sourceAssortmentIdentifier: [],
@@ -82,20 +85,18 @@ async function getAssortmentsAndSubFolders(parentId, assortments, subFolders, al
82
85
  relations: ['entity'],
83
86
  });
84
87
  const workspaceFolders = workspaceFolderLinks?.map((wfl) => wfl.entity);
85
- if (workspaceFolders?.length > 0) {
86
- for (const folder of workspaceFolders) {
87
- const converted = {
88
- identifier: folder.identifier,
89
- name: folder.name,
90
- principals: [],
91
- assortments: [],
92
- subFolders: [],
93
- };
94
- converted.principals = await getFolderPrincipals(folder);
95
- await getAssortmentsAndSubFolders(folder.id, converted.assortments, converted.subFolders, allAssortments);
96
- subFolders.push(converted);
97
- }
98
- }
88
+ await Promise.all((workspaceFolders ?? [])?.map((folder) => limit(async () => {
89
+ const converted = {
90
+ identifier: folder.identifier ?? `${folder.name}_${(0, uuid_1.v4)()}.folder`,
91
+ name: folder.name,
92
+ principals: [],
93
+ assortments: [],
94
+ subFolders: [],
95
+ };
96
+ converted.principals = await getFolderPrincipals(folder);
97
+ await getAssortmentsAndSubFolders(folder.id, converted.assortments, converted.subFolders, allAssortments);
98
+ subFolders.push(converted);
99
+ })));
99
100
  }
100
101
  function convertRelationshipsInFolders(folder, allAssortments) {
101
102
  if (!(allAssortments.length > 0)) {
@@ -159,6 +160,10 @@ function deleteNonUserKeys(assortment) {
159
160
  delete assortment.updatedById;
160
161
  delete assortment.updatedOn;
161
162
  delete assortment.workspaceId;
163
+ delete assortment.itemTypeId;
164
+ if (assortment.itemType && typeof assortment.itemType === 'object') {
165
+ assortment.itemType = assortment.itemType?.typePath;
166
+ }
162
167
  }
163
168
  function saveData(data, name) {
164
169
  const yamlStr = js_yaml_1.default.dump(data);