@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.
- package/.npmignore +13 -0
- package/LICENSE.md +9 -0
- package/README.md +272 -0
- package/dist/es2022/core/helpers/workflow-helper.d.ts +37 -0
- package/dist/es2022/core/helpers/workflow-helper.js +67 -0
- package/dist/es2022/core/helpers/workflow-helper.js.map +1 -0
- package/dist/es2022/core/index.d.ts +15 -0
- package/dist/es2022/core/index.js +16 -0
- package/dist/es2022/core/index.js.map +1 -0
- package/dist/es2022/core/logs/loggers.d.ts +2 -0
- package/dist/es2022/core/logs/loggers.js +69 -0
- package/dist/es2022/core/logs/loggers.js.map +1 -0
- package/dist/es2022/core/models/core.models.d.ts +91 -0
- package/dist/es2022/core/models/core.models.js +2 -0
- package/dist/es2022/core/models/core.models.js.map +1 -0
- package/dist/es2022/core/models/log.models.d.ts +15 -0
- package/dist/es2022/core/models/log.models.js +2 -0
- package/dist/es2022/core/models/log.models.js.map +1 -0
- package/dist/es2022/core/models/migration.models.d.ts +136 -0
- package/dist/es2022/core/models/migration.models.js +2 -0
- package/dist/es2022/core/models/migration.models.js.map +1 -0
- package/dist/es2022/core/utils/array.utils.d.ts +5 -0
- package/dist/es2022/core/utils/array.utils.js +27 -0
- package/dist/es2022/core/utils/array.utils.js.map +1 -0
- package/dist/es2022/core/utils/binary-data.utils.d.ts +5 -0
- package/dist/es2022/core/utils/binary-data.utils.js +21 -0
- package/dist/es2022/core/utils/binary-data.utils.js.map +1 -0
- package/dist/es2022/core/utils/confirm.utils.d.ts +31 -0
- package/dist/es2022/core/utils/confirm.utils.js +73 -0
- package/dist/es2022/core/utils/confirm.utils.js.map +1 -0
- package/dist/es2022/core/utils/error.utils.d.ts +4 -0
- package/dist/es2022/core/utils/error.utils.js +50 -0
- package/dist/es2022/core/utils/error.utils.js.map +1 -0
- package/dist/es2022/core/utils/external-id.utils.d.ts +5 -0
- package/dist/es2022/core/utils/external-id.utils.js +5 -0
- package/dist/es2022/core/utils/external-id.utils.js.map +1 -0
- package/dist/es2022/core/utils/global.utils.d.ts +14 -0
- package/dist/es2022/core/utils/global.utils.js +45 -0
- package/dist/es2022/core/utils/global.utils.js.map +1 -0
- package/dist/es2022/core/utils/http.utils.d.ts +3 -0
- package/dist/es2022/core/utils/http.utils.js +29 -0
- package/dist/es2022/core/utils/http.utils.js.map +1 -0
- package/dist/es2022/core/utils/management-client-utils.d.ts +19 -0
- package/dist/es2022/core/utils/management-client-utils.js +129 -0
- package/dist/es2022/core/utils/management-client-utils.js.map +1 -0
- package/dist/es2022/core/utils/processing-utils.d.ts +12 -0
- package/dist/es2022/core/utils/processing-utils.js +39 -0
- package/dist/es2022/core/utils/processing-utils.js.map +1 -0
- package/dist/es2022/core/utils/run.utils.d.ts +10 -0
- package/dist/es2022/core/utils/run.utils.js +37 -0
- package/dist/es2022/core/utils/run.utils.js.map +1 -0
- package/dist/es2022/export/context/export-context-fetcher.d.ts +4 -0
- package/dist/es2022/export/context/export-context-fetcher.js +289 -0
- package/dist/es2022/export/context/export-context-fetcher.js.map +1 -0
- package/dist/es2022/export/export-manager.d.ts +5 -0
- package/dist/es2022/export/export-manager.js +167 -0
- package/dist/es2022/export/export-manager.js.map +1 -0
- package/dist/es2022/export/export.models.d.ts +55 -0
- package/dist/es2022/export/export.models.js +2 -0
- package/dist/es2022/export/export.models.js.map +1 -0
- package/dist/es2022/export/index.d.ts +2 -0
- package/dist/es2022/export/index.js +3 -0
- package/dist/es2022/export/index.js.map +1 -0
- package/dist/es2022/export/utils/export.utils.d.ts +2 -0
- package/dist/es2022/export/utils/export.utils.js +5 -0
- package/dist/es2022/export/utils/export.utils.js.map +1 -0
- package/dist/es2022/file/file-manager.d.ts +5 -0
- package/dist/es2022/file/file-manager.js +29 -0
- package/dist/es2022/file/file-manager.js.map +1 -0
- package/dist/es2022/file/index.d.ts +1 -0
- package/dist/es2022/file/index.js +2 -0
- package/dist/es2022/file/index.js.map +1 -0
- package/dist/es2022/import/comparers/asset-comparer.d.ts +12 -0
- package/dist/es2022/import/comparers/asset-comparer.js +65 -0
- package/dist/es2022/import/comparers/asset-comparer.js.map +1 -0
- package/dist/es2022/import/context/import-context-fetcher.d.ts +4 -0
- package/dist/es2022/import/context/import-context-fetcher.js +235 -0
- package/dist/es2022/import/context/import-context-fetcher.js.map +1 -0
- package/dist/es2022/import/import-manager.d.ts +4 -0
- package/dist/es2022/import/import-manager.js +80 -0
- package/dist/es2022/import/import-manager.js.map +1 -0
- package/dist/es2022/import/import.models.d.ts +45 -0
- package/dist/es2022/import/import.models.js +2 -0
- package/dist/es2022/import/import.models.js.map +1 -0
- package/dist/es2022/import/importers/assets-importer.d.ts +10 -0
- package/dist/es2022/import/importers/assets-importer.js +175 -0
- package/dist/es2022/import/importers/assets-importer.js.map +1 -0
- package/dist/es2022/import/importers/content-items-importer.d.ts +10 -0
- package/dist/es2022/import/importers/content-items-importer.js +97 -0
- package/dist/es2022/import/importers/content-items-importer.js.map +1 -0
- package/dist/es2022/import/importers/language-variant-importer.d.ts +11 -0
- package/dist/es2022/import/importers/language-variant-importer.js +215 -0
- package/dist/es2022/import/importers/language-variant-importer.js.map +1 -0
- package/dist/es2022/import/importers/workflow-importer.d.ts +18 -0
- package/dist/es2022/import/importers/workflow-importer.js +122 -0
- package/dist/es2022/import/importers/workflow-importer.js.map +1 -0
- package/dist/es2022/import/index.d.ts +2 -0
- package/dist/es2022/import/index.js +3 -0
- package/dist/es2022/import/index.js.map +1 -0
- package/dist/es2022/import/utils/import.utils.d.ts +2 -0
- package/dist/es2022/import/utils/import.utils.js +5 -0
- package/dist/es2022/import/utils/import.utils.js.map +1 -0
- package/dist/es2022/index.d.ts +8 -0
- package/dist/es2022/index.js +10 -0
- package/dist/es2022/index.js.map +1 -0
- package/dist/es2022/metadata.d.ts +5 -0
- package/dist/es2022/metadata.js +6 -0
- package/dist/es2022/metadata.js.map +1 -0
- package/dist/es2022/node/cli/actions/export-action.d.ts +2 -0
- package/dist/es2022/node/cli/actions/export-action.js +40 -0
- package/dist/es2022/node/cli/actions/export-action.js.map +1 -0
- package/dist/es2022/node/cli/actions/import-action.d.ts +2 -0
- package/dist/es2022/node/cli/actions/import-action.js +29 -0
- package/dist/es2022/node/cli/actions/import-action.js.map +1 -0
- package/dist/es2022/node/cli/actions/migrate-action.d.ts +2 -0
- package/dist/es2022/node/cli/actions/migrate-action.js +47 -0
- package/dist/es2022/node/cli/actions/migrate-action.js.map +1 -0
- package/dist/es2022/node/cli/app.d.ts +2 -0
- package/dist/es2022/node/cli/app.js +27 -0
- package/dist/es2022/node/cli/app.js.map +1 -0
- package/dist/es2022/node/cli/args/args-fetcher.d.ts +2 -0
- package/dist/es2022/node/cli/args/args-fetcher.js +46 -0
- package/dist/es2022/node/cli/args/args-fetcher.js.map +1 -0
- package/dist/es2022/node/cli/args/args-setter.d.ts +2 -0
- package/dist/es2022/node/cli/args/args-setter.js +31 -0
- package/dist/es2022/node/cli/args/args-setter.js.map +1 -0
- package/dist/es2022/node/cli/cli.models.d.ts +24 -0
- package/dist/es2022/node/cli/cli.models.js +2 -0
- package/dist/es2022/node/cli/cli.models.js.map +1 -0
- package/dist/es2022/node/cli/commands.d.ts +1 -0
- package/dist/es2022/node/cli/commands.js +157 -0
- package/dist/es2022/node/cli/commands.js.map +1 -0
- package/dist/es2022/toolkit/elements-builder.d.ts +14 -0
- package/dist/es2022/toolkit/elements-builder.js +69 -0
- package/dist/es2022/toolkit/elements-builder.js.map +1 -0
- package/dist/es2022/toolkit/export.d.ts +3 -0
- package/dist/es2022/toolkit/export.js +21 -0
- package/dist/es2022/toolkit/export.js.map +1 -0
- package/dist/es2022/toolkit/file.d.ts +12 -0
- package/dist/es2022/toolkit/file.js +50 -0
- package/dist/es2022/toolkit/file.js.map +1 -0
- package/dist/es2022/toolkit/import.d.ts +2 -0
- package/dist/es2022/toolkit/import.js +21 -0
- package/dist/es2022/toolkit/import.js.map +1 -0
- package/dist/es2022/toolkit/index.d.ts +5 -0
- package/dist/es2022/toolkit/index.js +6 -0
- package/dist/es2022/toolkit/index.js.map +1 -0
- package/dist/es2022/toolkit/migrate.d.ts +21 -0
- package/dist/es2022/toolkit/migrate.js +39 -0
- package/dist/es2022/toolkit/migrate.js.map +1 -0
- package/dist/es2022/translation/extraction/items-extraction.processor.d.ts +24 -0
- package/dist/es2022/translation/extraction/items-extraction.processor.js +108 -0
- package/dist/es2022/translation/extraction/items-extraction.processor.js.map +1 -0
- package/dist/es2022/translation/helpers/rich-text.processor.d.ts +22 -0
- package/dist/es2022/translation/helpers/rich-text.processor.js +209 -0
- package/dist/es2022/translation/helpers/rich-text.processor.js.map +1 -0
- package/dist/es2022/translation/index.d.ts +4 -0
- package/dist/es2022/translation/index.js +5 -0
- package/dist/es2022/translation/index.js.map +1 -0
- package/dist/es2022/translation/transforms/export-transforms.d.ts +3 -0
- package/dist/es2022/translation/transforms/export-transforms.js +196 -0
- package/dist/es2022/translation/transforms/export-transforms.js.map +1 -0
- package/dist/es2022/translation/transforms/import-transforms.d.ts +7 -0
- package/dist/es2022/translation/transforms/import-transforms.js +183 -0
- package/dist/es2022/translation/transforms/import-transforms.js.map +1 -0
- package/dist/es2022/zip/index.d.ts +4 -0
- package/dist/es2022/zip/index.js +5 -0
- package/dist/es2022/zip/index.js.map +1 -0
- package/dist/es2022/zip/zip-manager.d.ts +6 -0
- package/dist/es2022/zip/zip-manager.js +27 -0
- package/dist/es2022/zip/zip-manager.js.map +1 -0
- package/dist/es2022/zip/zip-packager.d.ts +3 -0
- package/dist/es2022/zip/zip-packager.js +69 -0
- package/dist/es2022/zip/zip-packager.js.map +1 -0
- package/dist/es2022/zip/zip-transformer.d.ts +6 -0
- package/dist/es2022/zip/zip-transformer.js +82 -0
- package/dist/es2022/zip/zip-transformer.js.map +1 -0
- package/dist/es2022/zip/zip.models.d.ts +13 -0
- package/dist/es2022/zip/zip.models.js +2 -0
- package/dist/es2022/zip/zip.models.js.map +1 -0
- package/lib/core/helpers/workflow-helper.ts +104 -0
- package/lib/core/index.ts +17 -0
- package/lib/core/logs/loggers.ts +80 -0
- package/lib/core/models/core.models.ts +134 -0
- package/lib/core/models/log.models.ts +31 -0
- package/lib/core/models/migration.models.ts +165 -0
- package/lib/core/utils/array.utils.ts +49 -0
- package/lib/core/utils/binary-data.utils.ts +29 -0
- package/lib/core/utils/confirm.utils.ts +139 -0
- package/lib/core/utils/error.utils.ts +65 -0
- package/lib/core/utils/external-id.utils.ts +9 -0
- package/lib/core/utils/global.utils.ts +59 -0
- package/lib/core/utils/http.utils.ts +35 -0
- package/lib/core/utils/management-client-utils.ts +182 -0
- package/lib/core/utils/processing-utils.ts +71 -0
- package/lib/core/utils/run.utils.ts +51 -0
- package/lib/export/context/export-context-fetcher.ts +475 -0
- package/lib/export/export-manager.ts +249 -0
- package/lib/export/export.models.ts +87 -0
- package/lib/export/index.ts +2 -0
- package/lib/export/utils/export.utils.ts +10 -0
- package/lib/file/file-manager.ts +37 -0
- package/lib/file/index.ts +1 -0
- package/lib/import/comparers/asset-comparer.ts +113 -0
- package/lib/import/context/import-context-fetcher.ts +367 -0
- package/lib/import/import-manager.ts +103 -0
- package/lib/import/import.models.ts +84 -0
- package/lib/import/importers/assets-importer.ts +239 -0
- package/lib/import/importers/content-items-importer.ts +142 -0
- package/lib/import/importers/language-variant-importer.ts +342 -0
- package/lib/import/importers/workflow-importer.ts +159 -0
- package/lib/import/index.ts +2 -0
- package/lib/import/utils/import.utils.ts +10 -0
- package/lib/index.ts +9 -0
- package/lib/metadata.ts +6 -0
- package/lib/node/cli/actions/export-action.ts +45 -0
- package/lib/node/cli/actions/import-action.ts +34 -0
- package/lib/node/cli/actions/migrate-action.ts +52 -0
- package/lib/node/cli/app.ts +29 -0
- package/lib/node/cli/args/args-fetcher.ts +61 -0
- package/lib/node/cli/args/args-setter.ts +35 -0
- package/lib/node/cli/cli.models.ts +28 -0
- package/lib/node/cli/commands.ts +161 -0
- package/lib/toolkit/elements-builder.ts +84 -0
- package/lib/toolkit/export.ts +21 -0
- package/lib/toolkit/file.ts +70 -0
- package/lib/toolkit/import.ts +21 -0
- package/lib/toolkit/index.ts +5 -0
- package/lib/toolkit/migrate.ts +71 -0
- package/lib/translation/extraction/items-extraction.processor.ts +181 -0
- package/lib/translation/helpers/rich-text.processor.ts +300 -0
- package/lib/translation/index.ts +4 -0
- package/lib/translation/transforms/export-transforms.ts +253 -0
- package/lib/translation/transforms/import-transforms.ts +215 -0
- package/lib/zip/index.ts +4 -0
- package/lib/zip/zip-manager.ts +33 -0
- package/lib/zip/zip-packager.ts +86 -0
- package/lib/zip/zip-transformer.ts +105 -0
- package/lib/zip/zip.models.ts +12 -0
- package/package.json +88 -0
|
@@ -0,0 +1,253 @@
|
|
|
1
|
+
import {
|
|
2
|
+
MigrationElementType,
|
|
3
|
+
MigrationReference,
|
|
4
|
+
MigrationRichTextElementValue,
|
|
5
|
+
MigrationUrlSlugElementValue,
|
|
6
|
+
findRequired,
|
|
7
|
+
isNotUndefined
|
|
8
|
+
} from '../../core/index.js';
|
|
9
|
+
import { ContentTypeElements, TaxonomyModels } from '@kontent-ai/management-sdk';
|
|
10
|
+
import { ExportTransformFunc, ExportContext, ExportElement } from '../../export/index.js';
|
|
11
|
+
import { richTextProcessor } from '../helpers/rich-text.processor.js';
|
|
12
|
+
import chalk from 'chalk';
|
|
13
|
+
|
|
14
|
+
export const exportTransforms: Readonly<Record<MigrationElementType, ExportTransformFunc>> = {
|
|
15
|
+
text: (data) => data.exportElement.value?.toString(),
|
|
16
|
+
number: (data) => {
|
|
17
|
+
if (!data.exportElement.value) {
|
|
18
|
+
return undefined;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
if (Array.isArray(data.exportElement.value)) {
|
|
22
|
+
throw Error(`Expected value to be a number, not array`);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
if (data.exportElement.value === 0) {
|
|
26
|
+
return 0;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
return +data.exportElement.value;
|
|
30
|
+
},
|
|
31
|
+
date_time: (data) => data.exportElement.value?.toString(),
|
|
32
|
+
rich_text: (data) => transformRichTextValue(data.exportElement, data.context),
|
|
33
|
+
asset: (data) => {
|
|
34
|
+
if (!data.exportElement.value) {
|
|
35
|
+
return [];
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
if (!Array.isArray(data.exportElement.value)) {
|
|
39
|
+
throw Error(`Expected value to be an array`);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// translate asset id to codename
|
|
43
|
+
return data.exportElement.value
|
|
44
|
+
.map((m) => m.id)
|
|
45
|
+
.filter(isNotUndefined)
|
|
46
|
+
.map<MigrationReference>((id) => {
|
|
47
|
+
const assetState = data.context.getAssetStateInSourceEnvironment(id);
|
|
48
|
+
|
|
49
|
+
if (assetState.asset) {
|
|
50
|
+
// reference asset by codename
|
|
51
|
+
return { codename: assetState.asset.codename };
|
|
52
|
+
} else {
|
|
53
|
+
throw Error(`Missing asset with id '${chalk.red(id)}'`);
|
|
54
|
+
}
|
|
55
|
+
});
|
|
56
|
+
},
|
|
57
|
+
taxonomy: (data) => {
|
|
58
|
+
if (!data.exportElement.value) {
|
|
59
|
+
return [];
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
if (!Array.isArray(data.exportElement.value)) {
|
|
63
|
+
throw Error(`Expected value to be an array`);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
const taxonomyElement = data.typeElement.element as Readonly<ContentTypeElements.ITaxonomyElement>;
|
|
67
|
+
const taxonomyGroupId = taxonomyElement.taxonomy_group.id ?? 'n/a';
|
|
68
|
+
|
|
69
|
+
// get taxonomy group
|
|
70
|
+
const taxonomy = findRequired(
|
|
71
|
+
data.context.environmentData.taxonomies,
|
|
72
|
+
(taxonomy) => taxonomy.id === taxonomyGroupId,
|
|
73
|
+
`Could not find taxonomy group with id '${chalk.red(taxonomyGroupId)}'`
|
|
74
|
+
);
|
|
75
|
+
|
|
76
|
+
// translate taxonomy term to codename
|
|
77
|
+
return data.exportElement.value
|
|
78
|
+
.map((m) => m.id)
|
|
79
|
+
.filter(isNotUndefined)
|
|
80
|
+
.map<MigrationReference>((id) => {
|
|
81
|
+
const taxonomyTerm = findTaxonomy(id, taxonomy);
|
|
82
|
+
|
|
83
|
+
if (taxonomyTerm) {
|
|
84
|
+
// reference taxonomy term by codename
|
|
85
|
+
return { codename: taxonomyTerm.codename };
|
|
86
|
+
} else {
|
|
87
|
+
throw Error(`Missing taxonomy term with id '${chalk.red(id)}'`);
|
|
88
|
+
}
|
|
89
|
+
});
|
|
90
|
+
},
|
|
91
|
+
modular_content: (data) => {
|
|
92
|
+
if (!data.exportElement.value) {
|
|
93
|
+
return [];
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
if (!Array.isArray(data.exportElement.value)) {
|
|
97
|
+
throw Error(`Expected value to be an array`);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
// translate item id to codename
|
|
101
|
+
return data.exportElement.value
|
|
102
|
+
.map((m) => m.id)
|
|
103
|
+
.filter(isNotUndefined)
|
|
104
|
+
.map<MigrationReference>((id) => {
|
|
105
|
+
const itemState = data.context.getItemStateInSourceEnvironment(id);
|
|
106
|
+
|
|
107
|
+
if (itemState.item) {
|
|
108
|
+
// reference item by codename
|
|
109
|
+
return { codename: itemState.item.codename };
|
|
110
|
+
} else {
|
|
111
|
+
throw Error(`Missing item with id '${chalk.red(id)}'`);
|
|
112
|
+
}
|
|
113
|
+
});
|
|
114
|
+
},
|
|
115
|
+
custom: (data) => data.exportElement.value?.toString(),
|
|
116
|
+
url_slug: (data) => {
|
|
117
|
+
const urlSlugElementValue: MigrationUrlSlugElementValue = {
|
|
118
|
+
mode: data.exportElement.urlSlugMode ?? 'autogenerated',
|
|
119
|
+
value: data.exportElement.value?.toString() ?? undefined
|
|
120
|
+
};
|
|
121
|
+
|
|
122
|
+
return urlSlugElementValue;
|
|
123
|
+
},
|
|
124
|
+
multiple_choice: (data) => {
|
|
125
|
+
if (!data.exportElement.value) {
|
|
126
|
+
return [];
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
if (!Array.isArray(data.exportElement.value)) {
|
|
130
|
+
throw Error(`Expected value to be an array`);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
// translate multiple choice option id to codename
|
|
134
|
+
const multipleChoiceElement = data.typeElement.element as Readonly<ContentTypeElements.IMultipleChoiceElement>;
|
|
135
|
+
|
|
136
|
+
return data.exportElement.value
|
|
137
|
+
.map((m) => m.id)
|
|
138
|
+
.filter(isNotUndefined)
|
|
139
|
+
.map<MigrationReference>((id) => {
|
|
140
|
+
const option = findRequired(
|
|
141
|
+
multipleChoiceElement.options,
|
|
142
|
+
(option) => option.id === id,
|
|
143
|
+
`Could not find multiple choice element with option id '${chalk.red(id)}'`
|
|
144
|
+
);
|
|
145
|
+
|
|
146
|
+
if (!option.codename) {
|
|
147
|
+
throw Error(`Invalid codename for multiple choice option '${chalk.red(option.name)}'`);
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
return { codename: option.codename };
|
|
151
|
+
});
|
|
152
|
+
},
|
|
153
|
+
subpages: (data) => {
|
|
154
|
+
if (!data.exportElement.value) {
|
|
155
|
+
return [];
|
|
156
|
+
}
|
|
157
|
+
if (!Array.isArray(data.exportElement.value)) {
|
|
158
|
+
throw Error(`Expected value to be an array`);
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
// translate item id to codename
|
|
162
|
+
return data.exportElement.value
|
|
163
|
+
.map((m) => m.id)
|
|
164
|
+
.filter(isNotUndefined)
|
|
165
|
+
.map<MigrationReference>((id) => {
|
|
166
|
+
const itemState = data.context.getItemStateInSourceEnvironment(id);
|
|
167
|
+
|
|
168
|
+
if (itemState.item) {
|
|
169
|
+
// reference item by codename
|
|
170
|
+
return { codename: itemState.item.codename };
|
|
171
|
+
} else {
|
|
172
|
+
throw Error(`Missing item with id '${chalk.red(id)}'`);
|
|
173
|
+
}
|
|
174
|
+
});
|
|
175
|
+
}
|
|
176
|
+
};
|
|
177
|
+
|
|
178
|
+
function findTaxonomy(
|
|
179
|
+
termId: string,
|
|
180
|
+
taxonomy: Readonly<TaxonomyModels.Taxonomy>
|
|
181
|
+
): Readonly<TaxonomyModels.Taxonomy> | undefined {
|
|
182
|
+
if (taxonomy.id === termId) {
|
|
183
|
+
return taxonomy;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
if (taxonomy.terms) {
|
|
187
|
+
const foundTerm = taxonomy.terms.find((term) => findTaxonomy(term.id, term));
|
|
188
|
+
|
|
189
|
+
if (foundTerm) {
|
|
190
|
+
return foundTerm;
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
return undefined;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
function transformRichTextValue(
|
|
198
|
+
exportElement: ExportElement | undefined,
|
|
199
|
+
context: ExportContext
|
|
200
|
+
): MigrationRichTextElementValue | undefined {
|
|
201
|
+
if (!exportElement || !exportElement.value) {
|
|
202
|
+
return {
|
|
203
|
+
components: [],
|
|
204
|
+
value: ''
|
|
205
|
+
};
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
let richTextHtml: string = exportElement.value.toString();
|
|
209
|
+
|
|
210
|
+
// replace item ids with codenames
|
|
211
|
+
richTextHtml = richTextProcessor().processDataIds(richTextHtml, (id) => {
|
|
212
|
+
const itemInEnv = context.getItemStateInSourceEnvironment(id).item;
|
|
213
|
+
|
|
214
|
+
if (!itemInEnv) {
|
|
215
|
+
throw Error(`Failed to get item with id '${chalk.red(id)}'`);
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
return {
|
|
219
|
+
codename: itemInEnv.codename
|
|
220
|
+
};
|
|
221
|
+
}).html;
|
|
222
|
+
|
|
223
|
+
// replace link item ids with codenames
|
|
224
|
+
richTextHtml = richTextProcessor().processLinkItemIds(richTextHtml, (id) => {
|
|
225
|
+
const itemInEnv = context.getItemStateInSourceEnvironment(id).item;
|
|
226
|
+
|
|
227
|
+
if (!itemInEnv) {
|
|
228
|
+
throw Error(`Failed to get item with id '${chalk.red(id)}'`);
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
return {
|
|
232
|
+
codename: itemInEnv.codename
|
|
233
|
+
};
|
|
234
|
+
}).html;
|
|
235
|
+
|
|
236
|
+
// replace asset ids with codenames
|
|
237
|
+
richTextHtml = richTextProcessor().processAssetIds(richTextHtml, (id) => {
|
|
238
|
+
const assetInEnv = context.getAssetStateInSourceEnvironment(id).asset;
|
|
239
|
+
|
|
240
|
+
if (!assetInEnv) {
|
|
241
|
+
throw Error(`Failed to get asset with id '${chalk.red(id)}'`);
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
return {
|
|
245
|
+
codename: assetInEnv.codename
|
|
246
|
+
};
|
|
247
|
+
}).html;
|
|
248
|
+
|
|
249
|
+
return {
|
|
250
|
+
components: exportElement.components,
|
|
251
|
+
value: richTextHtml
|
|
252
|
+
};
|
|
253
|
+
}
|
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
import { SharedContracts, LanguageVariantElementsBuilder, LanguageVariantElements } from '@kontent-ai/management-sdk';
|
|
2
|
+
import {
|
|
3
|
+
parseAsMigrationReferencesArray,
|
|
4
|
+
MigrationElementType,
|
|
5
|
+
MigrationRichTextElementValue,
|
|
6
|
+
MigrationItem,
|
|
7
|
+
MigrationUrlSlugElementValue
|
|
8
|
+
} from '../../core/index.js';
|
|
9
|
+
import { ImportContext, ImportTransformFunc } from '../../import/index.js';
|
|
10
|
+
import { richTextProcessor } from '../helpers/rich-text.processor.js';
|
|
11
|
+
|
|
12
|
+
const elementsBuilder = new LanguageVariantElementsBuilder();
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* The purpose of import transform is to take the exported value and convert it to a value that
|
|
16
|
+
* Kontent.ai Management API understands
|
|
17
|
+
*/
|
|
18
|
+
export const importTransforms: Readonly<Record<MigrationElementType, ImportTransformFunc>> = {
|
|
19
|
+
subpages: (data) => {
|
|
20
|
+
return elementsBuilder.linkedItemsElement({
|
|
21
|
+
element: {
|
|
22
|
+
codename: data.elementCodename
|
|
23
|
+
},
|
|
24
|
+
value: parseAsMigrationReferencesArray(data.value).map((m) => {
|
|
25
|
+
return {
|
|
26
|
+
codename: m.codename
|
|
27
|
+
};
|
|
28
|
+
})
|
|
29
|
+
});
|
|
30
|
+
},
|
|
31
|
+
asset: (data) => {
|
|
32
|
+
const assetReferences = parseAsMigrationReferencesArray(data.value)
|
|
33
|
+
.map((reference) => reference.codename)
|
|
34
|
+
.map<Readonly<SharedContracts.IReferenceObjectContract>>((codename) => {
|
|
35
|
+
const assetState = data.importContext.getAssetStateInTargetEnvironment(codename);
|
|
36
|
+
|
|
37
|
+
// only reference with external_id if item does not exist in target env
|
|
38
|
+
// API currently only supports referencing assets by ids only, not by codenames
|
|
39
|
+
return {
|
|
40
|
+
id: assetState.asset ? assetState.asset.id : undefined,
|
|
41
|
+
external_id: assetState.asset ? undefined : assetState.externalIdToUse
|
|
42
|
+
};
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
return elementsBuilder.assetElement({
|
|
46
|
+
element: {
|
|
47
|
+
codename: data.elementCodename
|
|
48
|
+
},
|
|
49
|
+
value: assetReferences
|
|
50
|
+
});
|
|
51
|
+
},
|
|
52
|
+
custom: (data) => {
|
|
53
|
+
return elementsBuilder.customElement({
|
|
54
|
+
element: {
|
|
55
|
+
codename: data.elementCodename
|
|
56
|
+
},
|
|
57
|
+
value: data.value?.toString() ?? ''
|
|
58
|
+
});
|
|
59
|
+
},
|
|
60
|
+
date_time: (data) => {
|
|
61
|
+
return elementsBuilder.dateTimeElement({
|
|
62
|
+
element: {
|
|
63
|
+
codename: data.elementCodename
|
|
64
|
+
},
|
|
65
|
+
value: data.value?.toString() ?? null
|
|
66
|
+
});
|
|
67
|
+
},
|
|
68
|
+
modular_content: (data) => {
|
|
69
|
+
const linkedItemReferences = parseAsMigrationReferencesArray(data.value)
|
|
70
|
+
.map((reference) => reference.codename)
|
|
71
|
+
.map<Readonly<SharedContracts.IReferenceObjectContract>>((codename) => {
|
|
72
|
+
const itemState = data.importContext.getItemStateInTargetEnvironment(codename);
|
|
73
|
+
|
|
74
|
+
// only reference with external_id if item does not exist in target env
|
|
75
|
+
return {
|
|
76
|
+
codename: itemState.item ? itemState.item.codename : undefined,
|
|
77
|
+
external_id: itemState.item ? undefined : itemState.externalIdToUse
|
|
78
|
+
};
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
return elementsBuilder.linkedItemsElement({
|
|
82
|
+
element: {
|
|
83
|
+
codename: data.elementCodename
|
|
84
|
+
},
|
|
85
|
+
value: linkedItemReferences
|
|
86
|
+
});
|
|
87
|
+
},
|
|
88
|
+
multiple_choice: (data) => {
|
|
89
|
+
return elementsBuilder.multipleChoiceElement({
|
|
90
|
+
element: {
|
|
91
|
+
codename: data.elementCodename
|
|
92
|
+
},
|
|
93
|
+
value: parseAsMigrationReferencesArray(data.value).map((m) => {
|
|
94
|
+
return {
|
|
95
|
+
codename: m.codename
|
|
96
|
+
};
|
|
97
|
+
})
|
|
98
|
+
});
|
|
99
|
+
},
|
|
100
|
+
number: (data) => {
|
|
101
|
+
return elementsBuilder.numberElement({
|
|
102
|
+
element: {
|
|
103
|
+
codename: data.elementCodename
|
|
104
|
+
},
|
|
105
|
+
value: data.value ? +data.value : null
|
|
106
|
+
});
|
|
107
|
+
},
|
|
108
|
+
rich_text: (data) => {
|
|
109
|
+
const rteElementValue = data.value as MigrationRichTextElementValue;
|
|
110
|
+
|
|
111
|
+
return elementsBuilder.richTextElement({
|
|
112
|
+
element: {
|
|
113
|
+
codename: data.elementCodename
|
|
114
|
+
},
|
|
115
|
+
components: mapComponents({
|
|
116
|
+
importContext: data.importContext,
|
|
117
|
+
migrationItems: data.migrationItems,
|
|
118
|
+
rteValue: rteElementValue
|
|
119
|
+
}),
|
|
120
|
+
value:
|
|
121
|
+
processImportRichTextHtmlValue({
|
|
122
|
+
element: rteElementValue,
|
|
123
|
+
importContext: data.importContext,
|
|
124
|
+
migrationItems: data.migrationItems
|
|
125
|
+
}) ?? null
|
|
126
|
+
});
|
|
127
|
+
},
|
|
128
|
+
taxonomy: (data) => {
|
|
129
|
+
return elementsBuilder.taxonomyElement({
|
|
130
|
+
element: {
|
|
131
|
+
codename: data.elementCodename
|
|
132
|
+
},
|
|
133
|
+
value: parseAsMigrationReferencesArray(data.value).map((m) => {
|
|
134
|
+
return {
|
|
135
|
+
codename: m.codename
|
|
136
|
+
};
|
|
137
|
+
})
|
|
138
|
+
});
|
|
139
|
+
},
|
|
140
|
+
text: (data) => {
|
|
141
|
+
return elementsBuilder.textElement({
|
|
142
|
+
element: {
|
|
143
|
+
codename: data.elementCodename
|
|
144
|
+
},
|
|
145
|
+
value: data.value?.toString() ?? null
|
|
146
|
+
});
|
|
147
|
+
},
|
|
148
|
+
url_slug: (data) => {
|
|
149
|
+
const urlSlugElementValue = data.value as Readonly<MigrationUrlSlugElementValue>;
|
|
150
|
+
|
|
151
|
+
return elementsBuilder.urlSlugElement({
|
|
152
|
+
element: {
|
|
153
|
+
codename: data.elementCodename
|
|
154
|
+
},
|
|
155
|
+
value: urlSlugElementValue.value?.toString() ?? '',
|
|
156
|
+
mode: urlSlugElementValue.mode
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
};
|
|
160
|
+
|
|
161
|
+
function mapComponents(data: {
|
|
162
|
+
readonly rteValue: MigrationRichTextElementValue;
|
|
163
|
+
readonly importContext: ImportContext;
|
|
164
|
+
readonly migrationItems: readonly MigrationItem[];
|
|
165
|
+
}): LanguageVariantElements.IRichTextComponent[] {
|
|
166
|
+
return data.rteValue.components.map((component) => {
|
|
167
|
+
const mappedComponent: Readonly<LanguageVariantElements.IRichTextComponent> = {
|
|
168
|
+
id: component.system.id,
|
|
169
|
+
type: {
|
|
170
|
+
codename: component.system.type.codename
|
|
171
|
+
},
|
|
172
|
+
elements: Object.entries(component.elements).map(([key, element]) => {
|
|
173
|
+
const transformedElementValue = importTransforms[element.type]({
|
|
174
|
+
elementCodename: key,
|
|
175
|
+
importContext: data.importContext,
|
|
176
|
+
migrationItems: data.migrationItems,
|
|
177
|
+
value: element.value
|
|
178
|
+
});
|
|
179
|
+
|
|
180
|
+
return transformedElementValue;
|
|
181
|
+
})
|
|
182
|
+
};
|
|
183
|
+
|
|
184
|
+
return mappedComponent;
|
|
185
|
+
});
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
function processImportRichTextHtmlValue(data: {
|
|
189
|
+
readonly element: MigrationRichTextElementValue;
|
|
190
|
+
readonly importContext: ImportContext;
|
|
191
|
+
readonly migrationItems: readonly MigrationItem[];
|
|
192
|
+
}): string | undefined {
|
|
193
|
+
if (!data.element) {
|
|
194
|
+
return undefined;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
let richTextHtml: string = data.element.value ?? '';
|
|
198
|
+
|
|
199
|
+
// replace item codenames with existing codename or external_id
|
|
200
|
+
richTextHtml = richTextProcessor().processItemCodenames(richTextHtml, (codename) => {
|
|
201
|
+
return data.importContext.getItemStateInTargetEnvironment(codename);
|
|
202
|
+
}).html;
|
|
203
|
+
|
|
204
|
+
// replace link item codenames with existing codename or external_id
|
|
205
|
+
richTextHtml = richTextProcessor().processLinkItemCodenames(richTextHtml, (codename) => {
|
|
206
|
+
return data.importContext.getItemStateInTargetEnvironment(codename);
|
|
207
|
+
}).html;
|
|
208
|
+
|
|
209
|
+
// replace asset codenames with existing codename or external_id
|
|
210
|
+
richTextHtml = richTextProcessor().processAssetCodenames(richTextHtml, (codename) => {
|
|
211
|
+
return data.importContext.getAssetStateInTargetEnvironment(codename);
|
|
212
|
+
}).html;
|
|
213
|
+
|
|
214
|
+
return richTextHtml;
|
|
215
|
+
}
|
package/lib/zip/index.ts
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import JSZip from 'jszip';
|
|
2
|
+
import { Logger, MigrationData, getDefaultLogger } from '../core/index.js';
|
|
3
|
+
import { zipTransformer } from './zip-transformer.js';
|
|
4
|
+
import { zipPackager } from './zip-packager.js';
|
|
5
|
+
import { FileBinaryData } from './zip.models.js';
|
|
6
|
+
|
|
7
|
+
export function zipManager(logger?: Logger) {
|
|
8
|
+
const loggerToUse = logger ?? getDefaultLogger();
|
|
9
|
+
|
|
10
|
+
const createZipAsync = async (migrationData: MigrationData): Promise<FileBinaryData> => {
|
|
11
|
+
loggerToUse.log({
|
|
12
|
+
type: 'info',
|
|
13
|
+
message: `Creating zip package`
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
return await zipTransformer(zipPackager(new JSZip()), loggerToUse).transformAsync(migrationData);
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
const parseZipAsync = async (zipFile: Buffer): Promise<MigrationData> => {
|
|
20
|
+
loggerToUse.log({
|
|
21
|
+
type: 'info',
|
|
22
|
+
message: `Parsing zip file`
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
const zipPackage = zipPackager(await JSZip.loadAsync(zipFile, {}));
|
|
26
|
+
return await zipTransformer(zipPackage, loggerToUse).parseAsync();
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
return {
|
|
30
|
+
createZipAsync,
|
|
31
|
+
parseZipAsync
|
|
32
|
+
};
|
|
33
|
+
}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import JSZip from 'jszip';
|
|
2
|
+
import chalk from 'chalk';
|
|
3
|
+
import { Logger, formatBytes, getCurrentEnvironment, exitProgram, getDefaultLogger } from '../core/index.js';
|
|
4
|
+
import { FileBinaryData, ZipCompressionLevel, ZipPackager } from './zip.models.js';
|
|
5
|
+
|
|
6
|
+
export function zipPackager(jsZip: JSZip): ZipPackager {
|
|
7
|
+
const getZipOutputType = (): 'nodebuffer' | 'blob' => {
|
|
8
|
+
const currentEnv = getCurrentEnvironment();
|
|
9
|
+
|
|
10
|
+
if (currentEnv === 'browser') {
|
|
11
|
+
return 'blob';
|
|
12
|
+
}
|
|
13
|
+
if (currentEnv === 'node') {
|
|
14
|
+
return 'nodebuffer';
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
exitProgram({
|
|
18
|
+
message: `Unsupported context`
|
|
19
|
+
});
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
const getZipSizeInBytes = (zipData: FileBinaryData): number => {
|
|
23
|
+
if (zipData instanceof Blob) {
|
|
24
|
+
return zipData.size;
|
|
25
|
+
} else if (zipData instanceof Buffer) {
|
|
26
|
+
return zipData.byteLength;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
exitProgram({
|
|
30
|
+
message: `Unrecognized zip data type '${typeof zipData}'`
|
|
31
|
+
});
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
return {
|
|
35
|
+
addFile(filePath: string, data: string | FileBinaryData): JSZip {
|
|
36
|
+
return jsZip.file(filePath, data);
|
|
37
|
+
},
|
|
38
|
+
addFolder(name: string): ZipPackager {
|
|
39
|
+
const folder = jsZip.folder(name);
|
|
40
|
+
|
|
41
|
+
if (!folder) {
|
|
42
|
+
throw Error(`Failed to add folder '${name}'`);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
return zipPackager(folder);
|
|
46
|
+
},
|
|
47
|
+
async generateZipAsync(config: {
|
|
48
|
+
logger?: Logger;
|
|
49
|
+
compressionLevel?: ZipCompressionLevel;
|
|
50
|
+
}): Promise<FileBinaryData> {
|
|
51
|
+
const logger = config.logger ?? getDefaultLogger();
|
|
52
|
+
const zipOutputType = getZipOutputType();
|
|
53
|
+
const compressionLevel: ZipCompressionLevel = config.compressionLevel ?? 9;
|
|
54
|
+
|
|
55
|
+
logger.log({
|
|
56
|
+
type: 'info',
|
|
57
|
+
message: `Creating zip file using '${chalk.yellow(
|
|
58
|
+
zipOutputType
|
|
59
|
+
)}' with compression level '${chalk.yellow(compressionLevel.toString())}'`
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
const result = await jsZip.generateAsync({
|
|
63
|
+
type: zipOutputType,
|
|
64
|
+
compression: 'DEFLATE',
|
|
65
|
+
compressionOptions: {
|
|
66
|
+
level: compressionLevel
|
|
67
|
+
},
|
|
68
|
+
streamFiles: true
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
logger.log({
|
|
72
|
+
type: 'info',
|
|
73
|
+
message: `Zip successfully generated (${chalk.yellow(formatBytes(getZipSizeInBytes(result)))})`
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
return result;
|
|
77
|
+
},
|
|
78
|
+
async getBinaryDataAsync(filePath: string): Promise<FileBinaryData | undefined> {
|
|
79
|
+
const binaryData = await jsZip.file(filePath)?.async(getZipOutputType());
|
|
80
|
+
return binaryData;
|
|
81
|
+
},
|
|
82
|
+
async getFileContentAsync(filePath: string): Promise<string | undefined> {
|
|
83
|
+
return await jsZip.file(filePath)?.async('string');
|
|
84
|
+
}
|
|
85
|
+
};
|
|
86
|
+
}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import { FileBinaryData, ZipPackager } from './zip.models.js';
|
|
2
|
+
import { Logger, MigrationAsset, MigrationData, MigrationItem, getDefaultLogger, mapAsync } from '../core/index.js';
|
|
3
|
+
import chalk from 'chalk';
|
|
4
|
+
|
|
5
|
+
type ZipAssetRecord = Omit<MigrationAsset, 'binaryData'> & {
|
|
6
|
+
_zipFilename: string;
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
export function zipTransformer(zip: ZipPackager, logger?: Logger) {
|
|
10
|
+
const loggerToUse: Logger = logger ?? getDefaultLogger();
|
|
11
|
+
const filename: string = 'items.json';
|
|
12
|
+
const assetsFilename: string = 'assets.json';
|
|
13
|
+
const assetsBinaryFolderName: string = 'binary_data';
|
|
14
|
+
|
|
15
|
+
const getAssetFolderConfig = (asset: MigrationAsset): { partialColder: string; fullPath: string } => {
|
|
16
|
+
const codenamePartialFolder: string = asset.codename.slice(0, 2);
|
|
17
|
+
return {
|
|
18
|
+
partialColder: codenamePartialFolder,
|
|
19
|
+
fullPath: `${assetsBinaryFolderName}/${codenamePartialFolder}/${asset.codename}/${asset.filename}`
|
|
20
|
+
};
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
const transformItems = (items: readonly MigrationItem[]): void => {
|
|
24
|
+
zip.addFile(filename, items.length ? JSON.stringify(items) : '[]');
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
const transformAssets = (assets: readonly MigrationAsset[]): void => {
|
|
28
|
+
const assetRecords: ZipAssetRecord[] = [];
|
|
29
|
+
const binaryDataFolder = zip.addFolder(assetsBinaryFolderName);
|
|
30
|
+
|
|
31
|
+
assets.forEach((asset) => {
|
|
32
|
+
const folderConfig = getAssetFolderConfig(asset);
|
|
33
|
+
const partialFolder = binaryDataFolder.addFolder(folderConfig.partialColder);
|
|
34
|
+
const codenameFolder = partialFolder.addFolder(asset.codename);
|
|
35
|
+
|
|
36
|
+
assetRecords.push({
|
|
37
|
+
_zipFilename: folderConfig.fullPath,
|
|
38
|
+
filename: asset.filename,
|
|
39
|
+
title: asset.title,
|
|
40
|
+
codename: asset.codename,
|
|
41
|
+
collection: asset.collection,
|
|
42
|
+
descriptions: asset.descriptions
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
if (asset.binaryData) {
|
|
46
|
+
codenameFolder.addFile(asset.filename, asset.binaryData);
|
|
47
|
+
}
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
zip.addFile(assetsFilename, JSON.stringify(assetRecords));
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
const parseItems = async () => {
|
|
54
|
+
const fileContent = await zip.getFileContentAsync(filename);
|
|
55
|
+
return fileContent ? (JSON.parse(fileContent) as MigrationItem[]) : [];
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
const parseAssets = async () => {
|
|
59
|
+
const text = await zip.getFileContentAsync(assetsFilename);
|
|
60
|
+
|
|
61
|
+
if (!text) {
|
|
62
|
+
return [];
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
const assetRecords = JSON.parse(text) as ZipAssetRecord[];
|
|
66
|
+
|
|
67
|
+
return await mapAsync(assetRecords, async (assetRecord) => {
|
|
68
|
+
const binaryFile = await zip.getBinaryDataAsync(`${assetRecord._zipFilename}`);
|
|
69
|
+
|
|
70
|
+
if (!binaryFile) {
|
|
71
|
+
throw Error(`Could not load binary data for file '${chalk.red(assetRecord._zipFilename)}'`);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
const migrationAsset: MigrationAsset = {
|
|
75
|
+
codename: assetRecord.codename,
|
|
76
|
+
filename: assetRecord.filename,
|
|
77
|
+
collection: assetRecord.collection,
|
|
78
|
+
title: assetRecord.title,
|
|
79
|
+
descriptions: assetRecord.descriptions,
|
|
80
|
+
binaryData: binaryFile
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
return migrationAsset;
|
|
84
|
+
});
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
return {
|
|
88
|
+
async transformAsync(data: MigrationData): Promise<FileBinaryData> {
|
|
89
|
+
transformItems(data.items);
|
|
90
|
+
transformAssets(data.assets);
|
|
91
|
+
|
|
92
|
+
return await zip.generateZipAsync({ logger: loggerToUse });
|
|
93
|
+
},
|
|
94
|
+
async parseAsync(): Promise<MigrationData> {
|
|
95
|
+
const items = await parseItems();
|
|
96
|
+
const assets = await parseAssets();
|
|
97
|
+
|
|
98
|
+
const migrationData: MigrationData = {
|
|
99
|
+
assets: assets,
|
|
100
|
+
items: items
|
|
101
|
+
};
|
|
102
|
+
return migrationData;
|
|
103
|
+
}
|
|
104
|
+
};
|
|
105
|
+
}
|