@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,291 +1,325 @@
1
- import type { ContentTypeElements, TaxonomyModels } from '@kontent-ai/management-sdk';
2
- import chalk from 'chalk';
3
- import type { MigrationElementTransformData, MigrationElementType, MigrationReference } from '../../core/index.js';
4
- import { findRequired, isArray, isNotUndefined, isString } from '../../core/index.js';
5
- import type { ExportContext, ExportElement, ExportTransformFunc } from '../../export/index.js';
6
- import { richTextProcessor } from '../helpers/rich-text.processor.js';
1
+ import type { ContentTypeElements, TaxonomyModels } from "@kontent-ai/management-sdk";
2
+ import chalk from "chalk";
3
+ import { match } from "ts-pattern";
4
+ import { MigrationToolkitError, MissingAssetError, MissingItemError } from "../../core/models/error.models.js";
5
+ import type { MigrationElementTransformData, MigrationElementType, MigrationReference } from "../../core/models/migration.models.js";
6
+ import { findRequired } from "../../core/utils/array.utils.js";
7
+ import { isArray, isNotUndefined, isString } from "../../core/utils/global.utils.js";
8
+ import type { ExportContext, ExportElement, ExportTransformFunc } from "../../export/export.models.js";
9
+ import { getMissingReferencePlaceholder } from "../helpers/export-placeholder.utils.js";
10
+ import { richTextProcessor } from "../helpers/rich-text.processor.js";
7
11
 
8
12
  export const exportTransforms: Readonly<Record<MigrationElementType, ExportTransformFunc>> = {
9
- text: (data) => {
10
- return {
11
- value: data.exportElement.value && isString(data.exportElement.value) ? data.exportElement.value : undefined
12
- };
13
- },
14
- number: (data) => {
15
- if (data.exportElement.value === undefined || data.exportElement.value === null) {
16
- return {
17
- value: undefined
18
- };
19
- }
20
-
21
- if (isArray(data.exportElement.value)) {
22
- throw Error(`Expected value to be a number, not array`);
23
- }
24
-
25
- if (data.exportElement.value === 0) {
26
- return {
27
- value: 0
28
- };
29
- }
30
-
31
- return {
32
- value: +data.exportElement.value
33
- };
34
- },
35
- date_time: (data) => {
36
- return {
37
- value: data.exportElement.value && isString(data.exportElement.value) ? data.exportElement.value : undefined,
38
- display_timezone: data.exportElement.displayTimezone ?? undefined
39
- };
40
- },
41
- rich_text: (data) => transformRichTextValue(data.exportElement, data.context),
42
- asset: (data) => {
43
- if (!data.exportElement.value) {
44
- return {
45
- value: []
46
- };
47
- }
48
-
49
- if (!isArray(data.exportElement.value)) {
50
- throw Error(`Expected value to be an array`);
51
- }
52
-
53
- return {
54
- // translate asset id to codename
55
- value: data.exportElement.value
56
- .map((m) => m.id)
57
- .filter(isNotUndefined)
58
- .map<MigrationReference>((id) => {
59
- const assetState = data.context.getAssetStateInSourceEnvironment(id);
60
-
61
- if (assetState.asset) {
62
- // reference asset by codename
63
- return { codename: assetState.asset.codename };
64
- } else {
65
- throw Error(`Missing asset with id '${chalk.red(id)}'`);
66
- }
67
- })
68
- };
69
- },
70
- taxonomy: (data) => {
71
- if (!data.exportElement.value) {
72
- return {
73
- value: []
74
- };
75
- }
76
-
77
- if (!isArray(data.exportElement.value)) {
78
- throw Error(`Expected value to be an array`);
79
- }
80
-
81
- const taxonomyElement = data.typeElement.element as Readonly<ContentTypeElements.ITaxonomyElement>;
82
- const taxonomyGroupId = taxonomyElement.taxonomy_group.id ?? 'n/a';
83
-
84
- // get taxonomy group
85
- const taxonomy = findRequired(
86
- data.context.environmentData.taxonomies,
87
- (taxonomy) => taxonomy.id === taxonomyGroupId,
88
- `Could not find taxonomy group with id '${chalk.red(taxonomyGroupId)}'`
89
- );
90
-
91
- return {
92
- // translate taxonomy term to codename
93
- value: data.exportElement.value
94
- .map((m) => m.id)
95
- .filter(isNotUndefined)
96
- .map<MigrationReference>((id) => {
97
- const taxonomyTerm = findTaxonomy(id, taxonomy);
98
-
99
- if (taxonomyTerm) {
100
- // reference taxonomy term by codename
101
- return { codename: taxonomyTerm.codename };
102
- } else {
103
- throw Error(`Missing taxonomy term with id '${chalk.red(id)}'`);
104
- }
105
- })
106
- };
107
- },
108
- modular_content: (data) => {
109
- if (!data.exportElement.value) {
110
- return {
111
- value: []
112
- };
113
- }
114
-
115
- if (!isArray(data.exportElement.value)) {
116
- throw Error(`Expected value to be an array`);
117
- }
118
-
119
- return {
120
- // translate item id to codename
121
- value: data.exportElement.value
122
- .map((m) => m.id)
123
- .filter(isNotUndefined)
124
- .map<MigrationReference>((id) => {
125
- const itemState = data.context.getItemStateInSourceEnvironment(id);
126
-
127
- if (itemState.item) {
128
- // reference item by codename
129
- return { codename: itemState.item.codename };
130
- } else {
131
- throw Error(`Missing item with id '${chalk.red(id)}'`);
132
- }
133
- })
134
- };
135
- },
136
- custom: (data) => {
137
- return {
138
- value: data.exportElement.value && isString(data.exportElement.value) ? data.exportElement.value : undefined
139
- };
140
- },
141
- url_slug: (data) => {
142
- return {
143
- value: data.exportElement.value && isString(data.exportElement.value) ? data.exportElement.value : undefined,
144
- mode: data.exportElement.urlSlugMode ?? 'autogenerated'
145
- };
146
- },
147
- multiple_choice: (data) => {
148
- if (!data.exportElement.value) {
149
- return {
150
- value: []
151
- };
152
- }
153
-
154
- if (!isArray(data.exportElement.value)) {
155
- throw Error(`Expected value to be an array`);
156
- }
157
-
158
- // translate multiple choice option id to codename
159
- const multipleChoiceElement = data.typeElement.element as Readonly<ContentTypeElements.IMultipleChoiceElement>;
160
-
161
- return {
162
- value: data.exportElement.value
163
- .map((m) => m.id)
164
- .filter(isNotUndefined)
165
- .map<MigrationReference>((id) => {
166
- const option = findRequired(
167
- multipleChoiceElement.options,
168
- (option) => option.id === id,
169
- `Could not find multiple choice element with option id '${chalk.red(id)}'`
170
- );
171
-
172
- if (!option.codename) {
173
- throw Error(`Invalid codename for multiple choice option '${chalk.red(option.name)}'`);
174
- }
175
-
176
- return { codename: option.codename };
177
- })
178
- };
179
- },
180
- subpages: (data) => {
181
- if (!data.exportElement.value) {
182
- return {
183
- value: []
184
- };
185
- }
186
- if (!isArray(data.exportElement.value)) {
187
- throw Error(`Expected value to be an array`);
188
- }
189
-
190
- return {
191
- // translate item id to codename
192
- value: data.exportElement.value
193
- .map((m) => m.id)
194
- .filter(isNotUndefined)
195
- .map<MigrationReference>((id) => {
196
- const itemState = data.context.getItemStateInSourceEnvironment(id);
197
-
198
- if (itemState.item) {
199
- // reference item by codename
200
- return { codename: itemState.item.codename };
201
- } else {
202
- throw Error(`Missing item with id '${chalk.red(id)}'`);
203
- }
204
- })
205
- };
206
- }
13
+ text: (data) => {
14
+ return {
15
+ value: data.exportElement.value && isString(data.exportElement.value) ? data.exportElement.value : undefined,
16
+ };
17
+ },
18
+ number: (data) => {
19
+ if (!data.exportElement.value) {
20
+ return {
21
+ value: undefined,
22
+ };
23
+ }
24
+
25
+ if (isArray(data.exportElement.value)) {
26
+ throw new MigrationToolkitError("invalidValue", `Expected value to be a number, not array`);
27
+ }
28
+
29
+ if (data.exportElement.value === 0) {
30
+ return {
31
+ value: 0,
32
+ };
33
+ }
34
+
35
+ return {
36
+ value: +data.exportElement.value,
37
+ };
38
+ },
39
+ date_time: (data) => {
40
+ return {
41
+ value: data.exportElement.value && isString(data.exportElement.value) ? data.exportElement.value : undefined,
42
+ display_timezone: data.exportElement.displayTimezone ?? undefined,
43
+ };
44
+ },
45
+ rich_text: (data) => transformRichTextValue(data.exportElement, data.context),
46
+ asset: (data) => {
47
+ if (!data.exportElement.value) {
48
+ return {
49
+ value: [],
50
+ };
51
+ }
52
+
53
+ if (!isArray(data.exportElement.value)) {
54
+ throw new MigrationToolkitError("invalidValue", `Expected value to be an array`);
55
+ }
56
+
57
+ return {
58
+ // translate asset id to codename
59
+ value: data.exportElement.value
60
+ .map((m) => m.id)
61
+ .filter(isNotUndefined)
62
+ .map<MigrationReference | undefined>((id) => {
63
+ const assetState = data.context.getAssetStateInSourceEnvironment(id);
64
+
65
+ return match(assetState)
66
+ .returnType<MigrationReference | undefined>()
67
+ .with({ state: "exists" }, (m) => {
68
+ return { codename: m.data.codename };
69
+ })
70
+ .with({ state: "skip" }, () => undefined)
71
+ .with({ state: "doesNotExists" }, () => {
72
+ throw new MissingAssetError(id);
73
+ })
74
+ .exhaustive();
75
+ })
76
+ .filter(isNotUndefined),
77
+ };
78
+ },
79
+ taxonomy: (data) => {
80
+ if (!data.exportElement.value) {
81
+ return {
82
+ value: [],
83
+ };
84
+ }
85
+
86
+ if (!isArray(data.exportElement.value)) {
87
+ throw new MigrationToolkitError("invalidValue", `Expected value to be an array`);
88
+ }
89
+
90
+ const taxonomyElement = data.typeElement.element as Readonly<ContentTypeElements.ITaxonomyElement>;
91
+ const taxonomyGroupId = taxonomyElement.taxonomy_group.id ?? "n/a";
92
+
93
+ // get taxonomy group
94
+ const taxonomy = findRequired(
95
+ data.context.environmentData.taxonomies,
96
+ (taxonomy) => taxonomy.id === taxonomyGroupId,
97
+ `Could not find taxonomy group with id '${chalk.red(taxonomyGroupId)}'`,
98
+ );
99
+
100
+ return {
101
+ // translate taxonomy term to codename
102
+ value: data.exportElement.value
103
+ .map((m) => m.id)
104
+ .filter(isNotUndefined)
105
+ .map<MigrationReference>((id) => {
106
+ const taxonomyTerm = findTaxonomy(id, taxonomy);
107
+
108
+ if (taxonomyTerm) {
109
+ // reference taxonomy term by codename
110
+ return { codename: taxonomyTerm.codename };
111
+ }
112
+
113
+ throw new MigrationToolkitError("missingTaxonomyTerm", `Missing taxonomy term with id '${chalk.red(id)}'`);
114
+ }),
115
+ };
116
+ },
117
+ modular_content: (data) => {
118
+ if (!data.exportElement.value) {
119
+ return {
120
+ value: [],
121
+ };
122
+ }
123
+
124
+ if (!isArray(data.exportElement.value)) {
125
+ throw new MigrationToolkitError("invalidValue", `Expected value to be an array`);
126
+ }
127
+
128
+ return {
129
+ // translate item id to codename
130
+ value: data.exportElement.value
131
+ .map((m) => m.id)
132
+ .filter(isNotUndefined)
133
+ .map<MigrationReference | undefined>((id) => {
134
+ const itemState = data.context.getItemStateInSourceEnvironment(id);
135
+
136
+ return match(itemState)
137
+ .returnType<MigrationReference | undefined>()
138
+ .with({ state: "exists" }, (m) => {
139
+ return { codename: m.data.codename };
140
+ })
141
+ .with({ state: "skip" }, () => undefined)
142
+ .with({ state: "doesNotExists" }, () => {
143
+ throw new MissingItemError(id);
144
+ })
145
+ .exhaustive();
146
+ })
147
+ .filter(isNotUndefined),
148
+ };
149
+ },
150
+ custom: (data) => {
151
+ return {
152
+ value: data.exportElement.value && isString(data.exportElement.value) ? data.exportElement.value : undefined,
153
+ };
154
+ },
155
+ url_slug: (data) => {
156
+ return {
157
+ value: data.exportElement.value && isString(data.exportElement.value) ? data.exportElement.value : undefined,
158
+ mode: data.exportElement.urlSlugMode ?? "autogenerated",
159
+ };
160
+ },
161
+ multiple_choice: (data) => {
162
+ if (!data.exportElement.value) {
163
+ return {
164
+ value: [],
165
+ };
166
+ }
167
+
168
+ if (!isArray(data.exportElement.value)) {
169
+ throw new MigrationToolkitError("invalidValue", `Expected value to be an array`);
170
+ }
171
+
172
+ // translate multiple choice option id to codename
173
+ const multipleChoiceElement = data.typeElement.element as Readonly<ContentTypeElements.IMultipleChoiceElement>;
174
+
175
+ return {
176
+ value: data.exportElement.value
177
+ .map((m) => m.id)
178
+ .filter(isNotUndefined)
179
+ .map<MigrationReference>((id) => {
180
+ const option = findRequired(
181
+ multipleChoiceElement.options,
182
+ (option) => option.id === id,
183
+ `Could not find multiple choice element with option id '${chalk.red(id)}'`,
184
+ );
185
+
186
+ if (!option.codename) {
187
+ throw new MigrationToolkitError(
188
+ "invalidMultipleChoiceOption",
189
+ `Invalid codename for multiple choice option '${chalk.red(option.name)}'`,
190
+ );
191
+ }
192
+
193
+ return { codename: option.codename };
194
+ }),
195
+ };
196
+ },
197
+ subpages: (data) => {
198
+ if (!data.exportElement.value) {
199
+ return {
200
+ value: [],
201
+ };
202
+ }
203
+ if (!isArray(data.exportElement.value)) {
204
+ throw new MigrationToolkitError("invalidValue", `Expected value to be an array`);
205
+ }
206
+
207
+ return {
208
+ // translate item id to codename
209
+ value: data.exportElement.value
210
+ .map((m) => m.id)
211
+ .filter(isNotUndefined)
212
+ .map<MigrationReference | undefined>((id) => {
213
+ const itemState = data.context.getItemStateInSourceEnvironment(id);
214
+
215
+ return match(itemState)
216
+ .returnType<MigrationReference | undefined>()
217
+ .with({ state: "exists" }, (m) => {
218
+ return { codename: m.data.codename };
219
+ })
220
+ .with({ state: "skip" }, () => undefined)
221
+ .with({ state: "doesNotExists" }, () => {
222
+ throw new MissingItemError(id);
223
+ })
224
+ .exhaustive();
225
+ })
226
+ .filter(isNotUndefined),
227
+ };
228
+ },
207
229
  };
208
230
 
209
231
  function findTaxonomy(termId: string, taxonomy: Readonly<TaxonomyModels.Taxonomy>): Readonly<TaxonomyModels.Taxonomy> | undefined {
210
- if (taxonomy.id === termId) {
211
- return taxonomy;
212
- }
232
+ if (taxonomy.id === termId) {
233
+ return taxonomy;
234
+ }
213
235
 
214
- if (taxonomy.terms) {
215
- const foundTerm = taxonomy.terms.find((term) => findTaxonomy(termId, term));
236
+ if (taxonomy.terms.length) {
237
+ const foundTerm = taxonomy.terms.find((term) => findTaxonomy(termId, term));
216
238
 
217
- if (foundTerm) {
218
- return foundTerm;
219
- }
220
- }
239
+ if (foundTerm) {
240
+ return foundTerm;
241
+ }
242
+ }
221
243
 
222
- return undefined;
244
+ return undefined;
223
245
  }
224
246
 
225
247
  function transformRichTextValue(exportElement: ExportElement, context: ExportContext): MigrationElementTransformData {
226
- if (!exportElement.value) {
227
- return {
228
- components: [],
229
- value: ''
230
- };
231
- }
232
-
233
- let richTextHtml: string = exportElement.value && isString(exportElement.value) ? exportElement.value : '';
234
-
235
- // replace item ids with codenames
236
- richTextHtml = richTextProcessor().processDataIds(richTextHtml, (id) => {
237
- const itemInEnv = context.getItemStateInSourceEnvironment(id).item;
238
-
239
- if (!itemInEnv) {
240
- throw Error(`Failed to get item with id '${chalk.red(id)}'`);
241
- }
242
-
243
- return {
244
- codename: itemInEnv.codename
245
- };
246
- }).html;
247
-
248
- // replace link item ids with codenames
249
- richTextHtml = richTextProcessor().processLinkItemIds(richTextHtml, (id) => {
250
- const itemInEnv = context.getItemStateInSourceEnvironment(id).item;
251
-
252
- if (!itemInEnv) {
253
- throw Error(`Failed to get item with id '${chalk.red(id)}'`);
254
- }
255
-
256
- return {
257
- codename: itemInEnv.codename
258
- };
259
- }).html;
260
-
261
- // replace asset ids with codenames
262
- richTextHtml = richTextProcessor().processAssetIds(richTextHtml, (id) => {
263
- const assetInEnv = context.getAssetStateInSourceEnvironment(id).asset;
264
-
265
- if (!assetInEnv) {
266
- throw Error(`Failed to get asset with id '${chalk.red(id)}'`);
267
- }
268
-
269
- return {
270
- codename: assetInEnv.codename
271
- };
272
- }).html;
273
-
274
- // replace link asset ids with codenames
275
- richTextHtml = richTextProcessor().processLinkAssetIds(richTextHtml, (id) => {
276
- const assetInEnv = context.getAssetStateInSourceEnvironment(id).asset;
277
-
278
- if (!assetInEnv) {
279
- throw Error(`Failed to get asset with id '${chalk.red(id)}'`);
280
- }
281
-
282
- return {
283
- codename: assetInEnv.codename
284
- };
285
- }).html;
286
-
287
- return {
288
- components: exportElement.components,
289
- value: richTextHtml
290
- };
248
+ if (!exportElement.value) {
249
+ return {
250
+ components: [],
251
+ value: "",
252
+ };
253
+ }
254
+
255
+ let richTextHtml: string = exportElement.value && isString(exportElement.value) ? exportElement.value : "";
256
+
257
+ // replace item ids with codenames
258
+ richTextHtml = richTextProcessor().processDataIds(richTextHtml, (id) => {
259
+ const itemInEnv = context.getItemStateInSourceEnvironment(id).data;
260
+
261
+ if (!itemInEnv) {
262
+ if (context.exportContextOptions.skipMissingReferences) {
263
+ return { codename: getMissingReferencePlaceholder({ type: "item", id }) };
264
+ }
265
+ throw new MissingItemError(id);
266
+ }
267
+
268
+ return {
269
+ codename: itemInEnv.codename,
270
+ };
271
+ }).html;
272
+
273
+ // replace link item ids with codenames
274
+ richTextHtml = richTextProcessor().processLinkItemIds(richTextHtml, (id) => {
275
+ const itemInEnv = context.getItemStateInSourceEnvironment(id).data;
276
+
277
+ if (!itemInEnv) {
278
+ if (context.exportContextOptions.skipMissingReferences) {
279
+ return { codename: getMissingReferencePlaceholder({ type: "item", id }) };
280
+ }
281
+ throw new MissingItemError(id);
282
+ }
283
+
284
+ return {
285
+ codename: itemInEnv.codename,
286
+ };
287
+ }).html;
288
+
289
+ // replace asset ids with codenames
290
+ richTextHtml = richTextProcessor().processAssetIds(richTextHtml, (id) => {
291
+ const assetInEnv = context.getAssetStateInSourceEnvironment(id).data;
292
+
293
+ if (!assetInEnv) {
294
+ if (context.exportContextOptions.skipMissingReferences) {
295
+ return { codename: getMissingReferencePlaceholder({ type: "asset", id }) };
296
+ }
297
+ throw new MissingAssetError(id);
298
+ }
299
+
300
+ return {
301
+ codename: assetInEnv.codename,
302
+ };
303
+ }).html;
304
+
305
+ // replace link asset ids with codenames
306
+ richTextHtml = richTextProcessor().processLinkAssetIds(richTextHtml, (id) => {
307
+ const assetInEnv = context.getAssetStateInSourceEnvironment(id).data;
308
+
309
+ if (!assetInEnv) {
310
+ if (context.exportContextOptions.skipMissingReferences) {
311
+ return { codename: getMissingReferencePlaceholder({ type: "asset", id }) };
312
+ }
313
+ throw new MissingAssetError(id);
314
+ }
315
+
316
+ return {
317
+ codename: assetInEnv.codename,
318
+ };
319
+ }).html;
320
+
321
+ return {
322
+ components: exportElement.components,
323
+ value: richTextHtml,
324
+ };
291
325
  }