@kontent-ai/migration-toolkit 1.0.0 → 1.1.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/README.md +3 -7
- package/dist/es2022/core/index.d.ts +1 -0
- package/dist/es2022/core/index.js +1 -0
- package/dist/es2022/core/index.js.map +1 -1
- package/dist/es2022/core/models/migration.models.d.ts +35 -133
- package/dist/es2022/core/models/migration.schema.d.ts +1300 -0
- package/dist/es2022/core/models/migration.schema.js +114 -0
- package/dist/es2022/core/models/migration.schema.js.map +1 -0
- package/dist/es2022/core/utils/confirm.utils.js +3 -3
- package/dist/es2022/core/utils/confirm.utils.js.map +1 -1
- package/dist/es2022/core/utils/error.utils.js +8 -2
- package/dist/es2022/core/utils/error.utils.js.map +1 -1
- package/dist/es2022/core/utils/global.utils.d.ts +4 -1
- package/dist/es2022/core/utils/global.utils.js +1 -3
- package/dist/es2022/core/utils/global.utils.js.map +1 -1
- package/dist/es2022/export/context/export-context-fetcher.js +10 -6
- package/dist/es2022/export/context/export-context-fetcher.js.map +1 -1
- package/dist/es2022/export/export-manager.js +3 -3
- package/dist/es2022/export/export-manager.js.map +1 -1
- package/dist/es2022/import/import-manager.js.map +1 -1
- package/dist/es2022/metadata.js +2 -2
- package/dist/es2022/node/cli/actions/export-action.js +2 -2
- package/dist/es2022/node/cli/actions/export-action.js.map +1 -1
- package/dist/es2022/node/cli/actions/import-action.js +2 -2
- package/dist/es2022/node/cli/actions/import-action.js.map +1 -1
- package/dist/es2022/node/cli/app.js +3 -0
- package/dist/es2022/node/cli/app.js.map +1 -1
- package/dist/es2022/node/cli/args/args-setter.js +3 -0
- package/dist/es2022/node/cli/args/args-setter.js.map +1 -1
- package/dist/es2022/node/cli/cli.models.d.ts +1 -0
- package/dist/es2022/toolkit/file.js +3 -3
- package/dist/es2022/toolkit/file.js.map +1 -1
- package/dist/es2022/translation/transforms/export-transforms.js.map +1 -1
- package/dist/es2022/zip/zip-transformer.js +9 -6
- package/dist/es2022/zip/zip-transformer.js.map +1 -1
- package/dist/es2022/zip/zip.models.d.ts +1 -1
- package/lib/core/index.ts +1 -0
- package/lib/core/models/migration.models.ts +56 -159
- package/lib/core/models/migration.schema.ts +180 -0
- package/lib/core/utils/confirm.utils.ts +4 -4
- package/lib/core/utils/error.utils.ts +9 -6
- package/lib/core/utils/global.utils.ts +3 -3
- package/lib/export/context/export-context-fetcher.ts +9 -6
- package/lib/export/export-manager.ts +16 -20
- package/lib/import/import-manager.ts +2 -6
- package/lib/metadata.ts +2 -2
- package/lib/node/cli/actions/export-action.ts +2 -2
- package/lib/node/cli/actions/import-action.ts +2 -2
- package/lib/node/cli/app.ts +4 -0
- package/lib/node/cli/args/args-setter.ts +3 -0
- package/lib/node/cli/cli.models.ts +1 -0
- package/lib/toolkit/file.ts +3 -9
- package/lib/translation/transforms/export-transforms.ts +1 -4
- package/lib/zip/zip-transformer.ts +25 -11
- package/lib/zip/zip.models.ts +1 -1
- package/package.json +10 -10
|
@@ -16,7 +16,10 @@ import {
|
|
|
16
16
|
isNotUndefined,
|
|
17
17
|
MigrationElementValue,
|
|
18
18
|
getMigrationManagementClient,
|
|
19
|
-
findRequired
|
|
19
|
+
findRequired,
|
|
20
|
+
Writeable,
|
|
21
|
+
MigrationItemsSchema,
|
|
22
|
+
MigrationAssetsSchema
|
|
20
23
|
} from '../core/index.js';
|
|
21
24
|
import { exportTransforms } from '../translation/index.js';
|
|
22
25
|
import { exportContextFetcherAsync } from './context/export-context-fetcher.js';
|
|
@@ -61,11 +64,7 @@ export function exportManager(config: ExportConfig) {
|
|
|
61
64
|
const componentType = context.environmentData.contentTypes.find((m) => m.contentTypeId === component.type.id);
|
|
62
65
|
|
|
63
66
|
if (!componentType) {
|
|
64
|
-
throw Error(
|
|
65
|
-
`Could not find content type with id '${chalk.red(component.type.id)}' for component '${chalk.red(
|
|
66
|
-
component.id
|
|
67
|
-
)}'`
|
|
68
|
-
);
|
|
67
|
+
throw Error(`Could not find content type with id '${chalk.red(component.type.id)}' for component '${chalk.red(component.id)}'`);
|
|
69
68
|
}
|
|
70
69
|
|
|
71
70
|
const migrationItem: MigrationComponent = {
|
|
@@ -96,7 +95,7 @@ export function exportManager(config: ExportConfig) {
|
|
|
96
95
|
}
|
|
97
96
|
return 0;
|
|
98
97
|
})
|
|
99
|
-
.reduce<MigrationElements
|
|
98
|
+
.reduce<Writeable<MigrationElements>>((model, typeElement) => {
|
|
100
99
|
const itemElement = findRequired(
|
|
101
100
|
elements,
|
|
102
101
|
(m) => m.element.id === typeElement.id,
|
|
@@ -128,9 +127,7 @@ export function exportManager(config: ExportConfig) {
|
|
|
128
127
|
context: data.context,
|
|
129
128
|
typeElement: data.typeElement,
|
|
130
129
|
exportElement: {
|
|
131
|
-
components: data.exportElement.components.map((component) =>
|
|
132
|
-
mapToMigrationComponent(data.context, component)
|
|
133
|
-
),
|
|
130
|
+
components: data.exportElement.components.map((component) => mapToMigrationComponent(data.context, component)),
|
|
134
131
|
value: data.exportElement.value,
|
|
135
132
|
urlSlugMode: data.exportElement.mode
|
|
136
133
|
}
|
|
@@ -155,9 +152,7 @@ export function exportManager(config: ExportConfig) {
|
|
|
155
152
|
|
|
156
153
|
const exportAssetsAsync = async (context: ExportContext): Promise<readonly Readonly<MigrationAsset>[]> => {
|
|
157
154
|
const assets = Array.from(context.referencedData.assetIds)
|
|
158
|
-
.map<Readonly<AssetModels.Asset> | undefined>(
|
|
159
|
-
(assetId) => context.getAssetStateInSourceEnvironment(assetId).asset
|
|
160
|
-
)
|
|
155
|
+
.map<Readonly<AssetModels.Asset> | undefined>((assetId) => context.getAssetStateInSourceEnvironment(assetId).asset)
|
|
161
156
|
.filter(isNotUndefined);
|
|
162
157
|
|
|
163
158
|
return await getMigrationAssetsWithBinaryDataAsync(assets, context);
|
|
@@ -184,8 +179,9 @@ export function exportManager(config: ExportConfig) {
|
|
|
184
179
|
},
|
|
185
180
|
items: assets,
|
|
186
181
|
processAsync: async (asset, logSpinner) => {
|
|
187
|
-
const assetCollection: Readonly<CollectionModels.Collection> | undefined =
|
|
188
|
-
|
|
182
|
+
const assetCollection: Readonly<CollectionModels.Collection> | undefined = context.environmentData.collections.find(
|
|
183
|
+
(m) => m.id === asset.collection?.reference?.id
|
|
184
|
+
);
|
|
189
185
|
|
|
190
186
|
logSpinner({
|
|
191
187
|
type: 'download',
|
|
@@ -204,9 +200,9 @@ export function exportManager(config: ExportConfig) {
|
|
|
204
200
|
const language = findRequired(
|
|
205
201
|
context.environmentData.languages,
|
|
206
202
|
(language) => language.id === description.language.id,
|
|
207
|
-
`Could not find language with id '${chalk.red(
|
|
208
|
-
|
|
209
|
-
)}'
|
|
203
|
+
`Could not find language with id '${chalk.red(description.language.id)}' requested by asset '${chalk.red(
|
|
204
|
+
asset.codename
|
|
205
|
+
)}'`
|
|
210
206
|
);
|
|
211
207
|
|
|
212
208
|
return {
|
|
@@ -234,8 +230,8 @@ export function exportManager(config: ExportConfig) {
|
|
|
234
230
|
).getExportContextAsync();
|
|
235
231
|
|
|
236
232
|
const migrationData: MigrationData = {
|
|
237
|
-
items: getMigrationItems(exportContext),
|
|
238
|
-
assets: await exportAssetsAsync(exportContext)
|
|
233
|
+
items: MigrationItemsSchema.parse(getMigrationItems(exportContext)),
|
|
234
|
+
assets: MigrationAssetsSchema.parse(await exportAssetsAsync(exportContext))
|
|
239
235
|
};
|
|
240
236
|
|
|
241
237
|
logger.log({
|
|
@@ -11,9 +11,7 @@ export function importManager(config: ImportConfig) {
|
|
|
11
11
|
const logger: Logger = config.logger ?? getDefaultLogger();
|
|
12
12
|
const targetEnvironmentClient: ManagementClient = getMigrationManagementClient(config);
|
|
13
13
|
|
|
14
|
-
const importAssetsAsync = async (
|
|
15
|
-
importContext: ImportContext
|
|
16
|
-
): Promise<Pick<ImportResult, 'editedAssets' | 'uploadedAssets'>> => {
|
|
14
|
+
const importAssetsAsync = async (importContext: ImportContext): Promise<Pick<ImportResult, 'editedAssets' | 'uploadedAssets'>> => {
|
|
17
15
|
if (!importContext.categorizedImportData.assets.length) {
|
|
18
16
|
logger.log({
|
|
19
17
|
type: 'info',
|
|
@@ -31,9 +29,7 @@ export function importManager(config: ImportConfig) {
|
|
|
31
29
|
logger: logger
|
|
32
30
|
}).importAsync();
|
|
33
31
|
};
|
|
34
|
-
const importContentItemsAsync = async (
|
|
35
|
-
importContext: ImportContext
|
|
36
|
-
): Promise<readonly Readonly<ContentItemModels.ContentItem>[]> => {
|
|
32
|
+
const importContentItemsAsync = async (importContext: ImportContext): Promise<readonly Readonly<ContentItemModels.ContentItem>[]> => {
|
|
37
33
|
if (!importContext.categorizedImportData.contentItems.length) {
|
|
38
34
|
logger.log({
|
|
39
35
|
type: 'info',
|
package/lib/metadata.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { confirmExportAsync,
|
|
1
|
+
import { confirmExportAsync, defaultZipFilename, getDefaultLogger } from '../../../core/index.js';
|
|
2
2
|
import { exportAsync, storeAsync } from '../../../toolkit/index.js';
|
|
3
3
|
import { CliArgumentsFetcher } from '../cli.models.js';
|
|
4
4
|
|
|
@@ -10,7 +10,7 @@ export async function exportActionAsync(cliFetcher: CliArgumentsFetcher): Promis
|
|
|
10
10
|
const items = cliFetcher.getRequiredArgumentValue('items').split(',');
|
|
11
11
|
const baseUrl = cliFetcher.getOptionalArgumentValue('baseUrl');
|
|
12
12
|
const force = cliFetcher.getBooleanArgumentValue('force', false);
|
|
13
|
-
const filename = cliFetcher.getOptionalArgumentValue('filename') ??
|
|
13
|
+
const filename = cliFetcher.getOptionalArgumentValue('filename') ?? defaultZipFilename;
|
|
14
14
|
|
|
15
15
|
await confirmExportAsync({
|
|
16
16
|
force: force,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { confirmImportAsync,
|
|
1
|
+
import { confirmImportAsync, defaultZipFilename, getDefaultLogger } from '../../../core/index.js';
|
|
2
2
|
import { extractAsync, importAsync } from '../../../toolkit/index.js';
|
|
3
3
|
import { CliArgumentsFetcher } from '../cli.models.js';
|
|
4
4
|
|
|
@@ -8,7 +8,7 @@ export async function importActionAsync(argsFetcher: CliArgumentsFetcher): Promi
|
|
|
8
8
|
const apiKey = argsFetcher.getRequiredArgumentValue('targetApiKey');
|
|
9
9
|
const baseUrl = argsFetcher.getOptionalArgumentValue('baseUrl');
|
|
10
10
|
const force = argsFetcher.getBooleanArgumentValue('force', false);
|
|
11
|
-
const filename = argsFetcher.getOptionalArgumentValue('filename') ??
|
|
11
|
+
const filename = argsFetcher.getOptionalArgumentValue('filename') ?? defaultZipFilename;
|
|
12
12
|
|
|
13
13
|
await confirmImportAsync({
|
|
14
14
|
force: force,
|
package/lib/node/cli/app.ts
CHANGED
|
@@ -6,6 +6,10 @@ import { exportActionAsync } from './actions/export-action.js';
|
|
|
6
6
|
import { importActionAsync } from './actions/import-action.js';
|
|
7
7
|
import { migrateActionAsync } from './actions/migrate-action.js';
|
|
8
8
|
import { argumentsFetcherAsync } from './args/args-fetcher.js';
|
|
9
|
+
import { cliArgs } from './commands.js';
|
|
10
|
+
|
|
11
|
+
// This enabled --help with all commands, options & samples
|
|
12
|
+
cliArgs.registerCommands();
|
|
9
13
|
|
|
10
14
|
const run = async () => {
|
|
11
15
|
const argsFetcher = await argumentsFetcherAsync();
|
package/lib/toolkit/file.ts
CHANGED
|
@@ -1,11 +1,5 @@
|
|
|
1
1
|
import { fileManager } from '../file/index.js';
|
|
2
|
-
import {
|
|
3
|
-
Logger,
|
|
4
|
-
executeWithTrackingAsync,
|
|
5
|
-
getDefaultZipFilename,
|
|
6
|
-
getDefaultLogger,
|
|
7
|
-
MigrationData
|
|
8
|
-
} from '../core/index.js';
|
|
2
|
+
import { Logger, executeWithTrackingAsync, defaultZipFilename, getDefaultLogger, MigrationData } from '../core/index.js';
|
|
9
3
|
import { zipManager } from '../zip/index.js';
|
|
10
4
|
import { libMetadata } from '../metadata.js';
|
|
11
5
|
|
|
@@ -22,7 +16,7 @@ export interface ExtractConfig {
|
|
|
22
16
|
|
|
23
17
|
export async function storeAsync(config: StoreConfig): Promise<void> {
|
|
24
18
|
const logger = config.logger ?? getDefaultLogger();
|
|
25
|
-
const filename
|
|
19
|
+
const filename = config.filename ?? defaultZipFilename;
|
|
26
20
|
|
|
27
21
|
await executeWithTrackingAsync<void>({
|
|
28
22
|
event: {
|
|
@@ -49,7 +43,7 @@ export async function storeAsync(config: StoreConfig): Promise<void> {
|
|
|
49
43
|
|
|
50
44
|
export async function extractAsync(config: ExtractConfig): Promise<MigrationData> {
|
|
51
45
|
const logger = config.logger ?? getDefaultLogger();
|
|
52
|
-
const filename
|
|
46
|
+
const filename = config.filename ?? defaultZipFilename;
|
|
53
47
|
|
|
54
48
|
return await executeWithTrackingAsync({
|
|
55
49
|
event: {
|
|
@@ -175,10 +175,7 @@ export const exportTransforms: Readonly<Record<MigrationElementType, ExportTrans
|
|
|
175
175
|
}
|
|
176
176
|
};
|
|
177
177
|
|
|
178
|
-
function findTaxonomy(
|
|
179
|
-
termId: string,
|
|
180
|
-
taxonomy: Readonly<TaxonomyModels.Taxonomy>
|
|
181
|
-
): Readonly<TaxonomyModels.Taxonomy> | undefined {
|
|
178
|
+
function findTaxonomy(termId: string, taxonomy: Readonly<TaxonomyModels.Taxonomy>): Readonly<TaxonomyModels.Taxonomy> | undefined {
|
|
182
179
|
if (taxonomy.id === termId) {
|
|
183
180
|
return taxonomy;
|
|
184
181
|
}
|
|
@@ -1,10 +1,19 @@
|
|
|
1
|
-
import { FileBinaryData, ZipPackager } from './zip.models.js';
|
|
2
|
-
import { Logger, MigrationAsset, MigrationData, MigrationItem, getDefaultLogger, mapAsync } from '../core/index.js';
|
|
3
1
|
import chalk from 'chalk';
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
import { FileBinaryData, ZipPackager } from './zip.models.js';
|
|
4
|
+
import {
|
|
5
|
+
Logger,
|
|
6
|
+
MigrationAsset,
|
|
7
|
+
MigrationData,
|
|
8
|
+
MigrationItem,
|
|
9
|
+
MigrationItemsSchema,
|
|
10
|
+
ZipMigrationAssetSchema,
|
|
11
|
+
ZipMigrationAssetsSchema,
|
|
12
|
+
getDefaultLogger,
|
|
13
|
+
mapAsync
|
|
14
|
+
} from '../core/index.js';
|
|
15
|
+
|
|
16
|
+
type ZipAssetRecord = z.infer<typeof ZipMigrationAssetSchema>;
|
|
8
17
|
|
|
9
18
|
export function zipTransformer(zip: ZipPackager, logger?: Logger) {
|
|
10
19
|
const loggerToUse: Logger = logger ?? getDefaultLogger();
|
|
@@ -51,18 +60,23 @@ export function zipTransformer(zip: ZipPackager, logger?: Logger) {
|
|
|
51
60
|
};
|
|
52
61
|
|
|
53
62
|
const parseItems = async () => {
|
|
54
|
-
const
|
|
55
|
-
|
|
63
|
+
const content = await zip.getFileContentAsync(filename);
|
|
64
|
+
|
|
65
|
+
if (!content) {
|
|
66
|
+
return [];
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
return MigrationItemsSchema.parse(JSON.parse(content));
|
|
56
70
|
};
|
|
57
71
|
|
|
58
72
|
const parseAssets = async () => {
|
|
59
|
-
const
|
|
73
|
+
const content = await zip.getFileContentAsync(assetsFilename);
|
|
60
74
|
|
|
61
|
-
if (!
|
|
75
|
+
if (!content) {
|
|
62
76
|
return [];
|
|
63
77
|
}
|
|
64
78
|
|
|
65
|
-
const assetRecords = JSON.parse(
|
|
79
|
+
const assetRecords = ZipMigrationAssetsSchema.parse(JSON.parse(content));
|
|
66
80
|
|
|
67
81
|
return await mapAsync(assetRecords, async (assetRecord) => {
|
|
68
82
|
const binaryFile = await zip.getBinaryDataAsync(`${assetRecord._zipFilename}`);
|
package/lib/zip/zip.models.ts
CHANGED
|
@@ -4,7 +4,7 @@ export type FileBinaryData = Buffer | Blob;
|
|
|
4
4
|
export type ZipCompressionLevel = 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9;
|
|
5
5
|
|
|
6
6
|
export type ZipPackager = {
|
|
7
|
-
addFile(filePath: string, data: string |
|
|
7
|
+
addFile(filePath: string, data: string | FileBinaryData): void;
|
|
8
8
|
addFolder(name: string): ZipPackager;
|
|
9
9
|
generateZipAsync(config: { logger?: Logger; compressionLevel?: ZipCompressionLevel }): Promise<FileBinaryData>;
|
|
10
10
|
getBinaryDataAsync(filePath: string): Promise<FileBinaryData | undefined>;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kontent-ai/migration-toolkit",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.1.0",
|
|
4
4
|
"description": "This program can be used to import content related data into Kontent.ai from various formats. Additionally, it can also be used to export Kontent.ai data using Delivery API.",
|
|
5
5
|
"preferGlobal": true,
|
|
6
6
|
"private": false,
|
|
@@ -59,30 +59,30 @@
|
|
|
59
59
|
"chalk": "5.3.0",
|
|
60
60
|
"dotenv": "16.4.5",
|
|
61
61
|
"jszip": "3.10.1",
|
|
62
|
-
"mime": "4.0.
|
|
62
|
+
"mime": "4.0.4",
|
|
63
63
|
"ora": "8.0.1",
|
|
64
64
|
"prompts": "2.4.2",
|
|
65
65
|
"yargs": "17.7.2",
|
|
66
|
-
"p-limit": "
|
|
67
|
-
"deep-equal": "2.2.3"
|
|
66
|
+
"p-limit": "6.1.0",
|
|
67
|
+
"deep-equal": "2.2.3",
|
|
68
|
+
"zod": "3.23.8"
|
|
68
69
|
},
|
|
69
70
|
"devDependencies": {
|
|
70
|
-
"@eslint/js": "9.
|
|
71
|
+
"@eslint/js": "9.7.0",
|
|
71
72
|
"@types/deep-equal": "1.0.4",
|
|
72
73
|
"@types/browser-or-node": "1.3.2",
|
|
73
74
|
"@types/bytes": "3.1.4",
|
|
74
75
|
"@types/eslint__js": "8.42.3",
|
|
75
|
-
"@types/
|
|
76
|
-
"@types/node": "20.14.9",
|
|
76
|
+
"@types/node": "20.14.10",
|
|
77
77
|
"@types/prompts": "2.4.9",
|
|
78
78
|
"@types/yargs": "17.0.32",
|
|
79
|
-
"@typescript-eslint/eslint-plugin": "7.
|
|
80
|
-
"@typescript-eslint/parser": "7.
|
|
79
|
+
"@typescript-eslint/eslint-plugin": "7.16.0",
|
|
80
|
+
"@typescript-eslint/parser": "7.16.0",
|
|
81
81
|
"eslint": "8.57.0",
|
|
82
82
|
"standard-version": "9.5.0",
|
|
83
83
|
"tslib": "2.6.3",
|
|
84
84
|
"tsx": "4.16.2",
|
|
85
85
|
"typescript": "5.5.3",
|
|
86
|
-
"typescript-eslint": "7.
|
|
86
|
+
"typescript-eslint": "7.16.0"
|
|
87
87
|
}
|
|
88
88
|
}
|