@kontent-ai/migration-toolkit 2.9.1 → 3.0.0-1

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 (239) hide show
  1. package/README.md +19 -17
  2. package/dist/core/config.js +3 -3
  3. package/dist/core/config.js.map +1 -1
  4. package/dist/core/helpers/workflow-helper.d.ts +1 -1
  5. package/dist/core/helpers/workflow-helper.js +28 -26
  6. package/dist/core/helpers/workflow-helper.js.map +1 -1
  7. package/dist/core/logs/loggers.d.ts +1 -1
  8. package/dist/core/logs/loggers.js +15 -15
  9. package/dist/core/logs/loggers.js.map +1 -1
  10. package/dist/core/models/core.models.d.ts +29 -22
  11. package/dist/core/models/error.models.d.ts +26 -0
  12. package/dist/core/models/error.models.js +104 -0
  13. package/dist/core/models/error.models.js.map +1 -0
  14. package/dist/core/models/log.models.d.ts +2 -2
  15. package/dist/core/models/migration.models.d.ts +17 -19
  16. package/dist/core/models/migration.schema.d.ts +9 -9
  17. package/dist/core/models/migration.schema.js +28 -28
  18. package/dist/core/models/migration.schema.js.map +1 -1
  19. package/dist/core/utils/array.utils.d.ts +1 -1
  20. package/dist/core/utils/array.utils.js +4 -3
  21. package/dist/core/utils/array.utils.js.map +1 -1
  22. package/dist/core/utils/binary-data.utils.d.ts +1 -1
  23. package/dist/core/utils/binary-data.utils.js +6 -6
  24. package/dist/core/utils/binary-data.utils.js.map +1 -1
  25. package/dist/core/utils/confirm.utils.d.ts +3 -1
  26. package/dist/core/utils/confirm.utils.js +92 -24
  27. package/dist/core/utils/confirm.utils.js.map +1 -1
  28. package/dist/core/utils/error.utils.d.ts +1 -1
  29. package/dist/core/utils/error.utils.js +16 -14
  30. package/dist/core/utils/error.utils.js.map +1 -1
  31. package/dist/core/utils/external-id.utils.js +1 -1
  32. package/dist/core/utils/external-id.utils.js.map +1 -1
  33. package/dist/core/utils/global.utils.d.ts +3 -3
  34. package/dist/core/utils/global.utils.js +20 -18
  35. package/dist/core/utils/global.utils.js.map +1 -1
  36. package/dist/core/utils/http.utils.d.ts +2 -2
  37. package/dist/core/utils/http.utils.js +4 -4
  38. package/dist/core/utils/http.utils.js.map +1 -1
  39. package/dist/core/utils/management-client-utils.d.ts +4 -4
  40. package/dist/core/utils/management-client-utils.js +37 -34
  41. package/dist/core/utils/management-client-utils.js.map +1 -1
  42. package/dist/core/utils/processing-utils.d.ts +4 -4
  43. package/dist/core/utils/processing-utils.js +13 -13
  44. package/dist/core/utils/processing-utils.js.map +1 -1
  45. package/dist/core/utils/run.utils.d.ts +2 -2
  46. package/dist/core/utils/run.utils.js +7 -7
  47. package/dist/core/utils/run.utils.js.map +1 -1
  48. package/dist/core/utils/try.utils.d.ts +14 -0
  49. package/dist/core/utils/try.utils.js +18 -0
  50. package/dist/core/utils/try.utils.js.map +1 -0
  51. package/dist/export/context/export-context-fetcher.d.ts +1 -1
  52. package/dist/export/context/export-context-fetcher.js +92 -62
  53. package/dist/export/context/export-context-fetcher.js.map +1 -1
  54. package/dist/export/export-manager.d.ts +2 -2
  55. package/dist/export/export-manager.js +73 -59
  56. package/dist/export/export-manager.js.map +1 -1
  57. package/dist/export/export.models.d.ts +21 -2
  58. package/dist/export/utils/export.utils.d.ts +1 -1
  59. package/dist/export/utils/export.utils.js +3 -2
  60. package/dist/export/utils/export.utils.js.map +1 -1
  61. package/dist/file/file-manager.d.ts +2 -2
  62. package/dist/file/file-manager.js +7 -7
  63. package/dist/file/file-manager.js.map +1 -1
  64. package/dist/import/comparers/asset-comparer.d.ts +2 -2
  65. package/dist/import/comparers/asset-comparer.js +12 -11
  66. package/dist/import/comparers/asset-comparer.js.map +1 -1
  67. package/dist/import/context/import-context-fetcher.d.ts +1 -1
  68. package/dist/import/context/import-context-fetcher.js +77 -73
  69. package/dist/import/context/import-context-fetcher.js.map +1 -1
  70. package/dist/import/import-manager.d.ts +1 -1
  71. package/dist/import/import-manager.js +59 -56
  72. package/dist/import/import-manager.js.map +1 -1
  73. package/dist/import/import.models.d.ts +6 -2
  74. package/dist/import/importers/assets-importer.d.ts +3 -3
  75. package/dist/import/importers/assets-importer.js +46 -43
  76. package/dist/import/importers/assets-importer.js.map +1 -1
  77. package/dist/import/importers/content-items-importer.d.ts +3 -3
  78. package/dist/import/importers/content-items-importer.js +28 -25
  79. package/dist/import/importers/content-items-importer.js.map +1 -1
  80. package/dist/import/importers/language-variant-importer.d.ts +3 -3
  81. package/dist/import/importers/language-variant-importer.js +45 -45
  82. package/dist/import/importers/language-variant-importer.js.map +1 -1
  83. package/dist/import/importers/workflow-importer.d.ts +3 -2
  84. package/dist/import/importers/workflow-importer.js +58 -54
  85. package/dist/import/importers/workflow-importer.js.map +1 -1
  86. package/dist/import/utils/import.utils.d.ts +1 -1
  87. package/dist/import/utils/import.utils.js +3 -2
  88. package/dist/import/utils/import.utils.js.map +1 -1
  89. package/dist/index.d.ts +11 -7
  90. package/dist/index.js +10 -8
  91. package/dist/index.js.map +1 -1
  92. package/dist/metadata.js +3 -3
  93. package/dist/metadata.js.map +1 -1
  94. package/dist/node/cli/actions/export-action.d.ts +1 -1
  95. package/dist/node/cli/actions/export-action.js +29 -23
  96. package/dist/node/cli/actions/export-action.js.map +1 -1
  97. package/dist/node/cli/actions/import-action.d.ts +1 -1
  98. package/dist/node/cli/actions/import-action.js +15 -12
  99. package/dist/node/cli/actions/import-action.js.map +1 -1
  100. package/dist/node/cli/actions/migrate-action.d.ts +1 -1
  101. package/dist/node/cli/actions/migrate-action.js +26 -22
  102. package/dist/node/cli/actions/migrate-action.js.map +1 -1
  103. package/dist/node/cli/app.js +13 -12
  104. package/dist/node/cli/app.js.map +1 -1
  105. package/dist/node/cli/args/args-fetcher.d.ts +1 -1
  106. package/dist/node/cli/args/args-fetcher.js +14 -13
  107. package/dist/node/cli/args/args-fetcher.js.map +1 -1
  108. package/dist/node/cli/args/args-setter.d.ts +1 -1
  109. package/dist/node/cli/args/args-setter.js +8 -6
  110. package/dist/node/cli/args/args-setter.js.map +1 -1
  111. package/dist/node/cli/cli.models.d.ts +2 -2
  112. package/dist/node/cli/commands.js +68 -56
  113. package/dist/node/cli/commands.js.map +1 -1
  114. package/dist/toolkit/elements-builder.d.ts +1 -1
  115. package/dist/toolkit/elements-builder.js +12 -12
  116. package/dist/toolkit/elements-builder.js.map +1 -1
  117. package/dist/toolkit/export.d.ts +2 -2
  118. package/dist/toolkit/export.js +8 -8
  119. package/dist/toolkit/export.js.map +1 -1
  120. package/dist/toolkit/file.d.ts +2 -1
  121. package/dist/toolkit/file.js +18 -16
  122. package/dist/toolkit/file.js.map +1 -1
  123. package/dist/toolkit/import.d.ts +1 -1
  124. package/dist/toolkit/import.js +12 -12
  125. package/dist/toolkit/import.js.map +1 -1
  126. package/dist/toolkit/migrate.d.ts +13 -4
  127. package/dist/toolkit/migrate.js +15 -13
  128. package/dist/toolkit/migrate.js.map +1 -1
  129. package/dist/translation/extraction/items-extraction.processor.d.ts +5 -4
  130. package/dist/translation/extraction/items-extraction.processor.js +73 -35
  131. package/dist/translation/extraction/items-extraction.processor.js.map +1 -1
  132. package/dist/translation/helpers/export-placeholder.utils.d.ts +11 -0
  133. package/dist/translation/helpers/export-placeholder.utils.js +11 -0
  134. package/dist/translation/helpers/export-placeholder.utils.js.map +1 -0
  135. package/dist/translation/helpers/rich-text.processor.d.ts +6 -6
  136. package/dist/translation/helpers/rich-text.processor.js +38 -38
  137. package/dist/translation/helpers/rich-text.processor.js.map +1 -1
  138. package/dist/translation/transforms/export-transforms.d.ts +2 -2
  139. package/dist/translation/transforms/export-transforms.js +93 -67
  140. package/dist/translation/transforms/export-transforms.js.map +1 -1
  141. package/dist/translation/transforms/import-transforms.d.ts +2 -2
  142. package/dist/translation/transforms/import-transforms.js +38 -40
  143. package/dist/translation/transforms/import-transforms.js.map +1 -1
  144. package/dist/zip/zip-manager.d.ts +4 -3
  145. package/dist/zip/zip-manager.js +9 -9
  146. package/dist/zip/zip-manager.js.map +1 -1
  147. package/dist/zip/zip-packager.d.ts +2 -2
  148. package/dist/zip/zip-packager.js +19 -17
  149. package/dist/zip/zip-packager.js.map +1 -1
  150. package/dist/zip/zip-transformer.d.ts +3 -2
  151. package/dist/zip/zip-transformer.js +16 -15
  152. package/dist/zip/zip-transformer.js.map +1 -1
  153. package/dist/zip/zip.models.d.ts +2 -2
  154. package/lib/core/config.ts +6 -6
  155. package/lib/core/helpers/workflow-helper.ts +190 -185
  156. package/lib/core/logs/loggers.ts +52 -52
  157. package/lib/core/models/core.models.ts +130 -119
  158. package/lib/core/models/error.models.ts +148 -0
  159. package/lib/core/models/log.models.ts +20 -20
  160. package/lib/core/models/migration.models.ts +54 -57
  161. package/lib/core/models/migration.schema.ts +108 -108
  162. package/lib/core/utils/array.utils.ts +43 -42
  163. package/lib/core/utils/binary-data.utils.ts +16 -16
  164. package/lib/core/utils/confirm.utils.ts +184 -106
  165. package/lib/core/utils/error.utils.ts +69 -72
  166. package/lib/core/utils/external-id.utils.ts +4 -4
  167. package/lib/core/utils/global.utils.ts +81 -75
  168. package/lib/core/utils/http.utils.ts +23 -23
  169. package/lib/core/utils/management-client-utils.ts +189 -186
  170. package/lib/core/utils/processing-utils.ts +82 -82
  171. package/lib/core/utils/run.utils.ts +50 -50
  172. package/lib/core/utils/try.utils.ts +30 -0
  173. package/lib/export/context/export-context-fetcher.ts +472 -447
  174. package/lib/export/export-manager.ts +250 -232
  175. package/lib/export/export.models.ts +71 -56
  176. package/lib/export/utils/export.utils.ts +9 -7
  177. package/lib/file/file-manager.ts +28 -28
  178. package/lib/import/comparers/asset-comparer.ts +107 -106
  179. package/lib/import/context/import-context-fetcher.ts +462 -462
  180. package/lib/import/import-manager.ts +243 -240
  181. package/lib/import/import.models.ts +69 -67
  182. package/lib/import/importers/assets-importer.ts +240 -236
  183. package/lib/import/importers/content-items-importer.ts +126 -122
  184. package/lib/import/importers/language-variant-importer.ts +324 -328
  185. package/lib/import/importers/workflow-importer.ts +372 -367
  186. package/lib/import/utils/import.utils.ts +9 -7
  187. package/lib/index.ts +12 -8
  188. package/lib/metadata.ts +3 -4
  189. package/lib/node/cli/actions/export-action.ts +44 -38
  190. package/lib/node/cli/actions/import-action.ts +32 -29
  191. package/lib/node/cli/actions/migrate-action.ts +50 -46
  192. package/lib/node/cli/app.ts +21 -21
  193. package/lib/node/cli/args/args-fetcher.ts +55 -54
  194. package/lib/node/cli/args/args-setter.ts +34 -32
  195. package/lib/node/cli/cli.models.ts +17 -17
  196. package/lib/node/cli/commands.ts +165 -153
  197. package/lib/toolkit/elements-builder.ts +69 -69
  198. package/lib/toolkit/export.ts +21 -21
  199. package/lib/toolkit/file.ts +59 -53
  200. package/lib/toolkit/import.ts +32 -32
  201. package/lib/toolkit/migrate.ts +60 -49
  202. package/lib/translation/extraction/items-extraction.processor.ts +203 -173
  203. package/lib/translation/helpers/export-placeholder.utils.ts +10 -0
  204. package/lib/translation/helpers/rich-text.processor.ts +311 -311
  205. package/lib/translation/transforms/export-transforms.ts +313 -279
  206. package/lib/translation/transforms/import-transforms.ts +188 -191
  207. package/lib/zip/zip-manager.ts +28 -27
  208. package/lib/zip/zip-packager.ts +75 -73
  209. package/lib/zip/zip-transformer.ts +112 -107
  210. package/lib/zip/zip.models.ts +7 -7
  211. package/package.json +91 -84
  212. package/dist/core/index.d.ts +0 -16
  213. package/dist/core/index.js +0 -17
  214. package/dist/core/index.js.map +0 -1
  215. package/dist/export/index.d.ts +0 -2
  216. package/dist/export/index.js +0 -3
  217. package/dist/export/index.js.map +0 -1
  218. package/dist/file/index.d.ts +0 -1
  219. package/dist/file/index.js +0 -2
  220. package/dist/file/index.js.map +0 -1
  221. package/dist/import/index.d.ts +0 -2
  222. package/dist/import/index.js +0 -3
  223. package/dist/import/index.js.map +0 -1
  224. package/dist/toolkit/index.d.ts +0 -5
  225. package/dist/toolkit/index.js +0 -6
  226. package/dist/toolkit/index.js.map +0 -1
  227. package/dist/translation/index.d.ts +0 -4
  228. package/dist/translation/index.js +0 -5
  229. package/dist/translation/index.js.map +0 -1
  230. package/dist/zip/index.d.ts +0 -4
  231. package/dist/zip/index.js +0 -5
  232. package/dist/zip/index.js.map +0 -1
  233. package/lib/core/index.ts +0 -18
  234. package/lib/export/index.ts +0 -2
  235. package/lib/file/index.ts +0 -1
  236. package/lib/import/index.ts +0 -2
  237. package/lib/toolkit/index.ts +0 -5
  238. package/lib/translation/index.ts +0 -4
  239. package/lib/zip/index.ts +0 -4
@@ -1,202 +1,207 @@
1
- import type { WorkflowContracts, WorkflowModels } from '@kontent-ai/management-sdk';
2
- import chalk from 'chalk';
3
- import { findRequired } from '../utils/array.utils.js';
1
+ import type { WorkflowContracts, WorkflowModels } from "@kontent-ai/management-sdk";
2
+ import chalk from "chalk";
3
+ import { MigrationToolkitError } from "../models/error.models.js";
4
+ import { findRequired } from "../utils/array.utils.js";
4
5
 
5
6
  export type WorkflowStep = {
6
- readonly codename: string;
7
- readonly id: string;
8
- readonly transitionsTo: readonly TransitionTo[];
7
+ readonly codename: string;
8
+ readonly id: string;
9
+ readonly transitionsTo: readonly TransitionTo[];
9
10
  };
10
11
 
11
12
  export type ShortestPathResult = {
12
- readonly stepCodename: string;
13
+ readonly stepCodename: string;
13
14
  };
14
15
 
15
16
  type WorkflowMatcher = {
16
- readonly match: (workflow: Readonly<WorkflowModels.Workflow>, index: number) => boolean;
17
- readonly errorMessage: string;
17
+ readonly match: (workflow: Readonly<WorkflowModels.Workflow>, index: number) => boolean;
18
+ readonly errorMessage: string;
18
19
  };
19
20
  type StepMatcher = {
20
- readonly match: (step: WorkflowStep, index: number) => boolean;
21
- readonly errorMessage: string;
21
+ readonly match: (step: WorkflowStep, index: number) => boolean;
22
+ readonly errorMessage: string;
22
23
  };
23
24
 
24
25
  type TransitionTo = {
25
- readonly codename: string;
26
- readonly id: string;
26
+ readonly codename: string;
27
+ readonly id: string;
27
28
  };
28
29
 
29
30
  export function workflowHelper(workflows: readonly Readonly<WorkflowModels.Workflow>[]) {
30
- const mapContractToWorkflowSteps = (
31
- workflow: Readonly<WorkflowModels.Workflow>,
32
- stepsContract: readonly Readonly<WorkflowContracts.IWorkflowStepNewContract>[]
33
- ): readonly WorkflowStep[] => {
34
- const allStepsContracts = [...workflow.steps, workflow.archivedStep, workflow.publishedStep, workflow.scheduledStep];
35
-
36
- return stepsContract.map<WorkflowStep>((m) => {
37
- return {
38
- codename: m.codename,
39
- id: m.id,
40
- transitionsTo: m.transitions_to.map((transitionTo) => {
41
- const transitionStep = allStepsContracts.find((step) => step.id === transitionTo.step.id);
42
-
43
- if (!transitionStep) {
44
- throw Error(`Could not find transition step with id '${transitionTo.step.id}' in workflow '${workflow.codename}'`);
45
- }
46
-
47
- return {
48
- codename: transitionStep.codename,
49
- id: transitionStep.id
50
- };
51
- })
52
- };
53
- });
54
- };
55
-
56
- const getWorkflowStep = (workflow: Readonly<WorkflowModels.Workflow>, stepMatcher: StepMatcher): WorkflowStep => {
57
- const workflowSteps: readonly WorkflowStep[] = [
58
- ...mapContractToWorkflowSteps(workflow, workflow.steps),
59
- {
60
- codename: workflow.archivedStep.codename,
61
- id: workflow.archivedStep.id,
62
- transitionsTo: []
63
- },
64
- {
65
- codename: workflow.publishedStep.codename,
66
- id: workflow.publishedStep.id,
67
- transitionsTo: []
68
- },
69
- {
70
- codename: workflow.scheduledStep.codename,
71
- id: workflow.scheduledStep.id,
72
- transitionsTo: []
73
- }
74
- ];
75
-
76
- return findRequired(workflowSteps, stepMatcher.match, stepMatcher.errorMessage);
77
- };
78
-
79
- const getWorkflow = (workflowMatcher: WorkflowMatcher): Readonly<WorkflowModels.Workflow> => {
80
- return findRequired(workflows, workflowMatcher.match, workflowMatcher.errorMessage);
81
- };
82
-
83
- const getWorkflowByCodename = (workflowCodename: string): Readonly<WorkflowModels.Workflow> => {
84
- return getWorkflow({
85
- errorMessage: [
86
- `Workflow with codename '${chalk.red(workflowCodename)}' does not exist in target project`,
87
- `Available workflows are (${workflows.length}): ${workflows.map((m) => chalk.cyan(m.codename)).join(', ')}`
88
- ].join(', '),
89
- match: (workflow) => workflow.codename.toLowerCase() === workflowCodename.toLowerCase()
90
- });
91
- };
92
-
93
- const getWorkflowStepByCodename = (workflow: Readonly<WorkflowModels.Workflow>, stepCodename: string): WorkflowStep => {
94
- return getWorkflowStep(workflow, {
95
- errorMessage: [
96
- `Workflow step with codename '${chalk.red(stepCodename)}' does not exist in target project`,
97
- `Steps in workflow '${chalk.yellow(workflow.codename)}' are (${workflow.steps.length}): ${workflow.steps
98
- .map((m) => chalk.cyan(m.codename))
99
- .join(', ')}`
100
- ].join(', '),
101
- match: (step) => step.codename.toLowerCase() === stepCodename.toLowerCase()
102
- });
103
- };
104
-
105
- const getWorkflowStepById = (workflow: Readonly<WorkflowModels.Workflow>, stepId: string): WorkflowStep => {
106
- return getWorkflowStep(workflow, {
107
- errorMessage: [
108
- `Workflow step with codename '${chalk.red(stepId)}' does not exist in target project`,
109
- `Steps in workflow '${chalk.yellow(workflow.codename)}' are (${workflow.steps.length}): ${workflow.steps
110
- .map((m) => chalk.cyan(m.id))
111
- .join(', ')}`
112
- ].join(', '),
113
- match: (step) => step.id.toLowerCase() === stepId.toLowerCase()
114
- });
115
- };
116
-
117
- const getWorkflowAndStep = (data: {
118
- readonly workflowMatcher: WorkflowMatcher;
119
- readonly stepMatcher: StepMatcher;
120
- }): { step: WorkflowStep; workflow: Readonly<WorkflowModels.Workflow> } => {
121
- const workflow = getWorkflow(data.workflowMatcher);
122
- return {
123
- workflow,
124
- step: getWorkflowStep(workflow, data.stepMatcher)
125
- };
126
- };
127
-
128
- const getWorkflowAndStepByCodenames = (data: {
129
- readonly workflowCodename: string;
130
- readonly stepCodename: string;
131
- }): { step: WorkflowStep; workflow: Readonly<WorkflowModels.Workflow> } => {
132
- const workflow = getWorkflowByCodename(data.workflowCodename);
133
- return {
134
- workflow,
135
- step: getWorkflowStepByCodename(workflow, data.stepCodename)
136
- };
137
- };
138
-
139
- const findShortestPathBetweenSteps = (
140
- workflow: WorkflowModels.Workflow,
141
- startStep: WorkflowStep,
142
- endStep: WorkflowStep
143
- ): ReadonlyArray<ShortestPathResult> => {
144
- type Node = Readonly<{ parent: null | Node; step: WorkflowStep }>;
145
- let deque: Array<Node> = [{ parent: null, step: startStep }];
146
-
147
- const getResult = (node: Node): ReadonlyArray<ShortestPathResult> =>
148
- node.parent === null ? [] : [...getResult(node.parent), { stepCodename: node.step.codename }];
149
-
150
- while (deque.length !== 0) {
151
- const node = deque.shift() as Node;
152
-
153
- if (node.step.codename === endStep.codename) {
154
- return getResult(node);
155
- }
156
-
157
- const newNodes = node.step.transitionsTo
158
- .filter((s) => deque.find((n) => n.step.codename === s.codename) === undefined)
159
- .map((t) => ({
160
- parent: node,
161
- step: getWorkflowStepByCodename(workflow, t.codename)
162
- }));
163
-
164
- deque = deque.concat(newNodes);
165
- }
166
-
167
- throw new Error(
168
- `Could not find the path from step (codename: ${startStep.codename}) to step (codename: ${endStep.codename}) in workflow (codename: ${workflow.codename})`
169
- );
170
- };
171
-
172
- const isPublishedStepByCodename = (stepCodename: string): boolean => {
173
- return workflows.find((workflow) => workflow.publishedStep.codename === stepCodename) ? true : false;
174
- };
175
-
176
- const isArchivedStepByCodename = (stepCodename: string): boolean => {
177
- return workflows.find((workflow) => workflow.archivedStep.codename === stepCodename) ? true : false;
178
- };
179
-
180
- const isScheduledStepByCodename = (stepCodename: string): boolean => {
181
- return workflows.find((workflow) => workflow.scheduledStep.codename === stepCodename) ? true : false;
182
- };
183
-
184
- const isPublishedStepById = (stepId: string): boolean => {
185
- return workflows.find((workflow) => workflow.publishedStep.id === stepId) ? true : false;
186
- };
187
-
188
- return {
189
- getWorkflowByCodename,
190
- getWorkflowStepByCodename,
191
- getWorkflowAndStepByCodenames,
192
- getWorkflowStepById,
193
- getWorkflowStep,
194
- getWorkflowAndStep,
195
- getWorkflow,
196
- isPublishedStepByCodename,
197
- isArchivedStepByCodename,
198
- isScheduledStepByCodename,
199
- isPublishedStepById,
200
- findShortestPathBetweenSteps
201
- };
31
+ const mapContractToWorkflowSteps = (
32
+ workflow: Readonly<WorkflowModels.Workflow>,
33
+ stepsContract: readonly Readonly<WorkflowContracts.IWorkflowStepNewContract>[],
34
+ ): readonly WorkflowStep[] => {
35
+ const allStepsContracts = [...workflow.steps, workflow.archivedStep, workflow.publishedStep, workflow.scheduledStep];
36
+
37
+ return stepsContract.map<WorkflowStep>((m) => {
38
+ return {
39
+ codename: m.codename,
40
+ id: m.id,
41
+ transitionsTo: m.transitions_to.map((transitionTo) => {
42
+ const transitionStep = allStepsContracts.find((step) => step.id === transitionTo.step.id);
43
+
44
+ if (!transitionStep) {
45
+ throw new MigrationToolkitError(
46
+ "missingWorkflowStep",
47
+ `Could not find transition step with id '${transitionTo.step.id}' in workflow '${workflow.codename}'`,
48
+ );
49
+ }
50
+
51
+ return {
52
+ codename: transitionStep.codename,
53
+ id: transitionStep.id,
54
+ };
55
+ }),
56
+ };
57
+ });
58
+ };
59
+
60
+ const getWorkflowStep = (workflow: Readonly<WorkflowModels.Workflow>, stepMatcher: StepMatcher): WorkflowStep => {
61
+ const workflowSteps: readonly WorkflowStep[] = [
62
+ ...mapContractToWorkflowSteps(workflow, workflow.steps),
63
+ {
64
+ codename: workflow.archivedStep.codename,
65
+ id: workflow.archivedStep.id,
66
+ transitionsTo: [],
67
+ },
68
+ {
69
+ codename: workflow.publishedStep.codename,
70
+ id: workflow.publishedStep.id,
71
+ transitionsTo: [],
72
+ },
73
+ {
74
+ codename: workflow.scheduledStep.codename,
75
+ id: workflow.scheduledStep.id,
76
+ transitionsTo: [],
77
+ },
78
+ ];
79
+
80
+ return findRequired(workflowSteps, stepMatcher.match, stepMatcher.errorMessage);
81
+ };
82
+
83
+ const getWorkflow = (workflowMatcher: WorkflowMatcher): Readonly<WorkflowModels.Workflow> => {
84
+ return findRequired(workflows, workflowMatcher.match, workflowMatcher.errorMessage);
85
+ };
86
+
87
+ const getWorkflowByCodename = (workflowCodename: string): Readonly<WorkflowModels.Workflow> => {
88
+ return getWorkflow({
89
+ errorMessage: [
90
+ `Workflow with codename '${chalk.red(workflowCodename)}' does not exist in target project`,
91
+ `Available workflows are (${workflows.length}): ${workflows.map((m) => chalk.cyan(m.codename)).join(", ")}`,
92
+ ].join(", "),
93
+ match: (workflow) => workflow.codename.toLowerCase() === workflowCodename.toLowerCase(),
94
+ });
95
+ };
96
+
97
+ const getWorkflowStepByCodename = (workflow: Readonly<WorkflowModels.Workflow>, stepCodename: string): WorkflowStep => {
98
+ return getWorkflowStep(workflow, {
99
+ errorMessage: [
100
+ `Workflow step with codename '${chalk.red(stepCodename)}' does not exist in target project`,
101
+ `Steps in workflow '${chalk.yellow(workflow.codename)}' are (${workflow.steps.length}): ${workflow.steps
102
+ .map((m) => chalk.cyan(m.codename))
103
+ .join(", ")}`,
104
+ ].join(", "),
105
+ match: (step) => step.codename.toLowerCase() === stepCodename.toLowerCase(),
106
+ });
107
+ };
108
+
109
+ const getWorkflowStepById = (workflow: Readonly<WorkflowModels.Workflow>, stepId: string): WorkflowStep => {
110
+ return getWorkflowStep(workflow, {
111
+ errorMessage: [
112
+ `Workflow step with codename '${chalk.red(stepId)}' does not exist in target project`,
113
+ `Steps in workflow '${chalk.yellow(workflow.codename)}' are (${workflow.steps.length}): ${workflow.steps
114
+ .map((m) => chalk.cyan(m.id))
115
+ .join(", ")}`,
116
+ ].join(", "),
117
+ match: (step) => step.id.toLowerCase() === stepId.toLowerCase(),
118
+ });
119
+ };
120
+
121
+ const getWorkflowAndStep = (data: {
122
+ readonly workflowMatcher: WorkflowMatcher;
123
+ readonly stepMatcher: StepMatcher;
124
+ }): { step: WorkflowStep; workflow: Readonly<WorkflowModels.Workflow> } => {
125
+ const workflow = getWorkflow(data.workflowMatcher);
126
+ return {
127
+ workflow,
128
+ step: getWorkflowStep(workflow, data.stepMatcher),
129
+ };
130
+ };
131
+
132
+ const getWorkflowAndStepByCodenames = (data: {
133
+ readonly workflowCodename: string;
134
+ readonly stepCodename: string;
135
+ }): { step: WorkflowStep; workflow: Readonly<WorkflowModels.Workflow> } => {
136
+ const workflow = getWorkflowByCodename(data.workflowCodename);
137
+ return {
138
+ workflow,
139
+ step: getWorkflowStepByCodename(workflow, data.stepCodename),
140
+ };
141
+ };
142
+
143
+ const findShortestPathBetweenSteps = (
144
+ workflow: WorkflowModels.Workflow,
145
+ startStep: WorkflowStep,
146
+ endStep: WorkflowStep,
147
+ ): ReadonlyArray<ShortestPathResult> => {
148
+ type Node = Readonly<{ parent: null | Node; step: WorkflowStep }>;
149
+ let deque: Array<Node> = [{ parent: null, step: startStep }];
150
+
151
+ const getResult = (node: Node): ReadonlyArray<ShortestPathResult> =>
152
+ node.parent === null ? [] : [...getResult(node.parent), { stepCodename: node.step.codename }];
153
+
154
+ while (deque.length !== 0) {
155
+ const node = deque.shift() as Node;
156
+
157
+ if (node.step.codename === endStep.codename) {
158
+ return getResult(node);
159
+ }
160
+
161
+ const newNodes = node.step.transitionsTo
162
+ // eslint-disable-next-line @typescript-eslint/no-loop-func
163
+ .filter((s) => deque.find((n) => n.step.codename === s.codename) === undefined)
164
+ .map((t) => ({
165
+ parent: node,
166
+ step: getWorkflowStepByCodename(workflow, t.codename),
167
+ }));
168
+
169
+ deque = deque.concat(newNodes);
170
+ }
171
+
172
+ throw new Error(
173
+ `Could not find the path from step (codename: ${startStep.codename}) to step (codename: ${endStep.codename}) in workflow (codename: ${workflow.codename})`,
174
+ );
175
+ };
176
+
177
+ const isPublishedStepByCodename = (stepCodename: string): boolean => {
178
+ return workflows.some((workflow) => workflow.publishedStep.codename === stepCodename);
179
+ };
180
+
181
+ const isArchivedStepByCodename = (stepCodename: string): boolean => {
182
+ return workflows.some((workflow) => workflow.archivedStep.codename === stepCodename);
183
+ };
184
+
185
+ const isScheduledStepByCodename = (stepCodename: string): boolean => {
186
+ return workflows.some((workflow) => workflow.scheduledStep.codename === stepCodename);
187
+ };
188
+
189
+ const isPublishedStepById = (stepId: string): boolean => {
190
+ return workflows.some((workflow) => workflow.publishedStep.id === stepId);
191
+ };
192
+
193
+ return {
194
+ getWorkflowByCodename,
195
+ getWorkflowStepByCodename,
196
+ getWorkflowAndStepByCodenames,
197
+ getWorkflowStepById,
198
+ getWorkflowStep,
199
+ getWorkflowAndStep,
200
+ getWorkflow,
201
+ isPublishedStepByCodename,
202
+ isArchivedStepByCodename,
203
+ isScheduledStepByCodename,
204
+ isPublishedStepById,
205
+ findShortestPathBetweenSteps,
206
+ };
202
207
  }
@@ -1,72 +1,72 @@
1
- import type { ChalkInstance } from 'chalk';
2
- import chalk from 'chalk';
3
- import { match, P } from 'ts-pattern';
4
- import type { Logger, LogSpinnerMessage } from '../models/log.models.js';
5
- import { getCurrentEnvironment } from '../utils/global.utils.js';
1
+ import type { ChalkInstance } from "chalk";
2
+ import chalk from "chalk";
3
+ import { match, P } from "ts-pattern";
4
+ import type { Logger, LogSpinnerMessage } from "../models/log.models.js";
5
+ import { getCurrentEnvironment } from "../utils/global.utils.js";
6
6
 
7
7
  const originalWarn = console.warn;
8
8
 
9
9
  export function getDefaultLogger(): Logger {
10
- return match(getCurrentEnvironment())
11
- .with('node', () => defaultNodeLogger)
12
- .with('browser', () => defaultBrowserLogger)
13
- .exhaustive();
10
+ return match(getCurrentEnvironment())
11
+ .with("node", () => defaultNodeLogger)
12
+ .with("browser", () => defaultBrowserLogger)
13
+ .exhaustive();
14
14
  }
15
15
 
16
16
  const defaultNodeLogger: Logger = {
17
- log: (data) => console.log(getLogDataMessage(data)),
18
- logWithSpinnerAsync: async (func) => {
19
- const ora = await import('ora');
17
+ log: (data) => console.log(getLogDataMessage(data)),
18
+ logWithSpinnerAsync: async (func) => {
19
+ const ora = await import("ora");
20
20
 
21
- return await ora.oraPromise(async (spinner) => {
22
- // patch global console to prevent disrupting ora instance
23
- // this often happens when JS SDK logs console.warn for
24
- // retried requests. Patching this ensures the flow is uninterrupted
25
- global.console.warn = (m) => {
26
- if (m) {
27
- spinner.text = (m as unknown)?.toString() ?? 'Invalid warn value';
28
- }
29
- };
21
+ return await ora.oraPromise(async (spinner) => {
22
+ // patch global console to prevent disrupting ora instance
23
+ // this often happens when JS SDK logs console.warn for
24
+ // retried requests. Patching this ensures the flow is uninterrupted
25
+ global.console.warn = (m) => {
26
+ if (m) {
27
+ spinner.text = (m as unknown)?.toString() ?? "Invalid warn value";
28
+ }
29
+ };
30
30
 
31
- const result = await func((data) => {
32
- // remember last used prefix. This is useful as we don't have to pass prefix to every single function
33
- // calling the spinner
34
- if (data.prefix) {
35
- spinner.prefixText = data.prefix ?? '';
36
- }
37
- spinner.text = getLogDataMessage(data);
38
- });
31
+ const result = await func((data) => {
32
+ // remember last used prefix. This is useful as we don't have to pass prefix to every single function
33
+ // calling the spinner
34
+ if (data.prefix) {
35
+ spinner.prefixText = data.prefix ?? "";
36
+ }
37
+ spinner.text = getLogDataMessage(data);
38
+ });
39
39
 
40
- // restore original warn
41
- global.console.warn = originalWarn;
40
+ // restore original warn
41
+ global.console.warn = originalWarn;
42
42
 
43
- return result;
44
- }, {});
45
- }
43
+ return result;
44
+ }, {});
45
+ },
46
46
  };
47
47
 
48
48
  const defaultBrowserLogger: Logger = {
49
- log: (data) => console.log(getLogDataMessage(data)),
50
- logWithSpinnerAsync: async (func) => {
51
- return await func((data) => {
52
- const prefix = data.prefix ? `${data.prefix}: ` : '';
53
- console.log(`${prefix}${getLogDataMessage(data)}`);
54
- });
55
- }
49
+ log: (data) => console.log(getLogDataMessage(data)),
50
+ logWithSpinnerAsync: async (func) => {
51
+ return await func((data) => {
52
+ const prefix = data.prefix ? `${data.prefix}: ` : "";
53
+ console.log(`${prefix}${getLogDataMessage(data)}`);
54
+ });
55
+ },
56
56
  };
57
57
 
58
58
  function getLogDataMessage(data: LogSpinnerMessage): string {
59
- if (!data.type) {
60
- return data.message;
61
- }
59
+ if (!data.type) {
60
+ return data.message;
61
+ }
62
62
 
63
- const color = match(data.type)
64
- .returnType<ChalkInstance>()
65
- .with('info', () => chalk.cyan)
66
- .with(P.union('error', 'errorData', 'warning', 'cancel'), () => chalk.red)
67
- .with('completed', () => chalk.green)
68
- .with('skip', () => chalk.gray)
69
- .otherwise(() => chalk.yellow);
63
+ const color = match(data.type)
64
+ .returnType<ChalkInstance>()
65
+ .with("info", () => chalk.cyan)
66
+ .with(P.union("error", "errorData", "warning", "cancel"), () => chalk.red)
67
+ .with("completed", () => chalk.green)
68
+ .with("skip", () => chalk.gray)
69
+ .otherwise(() => chalk.yellow);
70
70
 
71
- return `${color(data.type)}: ${data.message}`;
71
+ return `${color(data.type)}: ${data.message}`;
72
72
  }