@kontent-ai/migration-toolkit 1.3.0 → 1.5.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 +79 -67
- package/dist/es2022/core/helpers/workflow-helper.d.ts +1 -0
- package/dist/es2022/core/helpers/workflow-helper.js +6 -4
- package/dist/es2022/core/helpers/workflow-helper.js.map +1 -1
- package/dist/es2022/core/logs/loggers.js +13 -22
- package/dist/es2022/core/logs/loggers.js.map +1 -1
- package/dist/es2022/core/models/core.models.d.ts +16 -6
- package/dist/es2022/core/models/migration.models.d.ts +9 -9
- package/dist/es2022/core/models/migration.schema.d.ts +247 -0
- package/dist/es2022/core/models/migration.schema.js +12 -2
- package/dist/es2022/core/models/migration.schema.js.map +1 -1
- package/dist/es2022/core/utils/array.utils.js.map +1 -1
- package/dist/es2022/core/utils/binary-data.utils.js +2 -6
- package/dist/es2022/core/utils/binary-data.utils.js.map +1 -1
- package/dist/es2022/core/utils/confirm.utils.js +10 -14
- package/dist/es2022/core/utils/confirm.utils.js.map +1 -1
- package/dist/es2022/core/utils/error.utils.js +35 -27
- package/dist/es2022/core/utils/error.utils.js.map +1 -1
- package/dist/es2022/core/utils/http.utils.js +7 -11
- package/dist/es2022/core/utils/http.utils.js.map +1 -1
- package/dist/es2022/core/utils/management-client-utils.d.ts +2 -1
- package/dist/es2022/core/utils/management-client-utils.js +12 -2
- package/dist/es2022/core/utils/management-client-utils.js.map +1 -1
- package/dist/es2022/core/utils/run.utils.js +12 -10
- package/dist/es2022/core/utils/run.utils.js.map +1 -1
- package/dist/es2022/export/context/export-context-fetcher.js +2 -1
- package/dist/es2022/export/context/export-context-fetcher.js.map +1 -1
- package/dist/es2022/export/export-manager.js +8 -0
- package/dist/es2022/export/export-manager.js.map +1 -1
- package/dist/es2022/export/export.models.d.ts +2 -1
- package/dist/es2022/import/comparers/asset-comparer.d.ts +2 -1
- package/dist/es2022/import/comparers/asset-comparer.js +9 -17
- package/dist/es2022/import/comparers/asset-comparer.js.map +1 -1
- package/dist/es2022/import/context/import-context-fetcher.js +120 -40
- package/dist/es2022/import/context/import-context-fetcher.js.map +1 -1
- package/dist/es2022/import/import.models.d.ts +2 -1
- package/dist/es2022/import/importers/assets-importer.js +12 -2
- package/dist/es2022/import/importers/assets-importer.js.map +1 -1
- package/dist/es2022/import/importers/language-variant-importer.js +95 -83
- package/dist/es2022/import/importers/language-variant-importer.js.map +1 -1
- package/dist/es2022/import/importers/workflow-importer.d.ts +41 -4
- package/dist/es2022/import/importers/workflow-importer.js +158 -17
- package/dist/es2022/import/importers/workflow-importer.js.map +1 -1
- package/dist/es2022/metadata.js +2 -2
- package/dist/es2022/node/cli/app.js +8 -12
- package/dist/es2022/node/cli/app.js.map +1 -1
- package/dist/es2022/node/cli/args/args-fetcher.js +9 -10
- package/dist/es2022/node/cli/args/args-fetcher.js.map +1 -1
- package/dist/es2022/toolkit/migrate.d.ts +1 -3
- package/dist/es2022/toolkit/migrate.js.map +1 -1
- package/dist/es2022/translation/extraction/items-extraction.processor.js +17 -17
- package/dist/es2022/translation/extraction/items-extraction.processor.js.map +1 -1
- package/dist/es2022/translation/transforms/export-transforms.js +1 -1
- package/dist/es2022/translation/transforms/export-transforms.js.map +1 -1
- package/dist/es2022/zip/zip-packager.js +13 -18
- package/dist/es2022/zip/zip-packager.js.map +1 -1
- package/dist/es2022/zip/zip-transformer.js +3 -1
- package/dist/es2022/zip/zip-transformer.js.map +1 -1
- package/lib/core/helpers/workflow-helper.ts +8 -8
- package/lib/core/logs/loggers.ts +14 -22
- package/lib/core/models/core.models.ts +23 -4
- package/lib/core/models/migration.models.ts +13 -12
- package/lib/core/models/migration.schema.ts +189 -178
- package/lib/core/utils/array.utils.ts +2 -10
- package/lib/core/utils/binary-data.utils.ts +2 -7
- package/lib/core/utils/confirm.utils.ts +18 -24
- package/lib/core/utils/error.utils.ts +50 -30
- package/lib/core/utils/http.utils.ts +14 -15
- package/lib/core/utils/management-client-utils.ts +188 -182
- package/lib/core/utils/run.utils.ts +27 -18
- package/lib/export/context/export-context-fetcher.ts +2 -1
- package/lib/export/export-manager.ts +14 -3
- package/lib/export/export.models.ts +3 -1
- package/lib/import/comparers/asset-comparer.ts +16 -24
- package/lib/import/context/import-context-fetcher.ts +179 -85
- package/lib/import/import.models.ts +2 -0
- package/lib/import/importers/assets-importer.ts +19 -12
- package/lib/import/importers/language-variant-importer.ts +125 -129
- package/lib/import/importers/workflow-importer.ts +228 -20
- package/lib/metadata.ts +2 -2
- package/lib/node/cli/app.ts +11 -12
- package/lib/node/cli/args/args-fetcher.ts +12 -14
- package/lib/toolkit/migrate.ts +1 -3
- package/lib/translation/extraction/items-extraction.processor.ts +93 -93
- package/lib/translation/transforms/export-transforms.ts +1 -1
- package/lib/zip/zip-packager.ts +26 -28
- package/lib/zip/zip-transformer.ts +3 -1
- package/package.json +14 -13
|
@@ -1,178 +1,189 @@
|
|
|
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
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
export const
|
|
117
|
-
.
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
})
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
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
|
+
export const ScheduleSchema = z
|
|
73
|
+
.strictObject({
|
|
74
|
+
publish_time: z.string().datetime().optional().readonly(),
|
|
75
|
+
publish_display_timezone: z.string().optional().readonly(),
|
|
76
|
+
unpublish_time: z.string().datetime().optional().readonly(),
|
|
77
|
+
unpublish_display_timezone: z.string().optional().readonly()
|
|
78
|
+
})
|
|
79
|
+
.readonly();
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* ZodType is needed to be specified here due to the use of 'lazy' & circular dependency between types
|
|
83
|
+
* Otherwise TS has no way of statically inferring the type
|
|
84
|
+
*/
|
|
85
|
+
export const MigrationElementsSchema: z.ZodReadonly<z.ZodType<Elements>> = z
|
|
86
|
+
.record(
|
|
87
|
+
z.string(),
|
|
88
|
+
z.lazy(() => MigrationElementSchema)
|
|
89
|
+
)
|
|
90
|
+
.readonly();
|
|
91
|
+
|
|
92
|
+
export const MigrationComponentSchema = z
|
|
93
|
+
.strictObject({
|
|
94
|
+
system: z.strictObject({
|
|
95
|
+
id: z.string(),
|
|
96
|
+
type: MigrationReferenceSchema
|
|
97
|
+
}),
|
|
98
|
+
elements: MigrationElementsSchema
|
|
99
|
+
})
|
|
100
|
+
.readonly();
|
|
101
|
+
|
|
102
|
+
export const MigrationUrlSlugElementValueSchema = z
|
|
103
|
+
.strictObject({
|
|
104
|
+
value: z.optional(z.string()),
|
|
105
|
+
mode: MigrationUrlSlugModeSchema
|
|
106
|
+
})
|
|
107
|
+
.readonly();
|
|
108
|
+
|
|
109
|
+
export const MigrationRichTextElementValueSchema = z
|
|
110
|
+
.strictObject({
|
|
111
|
+
value: z.string(),
|
|
112
|
+
components: z.array(MigrationComponentSchema).readonly()
|
|
113
|
+
})
|
|
114
|
+
.readonly();
|
|
115
|
+
|
|
116
|
+
export const MigrationElementValueSchema = z.union([
|
|
117
|
+
z.string(),
|
|
118
|
+
z.undefined(),
|
|
119
|
+
z.number(),
|
|
120
|
+
z.array(MigrationReferenceSchema),
|
|
121
|
+
MigrationRichTextElementValueSchema,
|
|
122
|
+
MigrationUrlSlugElementValueSchema
|
|
123
|
+
]);
|
|
124
|
+
|
|
125
|
+
export const MigrationElementSchema = z
|
|
126
|
+
.strictObject({
|
|
127
|
+
type: MigrationElementTypeSchema,
|
|
128
|
+
value: MigrationElementValueSchema
|
|
129
|
+
})
|
|
130
|
+
.readonly();
|
|
131
|
+
|
|
132
|
+
export const MigrationItemVersionSchema = z
|
|
133
|
+
.strictObject({
|
|
134
|
+
workflow_step: MigrationReferenceSchema,
|
|
135
|
+
elements: MigrationElementsSchema,
|
|
136
|
+
schedule: ScheduleSchema.optional()
|
|
137
|
+
})
|
|
138
|
+
.readonly();
|
|
139
|
+
|
|
140
|
+
export const MigrationItemSystemSchema = z.strictObject({
|
|
141
|
+
codename: z.string(),
|
|
142
|
+
name: z.string(),
|
|
143
|
+
language: MigrationReferenceSchema,
|
|
144
|
+
type: MigrationReferenceSchema,
|
|
145
|
+
collection: MigrationReferenceSchema,
|
|
146
|
+
workflow: MigrationReferenceSchema
|
|
147
|
+
});
|
|
148
|
+
|
|
149
|
+
export const MigrationItemSchema = z
|
|
150
|
+
.strictObject({
|
|
151
|
+
system: MigrationItemSystemSchema,
|
|
152
|
+
versions: z.array(MigrationItemVersionSchema).readonly()
|
|
153
|
+
})
|
|
154
|
+
.readonly();
|
|
155
|
+
|
|
156
|
+
export const MigrationAssetDescriptionSchema = z
|
|
157
|
+
.strictObject({
|
|
158
|
+
language: MigrationReferenceSchema,
|
|
159
|
+
description: z.optional(z.string())
|
|
160
|
+
})
|
|
161
|
+
.readonly();
|
|
162
|
+
|
|
163
|
+
const BaseMigrationAssetSchema = z.strictObject({
|
|
164
|
+
codename: z.string(),
|
|
165
|
+
filename: z.string(),
|
|
166
|
+
title: z.string(),
|
|
167
|
+
collection: z.optional(MigrationReferenceSchema),
|
|
168
|
+
descriptions: z.optional(z.array(MigrationAssetDescriptionSchema)).readonly(),
|
|
169
|
+
folder: z.optional(MigrationReferenceSchema)
|
|
170
|
+
});
|
|
171
|
+
|
|
172
|
+
export const MigrationAssetSchema = BaseMigrationAssetSchema.extend({
|
|
173
|
+
binaryData: z.union([z.instanceof(Buffer), z.instanceof(Blob)])
|
|
174
|
+
}).readonly();
|
|
175
|
+
|
|
176
|
+
export const ZipMigrationAssetSchema = BaseMigrationAssetSchema.extend({
|
|
177
|
+
_zipFilename: z.string()
|
|
178
|
+
}).readonly();
|
|
179
|
+
|
|
180
|
+
export const MigrationAssetsSchema = z.array(MigrationAssetSchema).readonly();
|
|
181
|
+
export const ZipMigrationAssetsSchema = z.array(ZipMigrationAssetSchema).readonly();
|
|
182
|
+
export const MigrationItemsSchema = z.array(MigrationItemSchema).readonly();
|
|
183
|
+
|
|
184
|
+
export const MigrationDataSchema = z
|
|
185
|
+
.strictObject({
|
|
186
|
+
items: MigrationItemsSchema,
|
|
187
|
+
assets: MigrationAssetsSchema
|
|
188
|
+
})
|
|
189
|
+
.readonly();
|
|
@@ -10,16 +10,8 @@ export function parseAsMigrationReferencesArray(value: MigrationElementValue): r
|
|
|
10
10
|
throw Error(`Value is not an array`);
|
|
11
11
|
}
|
|
12
12
|
|
|
13
|
-
export function findRequired<T>(
|
|
14
|
-
|
|
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;
|
|
13
|
+
export function findRequired<T>(array: readonly T[], predicate: (item: T, index: number) => boolean, errorMessage: string): T;
|
|
14
|
+
export function findRequired<T>(array: readonly T[], predicate: (item: T, index: number) => boolean, errorMessage: () => never): T;
|
|
23
15
|
export function findRequired<T>(
|
|
24
16
|
array: readonly T[],
|
|
25
17
|
predicate: (item: T, index: number) => boolean,
|
|
@@ -14,16 +14,11 @@ export async function getBinaryDataFromUrlAsync(url: string): Promise<{ data: Bu
|
|
|
14
14
|
}
|
|
15
15
|
);
|
|
16
16
|
|
|
17
|
-
const
|
|
18
|
-
const contentLength = contentLengthHeader ? +contentLengthHeader.value : 0;
|
|
17
|
+
const contentLength = +(response.headers.find((m) => m.header.toLowerCase() === 'content-length')?.value ?? 0);
|
|
19
18
|
|
|
20
19
|
return { data: response.data, contentLength: contentLength };
|
|
21
20
|
}
|
|
22
21
|
|
|
23
22
|
export function geSizeInBytes(data: Blob | Buffer): number {
|
|
24
|
-
|
|
25
|
-
return data.size;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
return data.byteLength;
|
|
23
|
+
return data instanceof Blob ? data.size : data.byteLength;
|
|
29
24
|
}
|
|
@@ -19,11 +19,9 @@ export async function confirmExportAsync(data: {
|
|
|
19
19
|
data.logger
|
|
20
20
|
).getEnvironmentAsync();
|
|
21
21
|
|
|
22
|
-
const text: string = `Are you sure to export '${chalk.cyan(
|
|
22
|
+
const text: string = `Are you sure to export '${chalk.cyan(data.dataToExport.itemsCount)}' content ${getItemsPluralText(
|
|
23
23
|
data.dataToExport.itemsCount
|
|
24
|
-
)}
|
|
25
|
-
environment.name
|
|
26
|
-
)} (${chalk.magenta(environment.environment)})?`;
|
|
24
|
+
)} from ${chalk.yellow(environment.name)} (${chalk.magenta(environment.environment)})?`;
|
|
27
25
|
|
|
28
26
|
await confirmAsync({
|
|
29
27
|
force: data.force,
|
|
@@ -65,9 +63,9 @@ export async function confirmMigrateAsync(data: {
|
|
|
65
63
|
|
|
66
64
|
const text: string = `Are you sure to migrate '${chalk.cyan(data.dataToMigrate.itemsCount)}' ${getItemsPluralText(
|
|
67
65
|
data.dataToMigrate.itemsCount
|
|
68
|
-
)} from ${chalk.yellow(sourceEnvironment.name)} (${chalk.magenta(
|
|
69
|
-
|
|
70
|
-
)}
|
|
66
|
+
)} from ${chalk.yellow(sourceEnvironment.name)} (${chalk.magenta(sourceEnvironment.environment)}) to environment ${chalk.yellow(
|
|
67
|
+
targetEnvironment.name
|
|
68
|
+
)} (${chalk.magenta(targetEnvironment.environment)}) ?`;
|
|
71
69
|
|
|
72
70
|
await confirmAsync({
|
|
73
71
|
force: data.force,
|
|
@@ -91,9 +89,7 @@ export async function confirmImportAsync(data: {
|
|
|
91
89
|
data.logger
|
|
92
90
|
).getEnvironmentAsync();
|
|
93
91
|
|
|
94
|
-
const text: string = `Are you sure to import data into ${chalk.yellow(environment.name)} (${chalk.magenta(
|
|
95
|
-
environment.environment
|
|
96
|
-
)})?`;
|
|
92
|
+
const text: string = `Are you sure to import data into ${chalk.yellow(environment.name)} (${chalk.magenta(environment.environment)})?`;
|
|
97
93
|
|
|
98
94
|
await confirmAsync({
|
|
99
95
|
force: data.force,
|
|
@@ -116,24 +112,22 @@ async function confirmAsync(data: {
|
|
|
116
112
|
if (data.force) {
|
|
117
113
|
data.logger.log({
|
|
118
114
|
type: 'info',
|
|
119
|
-
message: `Skipping confirmation
|
|
120
|
-
});
|
|
121
|
-
} else {
|
|
122
|
-
const confirmed = await prompts.default({
|
|
123
|
-
type: 'confirm',
|
|
124
|
-
name: 'confirm',
|
|
125
|
-
message: `${chalk.cyan(data.action)}: ${data.message}`
|
|
115
|
+
message: `Skipping confirmation`
|
|
126
116
|
});
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
127
119
|
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
120
|
+
const confirmed = await prompts.default({
|
|
121
|
+
type: 'confirm',
|
|
122
|
+
name: 'confirm',
|
|
123
|
+
message: `${chalk.cyan(data.action)}: ${data.message}`
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
if (!confirmed.confirm) {
|
|
127
|
+
throw Error(`Confirmation refused.`);
|
|
131
128
|
}
|
|
132
129
|
}
|
|
133
130
|
|
|
134
131
|
function getItemsPluralText(count: number): string {
|
|
135
|
-
|
|
136
|
-
return 'item';
|
|
137
|
-
}
|
|
138
|
-
return 'items';
|
|
132
|
+
return count === 1 ? 'item' : 'items';
|
|
139
133
|
}
|
|
@@ -2,39 +2,59 @@ import { SharedModels } from '@kontent-ai/management-sdk';
|
|
|
2
2
|
import chalk from 'chalk';
|
|
3
3
|
import { ErrorData, OriginalManagementError } from '../models/core.models.js';
|
|
4
4
|
import { ZodError } from 'zod';
|
|
5
|
+
import { match } from 'ts-pattern';
|
|
5
6
|
|
|
6
7
|
export function extractErrorData(error: unknown): ErrorData {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
8
|
+
return match(error)
|
|
9
|
+
.returnType<ErrorData>()
|
|
10
|
+
.when(
|
|
11
|
+
(error) => error instanceof SharedModels.ContentManagementBaseKontentError,
|
|
12
|
+
(error) => {
|
|
13
|
+
const originalError = error.originalError as OriginalManagementError | undefined;
|
|
11
14
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
15
|
+
return {
|
|
16
|
+
isUnknownError: false,
|
|
17
|
+
error: error,
|
|
18
|
+
message: `${error.message} ${error.validationErrors.map((m) => m.message).join(', ')}`,
|
|
19
|
+
requestUrl: originalError?.response?.config?.url,
|
|
20
|
+
requestData: originalError?.response?.config?.data
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
)
|
|
24
|
+
.when(
|
|
25
|
+
(error) => error instanceof ZodError,
|
|
26
|
+
(error) => {
|
|
27
|
+
return {
|
|
28
|
+
isUnknownError: false,
|
|
29
|
+
error: error,
|
|
30
|
+
message: `Found '${chalk.red(error.issues.length)}' parsing errors: \n${error.issues.reduce<string>(
|
|
31
|
+
(current, issue, index) => {
|
|
32
|
+
return (current += `\n${index + 1}. ${chalk.red(issue.message)} (${chalk.yellow('path')}: ${issue.path.join(
|
|
33
|
+
','
|
|
34
|
+
)})`);
|
|
35
|
+
},
|
|
36
|
+
''
|
|
37
|
+
)}`
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
)
|
|
41
|
+
.when(
|
|
42
|
+
(error) => error instanceof Error,
|
|
43
|
+
(error) => {
|
|
44
|
+
return {
|
|
45
|
+
isUnknownError: false,
|
|
46
|
+
error: error,
|
|
47
|
+
message: error.message
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
)
|
|
51
|
+
.otherwise((error) => {
|
|
52
|
+
return {
|
|
53
|
+
isUnknownError: true,
|
|
54
|
+
error: error,
|
|
55
|
+
message: `Unknown error`
|
|
56
|
+
};
|
|
57
|
+
});
|
|
38
58
|
}
|
|
39
59
|
|
|
40
60
|
export function is404Error(error: unknown): boolean {
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { HttpService, IRetryStrategyOptions } from '@kontent-ai/core-sdk';
|
|
2
2
|
import { OriginalManagementError } from '../models/core.models.js';
|
|
3
|
+
import { match } from 'ts-pattern';
|
|
3
4
|
|
|
4
5
|
const rateExceededErrorCode: number = 10000;
|
|
5
6
|
const notFoundErrorCode: number = 10000;
|
|
@@ -14,21 +15,19 @@ export const defaultRetryStrategy: Readonly<IRetryStrategyOptions> = {
|
|
|
14
15
|
const originalError = err as OriginalManagementError | undefined;
|
|
15
16
|
const errorCode: number = originalError?.response?.data?.error_code ?? -1;
|
|
16
17
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
}
|
|
31
|
-
return true;
|
|
18
|
+
return (
|
|
19
|
+
match(errorCode)
|
|
20
|
+
// retry rate exceeded error
|
|
21
|
+
.with(rateExceededErrorCode, () => true)
|
|
22
|
+
// do not retry errors indicating resource does not exist
|
|
23
|
+
.with(notFoundErrorCode, () => false)
|
|
24
|
+
// if error code is set, do not retry the request
|
|
25
|
+
.when(
|
|
26
|
+
(errorCode) => errorCode >= 0,
|
|
27
|
+
() => false
|
|
28
|
+
)
|
|
29
|
+
.otherwise(() => true)
|
|
30
|
+
);
|
|
32
31
|
},
|
|
33
32
|
maxAttempts: 3,
|
|
34
33
|
deltaBackoffMs: 1000
|