@kontent-ai/migration-toolkit 1.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 (240) hide show
  1. package/.npmignore +13 -0
  2. package/LICENSE.md +9 -0
  3. package/README.md +272 -0
  4. package/dist/es2022/core/helpers/workflow-helper.d.ts +37 -0
  5. package/dist/es2022/core/helpers/workflow-helper.js +67 -0
  6. package/dist/es2022/core/helpers/workflow-helper.js.map +1 -0
  7. package/dist/es2022/core/index.d.ts +15 -0
  8. package/dist/es2022/core/index.js +16 -0
  9. package/dist/es2022/core/index.js.map +1 -0
  10. package/dist/es2022/core/logs/loggers.d.ts +2 -0
  11. package/dist/es2022/core/logs/loggers.js +69 -0
  12. package/dist/es2022/core/logs/loggers.js.map +1 -0
  13. package/dist/es2022/core/models/core.models.d.ts +91 -0
  14. package/dist/es2022/core/models/core.models.js +2 -0
  15. package/dist/es2022/core/models/core.models.js.map +1 -0
  16. package/dist/es2022/core/models/log.models.d.ts +15 -0
  17. package/dist/es2022/core/models/log.models.js +2 -0
  18. package/dist/es2022/core/models/log.models.js.map +1 -0
  19. package/dist/es2022/core/models/migration.models.d.ts +136 -0
  20. package/dist/es2022/core/models/migration.models.js +2 -0
  21. package/dist/es2022/core/models/migration.models.js.map +1 -0
  22. package/dist/es2022/core/utils/array.utils.d.ts +5 -0
  23. package/dist/es2022/core/utils/array.utils.js +27 -0
  24. package/dist/es2022/core/utils/array.utils.js.map +1 -0
  25. package/dist/es2022/core/utils/binary-data.utils.d.ts +5 -0
  26. package/dist/es2022/core/utils/binary-data.utils.js +21 -0
  27. package/dist/es2022/core/utils/binary-data.utils.js.map +1 -0
  28. package/dist/es2022/core/utils/confirm.utils.d.ts +31 -0
  29. package/dist/es2022/core/utils/confirm.utils.js +73 -0
  30. package/dist/es2022/core/utils/confirm.utils.js.map +1 -0
  31. package/dist/es2022/core/utils/error.utils.d.ts +4 -0
  32. package/dist/es2022/core/utils/error.utils.js +50 -0
  33. package/dist/es2022/core/utils/error.utils.js.map +1 -0
  34. package/dist/es2022/core/utils/external-id.utils.d.ts +5 -0
  35. package/dist/es2022/core/utils/external-id.utils.js +5 -0
  36. package/dist/es2022/core/utils/external-id.utils.js.map +1 -0
  37. package/dist/es2022/core/utils/global.utils.d.ts +14 -0
  38. package/dist/es2022/core/utils/global.utils.js +45 -0
  39. package/dist/es2022/core/utils/global.utils.js.map +1 -0
  40. package/dist/es2022/core/utils/http.utils.d.ts +3 -0
  41. package/dist/es2022/core/utils/http.utils.js +29 -0
  42. package/dist/es2022/core/utils/http.utils.js.map +1 -0
  43. package/dist/es2022/core/utils/management-client-utils.d.ts +19 -0
  44. package/dist/es2022/core/utils/management-client-utils.js +129 -0
  45. package/dist/es2022/core/utils/management-client-utils.js.map +1 -0
  46. package/dist/es2022/core/utils/processing-utils.d.ts +12 -0
  47. package/dist/es2022/core/utils/processing-utils.js +39 -0
  48. package/dist/es2022/core/utils/processing-utils.js.map +1 -0
  49. package/dist/es2022/core/utils/run.utils.d.ts +10 -0
  50. package/dist/es2022/core/utils/run.utils.js +37 -0
  51. package/dist/es2022/core/utils/run.utils.js.map +1 -0
  52. package/dist/es2022/export/context/export-context-fetcher.d.ts +4 -0
  53. package/dist/es2022/export/context/export-context-fetcher.js +289 -0
  54. package/dist/es2022/export/context/export-context-fetcher.js.map +1 -0
  55. package/dist/es2022/export/export-manager.d.ts +5 -0
  56. package/dist/es2022/export/export-manager.js +167 -0
  57. package/dist/es2022/export/export-manager.js.map +1 -0
  58. package/dist/es2022/export/export.models.d.ts +55 -0
  59. package/dist/es2022/export/export.models.js +2 -0
  60. package/dist/es2022/export/export.models.js.map +1 -0
  61. package/dist/es2022/export/index.d.ts +2 -0
  62. package/dist/es2022/export/index.js +3 -0
  63. package/dist/es2022/export/index.js.map +1 -0
  64. package/dist/es2022/export/utils/export.utils.d.ts +2 -0
  65. package/dist/es2022/export/utils/export.utils.js +5 -0
  66. package/dist/es2022/export/utils/export.utils.js.map +1 -0
  67. package/dist/es2022/file/file-manager.d.ts +5 -0
  68. package/dist/es2022/file/file-manager.js +29 -0
  69. package/dist/es2022/file/file-manager.js.map +1 -0
  70. package/dist/es2022/file/index.d.ts +1 -0
  71. package/dist/es2022/file/index.js +2 -0
  72. package/dist/es2022/file/index.js.map +1 -0
  73. package/dist/es2022/import/comparers/asset-comparer.d.ts +12 -0
  74. package/dist/es2022/import/comparers/asset-comparer.js +65 -0
  75. package/dist/es2022/import/comparers/asset-comparer.js.map +1 -0
  76. package/dist/es2022/import/context/import-context-fetcher.d.ts +4 -0
  77. package/dist/es2022/import/context/import-context-fetcher.js +235 -0
  78. package/dist/es2022/import/context/import-context-fetcher.js.map +1 -0
  79. package/dist/es2022/import/import-manager.d.ts +4 -0
  80. package/dist/es2022/import/import-manager.js +80 -0
  81. package/dist/es2022/import/import-manager.js.map +1 -0
  82. package/dist/es2022/import/import.models.d.ts +45 -0
  83. package/dist/es2022/import/import.models.js +2 -0
  84. package/dist/es2022/import/import.models.js.map +1 -0
  85. package/dist/es2022/import/importers/assets-importer.d.ts +10 -0
  86. package/dist/es2022/import/importers/assets-importer.js +175 -0
  87. package/dist/es2022/import/importers/assets-importer.js.map +1 -0
  88. package/dist/es2022/import/importers/content-items-importer.d.ts +10 -0
  89. package/dist/es2022/import/importers/content-items-importer.js +97 -0
  90. package/dist/es2022/import/importers/content-items-importer.js.map +1 -0
  91. package/dist/es2022/import/importers/language-variant-importer.d.ts +11 -0
  92. package/dist/es2022/import/importers/language-variant-importer.js +215 -0
  93. package/dist/es2022/import/importers/language-variant-importer.js.map +1 -0
  94. package/dist/es2022/import/importers/workflow-importer.d.ts +18 -0
  95. package/dist/es2022/import/importers/workflow-importer.js +122 -0
  96. package/dist/es2022/import/importers/workflow-importer.js.map +1 -0
  97. package/dist/es2022/import/index.d.ts +2 -0
  98. package/dist/es2022/import/index.js +3 -0
  99. package/dist/es2022/import/index.js.map +1 -0
  100. package/dist/es2022/import/utils/import.utils.d.ts +2 -0
  101. package/dist/es2022/import/utils/import.utils.js +5 -0
  102. package/dist/es2022/import/utils/import.utils.js.map +1 -0
  103. package/dist/es2022/index.d.ts +8 -0
  104. package/dist/es2022/index.js +10 -0
  105. package/dist/es2022/index.js.map +1 -0
  106. package/dist/es2022/metadata.d.ts +5 -0
  107. package/dist/es2022/metadata.js +6 -0
  108. package/dist/es2022/metadata.js.map +1 -0
  109. package/dist/es2022/node/cli/actions/export-action.d.ts +2 -0
  110. package/dist/es2022/node/cli/actions/export-action.js +40 -0
  111. package/dist/es2022/node/cli/actions/export-action.js.map +1 -0
  112. package/dist/es2022/node/cli/actions/import-action.d.ts +2 -0
  113. package/dist/es2022/node/cli/actions/import-action.js +29 -0
  114. package/dist/es2022/node/cli/actions/import-action.js.map +1 -0
  115. package/dist/es2022/node/cli/actions/migrate-action.d.ts +2 -0
  116. package/dist/es2022/node/cli/actions/migrate-action.js +47 -0
  117. package/dist/es2022/node/cli/actions/migrate-action.js.map +1 -0
  118. package/dist/es2022/node/cli/app.d.ts +2 -0
  119. package/dist/es2022/node/cli/app.js +27 -0
  120. package/dist/es2022/node/cli/app.js.map +1 -0
  121. package/dist/es2022/node/cli/args/args-fetcher.d.ts +2 -0
  122. package/dist/es2022/node/cli/args/args-fetcher.js +46 -0
  123. package/dist/es2022/node/cli/args/args-fetcher.js.map +1 -0
  124. package/dist/es2022/node/cli/args/args-setter.d.ts +2 -0
  125. package/dist/es2022/node/cli/args/args-setter.js +31 -0
  126. package/dist/es2022/node/cli/args/args-setter.js.map +1 -0
  127. package/dist/es2022/node/cli/cli.models.d.ts +24 -0
  128. package/dist/es2022/node/cli/cli.models.js +2 -0
  129. package/dist/es2022/node/cli/cli.models.js.map +1 -0
  130. package/dist/es2022/node/cli/commands.d.ts +1 -0
  131. package/dist/es2022/node/cli/commands.js +157 -0
  132. package/dist/es2022/node/cli/commands.js.map +1 -0
  133. package/dist/es2022/toolkit/elements-builder.d.ts +14 -0
  134. package/dist/es2022/toolkit/elements-builder.js +69 -0
  135. package/dist/es2022/toolkit/elements-builder.js.map +1 -0
  136. package/dist/es2022/toolkit/export.d.ts +3 -0
  137. package/dist/es2022/toolkit/export.js +21 -0
  138. package/dist/es2022/toolkit/export.js.map +1 -0
  139. package/dist/es2022/toolkit/file.d.ts +12 -0
  140. package/dist/es2022/toolkit/file.js +50 -0
  141. package/dist/es2022/toolkit/file.js.map +1 -0
  142. package/dist/es2022/toolkit/import.d.ts +2 -0
  143. package/dist/es2022/toolkit/import.js +21 -0
  144. package/dist/es2022/toolkit/import.js.map +1 -0
  145. package/dist/es2022/toolkit/index.d.ts +5 -0
  146. package/dist/es2022/toolkit/index.js +6 -0
  147. package/dist/es2022/toolkit/index.js.map +1 -0
  148. package/dist/es2022/toolkit/migrate.d.ts +21 -0
  149. package/dist/es2022/toolkit/migrate.js +39 -0
  150. package/dist/es2022/toolkit/migrate.js.map +1 -0
  151. package/dist/es2022/translation/extraction/items-extraction.processor.d.ts +24 -0
  152. package/dist/es2022/translation/extraction/items-extraction.processor.js +108 -0
  153. package/dist/es2022/translation/extraction/items-extraction.processor.js.map +1 -0
  154. package/dist/es2022/translation/helpers/rich-text.processor.d.ts +22 -0
  155. package/dist/es2022/translation/helpers/rich-text.processor.js +209 -0
  156. package/dist/es2022/translation/helpers/rich-text.processor.js.map +1 -0
  157. package/dist/es2022/translation/index.d.ts +4 -0
  158. package/dist/es2022/translation/index.js +5 -0
  159. package/dist/es2022/translation/index.js.map +1 -0
  160. package/dist/es2022/translation/transforms/export-transforms.d.ts +3 -0
  161. package/dist/es2022/translation/transforms/export-transforms.js +196 -0
  162. package/dist/es2022/translation/transforms/export-transforms.js.map +1 -0
  163. package/dist/es2022/translation/transforms/import-transforms.d.ts +7 -0
  164. package/dist/es2022/translation/transforms/import-transforms.js +183 -0
  165. package/dist/es2022/translation/transforms/import-transforms.js.map +1 -0
  166. package/dist/es2022/zip/index.d.ts +4 -0
  167. package/dist/es2022/zip/index.js +5 -0
  168. package/dist/es2022/zip/index.js.map +1 -0
  169. package/dist/es2022/zip/zip-manager.d.ts +6 -0
  170. package/dist/es2022/zip/zip-manager.js +27 -0
  171. package/dist/es2022/zip/zip-manager.js.map +1 -0
  172. package/dist/es2022/zip/zip-packager.d.ts +3 -0
  173. package/dist/es2022/zip/zip-packager.js +69 -0
  174. package/dist/es2022/zip/zip-packager.js.map +1 -0
  175. package/dist/es2022/zip/zip-transformer.d.ts +6 -0
  176. package/dist/es2022/zip/zip-transformer.js +82 -0
  177. package/dist/es2022/zip/zip-transformer.js.map +1 -0
  178. package/dist/es2022/zip/zip.models.d.ts +13 -0
  179. package/dist/es2022/zip/zip.models.js +2 -0
  180. package/dist/es2022/zip/zip.models.js.map +1 -0
  181. package/lib/core/helpers/workflow-helper.ts +104 -0
  182. package/lib/core/index.ts +17 -0
  183. package/lib/core/logs/loggers.ts +80 -0
  184. package/lib/core/models/core.models.ts +134 -0
  185. package/lib/core/models/log.models.ts +31 -0
  186. package/lib/core/models/migration.models.ts +165 -0
  187. package/lib/core/utils/array.utils.ts +49 -0
  188. package/lib/core/utils/binary-data.utils.ts +29 -0
  189. package/lib/core/utils/confirm.utils.ts +139 -0
  190. package/lib/core/utils/error.utils.ts +65 -0
  191. package/lib/core/utils/external-id.utils.ts +9 -0
  192. package/lib/core/utils/global.utils.ts +59 -0
  193. package/lib/core/utils/http.utils.ts +35 -0
  194. package/lib/core/utils/management-client-utils.ts +182 -0
  195. package/lib/core/utils/processing-utils.ts +71 -0
  196. package/lib/core/utils/run.utils.ts +51 -0
  197. package/lib/export/context/export-context-fetcher.ts +475 -0
  198. package/lib/export/export-manager.ts +249 -0
  199. package/lib/export/export.models.ts +87 -0
  200. package/lib/export/index.ts +2 -0
  201. package/lib/export/utils/export.utils.ts +10 -0
  202. package/lib/file/file-manager.ts +37 -0
  203. package/lib/file/index.ts +1 -0
  204. package/lib/import/comparers/asset-comparer.ts +113 -0
  205. package/lib/import/context/import-context-fetcher.ts +367 -0
  206. package/lib/import/import-manager.ts +103 -0
  207. package/lib/import/import.models.ts +84 -0
  208. package/lib/import/importers/assets-importer.ts +239 -0
  209. package/lib/import/importers/content-items-importer.ts +142 -0
  210. package/lib/import/importers/language-variant-importer.ts +342 -0
  211. package/lib/import/importers/workflow-importer.ts +159 -0
  212. package/lib/import/index.ts +2 -0
  213. package/lib/import/utils/import.utils.ts +10 -0
  214. package/lib/index.ts +9 -0
  215. package/lib/metadata.ts +6 -0
  216. package/lib/node/cli/actions/export-action.ts +45 -0
  217. package/lib/node/cli/actions/import-action.ts +34 -0
  218. package/lib/node/cli/actions/migrate-action.ts +52 -0
  219. package/lib/node/cli/app.ts +29 -0
  220. package/lib/node/cli/args/args-fetcher.ts +61 -0
  221. package/lib/node/cli/args/args-setter.ts +35 -0
  222. package/lib/node/cli/cli.models.ts +28 -0
  223. package/lib/node/cli/commands.ts +161 -0
  224. package/lib/toolkit/elements-builder.ts +84 -0
  225. package/lib/toolkit/export.ts +21 -0
  226. package/lib/toolkit/file.ts +70 -0
  227. package/lib/toolkit/import.ts +21 -0
  228. package/lib/toolkit/index.ts +5 -0
  229. package/lib/toolkit/migrate.ts +71 -0
  230. package/lib/translation/extraction/items-extraction.processor.ts +181 -0
  231. package/lib/translation/helpers/rich-text.processor.ts +300 -0
  232. package/lib/translation/index.ts +4 -0
  233. package/lib/translation/transforms/export-transforms.ts +253 -0
  234. package/lib/translation/transforms/import-transforms.ts +215 -0
  235. package/lib/zip/index.ts +4 -0
  236. package/lib/zip/zip-manager.ts +33 -0
  237. package/lib/zip/zip-packager.ts +86 -0
  238. package/lib/zip/zip-transformer.ts +105 -0
  239. package/lib/zip/zip.models.ts +12 -0
  240. package/package.json +88 -0
@@ -0,0 +1,134 @@
1
+ import {
2
+ AssetModels,
3
+ ContentItemModels,
4
+ ContentTypeElements,
5
+ LanguageVariantModels,
6
+ WorkflowModels
7
+ } from '@kontent-ai/management-sdk';
8
+ import { MigrationElementType } from './migration.models.js';
9
+ import { WorkflowStep } from '../helpers/workflow-helper.js';
10
+
11
+ export type TargetItemState = 'exists' | 'doesNotExists';
12
+ export type CliAction = 'export' | 'import' | 'migrate';
13
+ export type GeneralItemType = 'exportedItem' | 'migrationItem';
14
+ export type GeneralActionType = 'readFs' | 'skip' | 'writeFs' | 'download';
15
+ export type EnvContext = 'browser' | 'node';
16
+
17
+ export type MapiAction =
18
+ | 'list'
19
+ | 'view'
20
+ | 'archive'
21
+ | 'unpublish'
22
+ | 'changeWorkflowStep'
23
+ | 'publish'
24
+ | 'upload'
25
+ | 'create'
26
+ | 'upsert'
27
+ | 'createNewVersion';
28
+
29
+ export type MapiType =
30
+ | 'contentType'
31
+ | 'asset'
32
+ | 'contentTypeSnippet'
33
+ | 'contentItem'
34
+ | 'languageVariant'
35
+ | 'language'
36
+ | 'collection'
37
+ | 'taxonomy'
38
+ | 'binaryFile'
39
+ | 'workflow';
40
+
41
+ export interface ItemInfo {
42
+ readonly title: string;
43
+ readonly itemType: GeneralItemType | MapiType;
44
+ }
45
+
46
+ export interface ErrorData {
47
+ readonly message: string;
48
+ readonly requestData?: string;
49
+ readonly requestUrl?: string;
50
+ readonly isUnknownError: boolean;
51
+ readonly error: unknown;
52
+ }
53
+
54
+ export interface ReferencedDataInMigrationItems {
55
+ readonly itemCodenames: ReadonlySet<string>;
56
+ readonly assetCodenames: ReadonlySet<string>;
57
+ }
58
+
59
+ export interface ReferencedDataInLanguageVariants {
60
+ readonly itemIds: ReadonlySet<string>;
61
+ readonly assetIds: ReadonlySet<string>;
62
+ }
63
+
64
+ export interface ItemStateInSourceEnvironmentById {
65
+ readonly state: TargetItemState;
66
+ readonly id: string;
67
+ readonly item: Readonly<ContentItemModels.ContentItem> | undefined;
68
+ }
69
+
70
+ export interface AssetStateInSourceEnvironmentById {
71
+ readonly state: TargetItemState;
72
+ readonly id: string;
73
+ readonly asset: Readonly<AssetModels.Asset> | undefined;
74
+ }
75
+
76
+ export interface ItemStateInTargetEnvironmentByCodename {
77
+ readonly state: TargetItemState;
78
+ readonly itemCodename: string;
79
+ readonly item: Readonly<ContentItemModels.ContentItem> | undefined;
80
+ readonly externalIdToUse: string;
81
+ }
82
+
83
+ export interface LanguageVariantStateInTargetEnvironmentByCodename {
84
+ readonly state: TargetItemState;
85
+ readonly itemCodename: string;
86
+ readonly languageCodename: string;
87
+ readonly languageVariant: Readonly<LanguageVariantModels.ContentItemLanguageVariant> | undefined;
88
+ readonly workflow: Readonly<WorkflowModels.Workflow> | undefined;
89
+ readonly step: Readonly<WorkflowStep> | undefined;
90
+ }
91
+
92
+ export interface AssetStateInTargetEnvironmentByCodename {
93
+ readonly state: TargetItemState;
94
+ readonly assetCodename: string;
95
+ readonly asset: Readonly<AssetModels.Asset> | undefined;
96
+ readonly externalIdToUse: string;
97
+ }
98
+
99
+ export interface PackageMetadata {
100
+ readonly created: Date;
101
+ readonly environmentId: string;
102
+ readonly dataOverview: PackageDataOverview;
103
+ }
104
+
105
+ export interface PackageDataOverview {
106
+ readonly contentItemsCount: number;
107
+ readonly assetsCount: number;
108
+ }
109
+
110
+ export interface FlattenedContentTypeElement {
111
+ readonly codename: string;
112
+ readonly id: string;
113
+ readonly type: MigrationElementType;
114
+ readonly element: Readonly<ContentTypeElements.ContentTypeElementModel>;
115
+ }
116
+
117
+ export interface FlattenedContentType {
118
+ readonly contentTypeCodename: string;
119
+ readonly contentTypeId: string;
120
+ readonly elements: readonly FlattenedContentTypeElement[];
121
+ }
122
+
123
+ export interface OriginalManagementError {
124
+ response?: {
125
+ status?: number;
126
+ config?: {
127
+ url?: string;
128
+ data?: string;
129
+ };
130
+ data?: {
131
+ error_code?: number;
132
+ };
133
+ };
134
+ }
@@ -0,0 +1,31 @@
1
+ import { GeneralActionType, GeneralItemType, MapiAction, MapiType } from '../index.js';
2
+
3
+ export type DebugType =
4
+ | 'error'
5
+ | 'completed'
6
+ | 'warning'
7
+ | 'info'
8
+ | 'errorData'
9
+ | 'cancel'
10
+ | 'process'
11
+ | MapiType
12
+ | GeneralActionType
13
+ | MapiAction
14
+ | GeneralItemType;
15
+
16
+ export interface LogMessage {
17
+ readonly type: DebugType;
18
+ readonly message: string;
19
+ }
20
+
21
+ export interface LogSpinnerMessage extends LogMessage {
22
+ readonly prefix?: string;
23
+ }
24
+
25
+ export type LogData = (data: LogMessage) => void;
26
+ export type LogSpinnerData = (data: LogSpinnerMessage) => void;
27
+
28
+ export interface Logger {
29
+ readonly logWithSpinnerAsync: <T>(func: (logData: LogSpinnerData) => Promise<T>) => Promise<T>;
30
+ readonly log: LogData;
31
+ }
@@ -0,0 +1,165 @@
1
+ export type MigrationElementType =
2
+ | 'text'
3
+ | 'rich_text'
4
+ | 'number'
5
+ | 'multiple_choice'
6
+ | 'date_time'
7
+ | 'asset'
8
+ | 'modular_content'
9
+ | 'taxonomy'
10
+ | 'url_slug'
11
+ | 'custom'
12
+ | 'subpages';
13
+
14
+ export type MigrationUrlSlugMode = 'autogenerated' | 'custom';
15
+
16
+ export interface MigrationRichTextElementValue {
17
+ value: string;
18
+ components: readonly MigrationComponent[];
19
+ }
20
+
21
+ export interface MigrationUrlSlugElementValue {
22
+ value: string | undefined;
23
+ mode: MigrationUrlSlugMode;
24
+ }
25
+
26
+ export interface MigrationComponent {
27
+ system: {
28
+ id: string;
29
+ type: MigrationReference;
30
+ };
31
+ elements: MigrationElements;
32
+ }
33
+
34
+ export type MigrationElementValue =
35
+ | string
36
+ | undefined
37
+ | MigrationReference[]
38
+ | number
39
+ | MigrationRichTextElementValue
40
+ | MigrationUrlSlugElementValue;
41
+
42
+ export interface MigrationElement<
43
+ TElementType extends MigrationElementType = MigrationElementType,
44
+ TValue extends MigrationElementValue = MigrationElementValue
45
+ > {
46
+ /**
47
+ * Value of the element
48
+ */
49
+ readonly value: TValue;
50
+
51
+ /**
52
+ * Type of the element
53
+ */
54
+ readonly type: TElementType;
55
+ }
56
+
57
+ export namespace MigrationElementModels {
58
+ export interface TextElement extends MigrationElement<'text', string | undefined> {}
59
+ export interface NumberElement extends MigrationElement<'number', number | undefined> {}
60
+ export interface RichTextElement extends MigrationElement<'rich_text', MigrationRichTextElementValue | undefined> {}
61
+ export interface MultipleChoiceElement
62
+ extends MigrationElement<'multiple_choice', MigrationReference[] | undefined> {}
63
+ export interface DateTimeElement extends MigrationElement<'date_time', string | undefined> {}
64
+ export interface AssetElement extends MigrationElement<'asset', MigrationReference[] | undefined> {}
65
+ export interface LinkedItemsElement extends MigrationElement<'modular_content', MigrationReference[] | undefined> {}
66
+ export interface TaxonomyElement extends MigrationElement<'taxonomy', MigrationReference[] | undefined> {}
67
+ export interface UrlSlugElement extends MigrationElement<'url_slug', MigrationUrlSlugElementValue | undefined> {}
68
+ export interface CustomElement extends MigrationElement<'custom', string | undefined> {}
69
+ export interface SubpagesElement extends MigrationElement<'subpages', MigrationReference[] | undefined> {}
70
+ }
71
+
72
+ export interface MigrationElements {
73
+ [elementCodename: string]: MigrationElement;
74
+ }
75
+
76
+ export interface MigrationItemVersion<TElements extends MigrationElements = MigrationElements> {
77
+ readonly elements: TElements;
78
+ readonly workflow_step: MigrationReference;
79
+ }
80
+
81
+ export interface MigrationItem<TElements extends MigrationElements = MigrationElements> {
82
+ readonly system: {
83
+ /**
84
+ * Codename of the content item
85
+ */
86
+ readonly codename: string;
87
+ /**
88
+ * Name of the content item
89
+ */
90
+ readonly name: string;
91
+ /**
92
+ * Language of the language variant
93
+ */
94
+ readonly language: MigrationReference;
95
+ /**
96
+ * Content type of the item
97
+ */
98
+ readonly type: MigrationReference;
99
+ /**
100
+ * Collection of the item
101
+ */
102
+ readonly collection: MigrationReference;
103
+
104
+ /**
105
+ * Workflow of the item
106
+ */
107
+ readonly workflow: MigrationReference;
108
+ };
109
+ readonly versions: MigrationItemVersion<TElements>[];
110
+ }
111
+
112
+ export interface MigrationReference {
113
+ /**
114
+ * Codename of the referenced object
115
+ */
116
+ readonly codename: string;
117
+ }
118
+
119
+ export interface MigrationAssetDescription {
120
+ readonly language: MigrationReference;
121
+ readonly description?: string;
122
+ }
123
+
124
+ export interface MigrationAsset {
125
+ /**
126
+ * Codename of the asset
127
+ */
128
+ readonly codename: string;
129
+ /**
130
+ * Binary data of the asset
131
+ */
132
+ readonly binaryData: Buffer | Blob;
133
+ /**
134
+ * Filename of the asset, will be used as a filename in Kontent.ai after importing the asset
135
+ */
136
+ readonly filename: string;
137
+ /**
138
+ * Title of the asset
139
+ */
140
+ readonly title: string;
141
+
142
+ /**
143
+ * Optional
144
+ * Collection of the asset
145
+ */
146
+ readonly collection?: MigrationReference;
147
+
148
+ /**
149
+ * Optional.
150
+ * Descriptions of the assets
151
+ */
152
+ readonly descriptions?: readonly MigrationAssetDescription[];
153
+ }
154
+
155
+ export interface MigrationData {
156
+ /**
157
+ * Array of migration items to process (export / import)
158
+ */
159
+ readonly items: readonly MigrationItem[];
160
+
161
+ /**
162
+ * Array of migration assets to process
163
+ */
164
+ readonly assets: readonly MigrationAsset[];
165
+ }
@@ -0,0 +1,49 @@
1
+ import { MigrationElementValue, MigrationReference } from '../models/migration.models.js';
2
+
3
+ export function parseAsMigrationReferencesArray(value: MigrationElementValue): readonly MigrationReference[] {
4
+ if (!value) {
5
+ return [];
6
+ }
7
+ if (Array.isArray(value)) {
8
+ return value;
9
+ }
10
+ throw Error(`Value is not an array`);
11
+ }
12
+
13
+ export function findRequired<T>(
14
+ array: readonly T[],
15
+ predicate: (item: T, index: number) => boolean,
16
+ errorMessage: string
17
+ ): T;
18
+ export function findRequired<T>(
19
+ array: readonly T[],
20
+ predicate: (item: T, index: number) => boolean,
21
+ errorMessage: () => never
22
+ ): T;
23
+ export function findRequired<T>(
24
+ array: readonly T[],
25
+ predicate: (item: T, index: number) => boolean,
26
+ errorMessage: string | (() => never)
27
+ ): T {
28
+ const item = array.find(predicate);
29
+
30
+ if (item) {
31
+ return item;
32
+ }
33
+
34
+ if (typeof errorMessage === 'string' || errorMessage instanceof String) {
35
+ throw Error(errorMessage.toString());
36
+ }
37
+ return errorMessage();
38
+ }
39
+
40
+ export async function mapAsync<Input, Result>(
41
+ array: readonly Input[],
42
+ callbackAsync: (item: Readonly<Input>, index: number, array: readonly Input[]) => Promise<Readonly<Result>>
43
+ ): Promise<Readonly<Result[]>> {
44
+ const results: Result[] = [];
45
+ for (let i = 0; i < array.length; i++) {
46
+ results.push(await callbackAsync(array[i], i, array));
47
+ }
48
+ return results;
49
+ }
@@ -0,0 +1,29 @@
1
+ import { defaultHttpService, defaultRetryStrategy } from './http.utils.js';
2
+
3
+ export async function getBinaryDataFromUrlAsync(url: string): Promise<{ data: Buffer | Blob; contentLength: number }> {
4
+ // temp fix for Kontent.ai Repository not validating url
5
+ url = url.replace('#', '%23');
6
+
7
+ const response = await defaultHttpService.getAsync<Buffer | Blob>(
8
+ {
9
+ url
10
+ },
11
+ {
12
+ responseType: 'arraybuffer',
13
+ retryStrategy: defaultRetryStrategy
14
+ }
15
+ );
16
+
17
+ const contentLengthHeader = response.headers.find((m) => m.header.toLowerCase() === 'content-length');
18
+ const contentLength = contentLengthHeader ? +contentLengthHeader.value : 0;
19
+
20
+ return { data: response.data, contentLength: contentLength };
21
+ }
22
+
23
+ export function geSizeInBytes(data: Blob | Buffer): number {
24
+ if (data instanceof Blob) {
25
+ return data.size;
26
+ }
27
+
28
+ return data.byteLength;
29
+ }
@@ -0,0 +1,139 @@
1
+ import chalk from 'chalk';
2
+ import { Logger } from '../models/log.models.js';
3
+ import { getMigrationManagementClient, managementClientUtils } from './management-client-utils.js';
4
+
5
+ export async function confirmExportAsync(data: {
6
+ readonly force: boolean;
7
+ readonly environmentId: string;
8
+ readonly apiKey: string;
9
+ readonly logger: Logger;
10
+ readonly dataToExport: {
11
+ readonly itemsCount: number;
12
+ };
13
+ }): Promise<void> {
14
+ const environment = await managementClientUtils(
15
+ getMigrationManagementClient({
16
+ environmentId: data.environmentId,
17
+ apiKey: data.apiKey
18
+ }),
19
+ data.logger
20
+ ).getEnvironmentAsync();
21
+
22
+ const text: string = `Are you sure to export '${chalk.cyan(
23
+ data.dataToExport.itemsCount
24
+ )}' content ${getItemsPluralText(data.dataToExport.itemsCount)} from ${chalk.yellow(
25
+ environment.name
26
+ )} (${chalk.yellow(environment.environment)}?`;
27
+
28
+ await confirmAsync({
29
+ force: data.force,
30
+ logger: data.logger,
31
+ action: 'Export',
32
+ message: text
33
+ });
34
+ }
35
+
36
+ export async function confirmMigrateAsync(data: {
37
+ readonly force: boolean;
38
+ readonly sourceEnvironment: {
39
+ readonly environmentId: string;
40
+ readonly apiKey: string;
41
+ };
42
+ readonly targetEnvironment: {
43
+ readonly environmentId: string;
44
+ readonly apiKey: string;
45
+ };
46
+ readonly logger: Logger;
47
+ readonly dataToMigrate: {
48
+ readonly itemsCount: number;
49
+ };
50
+ }): Promise<void> {
51
+ const sourceEnvironment = await managementClientUtils(
52
+ getMigrationManagementClient({
53
+ environmentId: data.sourceEnvironment.environmentId,
54
+ apiKey: data.sourceEnvironment.apiKey
55
+ }),
56
+ data.logger
57
+ ).getEnvironmentAsync();
58
+ const targetEnvironment = await managementClientUtils(
59
+ getMigrationManagementClient({
60
+ environmentId: data.targetEnvironment.environmentId,
61
+ apiKey: data.targetEnvironment.apiKey
62
+ }),
63
+ data.logger
64
+ ).getEnvironmentAsync();
65
+
66
+ const text: string = `Are you sure to migrate '${chalk.cyan(data.dataToMigrate.itemsCount)}' ${getItemsPluralText(
67
+ data.dataToMigrate.itemsCount
68
+ )} from ${chalk.yellow(sourceEnvironment.name)} (${chalk.yellow(
69
+ sourceEnvironment.environment
70
+ )}) to environment ${chalk.yellow(targetEnvironment.name)} (${chalk.yellow(targetEnvironment.environment)}) ?`;
71
+
72
+ await confirmAsync({
73
+ force: data.force,
74
+ logger: data.logger,
75
+ action: 'Migrate',
76
+ message: text
77
+ });
78
+ }
79
+
80
+ export async function confirmImportAsync(data: {
81
+ readonly force: boolean;
82
+ readonly environmentId: string;
83
+ readonly apiKey: string;
84
+ readonly logger: Logger;
85
+ }): Promise<void> {
86
+ const environment = await managementClientUtils(
87
+ getMigrationManagementClient({
88
+ environmentId: data.environmentId,
89
+ apiKey: data.apiKey
90
+ }),
91
+ data.logger
92
+ ).getEnvironmentAsync();
93
+
94
+ const text: string = `Are you sure to import data into ${chalk.yellow(environment.name)} (${chalk.yellow(
95
+ environment.environment
96
+ )})?`;
97
+
98
+ await confirmAsync({
99
+ force: data.force,
100
+ logger: data.logger,
101
+ action: 'Import',
102
+ message: text
103
+ });
104
+ }
105
+
106
+ async function confirmAsync(data: {
107
+ readonly action: string;
108
+ readonly message: string;
109
+ readonly force: boolean;
110
+ readonly logger: Logger;
111
+ }): Promise<void> {
112
+ // Prompts is imported dynamically because it's a node.js only module and would not work if user
113
+ // tried using this library in a browser
114
+ const prompts = await import('prompts');
115
+
116
+ if (data.force) {
117
+ data.logger.log({
118
+ type: 'info',
119
+ message: `Skipping confirmation prompt due to the use of 'force' param`
120
+ });
121
+ } else {
122
+ const confirmed = await prompts.default({
123
+ type: 'confirm',
124
+ name: 'confirm',
125
+ message: `${chalk.cyan(data.action)}: ${data.message}`
126
+ });
127
+
128
+ if (!confirmed.confirm) {
129
+ throw Error(`Confirmation refused.`);
130
+ }
131
+ }
132
+ }
133
+
134
+ function getItemsPluralText(count: number): string {
135
+ if (count === 1) {
136
+ return 'item';
137
+ }
138
+ return 'items';
139
+ }
@@ -0,0 +1,65 @@
1
+ import { SharedModels } from '@kontent-ai/management-sdk';
2
+ import chalk from 'chalk';
3
+ import { ErrorData, OriginalManagementError } from '../models/core.models.js';
4
+
5
+ export function extractErrorData(error: unknown): ErrorData {
6
+ let isUnknownError: boolean = true;
7
+ let message: string = `Unknown error`;
8
+ let requestUrl: string | undefined = undefined;
9
+ let requestData: string | undefined = undefined;
10
+
11
+ if (error instanceof SharedModels.ContentManagementBaseKontentError) {
12
+ isUnknownError = false;
13
+ message = `${error.message}`;
14
+
15
+ const originalError: OriginalManagementError | undefined = error.originalError as
16
+ | OriginalManagementError
17
+ | undefined;
18
+
19
+ requestUrl = originalError?.response?.config?.url;
20
+ requestData = originalError?.response?.config?.data;
21
+ message += error.validationErrors.map((m) => m.message).join(', ');
22
+ } else if (error instanceof Error) {
23
+ message = error.message;
24
+ }
25
+
26
+ const errorData: ErrorData = {
27
+ message: message,
28
+ requestData: requestData,
29
+ requestUrl: requestUrl,
30
+ error: error,
31
+ isUnknownError: isUnknownError
32
+ };
33
+
34
+ return errorData;
35
+ }
36
+
37
+ export function is404Error(error: unknown): boolean {
38
+ if (error instanceof SharedModels.ContentManagementBaseKontentError) {
39
+ const originalError = error.originalError as OriginalManagementError | undefined;
40
+
41
+ if (originalError?.response?.status === 404) {
42
+ return true;
43
+ }
44
+ }
45
+
46
+ return false;
47
+ }
48
+
49
+ export function handleError(error: unknown): void {
50
+ const errorData = extractErrorData(error);
51
+
52
+ if (errorData.isUnknownError) {
53
+ console.error(error);
54
+ }
55
+
56
+ if (errorData.requestData) {
57
+ console.log(`${chalk.red('Request data')}: ${errorData.requestData}`);
58
+ }
59
+
60
+ if (errorData.requestUrl) {
61
+ console.log(`${chalk.red('Request url')}: ${errorData.requestUrl}`);
62
+ }
63
+
64
+ console.error(`${chalk.red('Error:')} ${errorData.message}`);
65
+ }
@@ -0,0 +1,9 @@
1
+ export interface ExternalIdGenerator {
2
+ readonly assetExternalId: (codename: string) => string;
3
+ readonly contentItemExternalId: (codename: string) => string;
4
+ }
5
+
6
+ export const defaultExternalIdGenerator: ExternalIdGenerator = {
7
+ assetExternalId: (codename) => `asset_${codename}`,
8
+ contentItemExternalId: (codename) => `item_${codename}`
9
+ };
@@ -0,0 +1,59 @@
1
+ import { format } from 'bytes';
2
+ import { ITrackingEventData, getTrackingService } from '@kontent-ai-consulting/tools-analytics';
3
+ import { isBrowser, isNode, isWebWorker } from 'browser-or-node';
4
+ import { EnvContext } from '../models/core.models.js';
5
+
6
+ export const isNotUndefined = <T>(item: T | undefined): item is T => item !== undefined;
7
+
8
+ export function formatBytes(bytes: number): string {
9
+ return format(bytes);
10
+ }
11
+
12
+ export function sleepAsync(ms: number): Promise<void> {
13
+ return new Promise((resolve) => setTimeout(resolve, ms));
14
+ }
15
+
16
+ export function exitProgram(data: { readonly message: string }): never {
17
+ throw Error(data.message);
18
+ }
19
+
20
+ export function getCurrentEnvironment(): EnvContext {
21
+ if (isNode) {
22
+ return 'node';
23
+ }
24
+ if (isBrowser || isWebWorker) {
25
+ return 'browser';
26
+ }
27
+
28
+ throw Error(`Invalid current environment. This library can be used in node.js or in browsers.`);
29
+ }
30
+
31
+ export function getDefaultZipFilename(): string {
32
+ return `data.zip`;
33
+ }
34
+
35
+ export async function executeWithTrackingAsync<TResult>(data: {
36
+ func: () => Promise<TResult extends void ? void : Readonly<TResult>>;
37
+ event: Readonly<ITrackingEventData>;
38
+ }): Promise<TResult extends void ? void : Readonly<TResult>> {
39
+ const trackingService = getTrackingService();
40
+ const event = await trackingService.trackEventAsync(data.event);
41
+
42
+ try {
43
+ const result = await data.func();
44
+
45
+ await trackingService.setEventResultAsync({
46
+ eventId: event.eventId,
47
+ result: 'success'
48
+ });
49
+
50
+ return result;
51
+ } catch (error) {
52
+ await trackingService.setEventResultAsync({
53
+ eventId: event.eventId,
54
+ result: 'fail'
55
+ });
56
+
57
+ throw error;
58
+ }
59
+ }