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

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 (235) 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 +27 -22
  11. package/dist/core/models/error.models.d.ts +14 -0
  12. package/dist/core/models/error.models.js +25 -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 +14 -14
  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 +1 -1
  26. package/dist/core/utils/confirm.utils.js +21 -20
  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 +34 -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/export/context/export-context-fetcher.d.ts +1 -1
  49. package/dist/export/context/export-context-fetcher.js +92 -62
  50. package/dist/export/context/export-context-fetcher.js.map +1 -1
  51. package/dist/export/export-manager.d.ts +2 -2
  52. package/dist/export/export-manager.js +46 -37
  53. package/dist/export/export-manager.js.map +1 -1
  54. package/dist/export/export.models.d.ts +21 -2
  55. package/dist/export/utils/export.utils.d.ts +1 -1
  56. package/dist/export/utils/export.utils.js +3 -2
  57. package/dist/export/utils/export.utils.js.map +1 -1
  58. package/dist/file/file-manager.d.ts +2 -2
  59. package/dist/file/file-manager.js +7 -7
  60. package/dist/file/file-manager.js.map +1 -1
  61. package/dist/import/comparers/asset-comparer.d.ts +2 -2
  62. package/dist/import/comparers/asset-comparer.js +12 -11
  63. package/dist/import/comparers/asset-comparer.js.map +1 -1
  64. package/dist/import/context/import-context-fetcher.d.ts +1 -1
  65. package/dist/import/context/import-context-fetcher.js +77 -73
  66. package/dist/import/context/import-context-fetcher.js.map +1 -1
  67. package/dist/import/import-manager.d.ts +1 -1
  68. package/dist/import/import-manager.js +59 -56
  69. package/dist/import/import-manager.js.map +1 -1
  70. package/dist/import/import.models.d.ts +6 -2
  71. package/dist/import/importers/assets-importer.d.ts +3 -3
  72. package/dist/import/importers/assets-importer.js +46 -43
  73. package/dist/import/importers/assets-importer.js.map +1 -1
  74. package/dist/import/importers/content-items-importer.d.ts +3 -3
  75. package/dist/import/importers/content-items-importer.js +28 -25
  76. package/dist/import/importers/content-items-importer.js.map +1 -1
  77. package/dist/import/importers/language-variant-importer.d.ts +3 -3
  78. package/dist/import/importers/language-variant-importer.js +45 -45
  79. package/dist/import/importers/language-variant-importer.js.map +1 -1
  80. package/dist/import/importers/workflow-importer.d.ts +3 -2
  81. package/dist/import/importers/workflow-importer.js +58 -54
  82. package/dist/import/importers/workflow-importer.js.map +1 -1
  83. package/dist/import/utils/import.utils.d.ts +1 -1
  84. package/dist/import/utils/import.utils.js +3 -2
  85. package/dist/import/utils/import.utils.js.map +1 -1
  86. package/dist/index.d.ts +11 -7
  87. package/dist/index.js +10 -8
  88. package/dist/index.js.map +1 -1
  89. package/dist/metadata.js +3 -3
  90. package/dist/metadata.js.map +1 -1
  91. package/dist/node/cli/actions/export-action.d.ts +1 -1
  92. package/dist/node/cli/actions/export-action.js +28 -23
  93. package/dist/node/cli/actions/export-action.js.map +1 -1
  94. package/dist/node/cli/actions/import-action.d.ts +1 -1
  95. package/dist/node/cli/actions/import-action.js +15 -12
  96. package/dist/node/cli/actions/import-action.js.map +1 -1
  97. package/dist/node/cli/actions/migrate-action.d.ts +1 -1
  98. package/dist/node/cli/actions/migrate-action.js +25 -22
  99. package/dist/node/cli/actions/migrate-action.js.map +1 -1
  100. package/dist/node/cli/app.js +13 -12
  101. package/dist/node/cli/app.js.map +1 -1
  102. package/dist/node/cli/args/args-fetcher.d.ts +1 -1
  103. package/dist/node/cli/args/args-fetcher.js +14 -13
  104. package/dist/node/cli/args/args-fetcher.js.map +1 -1
  105. package/dist/node/cli/args/args-setter.d.ts +1 -1
  106. package/dist/node/cli/args/args-setter.js +8 -6
  107. package/dist/node/cli/args/args-setter.js.map +1 -1
  108. package/dist/node/cli/cli.models.d.ts +2 -2
  109. package/dist/node/cli/commands.js +68 -56
  110. package/dist/node/cli/commands.js.map +1 -1
  111. package/dist/toolkit/elements-builder.d.ts +1 -1
  112. package/dist/toolkit/elements-builder.js +12 -12
  113. package/dist/toolkit/elements-builder.js.map +1 -1
  114. package/dist/toolkit/export.d.ts +2 -2
  115. package/dist/toolkit/export.js +8 -8
  116. package/dist/toolkit/export.js.map +1 -1
  117. package/dist/toolkit/file.d.ts +2 -1
  118. package/dist/toolkit/file.js +18 -16
  119. package/dist/toolkit/file.js.map +1 -1
  120. package/dist/toolkit/import.d.ts +1 -1
  121. package/dist/toolkit/import.js +12 -12
  122. package/dist/toolkit/import.js.map +1 -1
  123. package/dist/toolkit/migrate.d.ts +13 -4
  124. package/dist/toolkit/migrate.js +15 -13
  125. package/dist/toolkit/migrate.js.map +1 -1
  126. package/dist/translation/extraction/items-extraction.processor.d.ts +5 -4
  127. package/dist/translation/extraction/items-extraction.processor.js +73 -35
  128. package/dist/translation/extraction/items-extraction.processor.js.map +1 -1
  129. package/dist/translation/helpers/export-placeholder.utils.d.ts +11 -0
  130. package/dist/translation/helpers/export-placeholder.utils.js +11 -0
  131. package/dist/translation/helpers/export-placeholder.utils.js.map +1 -0
  132. package/dist/translation/helpers/rich-text.processor.d.ts +6 -6
  133. package/dist/translation/helpers/rich-text.processor.js +38 -38
  134. package/dist/translation/helpers/rich-text.processor.js.map +1 -1
  135. package/dist/translation/transforms/export-transforms.d.ts +2 -2
  136. package/dist/translation/transforms/export-transforms.js +93 -67
  137. package/dist/translation/transforms/export-transforms.js.map +1 -1
  138. package/dist/translation/transforms/import-transforms.d.ts +2 -2
  139. package/dist/translation/transforms/import-transforms.js +38 -40
  140. package/dist/translation/transforms/import-transforms.js.map +1 -1
  141. package/dist/zip/zip-manager.d.ts +4 -3
  142. package/dist/zip/zip-manager.js +9 -9
  143. package/dist/zip/zip-manager.js.map +1 -1
  144. package/dist/zip/zip-packager.d.ts +2 -2
  145. package/dist/zip/zip-packager.js +19 -17
  146. package/dist/zip/zip-packager.js.map +1 -1
  147. package/dist/zip/zip-transformer.d.ts +3 -2
  148. package/dist/zip/zip-transformer.js +16 -15
  149. package/dist/zip/zip-transformer.js.map +1 -1
  150. package/dist/zip/zip.models.d.ts +2 -2
  151. package/lib/core/config.ts +6 -6
  152. package/lib/core/helpers/workflow-helper.ts +190 -185
  153. package/lib/core/logs/loggers.ts +52 -52
  154. package/lib/core/models/core.models.ts +128 -119
  155. package/lib/core/models/error.models.ts +41 -0
  156. package/lib/core/models/log.models.ts +20 -20
  157. package/lib/core/models/migration.models.ts +54 -54
  158. package/lib/core/models/migration.schema.ts +108 -108
  159. package/lib/core/utils/array.utils.ts +43 -42
  160. package/lib/core/utils/binary-data.utils.ts +16 -16
  161. package/lib/core/utils/confirm.utils.ts +106 -105
  162. package/lib/core/utils/error.utils.ts +69 -72
  163. package/lib/core/utils/external-id.utils.ts +4 -4
  164. package/lib/core/utils/global.utils.ts +81 -75
  165. package/lib/core/utils/http.utils.ts +23 -23
  166. package/lib/core/utils/management-client-utils.ts +186 -186
  167. package/lib/core/utils/processing-utils.ts +82 -82
  168. package/lib/core/utils/run.utils.ts +50 -50
  169. package/lib/export/context/export-context-fetcher.ts +472 -447
  170. package/lib/export/export-manager.ts +233 -232
  171. package/lib/export/export.models.ts +71 -56
  172. package/lib/export/utils/export.utils.ts +9 -7
  173. package/lib/file/file-manager.ts +28 -28
  174. package/lib/import/comparers/asset-comparer.ts +107 -106
  175. package/lib/import/context/import-context-fetcher.ts +462 -462
  176. package/lib/import/import-manager.ts +243 -240
  177. package/lib/import/import.models.ts +69 -67
  178. package/lib/import/importers/assets-importer.ts +240 -236
  179. package/lib/import/importers/content-items-importer.ts +126 -122
  180. package/lib/import/importers/language-variant-importer.ts +324 -328
  181. package/lib/import/importers/workflow-importer.ts +372 -367
  182. package/lib/import/utils/import.utils.ts +9 -7
  183. package/lib/index.ts +12 -8
  184. package/lib/metadata.ts +3 -4
  185. package/lib/node/cli/actions/export-action.ts +43 -38
  186. package/lib/node/cli/actions/import-action.ts +32 -29
  187. package/lib/node/cli/actions/migrate-action.ts +49 -46
  188. package/lib/node/cli/app.ts +21 -21
  189. package/lib/node/cli/args/args-fetcher.ts +55 -54
  190. package/lib/node/cli/args/args-setter.ts +34 -32
  191. package/lib/node/cli/cli.models.ts +17 -17
  192. package/lib/node/cli/commands.ts +165 -153
  193. package/lib/toolkit/elements-builder.ts +69 -69
  194. package/lib/toolkit/export.ts +21 -21
  195. package/lib/toolkit/file.ts +59 -53
  196. package/lib/toolkit/import.ts +32 -32
  197. package/lib/toolkit/migrate.ts +60 -49
  198. package/lib/translation/extraction/items-extraction.processor.ts +203 -173
  199. package/lib/translation/helpers/export-placeholder.utils.ts +10 -0
  200. package/lib/translation/helpers/rich-text.processor.ts +311 -311
  201. package/lib/translation/transforms/export-transforms.ts +313 -279
  202. package/lib/translation/transforms/import-transforms.ts +188 -191
  203. package/lib/zip/zip-manager.ts +28 -27
  204. package/lib/zip/zip-packager.ts +75 -73
  205. package/lib/zip/zip-transformer.ts +112 -107
  206. package/lib/zip/zip.models.ts +7 -7
  207. package/package.json +91 -84
  208. package/dist/core/index.d.ts +0 -16
  209. package/dist/core/index.js +0 -17
  210. package/dist/core/index.js.map +0 -1
  211. package/dist/export/index.d.ts +0 -2
  212. package/dist/export/index.js +0 -3
  213. package/dist/export/index.js.map +0 -1
  214. package/dist/file/index.d.ts +0 -1
  215. package/dist/file/index.js +0 -2
  216. package/dist/file/index.js.map +0 -1
  217. package/dist/import/index.d.ts +0 -2
  218. package/dist/import/index.js +0 -3
  219. package/dist/import/index.js.map +0 -1
  220. package/dist/toolkit/index.d.ts +0 -5
  221. package/dist/toolkit/index.js +0 -6
  222. package/dist/toolkit/index.js.map +0 -1
  223. package/dist/translation/index.d.ts +0 -4
  224. package/dist/translation/index.js +0 -5
  225. package/dist/translation/index.js.map +0 -1
  226. package/dist/zip/index.d.ts +0 -4
  227. package/dist/zip/index.js +0 -5
  228. package/dist/zip/index.js.map +0 -1
  229. package/lib/core/index.ts +0 -18
  230. package/lib/export/index.ts +0 -2
  231. package/lib/file/index.ts +0 -1
  232. package/lib/import/index.ts +0 -2
  233. package/lib/toolkit/index.ts +0 -5
  234. package/lib/translation/index.ts +0 -4
  235. 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
  }