@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,240 +1,244 @@
1
- import type { AssetModels, LanguageModels, ManagementClient, SharedContracts } from '@kontent-ai/management-sdk';
2
- import chalk from 'chalk';
3
- import mime from 'mime';
4
- import type { Logger, LogSpinnerData, MigrationAsset, MigrationAssetDescription, MigrationReference } from '../../core/index.js';
5
- import { geSizeInBytes, isNotUndefined, processItemsAsync, runMapiRequestAsync } from '../../core/index.js';
6
- import { shouldReplaceBinaryFile, shouldUpdateAsset } from '../comparers/asset-comparer.js';
7
- import type { AssetToEdit, EditedAsset, ImportContext, ImportedAsset, ImportResult } from '../import.models.js';
1
+ import type { AssetModels, LanguageModels, ManagementClient, SharedContracts } from "@kontent-ai/management-sdk";
2
+ import chalk from "chalk";
3
+ import mime from "mime";
4
+ import type { Logger, LogSpinnerData } from "../../core/models/log.models.js";
5
+ import type { MigrationAsset, MigrationAssetDescription, MigrationReference } from "../../core/models/migration.models.js";
6
+ import { geSizeInBytes } from "../../core/utils/binary-data.utils.js";
7
+ import { isNotUndefined } from "../../core/utils/global.utils.js";
8
+ import { processItemsAsync } from "../../core/utils/processing-utils.js";
9
+ import { runMapiRequestAsync } from "../../core/utils/run.utils.js";
10
+ import { shouldReplaceBinaryFile, shouldUpdateAsset } from "../comparers/asset-comparer.js";
11
+ import type { AssetToEdit, EditedAsset, ImportContext, ImportedAsset, ImportResult } from "../import.models.js";
8
12
 
9
13
  export function assetsImporter(data: {
10
- readonly logger: Logger;
11
- readonly client: Readonly<ManagementClient>;
12
- readonly importContext: ImportContext;
14
+ readonly logger: Logger;
15
+ readonly client: Readonly<ManagementClient>;
16
+ readonly importContext: ImportContext;
13
17
  }) {
14
- const getAssetsToUpload = (): readonly MigrationAsset[] => {
15
- return data.importContext.categorizedImportData.assets
16
- .filter((asset) => {
17
- return data.importContext.getAssetStateInTargetEnvironment(asset.codename).state === 'doesNotExists';
18
- })
19
- .map((asset) => ({ ...asset, descriptions: asset.descriptions?.filter(filterInvalidLanguages) }));
20
- };
21
-
22
- const getAssetsToEdit = (): readonly AssetToEdit[] => {
23
- return data.importContext.categorizedImportData.assets
24
- .map<AssetToEdit | undefined>((migrationAsset) => {
25
- const assetState = data.importContext.getAssetStateInTargetEnvironment(migrationAsset.codename);
26
-
27
- if (!assetState.asset || assetState.state === 'doesNotExists') {
28
- return undefined;
29
- }
30
-
31
- if (
32
- !shouldUpdateAsset({
33
- collections: data.importContext.environmentData.collections,
34
- languages: data.importContext.environmentData.languages,
35
- assetFolders: data.importContext.environmentData.assetFolders,
36
- migrationAsset: migrationAsset,
37
- targetAsset: assetState.asset
38
- })
39
- ) {
40
- return undefined;
41
- }
42
-
43
- return {
44
- migrationAsset: {
45
- ...migrationAsset,
46
- descriptions: migrationAsset.descriptions?.filter(filterInvalidLanguages)
47
- },
48
- replaceBinaryFile: shouldReplaceBinaryFile({
49
- migrationAsset: migrationAsset,
50
- targetAsset: assetState.asset
51
- }),
52
- targetAsset: assetState.asset
53
- };
54
- })
55
- .filter(isNotUndefined);
56
- };
57
-
58
- const editAssets = async (assetsToEdit: readonly AssetToEdit[]): Promise<readonly EditedAsset[]> => {
59
- data.logger.log({
60
- type: 'upsert',
61
- message: `Upserting '${chalk.yellow(assetsToEdit.length.toString())}' assets`
62
- });
63
-
64
- return await processItemsAsync<AssetToEdit, Readonly<AssetModels.Asset>>({
65
- action: 'Upserting assets',
66
- logger: data.logger,
67
- parallelLimit: 1,
68
- items: assetsToEdit,
69
- itemInfo: (input) => {
70
- return {
71
- itemType: 'asset',
72
- title: input.migrationAsset.title
73
- };
74
- },
75
- processAsync: async (assetEditRequest, logSpinner) => {
76
- let uploadedBinaryFile: Readonly<AssetModels.AssetFileReference> | undefined;
77
-
78
- if (assetEditRequest.replaceBinaryFile) {
79
- uploadedBinaryFile = await uploadBinaryFileAsync(assetEditRequest.migrationAsset, logSpinner);
80
- }
81
-
82
- return await runMapiRequestAsync({
83
- logger: data.logger,
84
- func: async () => {
85
- return (
86
- await data.client
87
- .upsertAsset()
88
- .byAssetCodename(assetEditRequest.migrationAsset.codename)
89
- .withData(() => {
90
- return {
91
- title: assetEditRequest.migrationAsset.title,
92
- descriptions: mapAssetDescriptions(assetEditRequest.migrationAsset.descriptions),
93
- collection: mapAssetCollection(assetEditRequest.migrationAsset.collection),
94
- file_reference: uploadedBinaryFile ?? undefined,
95
- folder: mapAssetFolder(assetEditRequest.migrationAsset.folder)
96
- };
97
- })
98
- .toPromise()
99
- ).data;
100
- },
101
- action: 'upsert',
102
- type: 'asset',
103
- logSpinner: logSpinner,
104
- itemName: `${assetEditRequest.migrationAsset.title ?? assetEditRequest.migrationAsset.filename}`
105
- });
106
- }
107
- });
108
- };
109
-
110
- const filterInvalidLanguages = (description: MigrationAssetDescription): Readonly<LanguageModels.LanguageModel> | undefined => {
111
- return data.importContext.environmentData.languages.find((lang) => lang.codename === description.language.codename);
112
- };
113
-
114
- const mapAssetCollection = (
115
- migrationCollection: MigrationReference | undefined
116
- ): Readonly<AssetModels.IAssetCollectionReferenceObject> | undefined => {
117
- return migrationCollection
118
- ? {
119
- reference: {
120
- codename: migrationCollection.codename
121
- }
122
- }
123
- : undefined;
124
- };
125
-
126
- const mapAssetFolder = (
127
- migrationFolder: MigrationReference | undefined
128
- ): Readonly<SharedContracts.IReferenceObjectContract> | undefined => {
129
- return migrationFolder
130
- ? {
131
- codename: migrationFolder.codename
132
- }
133
- : undefined;
134
- };
135
-
136
- const mapAssetDescriptions = (
137
- migrationDescription: readonly MigrationAssetDescription[] | undefined
138
- ): Readonly<AssetModels.IAssetFileDescription>[] => {
139
- return (migrationDescription ?? []).map((m) => {
140
- const assetDescription: Readonly<AssetModels.IAssetFileDescription> = {
141
- description: m.description ?? '',
142
- language: {
143
- codename: m.language.codename
144
- }
145
- };
146
-
147
- return assetDescription;
148
- });
149
- };
150
-
151
- const uploadBinaryFileAsync = async (
152
- migrationAsset: MigrationAsset,
153
- logSpinner: LogSpinnerData
154
- ): Promise<Readonly<AssetModels.AssetFileReference>> => {
155
- return await runMapiRequestAsync({
156
- logger: data.logger,
157
- func: async () => {
158
- return (
159
- await data.client
160
- .uploadBinaryFile()
161
- .withData({
162
- binaryData: migrationAsset.binary_data,
163
- contentLength: geSizeInBytes(migrationAsset.binary_data),
164
- contentType: mime.getType(migrationAsset.filename) ?? '',
165
- filename: migrationAsset.filename
166
- })
167
- .toPromise()
168
- ).data;
169
- },
170
- action: 'upload',
171
- type: 'binaryFile',
172
- logSpinner: logSpinner,
173
- itemName: `${migrationAsset.title ?? migrationAsset.filename}`
174
- });
175
- };
176
-
177
- const uploadAssetsAsync = async (assetsToUpload: readonly MigrationAsset[]): Promise<readonly ImportedAsset[]> => {
178
- data.logger.log({
179
- type: 'upload',
180
- message: `Uploading '${chalk.yellow(assetsToUpload.length.toString())}' assets`
181
- });
182
-
183
- return await processItemsAsync<MigrationAsset, Readonly<AssetModels.Asset>>({
184
- action: 'Uploading assets',
185
- logger: data.logger,
186
- parallelLimit: 3,
187
- items: assetsToUpload,
188
- itemInfo: (input) => {
189
- return {
190
- itemType: 'asset',
191
- title: input.title
192
- };
193
- },
194
- processAsync: async (migrationAsset, logSpinner) => {
195
- const uploadedBinaryFile = await uploadBinaryFileAsync(migrationAsset, logSpinner);
196
-
197
- return await runMapiRequestAsync({
198
- logger: data.logger,
199
- func: async () =>
200
- (
201
- await data.client
202
- .addAsset()
203
- .withData(() => {
204
- const assetStateInTargetEnv = data.importContext.getAssetStateInTargetEnvironment(
205
- migrationAsset.codename
206
- );
207
-
208
- const assetRequestData: Readonly<AssetModels.IAddAssetRequestData> = {
209
- file_reference: uploadedBinaryFile,
210
- codename: migrationAsset.codename,
211
- title: migrationAsset.title,
212
- external_id: assetStateInTargetEnv.externalIdToUse,
213
- collection: mapAssetCollection(migrationAsset.collection),
214
- descriptions: mapAssetDescriptions(migrationAsset.descriptions),
215
- folder: mapAssetFolder(migrationAsset.folder)
216
- };
217
- return assetRequestData;
218
- })
219
- .toPromise()
220
- ).data,
221
- action: 'create',
222
- type: 'asset',
223
- logSpinner: logSpinner,
224
- itemName: `${migrationAsset.title ?? migrationAsset.filename}`
225
- });
226
- }
227
- });
228
- };
229
-
230
- const importAsync = async (): Promise<Pick<ImportResult, 'editedAssets' | 'uploadedAssets'>> => {
231
- return {
232
- editedAssets: await editAssets(getAssetsToEdit()),
233
- uploadedAssets: await uploadAssetsAsync(getAssetsToUpload())
234
- };
235
- };
236
-
237
- return {
238
- importAsync
239
- };
18
+ const getAssetsToUpload = (): readonly MigrationAsset[] => {
19
+ return data.importContext.categorizedImportData.assets
20
+ .filter((asset) => {
21
+ return data.importContext.getAssetStateInTargetEnvironment(asset.codename).state === "doesNotExists";
22
+ })
23
+ .map((asset) => ({ ...asset, descriptions: asset.descriptions?.filter(filterInvalidLanguages) }));
24
+ };
25
+
26
+ const getAssetsToEdit = (): readonly AssetToEdit[] => {
27
+ return data.importContext.categorizedImportData.assets
28
+ .map<AssetToEdit | undefined>((migrationAsset) => {
29
+ const assetState = data.importContext.getAssetStateInTargetEnvironment(migrationAsset.codename);
30
+
31
+ if (!assetState.asset || assetState.state === "doesNotExists") {
32
+ return undefined;
33
+ }
34
+
35
+ if (
36
+ !shouldUpdateAsset({
37
+ collections: data.importContext.environmentData.collections,
38
+ languages: data.importContext.environmentData.languages,
39
+ assetFolders: data.importContext.environmentData.assetFolders,
40
+ migrationAsset: migrationAsset,
41
+ targetAsset: assetState.asset,
42
+ })
43
+ ) {
44
+ return undefined;
45
+ }
46
+
47
+ return {
48
+ migrationAsset: {
49
+ ...migrationAsset,
50
+ descriptions: migrationAsset.descriptions?.filter(filterInvalidLanguages),
51
+ },
52
+ replaceBinaryFile: shouldReplaceBinaryFile({
53
+ migrationAsset: migrationAsset,
54
+ targetAsset: assetState.asset,
55
+ }),
56
+ targetAsset: assetState.asset,
57
+ };
58
+ })
59
+ .filter(isNotUndefined);
60
+ };
61
+
62
+ const editAssets = async (assetsToEdit: readonly AssetToEdit[]): Promise<readonly EditedAsset[]> => {
63
+ data.logger.log({
64
+ type: "upsert",
65
+ message: `Upserting '${chalk.yellow(assetsToEdit.length.toString())}' assets`,
66
+ });
67
+
68
+ return await processItemsAsync<AssetToEdit, Readonly<AssetModels.Asset>>({
69
+ action: "Upserting assets",
70
+ logger: data.logger,
71
+ parallelLimit: 1,
72
+ items: assetsToEdit,
73
+ itemInfo: (input) => {
74
+ return {
75
+ itemType: "asset",
76
+ title: input.migrationAsset.title ?? input.migrationAsset.filename,
77
+ };
78
+ },
79
+ processAsync: async (assetEditRequest, logSpinner) => {
80
+ let uploadedBinaryFile: Readonly<AssetModels.AssetFileReference> | undefined;
81
+
82
+ if (assetEditRequest.replaceBinaryFile) {
83
+ uploadedBinaryFile = await uploadBinaryFileAsync(assetEditRequest.migrationAsset, logSpinner);
84
+ }
85
+
86
+ return await runMapiRequestAsync({
87
+ logger: data.logger,
88
+ func: async () => {
89
+ return (
90
+ await data.client
91
+ .upsertAsset()
92
+ .byAssetCodename(assetEditRequest.migrationAsset.codename)
93
+ .withData(() => {
94
+ return {
95
+ title: assetEditRequest.migrationAsset.title,
96
+ descriptions: mapAssetDescriptions(assetEditRequest.migrationAsset.descriptions),
97
+ collection: mapAssetCollection(assetEditRequest.migrationAsset.collection),
98
+ file_reference: uploadedBinaryFile ?? undefined,
99
+ folder: mapAssetFolder(assetEditRequest.migrationAsset.folder),
100
+ };
101
+ })
102
+ .toPromise()
103
+ ).data;
104
+ },
105
+ action: "upsert",
106
+ type: "asset",
107
+ logSpinner: logSpinner,
108
+ itemName: `${assetEditRequest.migrationAsset.title ?? assetEditRequest.migrationAsset.filename}`,
109
+ });
110
+ },
111
+ });
112
+ };
113
+
114
+ const filterInvalidLanguages = (description: MigrationAssetDescription): Readonly<LanguageModels.LanguageModel> | undefined => {
115
+ return data.importContext.environmentData.languages.find((lang) => lang.codename === description.language.codename);
116
+ };
117
+
118
+ const mapAssetCollection = (
119
+ migrationCollection: MigrationReference | undefined,
120
+ ): Readonly<AssetModels.IAssetCollectionReferenceObject> | undefined => {
121
+ return migrationCollection
122
+ ? {
123
+ reference: {
124
+ codename: migrationCollection.codename,
125
+ },
126
+ }
127
+ : undefined;
128
+ };
129
+
130
+ const mapAssetFolder = (
131
+ migrationFolder: MigrationReference | undefined,
132
+ ): Readonly<SharedContracts.IReferenceObjectContract> | undefined => {
133
+ return migrationFolder
134
+ ? {
135
+ codename: migrationFolder.codename,
136
+ }
137
+ : undefined;
138
+ };
139
+
140
+ const mapAssetDescriptions = (
141
+ migrationDescription: readonly MigrationAssetDescription[] | undefined,
142
+ ): Readonly<AssetModels.IAssetFileDescription>[] => {
143
+ return (migrationDescription ?? []).map((m) => {
144
+ const assetDescription: Readonly<AssetModels.IAssetFileDescription> = {
145
+ description: m.description ?? "",
146
+ language: {
147
+ codename: m.language.codename,
148
+ },
149
+ };
150
+
151
+ return assetDescription;
152
+ });
153
+ };
154
+
155
+ const uploadBinaryFileAsync = async (
156
+ migrationAsset: MigrationAsset,
157
+ logSpinner: LogSpinnerData,
158
+ ): Promise<Readonly<AssetModels.AssetFileReference>> => {
159
+ return await runMapiRequestAsync({
160
+ logger: data.logger,
161
+ func: async () => {
162
+ return (
163
+ await data.client
164
+ .uploadBinaryFile()
165
+ .withData({
166
+ binaryData: migrationAsset.binary_data,
167
+ contentLength: geSizeInBytes(migrationAsset.binary_data),
168
+ contentType: mime.getType(migrationAsset.filename) ?? "",
169
+ filename: migrationAsset.filename,
170
+ })
171
+ .toPromise()
172
+ ).data;
173
+ },
174
+ action: "upload",
175
+ type: "binaryFile",
176
+ logSpinner: logSpinner,
177
+ itemName: `${migrationAsset.title ?? migrationAsset.filename}`,
178
+ });
179
+ };
180
+
181
+ const uploadAssetsAsync = async (assetsToUpload: readonly MigrationAsset[]): Promise<readonly ImportedAsset[]> => {
182
+ data.logger.log({
183
+ type: "upload",
184
+ message: `Uploading '${chalk.yellow(assetsToUpload.length.toString())}' assets`,
185
+ });
186
+
187
+ return await processItemsAsync<MigrationAsset, Readonly<AssetModels.Asset>>({
188
+ action: "Uploading assets",
189
+ logger: data.logger,
190
+ parallelLimit: 3,
191
+ items: assetsToUpload,
192
+ itemInfo: (input) => {
193
+ return {
194
+ itemType: "asset",
195
+ title: input.title ?? input.filename,
196
+ };
197
+ },
198
+ processAsync: async (migrationAsset, logSpinner) => {
199
+ const uploadedBinaryFile = await uploadBinaryFileAsync(migrationAsset, logSpinner);
200
+
201
+ return await runMapiRequestAsync({
202
+ logger: data.logger,
203
+ func: async () =>
204
+ (
205
+ await data.client
206
+ .addAsset()
207
+ .withData(() => {
208
+ const assetStateInTargetEnv = data.importContext.getAssetStateInTargetEnvironment(
209
+ migrationAsset.codename,
210
+ );
211
+
212
+ const assetRequestData: Readonly<AssetModels.IAddAssetRequestData> = {
213
+ file_reference: uploadedBinaryFile,
214
+ codename: migrationAsset.codename,
215
+ title: migrationAsset.title,
216
+ external_id: assetStateInTargetEnv.externalIdToUse,
217
+ collection: mapAssetCollection(migrationAsset.collection),
218
+ descriptions: mapAssetDescriptions(migrationAsset.descriptions),
219
+ folder: mapAssetFolder(migrationAsset.folder),
220
+ };
221
+ return assetRequestData;
222
+ })
223
+ .toPromise()
224
+ ).data,
225
+ action: "create",
226
+ type: "asset",
227
+ logSpinner: logSpinner,
228
+ itemName: `${migrationAsset.title ?? migrationAsset.filename}`,
229
+ });
230
+ },
231
+ });
232
+ };
233
+
234
+ const importAsync = async (): Promise<Pick<ImportResult, "editedAssets" | "uploadedAssets">> => {
235
+ return {
236
+ editedAssets: await editAssets(getAssetsToEdit()),
237
+ uploadedAssets: await uploadAssetsAsync(getAssetsToUpload()),
238
+ };
239
+ };
240
+
241
+ return {
242
+ importAsync,
243
+ };
240
244
  }