@kontent-ai/migration-toolkit 1.0.1 → 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 +1 -1
- 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/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/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 -9
|
@@ -1,165 +1,62 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
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
|
-
}
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import {
|
|
3
|
+
MigrationComponentSchema,
|
|
4
|
+
MigrationElementTypeSchema,
|
|
5
|
+
MigrationElementValueSchema,
|
|
6
|
+
MigrationReferenceSchema,
|
|
7
|
+
MigrationUrlSlugElementValueSchema,
|
|
8
|
+
MigrationUrlSlugModeSchema,
|
|
9
|
+
MigrationRichTextElementValueSchema,
|
|
10
|
+
MigrationElementSchema,
|
|
11
|
+
MigrationElementsSchema,
|
|
12
|
+
MigrationAssetDescriptionSchema,
|
|
13
|
+
MigrationDataSchema,
|
|
14
|
+
MigrationAssetSchema,
|
|
15
|
+
BaseMigrationItemSchema,
|
|
16
|
+
BaseMigrationItemVersionSchema
|
|
17
|
+
} from './migration.schema.js';
|
|
56
18
|
|
|
57
19
|
export namespace MigrationElementModels {
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
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
|
-
}
|
|
20
|
+
type MigrationElementDef<
|
|
21
|
+
TElementType extends MigrationElementType = MigrationElementType,
|
|
22
|
+
TValue extends MigrationElementValue = MigrationElementValue
|
|
23
|
+
> = {
|
|
24
|
+
readonly value: TValue;
|
|
25
|
+
readonly type: TElementType;
|
|
26
|
+
};
|
|
75
27
|
|
|
76
|
-
export
|
|
28
|
+
export type TextElement = MigrationElementDef<'text', string | undefined>;
|
|
29
|
+
export type NumberElement = MigrationElementDef<'number', number | undefined>;
|
|
30
|
+
export type RichTextElement = MigrationElementDef<'rich_text', MigrationRichTextElementValue | undefined>;
|
|
31
|
+
export type MultipleChoiceElement = MigrationElementDef<'multiple_choice', MigrationReference[] | undefined>;
|
|
32
|
+
export type DateTimeElement = MigrationElementDef<'date_time', string | undefined>;
|
|
33
|
+
export type AssetElement = MigrationElementDef<'asset', MigrationReference[] | undefined>;
|
|
34
|
+
export type LinkedItemsElement = MigrationElementDef<'modular_content', MigrationReference[] | undefined>;
|
|
35
|
+
export type TaxonomyElement = MigrationElementDef<'taxonomy', MigrationReference[] | undefined>;
|
|
36
|
+
export type UrlSlugElement = MigrationElementDef<'url_slug', MigrationUrlSlugElementValue | undefined>;
|
|
37
|
+
export type CustomElement = MigrationElementDef<'custom', string | undefined>;
|
|
38
|
+
export type SubpagesElement = MigrationElementDef<'subpages', MigrationReference[] | undefined>;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export type MigrationReference = z.infer<typeof MigrationReferenceSchema>;
|
|
42
|
+
export type MigrationUrlSlugMode = z.infer<typeof MigrationUrlSlugModeSchema>;
|
|
43
|
+
export type MigrationElementType = z.infer<typeof MigrationElementTypeSchema>;
|
|
44
|
+
export type MigrationUrlSlugElementValue = z.infer<typeof MigrationUrlSlugElementValueSchema>;
|
|
45
|
+
export type MigrationRichTextElementValue = z.infer<typeof MigrationRichTextElementValueSchema>;
|
|
46
|
+
export type MigrationComponent = z.infer<typeof MigrationComponentSchema>;
|
|
47
|
+
export type MigrationElementValue = z.infer<typeof MigrationElementValueSchema>;
|
|
48
|
+
export type MigrationElement = z.infer<typeof MigrationElementSchema>;
|
|
49
|
+
export type MigrationElements = z.infer<typeof MigrationElementsSchema>;
|
|
50
|
+
export type MigrationAssetDescription = z.infer<typeof MigrationAssetDescriptionSchema>;
|
|
51
|
+
export type MigrationAsset = z.infer<typeof MigrationAssetSchema>;
|
|
52
|
+
export type MigrationData = z.infer<typeof MigrationDataSchema>;
|
|
53
|
+
|
|
54
|
+
export type MigrationItemVersion<TElements extends MigrationElements = MigrationElements> = z.infer<
|
|
55
|
+
typeof BaseMigrationItemVersionSchema
|
|
56
|
+
> & {
|
|
77
57
|
readonly elements: TElements;
|
|
78
|
-
|
|
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;
|
|
58
|
+
};
|
|
103
59
|
|
|
104
|
-
|
|
105
|
-
* Workflow of the item
|
|
106
|
-
*/
|
|
107
|
-
readonly workflow: MigrationReference;
|
|
108
|
-
};
|
|
60
|
+
export type MigrationItem<TElements extends MigrationElements = MigrationElements> = z.infer<typeof BaseMigrationItemSchema> & {
|
|
109
61
|
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
|
-
}
|
|
62
|
+
};
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
|
|
3
|
+
interface Elements {
|
|
4
|
+
readonly [key: string]: Element;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
type UrlSlugMode = 'autogenerated' | 'custom';
|
|
8
|
+
|
|
9
|
+
type UrlSlugElementValue = {
|
|
10
|
+
readonly value?: string;
|
|
11
|
+
readonly mode: UrlSlugMode;
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
type Reference = { readonly codename: string };
|
|
15
|
+
|
|
16
|
+
type Component = {
|
|
17
|
+
readonly system: {
|
|
18
|
+
readonly id: string;
|
|
19
|
+
readonly type: Reference;
|
|
20
|
+
};
|
|
21
|
+
readonly elements: Elements;
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
type RichTextElementValue = {
|
|
25
|
+
readonly value: string;
|
|
26
|
+
readonly components: Readonly<Component[]>;
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
type ElementValue = string | undefined | number | Reference[] | RichTextElementValue | UrlSlugElementValue;
|
|
30
|
+
|
|
31
|
+
type Element = {
|
|
32
|
+
readonly type: ElementType;
|
|
33
|
+
readonly value?: ElementValue;
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
type ElementType =
|
|
37
|
+
| 'text'
|
|
38
|
+
| 'rich_text'
|
|
39
|
+
| 'number'
|
|
40
|
+
| 'multiple_choice'
|
|
41
|
+
| 'date_time'
|
|
42
|
+
| 'asset'
|
|
43
|
+
| 'modular_content'
|
|
44
|
+
| 'taxonomy'
|
|
45
|
+
| 'url_slug'
|
|
46
|
+
| 'custom'
|
|
47
|
+
| 'subpages';
|
|
48
|
+
|
|
49
|
+
export const MigrationUrlSlugModeSchema = z.enum(['autogenerated', 'custom']).readonly();
|
|
50
|
+
export const MigrationElementTypeSchema = z
|
|
51
|
+
.enum([
|
|
52
|
+
'text',
|
|
53
|
+
'rich_text',
|
|
54
|
+
'number',
|
|
55
|
+
'multiple_choice',
|
|
56
|
+
'date_time',
|
|
57
|
+
'asset',
|
|
58
|
+
'modular_content',
|
|
59
|
+
'taxonomy',
|
|
60
|
+
'url_slug',
|
|
61
|
+
'custom',
|
|
62
|
+
'subpages'
|
|
63
|
+
])
|
|
64
|
+
.readonly();
|
|
65
|
+
|
|
66
|
+
export const MigrationReferenceSchema = z
|
|
67
|
+
.strictObject({
|
|
68
|
+
codename: z.string().readonly()
|
|
69
|
+
})
|
|
70
|
+
.readonly();
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* ZodType is needed to be specified here due to the use of 'lazy' & circular dependency between types
|
|
74
|
+
* Otherwise TS has no way of statically inferring the type
|
|
75
|
+
*/
|
|
76
|
+
export const MigrationElementsSchema: z.ZodReadonly<z.ZodType<Elements>> = z
|
|
77
|
+
.record(
|
|
78
|
+
z.string(),
|
|
79
|
+
z.lazy(() => MigrationElementSchema)
|
|
80
|
+
)
|
|
81
|
+
.readonly();
|
|
82
|
+
|
|
83
|
+
export const MigrationComponentSchema = z
|
|
84
|
+
.strictObject({
|
|
85
|
+
system: z.strictObject({
|
|
86
|
+
id: z.string(),
|
|
87
|
+
type: MigrationReferenceSchema
|
|
88
|
+
}),
|
|
89
|
+
elements: MigrationElementsSchema
|
|
90
|
+
})
|
|
91
|
+
.readonly();
|
|
92
|
+
|
|
93
|
+
export const MigrationUrlSlugElementValueSchema = z
|
|
94
|
+
.strictObject({
|
|
95
|
+
value: z.optional(z.string()),
|
|
96
|
+
mode: MigrationUrlSlugModeSchema
|
|
97
|
+
})
|
|
98
|
+
.readonly();
|
|
99
|
+
|
|
100
|
+
export const MigrationRichTextElementValueSchema = z
|
|
101
|
+
.strictObject({
|
|
102
|
+
value: z.string(),
|
|
103
|
+
components: z.array(MigrationComponentSchema).readonly()
|
|
104
|
+
})
|
|
105
|
+
.readonly();
|
|
106
|
+
|
|
107
|
+
export const MigrationElementValueSchema = z.union([
|
|
108
|
+
z.string(),
|
|
109
|
+
z.undefined(),
|
|
110
|
+
z.number(),
|
|
111
|
+
z.array(MigrationReferenceSchema),
|
|
112
|
+
MigrationRichTextElementValueSchema,
|
|
113
|
+
MigrationUrlSlugElementValueSchema
|
|
114
|
+
]);
|
|
115
|
+
|
|
116
|
+
export const MigrationElementSchema = z
|
|
117
|
+
.strictObject({
|
|
118
|
+
type: MigrationElementTypeSchema,
|
|
119
|
+
value: MigrationElementValueSchema
|
|
120
|
+
})
|
|
121
|
+
.readonly();
|
|
122
|
+
|
|
123
|
+
export const BaseMigrationItemVersionSchema = z.strictObject({
|
|
124
|
+
workflow_step: MigrationReferenceSchema
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
export const MigrationItemVersionSchema = BaseMigrationItemVersionSchema.extend({
|
|
128
|
+
elements: MigrationElementsSchema
|
|
129
|
+
}).readonly();
|
|
130
|
+
|
|
131
|
+
export const BaseMigrationItemSchema = z.strictObject({
|
|
132
|
+
system: z
|
|
133
|
+
.strictObject({
|
|
134
|
+
codename: z.string(),
|
|
135
|
+
name: z.string(),
|
|
136
|
+
language: MigrationReferenceSchema,
|
|
137
|
+
type: MigrationReferenceSchema,
|
|
138
|
+
collection: MigrationReferenceSchema,
|
|
139
|
+
workflow: MigrationReferenceSchema
|
|
140
|
+
})
|
|
141
|
+
.readonly()
|
|
142
|
+
});
|
|
143
|
+
|
|
144
|
+
export const MigrationItemSchema = BaseMigrationItemSchema.extend({
|
|
145
|
+
versions: z.array(MigrationItemVersionSchema)
|
|
146
|
+
}).readonly();
|
|
147
|
+
|
|
148
|
+
export const MigrationAssetDescriptionSchema = z
|
|
149
|
+
.strictObject({
|
|
150
|
+
language: MigrationReferenceSchema,
|
|
151
|
+
description: z.optional(z.string())
|
|
152
|
+
})
|
|
153
|
+
.readonly();
|
|
154
|
+
|
|
155
|
+
const BaseMigrationAssetSchema = z.strictObject({
|
|
156
|
+
codename: z.string(),
|
|
157
|
+
filename: z.string(),
|
|
158
|
+
title: z.string(),
|
|
159
|
+
collection: z.optional(MigrationReferenceSchema),
|
|
160
|
+
descriptions: z.optional(z.array(MigrationAssetDescriptionSchema)).readonly()
|
|
161
|
+
});
|
|
162
|
+
|
|
163
|
+
export const MigrationAssetSchema = BaseMigrationAssetSchema.extend({
|
|
164
|
+
binaryData: z.union([z.instanceof(Buffer), z.instanceof(Blob)])
|
|
165
|
+
}).readonly();
|
|
166
|
+
|
|
167
|
+
export const ZipMigrationAssetSchema = BaseMigrationAssetSchema.extend({
|
|
168
|
+
_zipFilename: z.string()
|
|
169
|
+
}).readonly();
|
|
170
|
+
|
|
171
|
+
export const MigrationAssetsSchema = z.array(MigrationAssetSchema).readonly();
|
|
172
|
+
export const ZipMigrationAssetsSchema = z.array(ZipMigrationAssetSchema).readonly();
|
|
173
|
+
export const MigrationItemsSchema = z.array(MigrationItemSchema).readonly();
|
|
174
|
+
|
|
175
|
+
export const MigrationDataSchema = z
|
|
176
|
+
.strictObject({
|
|
177
|
+
items: MigrationItemsSchema,
|
|
178
|
+
assets: MigrationAssetsSchema
|
|
179
|
+
})
|
|
180
|
+
.readonly();
|
|
@@ -23,7 +23,7 @@ export async function confirmExportAsync(data: {
|
|
|
23
23
|
data.dataToExport.itemsCount
|
|
24
24
|
)}' content ${getItemsPluralText(data.dataToExport.itemsCount)} from ${chalk.yellow(
|
|
25
25
|
environment.name
|
|
26
|
-
)} (${chalk.
|
|
26
|
+
)} (${chalk.magenta(environment.environment)})?`;
|
|
27
27
|
|
|
28
28
|
await confirmAsync({
|
|
29
29
|
force: data.force,
|
|
@@ -65,9 +65,9 @@ export async function confirmMigrateAsync(data: {
|
|
|
65
65
|
|
|
66
66
|
const text: string = `Are you sure to migrate '${chalk.cyan(data.dataToMigrate.itemsCount)}' ${getItemsPluralText(
|
|
67
67
|
data.dataToMigrate.itemsCount
|
|
68
|
-
)} from ${chalk.yellow(sourceEnvironment.name)} (${chalk.
|
|
68
|
+
)} from ${chalk.yellow(sourceEnvironment.name)} (${chalk.magenta(
|
|
69
69
|
sourceEnvironment.environment
|
|
70
|
-
)}) to environment ${chalk.yellow(targetEnvironment.name)} (${chalk.
|
|
70
|
+
)}) to environment ${chalk.yellow(targetEnvironment.name)} (${chalk.magenta(targetEnvironment.environment)}) ?`;
|
|
71
71
|
|
|
72
72
|
await confirmAsync({
|
|
73
73
|
force: data.force,
|
|
@@ -91,7 +91,7 @@ export async function confirmImportAsync(data: {
|
|
|
91
91
|
data.logger
|
|
92
92
|
).getEnvironmentAsync();
|
|
93
93
|
|
|
94
|
-
const text: string = `Are you sure to import data into ${chalk.yellow(environment.name)} (${chalk.
|
|
94
|
+
const text: string = `Are you sure to import data into ${chalk.yellow(environment.name)} (${chalk.magenta(
|
|
95
95
|
environment.environment
|
|
96
96
|
)})?`;
|
|
97
97
|
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { SharedModels } from '@kontent-ai/management-sdk';
|
|
2
2
|
import chalk from 'chalk';
|
|
3
3
|
import { ErrorData, OriginalManagementError } from '../models/core.models.js';
|
|
4
|
+
import { ZodError } from 'zod';
|
|
4
5
|
|
|
5
6
|
export function extractErrorData(error: unknown): ErrorData {
|
|
6
7
|
let isUnknownError: boolean = true;
|
|
@@ -10,15 +11,17 @@ export function extractErrorData(error: unknown): ErrorData {
|
|
|
10
11
|
|
|
11
12
|
if (error instanceof SharedModels.ContentManagementBaseKontentError) {
|
|
12
13
|
isUnknownError = false;
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
const originalError: OriginalManagementError | undefined = error.originalError as
|
|
16
|
-
| OriginalManagementError
|
|
17
|
-
| undefined;
|
|
14
|
+
const originalError = error.originalError as OriginalManagementError | undefined;
|
|
18
15
|
|
|
19
16
|
requestUrl = originalError?.response?.config?.url;
|
|
20
17
|
requestData = originalError?.response?.config?.data;
|
|
21
|
-
|
|
18
|
+
|
|
19
|
+
message = `${error.message}: ${error.validationErrors.map((m) => m.message).join(', ')}`;
|
|
20
|
+
} else if (error instanceof ZodError) {
|
|
21
|
+
isUnknownError = false;
|
|
22
|
+
message = `Found '${chalk.red(error.issues.length)}' parsing errors: \n${error.issues.reduce<string>((current, issue, index) => {
|
|
23
|
+
return (current += `\n${index + 1}. ${chalk.red(issue.message)} (${chalk.yellow('path')}: ${issue.path.join(',')})`);
|
|
24
|
+
}, '')}`;
|
|
22
25
|
} else if (error instanceof Error) {
|
|
23
26
|
message = error.message;
|
|
24
27
|
}
|
|
@@ -3,6 +3,8 @@ import { ITrackingEventData, getTrackingService } from '@kontent-ai-consulting/t
|
|
|
3
3
|
import { isBrowser, isNode, isWebWorker } from 'browser-or-node';
|
|
4
4
|
import { EnvContext } from '../models/core.models.js';
|
|
5
5
|
|
|
6
|
+
export type Writeable<T> = { -readonly [P in keyof T]: T[P] };
|
|
7
|
+
|
|
6
8
|
export const isNotUndefined = <T>(item: T | undefined): item is T => item !== undefined;
|
|
7
9
|
|
|
8
10
|
export function formatBytes(bytes: number): string {
|
|
@@ -28,9 +30,7 @@ export function getCurrentEnvironment(): EnvContext {
|
|
|
28
30
|
throw Error(`Invalid current environment. This library can be used in node.js or in browsers.`);
|
|
29
31
|
}
|
|
30
32
|
|
|
31
|
-
export
|
|
32
|
-
return `data.zip`;
|
|
33
|
-
}
|
|
33
|
+
export const defaultZipFilename: string = 'data.zip';
|
|
34
34
|
|
|
35
35
|
export async function executeWithTrackingAsync<TResult>(data: {
|
|
36
36
|
func: () => Promise<TResult extends void ? void : Readonly<TResult>>;
|
|
@@ -62,10 +62,11 @@ export async function exportContextFetcherAsync(config: DefaultExportContextConf
|
|
|
62
62
|
return await runMapiRequestAsync({
|
|
63
63
|
logger: config.logger,
|
|
64
64
|
logSpinner: logSpinner,
|
|
65
|
-
func: async () =>
|
|
66
|
-
(
|
|
65
|
+
func: async () => {
|
|
66
|
+
return (
|
|
67
67
|
await config.managementClient.viewContentItem().byItemCodename(sourceItem.itemCodename).toPromise()
|
|
68
|
-
).data
|
|
68
|
+
).data;
|
|
69
|
+
},
|
|
69
70
|
action: 'view',
|
|
70
71
|
type: 'contentItem',
|
|
71
72
|
itemName: `codename -> ${sourceItem.itemCodename}`
|
|
@@ -79,14 +80,16 @@ export async function exportContextFetcherAsync(config: DefaultExportContextConf
|
|
|
79
80
|
return await runMapiRequestAsync({
|
|
80
81
|
logger: config.logger,
|
|
81
82
|
logSpinner: logSpinner,
|
|
82
|
-
func: async () =>
|
|
83
|
-
(
|
|
83
|
+
func: async () => {
|
|
84
|
+
return (
|
|
84
85
|
await config.managementClient
|
|
85
86
|
.viewLanguageVariant()
|
|
86
87
|
.byItemCodename(sourceItem.itemCodename)
|
|
87
88
|
.byLanguageCodename(sourceItem.languageCodename)
|
|
88
89
|
.toPromise()
|
|
89
|
-
).data
|
|
90
|
+
).data;
|
|
91
|
+
},
|
|
92
|
+
|
|
90
93
|
action: 'view',
|
|
91
94
|
type: 'languageVariant',
|
|
92
95
|
itemName: `codename -> ${sourceItem.itemCodename} -> latest (${sourceItem.languageCodename})`
|
|
@@ -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,
|