@contrail/cli 3.5.2 → 3.5.3-alpha.0e9434c

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.
Files changed (67) hide show
  1. package/README.md +11 -29
  2. package/dist/api/types.d.ts +0 -5
  3. package/dist/api/types.js +1 -36
  4. package/dist/commands/types/getAll.js +0 -18
  5. package/dist/commands/types/loadAll.js +0 -2
  6. package/dist/commands/types/mergeTypeProperties.js +0 -5
  7. package/dist/commands/types/uploadOptionSetHierarchies.js +0 -117
  8. package/dist/commands/types/uploadOptionSets.js +1 -1
  9. package/dist/commands/types/uploadRuleSets.js +2 -85
  10. package/dist/commands/types/uploadTypeOverrides.js +10 -2
  11. package/dist/commands/types/uploadTypePolicies.js +2 -86
  12. package/dist/commands/types/uploadTypePropertyPolicies.d.ts +0 -1
  13. package/dist/commands/types/uploadTypePropertyPolicies.js +3 -139
  14. package/dist/commands/workflow-templates/export.d.ts +3 -1
  15. package/dist/commands/workflow-templates/export.js +105 -28
  16. package/dist/helpers/types/type-uploader.js +1 -1
  17. package/dist/helpers/workflow-templates/helper.d.ts +1 -0
  18. package/dist/helpers/workflow-templates/helper.js +27 -6
  19. package/dist/interfaces.d.ts +0 -25
  20. package/dist/templates/typescript/tsup.config.ts +0 -0
  21. package/node_modules/@contrail/org-config-migration/.github/workflows/publish-to-npm.yml +117 -0
  22. package/node_modules/@contrail/org-config-migration/.husky/pre-commit +0 -0
  23. package/node_modules/@contrail/org-config-migration/lib/index.d.ts +3 -3
  24. package/node_modules/@contrail/org-config-migration/lib/index.js +19 -19
  25. package/node_modules/@contrail/org-config-migration/lib/interfaces.d.ts +87 -97
  26. package/node_modules/@contrail/org-config-migration/lib/interfaces.js +2 -2
  27. package/node_modules/@contrail/org-config-migration/lib/services/index.d.ts +1 -1
  28. package/node_modules/@contrail/org-config-migration/lib/services/index.js +17 -17
  29. package/node_modules/@contrail/org-config-migration/lib/services/types.d.ts +12 -17
  30. package/node_modules/@contrail/org-config-migration/lib/services/types.js +115 -155
  31. package/node_modules/@contrail/org-config-migration/lib/types/exportAll.d.ts +2 -2
  32. package/node_modules/@contrail/org-config-migration/lib/types/exportAll.js +34 -40
  33. package/node_modules/@contrail/org-config-migration/lib/types/exportOptionSet.d.ts +2 -2
  34. package/node_modules/@contrail/org-config-migration/lib/types/exportOptionSet.js +20 -20
  35. package/node_modules/@contrail/org-config-migration/lib/types/exportOptionSetHierarchies.d.ts +2 -3
  36. package/node_modules/@contrail/org-config-migration/lib/types/exportOptionSetHierarchies.js +16 -47
  37. package/node_modules/@contrail/org-config-migration/lib/types/exportOverrides.d.ts +2 -2
  38. package/node_modules/@contrail/org-config-migration/lib/types/exportOverrides.js +8 -8
  39. package/node_modules/@contrail/org-config-migration/lib/types/exportRuleSets.d.ts +2 -3
  40. package/node_modules/@contrail/org-config-migration/lib/types/exportRuleSets.js +14 -39
  41. package/node_modules/@contrail/org-config-migration/lib/types/exportTypePolicies.d.ts +2 -3
  42. package/node_modules/@contrail/org-config-migration/lib/types/exportTypePolicies.js +44 -56
  43. package/node_modules/@contrail/org-config-migration/lib/types/exportTypePropertyPolicies.d.ts +2 -3
  44. package/node_modules/@contrail/org-config-migration/lib/types/exportTypePropertyPolicies.js +44 -71
  45. package/node_modules/@contrail/org-config-migration/lib/types/exportTypes.d.ts +2 -2
  46. package/node_modules/@contrail/org-config-migration/lib/types/exportTypes.js +85 -85
  47. package/node_modules/@contrail/org-config-migration/lib/types/importAll.d.ts +2 -2
  48. package/node_modules/@contrail/org-config-migration/lib/types/importAll.js +386 -451
  49. package/node_modules/@contrail/org-config-migration/lib/types/index.d.ts +8 -9
  50. package/node_modules/@contrail/org-config-migration/lib/types/index.js +24 -25
  51. package/node_modules/@contrail/org-config-migration/lib/types/parseOptionSetHierarchy.d.ts +3 -3
  52. package/node_modules/@contrail/org-config-migration/lib/types/parseOptionSetHierarchy.js +210 -210
  53. package/node_modules/@contrail/org-config-migration/lib/users/export.d.ts +2 -2
  54. package/node_modules/@contrail/org-config-migration/lib/users/export.js +40 -40
  55. package/node_modules/@contrail/org-config-migration/lib/users/import.d.ts +2 -2
  56. package/node_modules/@contrail/org-config-migration/lib/users/import.js +41 -41
  57. package/node_modules/@contrail/org-config-migration/lib/users/index.d.ts +2 -2
  58. package/node_modules/@contrail/org-config-migration/lib/users/index.js +18 -18
  59. package/node_modules/@contrail/org-config-migration/package.json +1 -1
  60. package/oclif.manifest.json +15 -56
  61. package/package.json +2 -2
  62. package/dist/commands/types/uploadUsageInfo.d.ts +0 -15
  63. package/dist/commands/types/uploadUsageInfo.js +0 -180
  64. package/dist/commands/types/uploadUsageInfo.spec.d.ts +0 -1
  65. package/dist/commands/types/uploadUsageInfo.spec.js +0 -249
  66. package/node_modules/@contrail/org-config-migration/lib/types/exportUsageInfo.d.ts +0 -2
  67. package/node_modules/@contrail/org-config-migration/lib/types/exportUsageInfo.js +0 -39
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.findAllOccurrences = exports.uploadTypePropertyPolicies = void 0;
3
+ exports.uploadTypePropertyPolicies = 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"));
@@ -8,12 +8,10 @@ const path = tslib_1.__importStar(require("path"));
8
8
  const login_1 = require("../../auth/login");
9
9
  const chalk_1 = tslib_1.__importDefault(require("chalk"));
10
10
  const core_1 = require("@oclif/core");
11
- const type_extractor_1 = require("../../helpers/types/type-extractor");
12
11
  const users_1 = require("../../api/users");
13
12
  const basecommand_1 = require("../../basecommand");
14
13
  const logger_1 = tslib_1.__importDefault(require("../../logger"));
15
14
  const js_yaml_1 = tslib_1.__importDefault(require("js-yaml"));
16
- const _ = tslib_1.__importStar(require("lodash"));
17
15
  class UploadTypePropertyPolicies extends basecommand_1.BaseCommand {
18
16
  static description = 'Upload type property policies';
19
17
  static examples = [
@@ -38,14 +36,12 @@ async function uploadTypePropertyPolicies(dir) {
38
36
  try {
39
37
  await (0, login_1.authUser)();
40
38
  logger_1.default.info(`${chalk_1.default.yellow.bold('TYPE PROPERTY POLICY')} Uploading`);
41
- const [reducedTypePropertyPolicies, reducedTypePropertyPolicyLinks] = await loadTPPolicies(dir);
39
+ const reducedTypePropertyPolicies = await loadTPPolicies(dir);
42
40
  await uploadTPPolicyObjects(reducedTypePropertyPolicies);
43
- await uploadTypePropertyPolicyLinks(reducedTypePropertyPolicyLinks);
44
41
  logger_1.default.info(`${chalk_1.default.yellow.bold('TYPE PROPERTY POLICY')} Uploaded`);
45
42
  }
46
43
  catch (e) {
47
44
  logger_1.default.info(`${chalk_1.default.red.bold('FAIL')} Type Property Policy Upload Failed . ${e}`);
48
- //TODO make this only print if a debug flag is set
49
45
  console.trace(e);
50
46
  return;
51
47
  }
@@ -54,15 +50,13 @@ async function uploadTypePropertyPolicies(dir) {
54
50
  exports.uploadTypePropertyPolicies = uploadTypePropertyPolicies;
55
51
  function loadTPPolicies(fromDir) {
56
52
  const tpps = [];
57
- let tppLinks = [];
58
53
  const dir = path.join(fromDir, 'type-property-policies');
59
54
  try {
60
55
  const files = fs_1.default.readdirSync(dir);
61
56
  for (const file of files) {
62
57
  tpps.push(js_yaml_1.default.load(fs_1.default.readFileSync(path.join(dir, file), 'utf8')));
63
58
  }
64
- tppLinks = js_yaml_1.default.load(fs_1.default.readFileSync(path.join(fromDir, 'type-property-policy-links.yml'), 'utf8'));
65
- return [tpps, tppLinks];
59
+ return tpps;
66
60
  }
67
61
  catch (e) {
68
62
  throw new Error(`ERROR PARSING YAML: ${e}`);
@@ -155,133 +149,3 @@ async function uploadTPPolicyObjects(reducedTypePropertyPolicies) {
155
149
  }
156
150
  }
157
151
  }
158
- async function uploadTypePropertyPolicyLinks(reducedTypePropertyPolicyLinks) {
159
- const typesWithProperties = await (0, type_extractor_1.getTypes)();
160
- const typeProperties = [];
161
- typesWithProperties.forEach((type) => {
162
- if (type.typeProperties) {
163
- for (const tp of type.typeProperties) {
164
- tp.typeId = type.id;
165
- tp.typeSlug = type.slug;
166
- typeProperties.push(tp);
167
- }
168
- }
169
- });
170
- const currentTPPs = await new sdk_1.Entities().get({
171
- entityName: 'type-property-policy',
172
- });
173
- const currentTPPLinks = await new sdk_1.Entities().get({
174
- entityName: 'type-property-policy-link',
175
- });
176
- logger_1.default.info(`found ${currentTPPLinks.length} current type property policy links`);
177
- logger_1.default.info(`found ${reducedTypePropertyPolicyLinks.length} type property policy links to load`);
178
- const currentLinksHashes = {};
179
- for (const currentLink of currentTPPLinks) {
180
- const foundTPs = findAllOccurrences(typeProperties, (tp) => tp.id === currentLink.typePropertyId);
181
- for (const foundTP of foundTPs) {
182
- const foundTPP = currentTPPs.find((tpp) => tpp.id === currentLink.typePropertyPolicyId);
183
- if (!foundTP || !foundTPP) {
184
- logger_1.default.info(`skipping unhashable, invalid policy link: ${JSON.stringify(currentLink, null, 2)}`);
185
- continue;
186
- }
187
- const hash = `${foundTP.typeSlug}|${foundTP.slug}|${foundTPP.identifier}`;
188
- currentLinksHashes[hash] = currentLink;
189
- }
190
- }
191
- logger_1.default.debug(`current links hashes: ${JSON.stringify(currentLinksHashes, null, 2)}`);
192
- const reducedLinksByHashes = {};
193
- for (const loadedLink of reducedTypePropertyPolicyLinks) {
194
- const hash = `${loadedLink.typeSlug}|${loadedLink.typePropertySlug}|${loadedLink.typePropertyPolicyIdentifier}`;
195
- reducedLinksByHashes[hash] = loadedLink;
196
- }
197
- const toCreate = Object.keys(reducedLinksByHashes)
198
- .filter((x) => !currentLinksHashes[x])
199
- .map((x) => {
200
- return {
201
- [x]: reducedLinksByHashes[x],
202
- };
203
- })
204
- .reduce((a, b) => Object.assign(a, b), {});
205
- const toDelete = _.uniqBy(Object.keys(currentLinksHashes)
206
- .filter((x) => !reducedLinksByHashes[x])
207
- .map((x) => {
208
- return {
209
- [x]: currentLinksHashes[x],
210
- };
211
- }), 'id').reduce((a, b) => Object.assign(a, b), {});
212
- logger_1.default.debug(`reduced links hashes: ${JSON.stringify(reducedLinksByHashes, null, 2)}`);
213
- logger_1.default.info(`found ${Object.keys(toCreate).length} type property policy links to create`);
214
- logger_1.default.info(`found ${Object.keys(toDelete).length} type property policy links to delete`);
215
- logger_1.default.debug(`to create: ${JSON.stringify(toCreate, null, 2)}`);
216
- logger_1.default.debug(`to delete: ${JSON.stringify(toDelete, null, 2)}`);
217
- logger_1.default.debug(`current links hashes to delete: ${JSON.stringify(Object.keys(currentLinksHashes).filter((x) => !reducedLinksByHashes[x]), null, 2)}`);
218
- // fs.writeFileSync('toCreate.json', JSON.stringify(toCreate, null, 2));
219
- // fs.writeFileSync('toDelete.json', JSON.stringify(toDelete, null, 2));
220
- // fs.writeFileSync('currentLinksHashes.json', JSON.stringify(currentLinksHashes, null, 2));
221
- // fs.writeFileSync('reducedLinksByHashes.json', JSON.stringify(reducedLinksByHashes, null, 2));
222
- // fs.writeFileSync(
223
- // 'current_link_hashes_to_delete.json',
224
- // JSON.stringify(
225
- // Object.keys(currentLinksHashes).filter((x) => !reducedLinksByHashes[x]),
226
- // null,
227
- // 2,
228
- // ),
229
- // );
230
- // return;
231
- for (const [hash, link] of Object.entries(toCreate)) {
232
- try {
233
- if (!transformReducedLink(link, typeProperties, currentTPPs)) {
234
- continue;
235
- }
236
- logger_1.default.info(`Creating: ${hash}: ${JSON.stringify(link, null, 2)}`);
237
- await new sdk_1.Entities().create({
238
- entityName: 'type-property-policy-link',
239
- object: {
240
- typePropertyPolicyId: link.typePropertyPolicyId,
241
- typePropertyId: link.typePropertyId,
242
- },
243
- });
244
- }
245
- catch (err) {
246
- logger_1.default.error(`Error Uploading type property policy links: ${err}`);
247
- }
248
- }
249
- for (const [hash, link] of Object.entries(toDelete)) {
250
- try {
251
- logger_1.default.info(`Deleting: ${hash}`);
252
- await new sdk_1.Entities().delete({
253
- entityName: 'type-property-policy-link',
254
- id: link['id'],
255
- });
256
- }
257
- catch (err) {
258
- logger_1.default.error(`Error Deleting type property policy link: ${err}`);
259
- }
260
- }
261
- function transformReducedLink(TPPLink, typeProperties, typePropertyPolicies) {
262
- const foundTP = typeProperties.find((tp) => tp.slug === TPPLink.typePropertySlug && tp.typeSlug === TPPLink.typeSlug);
263
- if (!foundTP) {
264
- logger_1.default.error(`Could not find type property with slug ${TPPLink.typePropertySlug} `);
265
- return false;
266
- }
267
- TPPLink.typePropertyId = foundTP.id;
268
- const foundTPP = typePropertyPolicies.find((tpp) => tpp.identifier === TPPLink.typePropertyPolicyIdentifier);
269
- if (!foundTPP) {
270
- logger_1.default.error(`Could not find type property policy with identifier ${TPPLink.typePropertyPolicyIdentifier} `);
271
- return false;
272
- }
273
- TPPLink.typePropertyPolicyId = foundTPP.id;
274
- return true;
275
- }
276
- }
277
- function findAllOccurrences(array, evaluator) {
278
- const found = [];
279
- for (let i = 0; i < array.length; i++) {
280
- const element = array[i];
281
- if (evaluator(element)) {
282
- found.push(element);
283
- }
284
- }
285
- return found;
286
- }
287
- exports.findAllOccurrences = findAllOccurrences;
@@ -5,10 +5,12 @@ export default class ExportWorkflows extends BaseCommand {
5
5
  static examples: string[];
6
6
  static flags: {
7
7
  outFile: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces/parser").CustomOptions>;
8
+ dir: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces/parser").CustomOptions>;
8
9
  overwrite: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
9
10
  alwaysConfirmEnv: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces/parser").CustomOptions>;
10
11
  logLevel: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces/parser").CustomOptions>;
11
12
  };
12
13
  run(): Promise<void>;
13
14
  }
14
- export declare function exportWorkflows(fileLocation: string, overwrite: boolean): Promise<void>;
15
+ export declare function exportWorkflowsByApp(outputDir: string, overwrite: boolean): Promise<void>;
16
+ export declare function exportWorkflowsToFile(fileLocation: string, overwrite: boolean): Promise<void>;
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.exportWorkflows = exports.DEFAULT_FILE_LOCATION = void 0;
3
+ exports.exportWorkflowsToFile = exports.exportWorkflowsByApp = exports.DEFAULT_FILE_LOCATION = void 0;
4
4
  const tslib_1 = require("tslib");
5
5
  const path = tslib_1.__importStar(require("path"));
6
6
  const chalk_1 = tslib_1.__importDefault(require("chalk"));
@@ -11,22 +11,30 @@ const js_yaml_1 = tslib_1.__importDefault(require("js-yaml"));
11
11
  const core_1 = require("@oclif/core");
12
12
  const file_helpers_1 = require("../../helpers/file-helpers");
13
13
  const event_workflow_templates_1 = require("../../api/event-workflow-templates");
14
+ const schedules_1 = require("../../api/schedules");
15
+ const apps_1 = require("../../api/apps");
14
16
  const helper_1 = require("../../helpers/workflow-templates/helper");
15
17
  const basecommand_1 = require("../../basecommand");
16
18
  exports.DEFAULT_FILE_LOCATION = 'workflows.yml';
17
19
  class ExportWorkflows extends basecommand_1.BaseCommand {
18
- static description = 'Export all workflows in the org.';
20
+ static description = 'Export all workflows in the org. By default exports one file per app to the current directory.';
19
21
  static examples = [
20
- `$ contrail workflow-templates export
21
- `,
22
+ '$ contrail workflow-templates export',
23
+ '$ contrail workflow-templates export --dir ./workflows',
24
+ '$ contrail workflow-templates export --outFile workflows.yml',
22
25
  ];
23
26
  static flags = {
24
27
  ...basecommand_1.BaseCommand.baseFlags,
25
28
  outFile: core_1.Flags.string({
26
29
  char: 'f',
27
- description: 'The location for the file to be saved',
30
+ description: 'Export all workflows to a single file at this path (overrides per-app export)',
28
31
  required: false,
29
- default: exports.DEFAULT_FILE_LOCATION,
32
+ }),
33
+ dir: core_1.Flags.string({
34
+ char: 'd',
35
+ description: 'Directory to write per-app workflow files',
36
+ required: false,
37
+ default: '.',
30
38
  }),
31
39
  overwrite: core_1.Flags.boolean({
32
40
  description: 'Replaces existing files if they exist',
@@ -38,7 +46,12 @@ class ExportWorkflows extends basecommand_1.BaseCommand {
38
46
  try {
39
47
  await (0, login_1.authUser)();
40
48
  this.log(`${chalk_1.default.blue.bold('START')} Getting Workflows.`);
41
- await exportWorkflows(this.flags.outFile ?? exports.DEFAULT_FILE_LOCATION, this.flags.overwrite);
49
+ if (this.flags.outFile) {
50
+ await exportWorkflowsToFile(this.flags.outFile, this.flags.overwrite);
51
+ }
52
+ else {
53
+ await exportWorkflowsByApp(this.flags.dir ?? '.', this.flags.overwrite);
54
+ }
42
55
  this.log(`${chalk_1.default.yellow.bold('WORKFLOWS')} Done`);
43
56
  }
44
57
  catch (e) {
@@ -49,31 +62,95 @@ class ExportWorkflows extends basecommand_1.BaseCommand {
49
62
  }
50
63
  }
51
64
  exports.default = ExportWorkflows;
52
- async function exportWorkflows(fileLocation, overwrite) {
65
+ async function exportWorkflowsByApp(outputDir, overwrite) {
53
66
  const allWorkflowsInOrg = await (0, event_workflow_templates_1.getExistingWorkflowTemplates)();
67
+ const allSchedules = await (0, schedules_1.getExistingSchedules)();
68
+ const installedApps = await (0, apps_1.getInstalledApps)();
69
+ const appIdToIdentifier = new Map(installedApps.map((a) => [a.appId, a.app.identifier]));
70
+ const workflowsByApp = new Map();
71
+ const unassigned = [];
72
+ for (const workflow of allWorkflowsInOrg) {
73
+ let appIdentifier = workflow.supportingAppId
74
+ ? appIdToIdentifier.get(workflow.supportingAppId)
75
+ : undefined;
76
+ // If no supportingAppId, try to extract app identifier from workflow identifier
77
+ // Format: @{appIdentifier}@{randomId}:{workflowName}
78
+ if (!appIdentifier && workflow.identifier) {
79
+ const match = workflow.identifier.match(/^@([^@]+)@/);
80
+ if (match) {
81
+ // Keep the @ prefix in the appIdentifier
82
+ appIdentifier = `@${match[1]}`;
83
+ }
84
+ }
85
+ if (appIdentifier) {
86
+ if (!workflowsByApp.has(appIdentifier)) {
87
+ workflowsByApp.set(appIdentifier, []);
88
+ }
89
+ const workflows = workflowsByApp.get(appIdentifier);
90
+ if (workflows) {
91
+ workflows.push(workflow);
92
+ }
93
+ }
94
+ else {
95
+ unassigned.push(workflow);
96
+ }
97
+ }
98
+ const resolvedDir = path.resolve(process.cwd(), outputDir);
99
+ for (const [appIdentifier, workflows] of workflowsByApp.entries()) {
100
+ const exportObj = { appIdentifier, workflows: [] };
101
+ for (const workflow of workflows) {
102
+ exportObj.workflows.push(await buildExportWorkflow(workflow, allSchedules));
103
+ }
104
+ const safeAppIdentifier = appIdentifier.replace(/[\\/]/g, '-');
105
+ const filePath = path.join(resolvedDir, `workflows-${safeAppIdentifier}.yml`);
106
+ await writeYamlFile(exportObj, filePath, overwrite);
107
+ console.log(`${chalk_1.default.green('EXPORTED')} ${filePath}`);
108
+ }
109
+ if (unassigned.length > 0) {
110
+ const unassignedObj = { workflows: [] };
111
+ for (const workflow of unassigned) {
112
+ unassignedObj.workflows.push(await buildExportWorkflow(workflow, allSchedules));
113
+ }
114
+ const unassignedFilePath = path.join(resolvedDir, 'workflows-unassigned.yml');
115
+ await writeYamlFile(unassignedObj, unassignedFilePath, overwrite);
116
+ console.log(`${chalk_1.default.yellow('EXPORTED')} ${unassignedFilePath} (unassigned workflows)`);
117
+ }
118
+ }
119
+ exports.exportWorkflowsByApp = exportWorkflowsByApp;
120
+ async function exportWorkflowsToFile(fileLocation, overwrite) {
121
+ const allWorkflowsInOrg = await (0, event_workflow_templates_1.getExistingWorkflowTemplates)();
122
+ const allSchedules = await (0, schedules_1.getExistingSchedules)();
54
123
  const workflowsObj = { workflows: [] };
55
124
  for (const workflow of allWorkflowsInOrg) {
56
- const exportWorkflow = lodash_1.default.pick(workflow, [
57
- 'triggerKey',
58
- 'workflowDefinition',
59
- 'name',
60
- 'isActive',
61
- 'identifier',
62
- 'messageGroup',
63
- 'dynamicMessageGroupId',
64
- ]);
65
- await (0, helper_1.populateActionIdentifiers)(exportWorkflow);
66
- workflowsObj.workflows.push(exportWorkflow);
125
+ workflowsObj.workflows.push(await buildExportWorkflow(workflow, allSchedules));
126
+ }
127
+ const pathToWrite = path.resolve(process.cwd(), fileLocation);
128
+ await writeYamlFile(workflowsObj, pathToWrite, overwrite);
129
+ }
130
+ exports.exportWorkflowsToFile = exportWorkflowsToFile;
131
+ async function buildExportWorkflow(workflow, allSchedules) {
132
+ const exportWorkflow = lodash_1.default.pick(workflow, [
133
+ 'identifier',
134
+ 'name',
135
+ 'triggerKey',
136
+ 'isActive',
137
+ 'messageGroup',
138
+ 'dynamicMessageGroupId',
139
+ 'parallelWorkerCount',
140
+ 'workflowDefinition',
141
+ ]);
142
+ const schedules = allSchedules.filter((s) => s.ownerReference === `event-workflow-template:${workflow.id}`);
143
+ if (schedules.length > 0) {
144
+ exportWorkflow.crons = schedules.map((s) => ({ name: s.name, cron: s.cron }));
67
145
  }
68
- await saveData(workflowsObj, fileLocation, overwrite);
146
+ await (0, helper_1.populateActionIdentifiers)(exportWorkflow);
147
+ (0, helper_1.extractShortActionKeys)(exportWorkflow);
148
+ return exportWorkflow;
69
149
  }
70
- exports.exportWorkflows = exportWorkflows;
71
- async function saveData(data, fileLocation, overwrite) {
72
- const yamlStr = js_yaml_1.default.dump(data);
73
- const CURRENT_DIR = process.cwd();
74
- const pathToWrite = path.resolve(path.join(CURRENT_DIR, fileLocation));
75
- if (fs_1.default.existsSync(pathToWrite)) {
76
- await (0, file_helpers_1.safeFileOverwrite)(pathToWrite, overwrite);
150
+ async function writeYamlFile(data, absolutePath, overwrite) {
151
+ if (fs_1.default.existsSync(absolutePath)) {
152
+ await (0, file_helpers_1.safeFileOverwrite)(absolutePath, overwrite);
77
153
  }
78
- fs_1.default.writeFileSync(pathToWrite, yamlStr, 'utf8');
154
+ fs_1.default.mkdirSync(path.dirname(absolutePath), { recursive: true });
155
+ fs_1.default.writeFileSync(absolutePath, js_yaml_1.default.dump(data), 'utf8');
79
156
  }
@@ -303,7 +303,7 @@ async function uploadReducedTypeProperties(type, currentPropertyTypes, newProper
303
303
  }
304
304
  }
305
305
  catch (err) {
306
- throw new Error(`Error Deleting Properties: ${err}`);
306
+ logger_1.default.error(`Error Deleting Type-Property ${currentPropertyType.slug}: ${err}`);
307
307
  }
308
308
  }
309
309
  }
@@ -18,3 +18,4 @@ export declare class WorkflowTemplateDeployer {
18
18
  export declare function deleteWorkflowTemplates(): Promise<void>;
19
19
  export declare function localDeployWorkflowTemplate(saveFileLocation: string): Promise<void>;
20
20
  export declare function populateActionIdentifiers(workflowTemplate: WorkflowTemplate): Promise<void>;
21
+ export declare function extractShortActionKeys(workflowTemplate: WorkflowTemplate): void;
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.populateActionIdentifiers = exports.localDeployWorkflowTemplate = exports.deleteWorkflowTemplates = exports.WorkflowTemplateDeployer = exports.getActionByIdentifier = exports.getWorkflowTemplateIdentifier = exports.LocalWorkflowTemplateDeployer = void 0;
3
+ exports.extractShortActionKeys = exports.populateActionIdentifiers = exports.localDeployWorkflowTemplate = exports.deleteWorkflowTemplates = exports.WorkflowTemplateDeployer = exports.getActionByIdentifier = exports.getWorkflowTemplateIdentifier = exports.LocalWorkflowTemplateDeployer = void 0;
4
4
  const tslib_1 = require("tslib");
5
5
  const util_1 = require("@contrail/util");
6
6
  const chalk_1 = tslib_1.__importDefault(require("chalk"));
@@ -20,7 +20,6 @@ class LocalWorkflowTemplateDeployer {
20
20
  const existingWorkflows = await (0, event_workflow_templates_1.getExistingWorkflowTemplates)();
21
21
  // UPSERT / DELETE BASED ON WORKFLOW TEMPLATES IDENTIFIER
22
22
  logger_1.default.info(`${chalk_1.default.yellow.bold('WORKFLOW TEMPLATES')} Deploying workflow templates.`);
23
- logger_1.default.info(wtDeclaration);
24
23
  for (const workflowKey of Object.keys(wtDeclaration.workflows)) {
25
24
  await this.deployWorkflowTemplate(wtDeclaration.workflows[workflowKey], existingWorkflows, wtDeclaration.appIdentifier);
26
25
  }
@@ -35,7 +34,7 @@ class LocalWorkflowTemplateDeployer {
35
34
  return await this.createNewWorkflowTemplate(identifier, workflow, appIdentifier);
36
35
  }
37
36
  async createNewWorkflowTemplate(workflowKey, workflowTemplate, appIdentifier) {
38
- await this.populateActionIds(workflowTemplate, workflowKey, appIdentifier);
37
+ this.populateActionIds(workflowTemplate, workflowKey, appIdentifier);
39
38
  const newObject = {
40
39
  identifier: getWorkflowTemplateIdentifier(workflowTemplate),
41
40
  name: workflowTemplate.name,
@@ -44,6 +43,8 @@ class LocalWorkflowTemplateDeployer {
44
43
  isActive: workflowTemplate.isActive,
45
44
  supportingAppId: workflowTemplate.supportingAppId,
46
45
  messageGroupId: workflowTemplate.messageGroupId,
46
+ messageGroup: workflowTemplate.messageGroup,
47
+ dynamicMessageGroupId: workflowTemplate.dynamicMessageGroupId,
47
48
  parallelWorkerCount: workflowTemplate.parallelWorkerCount,
48
49
  };
49
50
  const newWorkflowTemplate = await (0, event_workflow_templates_1.createWorkflowTemplate)(newObject);
@@ -55,8 +56,10 @@ class LocalWorkflowTemplateDeployer {
55
56
  }
56
57
  async populateActionIds(workflowTemplate, workflowKey, appIdentifier) {
57
58
  const installedApps = await (0, apps_1.getInstalledApps)();
58
- const appOrg = installedApps.find((x) => x.app.identifier === appIdentifier);
59
- logger_1.default.info('workflow template:', JSON.stringify(workflowTemplate, null, 2));
59
+ const appOrg = installedApps.find((x) => x.app?.identifier === appIdentifier);
60
+ if (!appOrg) {
61
+ throw new Error(`Could not find installed app with identifier "${appIdentifier}". Make sure the app is installed in this org before importing workflows.`);
62
+ }
60
63
  if (!workflowTemplate?.workflowDefinition?.paths) {
61
64
  return;
62
65
  }
@@ -86,7 +89,7 @@ class LocalWorkflowTemplateDeployer {
86
89
  }
87
90
  }
88
91
  async createWorkflowSchedule(workflowTemplate, workflowId) {
89
- if (!workflowTemplate?.crons?.length || !workflowTemplate.id) {
92
+ if (!workflowTemplate?.crons?.length) {
90
93
  return;
91
94
  }
92
95
  const crons = [];
@@ -283,3 +286,21 @@ async function populateActionIdentifiers(workflowTemplate) {
283
286
  }
284
287
  }
285
288
  exports.populateActionIdentifiers = populateActionIdentifiers;
289
+ function extractShortActionKeys(workflowTemplate) {
290
+ if (!workflowTemplate?.workflowDefinition?.paths) {
291
+ return;
292
+ }
293
+ for (const wfPath of workflowTemplate.workflowDefinition.paths) {
294
+ if (!wfPath?.actionDefinitionConfigs) {
295
+ continue;
296
+ }
297
+ for (const actionConfig of wfPath.actionDefinitionConfigs) {
298
+ if (actionConfig.action?.includes(':')) {
299
+ // Full identifier format: "app-id@version:action-name" -> "action-name"
300
+ actionConfig.action = actionConfig.action.split(':').pop();
301
+ }
302
+ delete actionConfig.identifier;
303
+ }
304
+ }
305
+ }
306
+ exports.extractShortActionKeys = extractShortActionKeys;
@@ -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
@@ -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';