@contrail/cli 2.3.4 → 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 +5 -2
- package/dist/commands/projects/load.d.ts +3 -0
- package/dist/commands/projects/load.js +55 -36
- package/dist/commands/types/mergeOptionSets.js +3 -1
- package/dist/commands/types/parseOptionSetsLocalFiles.d.ts +9 -7
- package/dist/commands/types/parseOptionSetsLocalFiles.js +33 -14
- package/dist/commands/types/uploadOptionSets.d.ts +1 -0
- package/dist/commands/types/uploadOptionSets.js +33 -20
- package/dist/helpers/projects/helpers.js +21 -16
- package/dist/helpers/types/parseOptionSetsLocalFiles.spec.d.ts +1 -0
- package/dist/helpers/types/parseOptionSetsLocalFiles.spec.js +285 -0
- package/dist/helpers/types/uploadOptionSets.spec.d.ts +1 -0
- package/dist/helpers/types/uploadOptionSets.spec.js +19 -0
- package/dist/helpers/workflow-template-definitions/workflow-template-definition-deployer.js +4 -0
- package/dist/helpers/workflow-templates/helper.js +4 -0
- package/dist/interfaces.d.ts +4 -0
- package/dist/templates/typescript/app.yml +4 -1
- package/oclif.manifest.json +9 -2
- package/package.json +1 -1
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.
|
|
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
|
-
|
|
160
|
-
|
|
161
|
-
|
|
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
|
-
|
|
170
|
-
|
|
171
|
-
//
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
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
|
-
|
|
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
|
}
|
|
@@ -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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
-
|
|
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,
|
|
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:
|
|
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;
|
|
@@ -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
|
|
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
|
-
|
|
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:
|
|
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:
|
|
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
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
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
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
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);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,285 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const parseOptionSetsLocalFiles_1 = require("../../commands/types/parseOptionSetsLocalFiles");
|
|
4
|
+
describe('parseNameAndLabelAndKey', () => {
|
|
5
|
+
it('should parse Name, Value, and Display, Disabled columns correctly if they are all present', () => {
|
|
6
|
+
const input = [
|
|
7
|
+
{
|
|
8
|
+
Name: 'Category',
|
|
9
|
+
Value: 'bottoms',
|
|
10
|
+
Display: 'Bottoms',
|
|
11
|
+
Disabled: 'false',
|
|
12
|
+
},
|
|
13
|
+
{
|
|
14
|
+
Name: 'Category',
|
|
15
|
+
Value: 'dresses',
|
|
16
|
+
Display: 'Dresses',
|
|
17
|
+
Disabled: 'true',
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
Name: 'Category',
|
|
21
|
+
Value: 'jacket',
|
|
22
|
+
Display: 'Jacket',
|
|
23
|
+
Disabled: 'true',
|
|
24
|
+
},
|
|
25
|
+
{ Name: 'Fit', Value: 'active', Display: 'Active', Disabled: 'TRUE' },
|
|
26
|
+
];
|
|
27
|
+
const expectedOutput = [
|
|
28
|
+
{
|
|
29
|
+
name: 'Category',
|
|
30
|
+
slug: 'category',
|
|
31
|
+
isArchived: false,
|
|
32
|
+
optionSet: [
|
|
33
|
+
{
|
|
34
|
+
value: 'bottoms',
|
|
35
|
+
display: 'Bottoms',
|
|
36
|
+
disabled: false,
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
value: 'dresses',
|
|
40
|
+
display: 'Dresses',
|
|
41
|
+
disabled: true,
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
value: 'jacket',
|
|
45
|
+
display: 'Jacket',
|
|
46
|
+
disabled: true,
|
|
47
|
+
},
|
|
48
|
+
],
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
name: 'Fit',
|
|
52
|
+
slug: 'fit',
|
|
53
|
+
isArchived: false,
|
|
54
|
+
optionSet: [
|
|
55
|
+
{
|
|
56
|
+
value: 'active',
|
|
57
|
+
display: 'Active',
|
|
58
|
+
disabled: true,
|
|
59
|
+
},
|
|
60
|
+
],
|
|
61
|
+
},
|
|
62
|
+
];
|
|
63
|
+
const result = (0, parseOptionSetsLocalFiles_1.parseNameAndLabelAndKey)(input);
|
|
64
|
+
expect(result).toEqual(expectedOutput);
|
|
65
|
+
});
|
|
66
|
+
it('should skip invalid rows or rows with incorrect number of columns', () => {
|
|
67
|
+
const input = [
|
|
68
|
+
{
|
|
69
|
+
Name: 'Category',
|
|
70
|
+
Value: 'dresses',
|
|
71
|
+
Display: 'Dresses',
|
|
72
|
+
},
|
|
73
|
+
{
|
|
74
|
+
Name: 'Category',
|
|
75
|
+
Value: 'bottoms',
|
|
76
|
+
Display: 'Bottoms',
|
|
77
|
+
Disabled: '', // this is invalid row which should be skipped
|
|
78
|
+
},
|
|
79
|
+
{
|
|
80
|
+
Name: 'Category',
|
|
81
|
+
Value: 'jacket',
|
|
82
|
+
},
|
|
83
|
+
{ Name: 'Fit', Value: 'active', Display: 'Active', Disabled: 'true' },
|
|
84
|
+
];
|
|
85
|
+
const expectedOutput = [
|
|
86
|
+
{
|
|
87
|
+
name: 'Category',
|
|
88
|
+
slug: 'category',
|
|
89
|
+
isArchived: false,
|
|
90
|
+
optionSet: [
|
|
91
|
+
{
|
|
92
|
+
value: 'dresses',
|
|
93
|
+
display: 'Dresses',
|
|
94
|
+
disabled: false,
|
|
95
|
+
},
|
|
96
|
+
],
|
|
97
|
+
},
|
|
98
|
+
{
|
|
99
|
+
name: 'Fit',
|
|
100
|
+
slug: 'fit',
|
|
101
|
+
isArchived: false,
|
|
102
|
+
optionSet: [
|
|
103
|
+
{
|
|
104
|
+
value: 'active',
|
|
105
|
+
display: 'Active',
|
|
106
|
+
disabled: true,
|
|
107
|
+
},
|
|
108
|
+
],
|
|
109
|
+
},
|
|
110
|
+
];
|
|
111
|
+
const result = (0, parseOptionSetsLocalFiles_1.parseNameAndLabelAndKey)(input);
|
|
112
|
+
expect(result).toEqual(expectedOutput);
|
|
113
|
+
});
|
|
114
|
+
it('should set disabled value to default value of false for invalid row values', () => {
|
|
115
|
+
const input = [
|
|
116
|
+
{
|
|
117
|
+
Name: 'Category',
|
|
118
|
+
Value: 'bottoms',
|
|
119
|
+
Display: 'Bottoms',
|
|
120
|
+
Disabled: 'false',
|
|
121
|
+
},
|
|
122
|
+
{
|
|
123
|
+
Name: 'Category',
|
|
124
|
+
Value: 'dresses',
|
|
125
|
+
Display: 'Dresses',
|
|
126
|
+
Disabled: 'test',
|
|
127
|
+
},
|
|
128
|
+
{
|
|
129
|
+
Name: 'Category',
|
|
130
|
+
Value: 'jacket',
|
|
131
|
+
Display: 'Jacket',
|
|
132
|
+
Disabled: 'abc',
|
|
133
|
+
},
|
|
134
|
+
{ Name: 'Fit', Value: 'active', Display: 'Active', Disabled: 'true' },
|
|
135
|
+
];
|
|
136
|
+
const expectedOutput = [
|
|
137
|
+
{
|
|
138
|
+
name: 'Category',
|
|
139
|
+
slug: 'category',
|
|
140
|
+
isArchived: false,
|
|
141
|
+
optionSet: [
|
|
142
|
+
{
|
|
143
|
+
value: 'bottoms',
|
|
144
|
+
display: 'Bottoms',
|
|
145
|
+
disabled: false,
|
|
146
|
+
},
|
|
147
|
+
{
|
|
148
|
+
value: 'dresses',
|
|
149
|
+
display: 'Dresses',
|
|
150
|
+
disabled: false,
|
|
151
|
+
},
|
|
152
|
+
{
|
|
153
|
+
value: 'jacket',
|
|
154
|
+
display: 'Jacket',
|
|
155
|
+
disabled: false,
|
|
156
|
+
},
|
|
157
|
+
],
|
|
158
|
+
},
|
|
159
|
+
{
|
|
160
|
+
name: 'Fit',
|
|
161
|
+
slug: 'fit',
|
|
162
|
+
isArchived: false,
|
|
163
|
+
optionSet: [
|
|
164
|
+
{
|
|
165
|
+
value: 'active',
|
|
166
|
+
display: 'Active',
|
|
167
|
+
disabled: true,
|
|
168
|
+
},
|
|
169
|
+
],
|
|
170
|
+
},
|
|
171
|
+
];
|
|
172
|
+
const result = (0, parseOptionSetsLocalFiles_1.parseNameAndLabelAndKey)(input);
|
|
173
|
+
expect(result).toEqual(expectedOutput);
|
|
174
|
+
});
|
|
175
|
+
it('should handle missing disabled field correctly', () => {
|
|
176
|
+
const input = [
|
|
177
|
+
{
|
|
178
|
+
Name: 'Category',
|
|
179
|
+
Value: 'dresses',
|
|
180
|
+
Display: 'Dresses',
|
|
181
|
+
},
|
|
182
|
+
{ Name: 'Fit', Value: 'active', Display: 'Active' },
|
|
183
|
+
];
|
|
184
|
+
const expectedOutput = [
|
|
185
|
+
{
|
|
186
|
+
name: 'Category',
|
|
187
|
+
slug: 'category',
|
|
188
|
+
isArchived: false,
|
|
189
|
+
optionSet: [
|
|
190
|
+
{
|
|
191
|
+
value: 'dresses',
|
|
192
|
+
display: 'Dresses',
|
|
193
|
+
disabled: false,
|
|
194
|
+
},
|
|
195
|
+
],
|
|
196
|
+
},
|
|
197
|
+
{
|
|
198
|
+
name: 'Fit',
|
|
199
|
+
slug: 'fit',
|
|
200
|
+
isArchived: false,
|
|
201
|
+
optionSet: [
|
|
202
|
+
{
|
|
203
|
+
value: 'active',
|
|
204
|
+
display: 'Active',
|
|
205
|
+
disabled: false,
|
|
206
|
+
},
|
|
207
|
+
],
|
|
208
|
+
},
|
|
209
|
+
];
|
|
210
|
+
const result = (0, parseOptionSetsLocalFiles_1.parseNameAndLabelAndKey)(input);
|
|
211
|
+
expect(result).toEqual(expectedOutput);
|
|
212
|
+
});
|
|
213
|
+
it('should convert number value to string', () => {
|
|
214
|
+
const input = [
|
|
215
|
+
{
|
|
216
|
+
Name: 'Category',
|
|
217
|
+
Value: 123,
|
|
218
|
+
Display: 'Category',
|
|
219
|
+
Disabled: 'false',
|
|
220
|
+
},
|
|
221
|
+
];
|
|
222
|
+
const expectedOutput = [
|
|
223
|
+
{
|
|
224
|
+
name: 'Category',
|
|
225
|
+
slug: 'category',
|
|
226
|
+
isArchived: false,
|
|
227
|
+
optionSet: [
|
|
228
|
+
{
|
|
229
|
+
value: '123',
|
|
230
|
+
display: 'Category',
|
|
231
|
+
disabled: false,
|
|
232
|
+
},
|
|
233
|
+
],
|
|
234
|
+
},
|
|
235
|
+
];
|
|
236
|
+
const result = (0, parseOptionSetsLocalFiles_1.parseNameAndLabelAndKey)(input);
|
|
237
|
+
expect(result).toEqual(expectedOutput);
|
|
238
|
+
});
|
|
239
|
+
describe('parseDisabledValue', () => {
|
|
240
|
+
it('should return true for valid "true" string', () => {
|
|
241
|
+
const input = 'true';
|
|
242
|
+
const result = (0, parseOptionSetsLocalFiles_1.parseDisabledValue)(input);
|
|
243
|
+
expect(result).toBe(true);
|
|
244
|
+
});
|
|
245
|
+
it('should return true for valid case insensitive "true" string', () => {
|
|
246
|
+
const input = 'TRUE';
|
|
247
|
+
const result = (0, parseOptionSetsLocalFiles_1.parseDisabledValue)(input);
|
|
248
|
+
expect(result).toBe(true);
|
|
249
|
+
});
|
|
250
|
+
it('should return false for valid "false" string', () => {
|
|
251
|
+
const input = 'false';
|
|
252
|
+
const result = (0, parseOptionSetsLocalFiles_1.parseDisabledValue)(input);
|
|
253
|
+
expect(result).toBe(false);
|
|
254
|
+
});
|
|
255
|
+
it('should return true for valid case insensitive "false" string', () => {
|
|
256
|
+
const input = 'FALSE';
|
|
257
|
+
const result = (0, parseOptionSetsLocalFiles_1.parseDisabledValue)(input);
|
|
258
|
+
expect(result).toBe(false);
|
|
259
|
+
});
|
|
260
|
+
it('should return false for invalid string', () => {
|
|
261
|
+
const input = 'invalid';
|
|
262
|
+
const result = (0, parseOptionSetsLocalFiles_1.parseDisabledValue)(input);
|
|
263
|
+
expect(result).toBe(false);
|
|
264
|
+
});
|
|
265
|
+
});
|
|
266
|
+
});
|
|
267
|
+
describe('parseLabelsInColumn', () => {
|
|
268
|
+
it('should parse option sets with number values as strings', () => {
|
|
269
|
+
const input = [{ Gender: 1 }, { Gender: 2 }, { Gender: 3 }];
|
|
270
|
+
const expectedOutput = [
|
|
271
|
+
{
|
|
272
|
+
name: 'Gender',
|
|
273
|
+
slug: 'gender',
|
|
274
|
+
isArchived: false,
|
|
275
|
+
optionSet: [
|
|
276
|
+
{ value: '1', display: '1' },
|
|
277
|
+
{ value: '2', display: '2' },
|
|
278
|
+
{ value: '3', display: '3' },
|
|
279
|
+
],
|
|
280
|
+
},
|
|
281
|
+
];
|
|
282
|
+
const result = (0, parseOptionSetsLocalFiles_1.parseLabelsInColumn)(input);
|
|
283
|
+
expect(result).toEqual(expectedOutput);
|
|
284
|
+
});
|
|
285
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const uploadOptionSets_1 = require("../../commands/types/uploadOptionSets");
|
|
4
|
+
describe('parseOptionSetValuesToString', () => {
|
|
5
|
+
it('should convert all option set values to strings', () => {
|
|
6
|
+
const input = {
|
|
7
|
+
value1: 123,
|
|
8
|
+
value2: true,
|
|
9
|
+
value3: { nested: 'object' },
|
|
10
|
+
};
|
|
11
|
+
const expectedOutput = {
|
|
12
|
+
value1: '123',
|
|
13
|
+
value2: 'true',
|
|
14
|
+
value3: { nested: 'object' },
|
|
15
|
+
};
|
|
16
|
+
const result = (0, uploadOptionSets_1.parseOptionSetValuesToString)(input);
|
|
17
|
+
expect(result).toEqual(expectedOutput);
|
|
18
|
+
});
|
|
19
|
+
});
|
|
@@ -62,6 +62,8 @@ class WorkflowTemplateDefinitionDeployer {
|
|
|
62
62
|
identifier: definition.identifier,
|
|
63
63
|
builtIn: definition.builtIn,
|
|
64
64
|
messageGroupId: definition.messageGroupId,
|
|
65
|
+
messageGroup: definition.messageGroup,
|
|
66
|
+
dynamicMessageGroupId: definition.dynamicMessageGroupId,
|
|
65
67
|
parallelWorkerCount: definition.parallelWorkerCount,
|
|
66
68
|
triggerKey: definition.triggerKey,
|
|
67
69
|
workflowDefinition: definition.workflowDefinition,
|
|
@@ -115,6 +117,8 @@ class WorkflowTemplateDefinitionDeployer {
|
|
|
115
117
|
public: workflowDeclaration.public,
|
|
116
118
|
isActive: workflowDeclaration.isActive,
|
|
117
119
|
messageGroupId: workflowDeclaration.messageGroupId,
|
|
120
|
+
messageGroup: workflowDeclaration.messageGroup,
|
|
121
|
+
dynamicMessageGroupId: workflowDeclaration.dynamicMessageGroupId,
|
|
118
122
|
parallelWorkerCount: workflowDeclaration.parallelWorkerCount,
|
|
119
123
|
};
|
|
120
124
|
const workflowTemplate = await (0, event_workflow_template_definition_1.createWorkflowTemplateDefinition)(newObject);
|
|
@@ -44,6 +44,8 @@ class LocalWorkflowTemplateDeployer {
|
|
|
44
44
|
isActive: workflowTemplate.isActive,
|
|
45
45
|
supportingAppId: workflowTemplate.supportingAppId,
|
|
46
46
|
messageGroupId: workflowTemplate.messageGroupId,
|
|
47
|
+
messageGroup: workflowTemplate.messageGroup,
|
|
48
|
+
dynamicMessageGroupId: workflowTemplate.dynamicMessageGroupId,
|
|
47
49
|
parallelWorkerCount: workflowTemplate.parallelWorkerCount,
|
|
48
50
|
};
|
|
49
51
|
const newWorkflowTemplate = await (0, event_workflow_templates_1.createWorkflowTemplate)(newObject);
|
|
@@ -159,6 +161,8 @@ class LocalWorkflowTemplateDeployer {
|
|
|
159
161
|
builtIn: workflowTemplate.builtIn,
|
|
160
162
|
workflowDefinition: workflowTemplate.workflowDefinition,
|
|
161
163
|
messageGroupId: workflowTemplate.messageGroupId ?? existingWorkflowTemplate.messageGroupId,
|
|
164
|
+
messageGroup: workflowTemplate.messageGroup ?? existingWorkflowTemplate.messageGroup,
|
|
165
|
+
dynamicMessageGroupId: workflowTemplate.dynamicMessageGroupId ?? existingWorkflowTemplate.dynamicMessageGroupId,
|
|
162
166
|
parallelWorkerCount: workflowTemplate.parallelWorkerCount ?? existingWorkflowTemplate.parallelWorkerCount,
|
|
163
167
|
});
|
|
164
168
|
const updatedWorkflowTemplate = await (0, event_workflow_templates_1.updateWorkflowTemplate)({
|
package/dist/interfaces.d.ts
CHANGED
|
@@ -73,6 +73,8 @@ export interface WorkflowDefinition {
|
|
|
73
73
|
supportingAppId?: string;
|
|
74
74
|
parallelWorkerCount?: number;
|
|
75
75
|
messageGroupId?: string;
|
|
76
|
+
messageGroup?: string;
|
|
77
|
+
dynamicMessageGroupId?: string;
|
|
76
78
|
}
|
|
77
79
|
export interface WorkflowTemplateDeclaration {
|
|
78
80
|
appIdentifier: string;
|
|
@@ -91,6 +93,8 @@ export interface WorkflowTemplate {
|
|
|
91
93
|
supportingAppId?: string;
|
|
92
94
|
parallelWorkerCount?: number;
|
|
93
95
|
messageGroupId?: string;
|
|
96
|
+
messageGroup?: string;
|
|
97
|
+
dynamicMessageGroupId?: string;
|
|
94
98
|
createdOn?: Date;
|
|
95
99
|
updatedOn?: Date;
|
|
96
100
|
createdById?: string;
|
|
@@ -34,7 +34,10 @@ workflows:
|
|
|
34
34
|
triggerKey: item|update
|
|
35
35
|
isActive: true
|
|
36
36
|
public: true
|
|
37
|
-
|
|
37
|
+
parallelWorkerCount: 5 # The maximum number of concurrent jobs to run for this workflow (Range 1-30). Defaults to 5
|
|
38
|
+
messageGroupId: # Optional. Used to group jobs in a specific queue. Allows multiple workflows to use the same queue. Not to be used with dynamicMessageGroupId
|
|
39
|
+
messageGroup: # Optional. Used with dynamicMessageGroupId to allow for dynamic queue assignment and allows for multiple workflows to use the same queue
|
|
40
|
+
dynamicMessageGroupId: # Optional. Allows for dynamic queue assignment based on the event data. Example usage: 'family-queue-{newData.itemFamilyId}'
|
|
38
41
|
workflowDefinition:
|
|
39
42
|
paths:
|
|
40
43
|
- conditional: "true"
|
package/oclif.manifest.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "2.3.
|
|
2
|
+
"version": "2.3.5",
|
|
3
3
|
"commands": {
|
|
4
4
|
"app:create": {
|
|
5
5
|
"id": "app:create",
|
|
@@ -537,7 +537,14 @@
|
|
|
537
537
|
"examples": [
|
|
538
538
|
"$ contrail project load <TEMPLATE_FILE_LOCATION>\n"
|
|
539
539
|
],
|
|
540
|
-
"flags": {
|
|
540
|
+
"flags": {
|
|
541
|
+
"dumpTransformedFile": {
|
|
542
|
+
"name": "dumpTransformedFile",
|
|
543
|
+
"type": "boolean",
|
|
544
|
+
"description": "If set to true, stores a transformed version of the template file",
|
|
545
|
+
"allowNo": false
|
|
546
|
+
}
|
|
547
|
+
},
|
|
541
548
|
"args": {
|
|
542
549
|
"templateFileLocation": {
|
|
543
550
|
"name": "templateFileLocation",
|