@contentstack/cli-cm-import 1.25.1 → 1.26.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 -3
- package/lib/commands/cm/stacks/import.d.ts +1 -0
- package/lib/commands/cm/stacks/import.js +33 -12
- package/lib/import/module-importer.js +1 -1
- package/lib/import/modules/assets.d.ts +1 -1
- package/lib/import/modules/assets.js +93 -39
- package/lib/import/modules/content-types.js +76 -31
- package/lib/import/modules/custom-roles.js +95 -19
- package/lib/import/modules/entries.js +128 -57
- package/lib/import/modules/environments.js +48 -14
- package/lib/import/modules/extensions.js +78 -16
- package/lib/import/modules/global-fields.js +85 -20
- package/lib/import/modules/labels.d.ts +4 -4
- package/lib/import/modules/labels.js +60 -18
- package/lib/import/modules/locales.js +63 -20
- package/lib/import/modules/marketplace-apps.js +160 -31
- package/lib/import/modules/personalize.js +33 -7
- package/lib/import/modules/stack.js +5 -0
- package/lib/import/modules/taxonomies.js +52 -13
- package/lib/import/modules/variant-entries.js +21 -3
- package/lib/import/modules/webhooks.js +44 -12
- package/lib/import/modules/workflows.js +65 -21
- package/lib/types/import-config.d.ts +3 -1
- package/lib/types/index.d.ts +22 -0
- package/lib/utils/asset-helper.js +24 -1
- package/lib/utils/backup-handler.js +15 -1
- package/lib/utils/common-helper.js +41 -16
- package/lib/utils/content-type-helper.js +35 -2
- package/lib/utils/entries-helper.js +24 -2
- package/lib/utils/extension-helper.js +35 -1
- package/lib/utils/import-config-handler.js +21 -0
- package/lib/utils/login-handler.js +8 -4
- package/lib/utils/marketplace-app-helper.js +50 -11
- package/lib/utils/taxonomies-helper.js +22 -4
- package/oclif.manifest.json +2 -2
- package/package.json +5 -5
|
@@ -16,6 +16,7 @@ const global_field_helper_1 = require("../../utils/global-field-helper");
|
|
|
16
16
|
class ImportGlobalFields extends base_class_1.default {
|
|
17
17
|
constructor({ importConfig, stackAPIClient }) {
|
|
18
18
|
super({ importConfig, stackAPIClient });
|
|
19
|
+
this.importConfig.context.module = 'global-fields';
|
|
19
20
|
this.config = importConfig;
|
|
20
21
|
this.gFsConfig = importConfig.modules['global-fields'];
|
|
21
22
|
this.gFs = [];
|
|
@@ -34,54 +35,90 @@ class ImportGlobalFields extends base_class_1.default {
|
|
|
34
35
|
this.marketplaceAppMapperPath = path.join((0, cli_utilities_1.sanitizePath)(this.config.data), 'mapper', 'marketplace_apps', 'uid-mapping.json');
|
|
35
36
|
}
|
|
36
37
|
async start() {
|
|
37
|
-
var _a;
|
|
38
|
+
var _a, _b, _c, _d;
|
|
39
|
+
cli_utilities_1.log.debug('Reading global fields from file', this.importConfig.context);
|
|
38
40
|
this.gFs = utils_1.fsUtil.readFile(path.join(this.gFsFolderPath, this.gFsConfig.fileName));
|
|
39
41
|
if (!this.gFs || (0, lodash_1.isEmpty)(this.gFs)) {
|
|
40
|
-
|
|
42
|
+
cli_utilities_1.log.info('No global fields found to import', this.importConfig.context);
|
|
41
43
|
return;
|
|
42
44
|
}
|
|
45
|
+
const gfsCount = Array.isArray(this.gFs) ? this.gFs.length : Object.keys(this.gFs).length;
|
|
46
|
+
cli_utilities_1.log.debug(`Loaded ${gfsCount} global field items from file`, this.importConfig.context);
|
|
47
|
+
cli_utilities_1.log.debug('Creating global fields mapper directory', this.importConfig.context);
|
|
43
48
|
await utils_1.fsUtil.makeDirectory(this.gFsMapperPath);
|
|
49
|
+
cli_utilities_1.log.debug('Loading existing global fields UID data', this.importConfig.context);
|
|
44
50
|
if (utils_1.fileHelper.fileExistsSync(this.gFsUidMapperPath)) {
|
|
45
51
|
this.gFsUidMapper = (utils_1.fsUtil.readFile(this.gFsUidMapperPath) || {});
|
|
52
|
+
const gfsUidCount = Object.keys(this.gFsUidMapper || {}).length;
|
|
53
|
+
cli_utilities_1.log.debug(`Loaded existing global fields UID data: ${gfsUidCount} items`, this.importConfig.context);
|
|
46
54
|
}
|
|
55
|
+
else {
|
|
56
|
+
cli_utilities_1.log.debug('No existing global fields UID data found', this.importConfig.context);
|
|
57
|
+
}
|
|
58
|
+
cli_utilities_1.log.debug('Loading installed extensions data', this.importConfig.context);
|
|
47
59
|
this.installedExtensions = ((await utils_1.fsUtil.readFile(this.marketplaceAppMapperPath)) || { extension_uid: {} }).extension_uid;
|
|
60
|
+
const installedExtCount = Object.keys(this.installedExtensions || {}).length;
|
|
61
|
+
cli_utilities_1.log.debug(`Loaded ${installedExtCount} installed extension references`, this.importConfig.context);
|
|
62
|
+
cli_utilities_1.log.debug('Starting global fields seeding process', this.importConfig.context);
|
|
48
63
|
await this.seedGFs();
|
|
49
|
-
(
|
|
64
|
+
if ((_a = this.pendingGFs) === null || _a === void 0 ? void 0 : _a.length) {
|
|
65
|
+
utils_1.fsUtil.writeFile(this.gFsPendingPath, this.pendingGFs);
|
|
66
|
+
cli_utilities_1.log.debug(`Written ${this.pendingGFs.length} pending global fields to file`, this.importConfig.context);
|
|
67
|
+
}
|
|
68
|
+
cli_utilities_1.log.success('Created Global Fields', this.importConfig.context);
|
|
69
|
+
cli_utilities_1.log.debug('Starting global fields update process', this.importConfig.context);
|
|
50
70
|
await this.updateGFs();
|
|
51
|
-
if ((
|
|
71
|
+
if ((_b = this.pendingGFs) === null || _b === void 0 ? void 0 : _b.length)
|
|
52
72
|
utils_1.fsUtil.writeFile(this.gFsPendingPath, this.pendingGFs);
|
|
53
|
-
|
|
73
|
+
cli_utilities_1.log.success('Updated Global Fields', this.importConfig.context);
|
|
54
74
|
if (this.importConfig.replaceExisting && this.existingGFs.length > 0) {
|
|
75
|
+
cli_utilities_1.log.debug(`Replacing ${this.existingGFs.length} existing global fields`, this.importConfig.context);
|
|
55
76
|
await this.replaceGFs().catch((error) => {
|
|
56
|
-
|
|
77
|
+
cli_utilities_1.log.debug('Error replacing global fields', this.importConfig.context);
|
|
78
|
+
(0, cli_utilities_1.handleAndLogError)(error, Object.assign({}, this.importConfig.context));
|
|
57
79
|
});
|
|
58
80
|
}
|
|
59
|
-
|
|
81
|
+
cli_utilities_1.log.debug('Processing global fields import results', this.importConfig.context);
|
|
82
|
+
if ((_c = this.createdGFs) === null || _c === void 0 ? void 0 : _c.length) {
|
|
83
|
+
utils_1.fsUtil.writeFile(this.gFsSuccessPath, this.createdGFs);
|
|
84
|
+
cli_utilities_1.log.debug(`Written ${this.createdGFs.length} successful global fields to file`, this.importConfig.context);
|
|
85
|
+
}
|
|
86
|
+
if ((_d = this.failedGFs) === null || _d === void 0 ? void 0 : _d.length) {
|
|
87
|
+
utils_1.fsUtil.writeFile(this.gFsFailsPath, this.failedGFs);
|
|
88
|
+
cli_utilities_1.log.debug(`Written ${this.failedGFs.length} failed global fields to file`, this.importConfig.context);
|
|
89
|
+
}
|
|
90
|
+
cli_utilities_1.log.success('Global fields import has been completed!', this.importConfig.context);
|
|
60
91
|
}
|
|
61
92
|
async seedGFs() {
|
|
93
|
+
cli_utilities_1.log.debug('Starting global fields seeding process', this.importConfig.context);
|
|
94
|
+
const gfsToSeed = Array.isArray(this.gFs) ? this.gFs.length : Object.keys(this.gFs).length;
|
|
95
|
+
cli_utilities_1.log.debug(`Seeding ${gfsToSeed} global fields`, this.importConfig.context);
|
|
62
96
|
const onSuccess = ({ response: globalField, apiData: { uid } = undefined }) => {
|
|
63
97
|
this.createdGFs.push(globalField);
|
|
64
98
|
this.gFsUidMapper[uid] = globalField;
|
|
65
|
-
|
|
99
|
+
cli_utilities_1.log.success(`Global field ${globalField.uid} created successfully`, this.importConfig.context);
|
|
100
|
+
cli_utilities_1.log.debug(`Global field creation completed: ${globalField.uid}`, this.importConfig.context);
|
|
66
101
|
};
|
|
67
102
|
const onReject = ({ error, apiData: globalField = undefined }) => {
|
|
68
|
-
var _a, _b
|
|
103
|
+
var _a, _b;
|
|
69
104
|
const uid = (_a = globalField === null || globalField === void 0 ? void 0 : globalField.global_field) === null || _a === void 0 ? void 0 : _a.uid;
|
|
105
|
+
cli_utilities_1.log.debug(`Global field '${uid}' creation failed`, this.importConfig.context);
|
|
70
106
|
if ((_b = error === null || error === void 0 ? void 0 : error.errors) === null || _b === void 0 ? void 0 : _b.title) {
|
|
71
107
|
if (this.importConfig.replaceExisting) {
|
|
72
108
|
this.existingGFs.push(globalField);
|
|
109
|
+
cli_utilities_1.log.debug(`Global field '${uid}' marked for replacement`, this.importConfig.context);
|
|
73
110
|
}
|
|
74
111
|
if (!this.importConfig.skipExisting) {
|
|
75
|
-
|
|
112
|
+
cli_utilities_1.log.info(`Global fields '${uid}' already exist`, this.importConfig.context);
|
|
76
113
|
}
|
|
77
114
|
}
|
|
78
115
|
else {
|
|
79
|
-
(0,
|
|
80
|
-
(0, utils_1.log)(this.importConfig, (0, utils_1.formatError)(error), 'error');
|
|
116
|
+
(0, cli_utilities_1.handleAndLogError)(error, Object.assign(Object.assign({}, this.importConfig.context), { uid }), `Global fields '${uid}' failed to import`);
|
|
81
117
|
this.failedGFs.push({ uid });
|
|
82
118
|
}
|
|
83
119
|
};
|
|
84
|
-
|
|
120
|
+
cli_utilities_1.log.debug(`Using concurrency limit for seeding: ${this.reqConcurrency}`, this.importConfig.context);
|
|
121
|
+
const result = await this.makeConcurrentCall({
|
|
85
122
|
processName: 'Import global fields',
|
|
86
123
|
apiContent: this.gFs,
|
|
87
124
|
apiParams: {
|
|
@@ -93,6 +130,8 @@ class ImportGlobalFields extends base_class_1.default {
|
|
|
93
130
|
},
|
|
94
131
|
concurrencyLimit: this.reqConcurrency,
|
|
95
132
|
});
|
|
133
|
+
cli_utilities_1.log.debug('Global fields seeding process completed', this.importConfig.context);
|
|
134
|
+
return result;
|
|
96
135
|
}
|
|
97
136
|
/**
|
|
98
137
|
* @method serializeGFs
|
|
@@ -101,20 +140,28 @@ class ImportGlobalFields extends base_class_1.default {
|
|
|
101
140
|
*/
|
|
102
141
|
serializeGFs(apiOptions) {
|
|
103
142
|
const { apiData: globalField } = apiOptions;
|
|
143
|
+
cli_utilities_1.log.debug(`Serializing global field: ${globalField.uid}`, this.importConfig.context);
|
|
104
144
|
const updatedGF = (0, lodash_1.cloneDeep)(global_field_helper_1.gfSchemaTemplate);
|
|
105
145
|
updatedGF.global_field.uid = globalField.uid;
|
|
106
146
|
updatedGF.global_field.title = globalField.title;
|
|
147
|
+
cli_utilities_1.log.debug(`Global field serialization completed: ${globalField.uid}`, this.importConfig.context);
|
|
107
148
|
apiOptions.apiData = updatedGF;
|
|
108
149
|
return apiOptions;
|
|
109
150
|
}
|
|
110
151
|
async updateGFs() {
|
|
152
|
+
cli_utilities_1.log.debug('Starting global fields update process', this.importConfig.context);
|
|
153
|
+
const gfsToUpdate = Array.isArray(this.gFs) ? this.gFs.length : Object.keys(this.gFs).length;
|
|
154
|
+
cli_utilities_1.log.debug(`Updating ${gfsToUpdate} global fields`, this.importConfig.context);
|
|
111
155
|
const onSuccess = ({ response: globalField, apiData: { uid } = undefined }) => {
|
|
112
|
-
|
|
156
|
+
cli_utilities_1.log.info(`Updated the global field ${uid}`, this.importConfig.context);
|
|
157
|
+
cli_utilities_1.log.debug(`Global field update completed: ${uid}`, this.importConfig.context);
|
|
113
158
|
};
|
|
114
159
|
const onReject = ({ error, apiData: { uid } = undefined }) => {
|
|
115
|
-
|
|
160
|
+
cli_utilities_1.log.debug(`Global field '${uid}' update failed`, this.importConfig.context);
|
|
161
|
+
(0, cli_utilities_1.handleAndLogError)(error, Object.assign(Object.assign({}, this.importConfig.context), { uid }), `Failed to update the global field '${uid}'`);
|
|
116
162
|
};
|
|
117
|
-
|
|
163
|
+
cli_utilities_1.log.debug(`Using concurrency limit for updates: ${this.reqConcurrency}`, this.importConfig.context);
|
|
164
|
+
const result = await this.makeConcurrentCall({
|
|
118
165
|
processName: 'Update Global Fields',
|
|
119
166
|
apiContent: this.gFs,
|
|
120
167
|
apiParams: {
|
|
@@ -125,25 +172,34 @@ class ImportGlobalFields extends base_class_1.default {
|
|
|
125
172
|
},
|
|
126
173
|
concurrencyLimit: this.reqConcurrency,
|
|
127
174
|
}, this.updateSerializedGFs.bind(this));
|
|
175
|
+
cli_utilities_1.log.debug('Global fields update process completed', this.importConfig.context);
|
|
176
|
+
return result;
|
|
128
177
|
}
|
|
129
178
|
async updateSerializedGFs({ apiParams, element: globalField, isLastRequest, }) {
|
|
179
|
+
cli_utilities_1.log.debug(`Processing global field update: ${globalField.uid}`, this.importConfig.context);
|
|
130
180
|
return new Promise(async (resolve, reject) => {
|
|
181
|
+
cli_utilities_1.log.debug(`Looking up extensions for global field: ${globalField.uid}`, this.importConfig.context);
|
|
131
182
|
(0, utils_1.lookupExtension)(this.config, globalField.schema, this.config.preserveStackVersion, this.installedExtensions);
|
|
132
183
|
let flag = { supressed: false };
|
|
184
|
+
cli_utilities_1.log.debug(`Removing reference fields for global field: ${globalField.uid}`, this.importConfig.context);
|
|
133
185
|
await (0, utils_1.removeReferenceFields)(globalField.schema, flag, this.stack);
|
|
134
186
|
if (flag.supressed) {
|
|
187
|
+
cli_utilities_1.log.debug(`Global field '${globalField.uid}' has suppressed references, adding to pending`, this.importConfig.context);
|
|
135
188
|
this.pendingGFs.push(globalField.uid);
|
|
136
|
-
|
|
189
|
+
cli_utilities_1.log.info(`Global field '${globalField.uid}' will be updated later`, this.importConfig.context);
|
|
137
190
|
return resolve(true);
|
|
138
191
|
}
|
|
192
|
+
cli_utilities_1.log.debug(`Fetching existing global field: ${globalField.uid}`, this.importConfig.context);
|
|
139
193
|
return this.stack
|
|
140
194
|
.globalField(globalField.uid, { api_version: '3.2' })
|
|
141
195
|
.fetch()
|
|
142
196
|
.then((response) => {
|
|
197
|
+
cli_utilities_1.log.debug(`Updating global field: ${globalField.uid}`, this.importConfig.context);
|
|
143
198
|
Object.assign(response, globalField);
|
|
144
199
|
return response.update();
|
|
145
200
|
})
|
|
146
201
|
.then((response) => {
|
|
202
|
+
cli_utilities_1.log.debug(`Global field update successful: ${globalField.uid}`, this.importConfig.context);
|
|
147
203
|
apiParams.resolve({
|
|
148
204
|
response,
|
|
149
205
|
apiData: globalField,
|
|
@@ -151,6 +207,7 @@ class ImportGlobalFields extends base_class_1.default {
|
|
|
151
207
|
resolve(true);
|
|
152
208
|
})
|
|
153
209
|
.catch((error) => {
|
|
210
|
+
cli_utilities_1.log.debug(`Global field update failed: ${globalField.uid}`, this.importConfig.context);
|
|
154
211
|
apiParams.reject({
|
|
155
212
|
error,
|
|
156
213
|
apiData: globalField,
|
|
@@ -160,21 +217,24 @@ class ImportGlobalFields extends base_class_1.default {
|
|
|
160
217
|
});
|
|
161
218
|
}
|
|
162
219
|
async replaceGFs() {
|
|
220
|
+
cli_utilities_1.log.debug(`Replacing ${this.existingGFs.length} existing global fields`, this.importConfig.context);
|
|
163
221
|
const onSuccess = ({ response: globalField, apiData }) => {
|
|
164
222
|
var _a, _b, _c;
|
|
165
223
|
const uid = (_c = (_a = apiData === null || apiData === void 0 ? void 0 : apiData.uid) !== null && _a !== void 0 ? _a : (_b = apiData === null || apiData === void 0 ? void 0 : apiData.global_field) === null || _b === void 0 ? void 0 : _b.uid) !== null && _c !== void 0 ? _c : 'unknown';
|
|
166
224
|
this.createdGFs.push(globalField);
|
|
167
225
|
this.gFsUidMapper[uid] = globalField;
|
|
168
226
|
utils_1.fsUtil.writeFile(this.gFsUidMapperPath, this.gFsUidMapper);
|
|
169
|
-
|
|
227
|
+
cli_utilities_1.log.success(`Global field '${uid}' replaced successfully`, this.importConfig.context);
|
|
228
|
+
cli_utilities_1.log.debug(`Global field replacement completed: ${uid}`, this.importConfig.context);
|
|
170
229
|
};
|
|
171
230
|
const onReject = ({ error, apiData }) => {
|
|
172
231
|
var _a, _b, _c;
|
|
173
232
|
const uid = (_c = (_a = apiData === null || apiData === void 0 ? void 0 : apiData.uid) !== null && _a !== void 0 ? _a : (_b = apiData === null || apiData === void 0 ? void 0 : apiData.global_field) === null || _b === void 0 ? void 0 : _b.uid) !== null && _c !== void 0 ? _c : 'unknown';
|
|
174
|
-
|
|
175
|
-
(0,
|
|
233
|
+
cli_utilities_1.log.debug(`Global field '${uid}' replacement failed`, this.importConfig.context);
|
|
234
|
+
(0, cli_utilities_1.handleAndLogError)(error, Object.assign(Object.assign({}, this.importConfig.context), { uid }), `Global fields '${uid}' failed to replace`);
|
|
176
235
|
this.failedGFs.push({ uid });
|
|
177
236
|
};
|
|
237
|
+
cli_utilities_1.log.debug(`Using concurrency limit for replacement: ${this.importConfig.concurrency || this.importConfig.fetchConcurrency || 1}`, this.importConfig.context);
|
|
178
238
|
await this.makeConcurrentCall({
|
|
179
239
|
apiContent: this.existingGFs,
|
|
180
240
|
processName: 'Replace global fields',
|
|
@@ -187,6 +247,7 @@ class ImportGlobalFields extends base_class_1.default {
|
|
|
187
247
|
},
|
|
188
248
|
concurrencyLimit: this.importConfig.concurrency || this.importConfig.fetchConcurrency || 1,
|
|
189
249
|
}, undefined, false);
|
|
250
|
+
cli_utilities_1.log.debug('Global fields replacement process completed', this.importConfig.context);
|
|
190
251
|
}
|
|
191
252
|
/**
|
|
192
253
|
* @method serializeReplaceGFs
|
|
@@ -194,11 +255,15 @@ class ImportGlobalFields extends base_class_1.default {
|
|
|
194
255
|
* @returns {ApiOptions} ApiOptions
|
|
195
256
|
*/
|
|
196
257
|
serializeReplaceGFs(apiOptions) {
|
|
258
|
+
var _a, _b, _c;
|
|
197
259
|
const { apiData: globalField } = apiOptions;
|
|
260
|
+
const uid = (_c = (_a = globalField === null || globalField === void 0 ? void 0 : globalField.uid) !== null && _a !== void 0 ? _a : (_b = globalField === null || globalField === void 0 ? void 0 : globalField.global_field) === null || _b === void 0 ? void 0 : _b.uid) !== null && _c !== void 0 ? _c : 'unknown';
|
|
261
|
+
cli_utilities_1.log.debug(`Serializing global field replacement: ${uid}`, this.importConfig.context);
|
|
198
262
|
const globalFieldPayload = this.stack.globalField(globalField.uid, { api_version: '3.2' });
|
|
199
263
|
Object.assign(globalFieldPayload, (0, lodash_1.cloneDeep)(globalField), {
|
|
200
264
|
stackHeaders: globalFieldPayload.stackHeaders,
|
|
201
265
|
});
|
|
266
|
+
cli_utilities_1.log.debug(`Global field replacement serialization completed: ${uid}`, this.importConfig.context);
|
|
202
267
|
apiOptions.apiData = globalFieldPayload;
|
|
203
268
|
return apiOptions;
|
|
204
269
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import BaseClass, { ApiOptions } from './base-class';
|
|
2
2
|
import { ModuleClassParams } from '../../types';
|
|
3
|
-
export default class
|
|
3
|
+
export default class ImportLabels extends BaseClass {
|
|
4
4
|
private mapperDirPath;
|
|
5
5
|
private labelsFolderPath;
|
|
6
6
|
private labelUidMapperPath;
|
|
@@ -17,13 +17,13 @@ export default class Importlabels extends BaseClass {
|
|
|
17
17
|
* @returns {Promise<void>} Promise<void>
|
|
18
18
|
*/
|
|
19
19
|
start(): Promise<void>;
|
|
20
|
-
|
|
20
|
+
importLabels(): Promise<void>;
|
|
21
21
|
/**
|
|
22
|
-
* @method
|
|
22
|
+
* @method serializeLabels
|
|
23
23
|
* @param {ApiOptions} apiOptions ApiOptions
|
|
24
24
|
* @returns {ApiOptions} ApiOptions
|
|
25
25
|
*/
|
|
26
|
-
|
|
26
|
+
serializeLabels(apiOptions: ApiOptions): ApiOptions;
|
|
27
27
|
updateLabels(): Promise<void>;
|
|
28
28
|
/**
|
|
29
29
|
* @method serializeUpdatelabels
|
|
@@ -6,10 +6,12 @@ const values_1 = tslib_1.__importDefault(require("lodash/values"));
|
|
|
6
6
|
const omit_1 = tslib_1.__importDefault(require("lodash/omit"));
|
|
7
7
|
const node_path_1 = require("node:path");
|
|
8
8
|
const utils_1 = require("../../utils");
|
|
9
|
+
const cli_utilities_1 = require("@contentstack/cli-utilities");
|
|
9
10
|
const base_class_1 = tslib_1.__importDefault(require("./base-class"));
|
|
10
|
-
class
|
|
11
|
+
class ImportLabels extends base_class_1.default {
|
|
11
12
|
constructor({ importConfig, stackAPIClient }) {
|
|
12
13
|
super({ importConfig, stackAPIClient });
|
|
14
|
+
this.importConfig.context.module = 'labels';
|
|
13
15
|
this.labelsConfig = importConfig.modules.labels;
|
|
14
16
|
this.mapperDirPath = (0, node_path_1.join)(this.importConfig.backupDir, 'mapper', 'labels');
|
|
15
17
|
this.labelsFolderPath = (0, node_path_1.join)(this.importConfig.backupDir, this.labelsConfig.dirName);
|
|
@@ -27,40 +29,62 @@ class Importlabels extends base_class_1.default {
|
|
|
27
29
|
*/
|
|
28
30
|
async start() {
|
|
29
31
|
var _a, _b;
|
|
30
|
-
|
|
32
|
+
cli_utilities_1.log.debug('Checking for labels folder existence', this.importConfig.context);
|
|
31
33
|
//Step1 check folder exists or not
|
|
32
34
|
if (utils_1.fileHelper.fileExistsSync(this.labelsFolderPath)) {
|
|
35
|
+
cli_utilities_1.log.debug(`Found labels folder: ${this.labelsFolderPath}`, this.importConfig.context);
|
|
33
36
|
this.labels = utils_1.fsUtil.readFile((0, node_path_1.join)(this.labelsFolderPath, 'labels.json'), true);
|
|
37
|
+
// Check if labels file was read successfully
|
|
38
|
+
if (!this.labels) {
|
|
39
|
+
cli_utilities_1.log.info(`No labels found in file - '${(0, node_path_1.join)(this.labelsFolderPath, 'labels.json')}'`, this.importConfig.context);
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
const labelCount = Object.keys(this.labels || {}).length;
|
|
43
|
+
cli_utilities_1.log.debug(`Loaded ${labelCount} label items from file`, this.importConfig.context);
|
|
34
44
|
}
|
|
35
45
|
else {
|
|
36
|
-
|
|
46
|
+
cli_utilities_1.log.info(`No labels found - '${this.labelsFolderPath}'`, this.importConfig.context);
|
|
37
47
|
return;
|
|
38
48
|
}
|
|
39
49
|
//create labels in mapper directory
|
|
50
|
+
cli_utilities_1.log.debug('Creating labels mapper directory', this.importConfig.context);
|
|
40
51
|
await utils_1.fsUtil.makeDirectory(this.mapperDirPath);
|
|
52
|
+
cli_utilities_1.log.debug('Loading existing label UID mappings', this.importConfig.context);
|
|
41
53
|
this.labelUidMapper = utils_1.fileHelper.fileExistsSync(this.labelUidMapperPath)
|
|
42
|
-
? utils_1.fsUtil.readFile((0, node_path_1.join)(this.labelUidMapperPath), true)
|
|
54
|
+
? utils_1.fsUtil.readFile((0, node_path_1.join)(this.labelUidMapperPath), true) || {}
|
|
43
55
|
: {};
|
|
44
|
-
|
|
56
|
+
if (Object.keys(this.labelUidMapper || {}).length > 0) {
|
|
57
|
+
const labelUidCount = Object.keys(this.labelUidMapper || {}).length;
|
|
58
|
+
cli_utilities_1.log.debug(`Loaded existing label UID data: ${labelUidCount} items`, this.importConfig.context);
|
|
59
|
+
}
|
|
60
|
+
else {
|
|
61
|
+
cli_utilities_1.log.debug('No existing label UID mappings found', this.importConfig.context);
|
|
62
|
+
}
|
|
63
|
+
cli_utilities_1.log.debug('Starting labels import', this.importConfig.context);
|
|
64
|
+
await this.importLabels();
|
|
45
65
|
//update parent in created label
|
|
66
|
+
cli_utilities_1.log.debug('Starting labels update process', this.importConfig.context);
|
|
46
67
|
await this.updateLabels();
|
|
68
|
+
cli_utilities_1.log.debug('Processing labels import results', this.importConfig.context);
|
|
47
69
|
if ((_a = this.createdLabel) === null || _a === void 0 ? void 0 : _a.length) {
|
|
48
70
|
utils_1.fsUtil.writeFile(this.createdLabelPath, this.createdLabel);
|
|
71
|
+
cli_utilities_1.log.debug(`Written ${this.createdLabel.length} successful labels to file`, this.importConfig.context);
|
|
49
72
|
}
|
|
50
73
|
if ((_b = this.failedLabel) === null || _b === void 0 ? void 0 : _b.length) {
|
|
51
74
|
utils_1.fsUtil.writeFile(this.labelFailsPath, this.failedLabel);
|
|
75
|
+
cli_utilities_1.log.debug(`Written ${this.failedLabel.length} failed labels to file`, this.importConfig.context);
|
|
52
76
|
}
|
|
53
|
-
|
|
77
|
+
cli_utilities_1.log.success('Labels have been imported successfully!', this.importConfig.context);
|
|
54
78
|
}
|
|
55
|
-
async
|
|
79
|
+
async importLabels() {
|
|
56
80
|
if (this.labels === undefined || (0, isEmpty_1.default)(this.labels)) {
|
|
57
|
-
|
|
81
|
+
cli_utilities_1.log.info('No Labels Found', this.importConfig.context);
|
|
58
82
|
return;
|
|
59
83
|
}
|
|
60
84
|
const apiContent = (0, values_1.default)(this.labels);
|
|
61
85
|
const onSuccess = ({ response, apiData: { uid, name } = { uid: null, name: '' } }) => {
|
|
62
86
|
this.labelUidMapper[uid] = response;
|
|
63
|
-
|
|
87
|
+
cli_utilities_1.log.success(`Label '${name}' imported successfully`, this.importConfig.context);
|
|
64
88
|
utils_1.fsUtil.writeFile(this.labelUidMapperPath, this.labelUidMapper);
|
|
65
89
|
};
|
|
66
90
|
const onReject = ({ error, apiData }) => {
|
|
@@ -68,18 +92,18 @@ class Importlabels extends base_class_1.default {
|
|
|
68
92
|
const err = (error === null || error === void 0 ? void 0 : error.message) ? JSON.parse(error.message) : error;
|
|
69
93
|
const { name } = apiData;
|
|
70
94
|
if ((_a = err === null || err === void 0 ? void 0 : err.errors) === null || _a === void 0 ? void 0 : _a.name) {
|
|
71
|
-
|
|
95
|
+
cli_utilities_1.log.info(`Label '${name}' already exists`, this.importConfig.context);
|
|
72
96
|
}
|
|
73
97
|
else {
|
|
74
98
|
this.failedLabel.push(apiData);
|
|
75
|
-
(0,
|
|
99
|
+
(0, cli_utilities_1.handleAndLogError)(error, Object.assign(Object.assign({}, this.importConfig.context), { name }), `Label '${name}' failed to be import`);
|
|
76
100
|
}
|
|
77
101
|
};
|
|
78
102
|
await this.makeConcurrentCall({
|
|
79
103
|
apiContent,
|
|
80
104
|
processName: 'create labels',
|
|
81
105
|
apiParams: {
|
|
82
|
-
serializeData: this.
|
|
106
|
+
serializeData: this.serializeLabels.bind(this),
|
|
83
107
|
reject: onReject.bind(this),
|
|
84
108
|
resolve: onSuccess.bind(this),
|
|
85
109
|
entity: 'create-labels',
|
|
@@ -89,20 +113,23 @@ class Importlabels extends base_class_1.default {
|
|
|
89
113
|
}, undefined, false);
|
|
90
114
|
}
|
|
91
115
|
/**
|
|
92
|
-
* @method
|
|
116
|
+
* @method serializeLabels
|
|
93
117
|
* @param {ApiOptions} apiOptions ApiOptions
|
|
94
118
|
* @returns {ApiOptions} ApiOptions
|
|
95
119
|
*/
|
|
96
|
-
|
|
120
|
+
serializeLabels(apiOptions) {
|
|
97
121
|
var _a;
|
|
98
122
|
const { apiData: label } = apiOptions;
|
|
123
|
+
cli_utilities_1.log.debug(`Serializing label: ${label.name} (${label.uid})`, this.importConfig.context);
|
|
99
124
|
if (this.labelUidMapper.hasOwnProperty(label.uid)) {
|
|
100
|
-
|
|
125
|
+
cli_utilities_1.log.info(`Label '${label.name}' already exists. Skipping it to avoid duplicates!`, this.importConfig.context);
|
|
126
|
+
cli_utilities_1.log.debug(`Skipping label serialization for: ${label.uid}`, this.importConfig.context);
|
|
101
127
|
apiOptions.entity = undefined;
|
|
102
128
|
}
|
|
103
129
|
else {
|
|
104
130
|
let labelReq = label;
|
|
105
131
|
if (((_a = label === null || label === void 0 ? void 0 : label.parent) === null || _a === void 0 ? void 0 : _a.length) != 0) {
|
|
132
|
+
cli_utilities_1.log.debug(`Label '${label.name}' has parent labels, removing parent for initial creation`, this.importConfig.context);
|
|
106
133
|
labelReq = (0, omit_1.default)(label, ['parent']);
|
|
107
134
|
}
|
|
108
135
|
apiOptions.apiData = labelReq;
|
|
@@ -110,15 +137,20 @@ class Importlabels extends base_class_1.default {
|
|
|
110
137
|
return apiOptions;
|
|
111
138
|
}
|
|
112
139
|
async updateLabels() {
|
|
140
|
+
cli_utilities_1.log.debug('Starting labels update process', this.importConfig.context);
|
|
113
141
|
if (!(0, isEmpty_1.default)(this.labels)) {
|
|
114
142
|
const apiContent = (0, values_1.default)(this.labels);
|
|
143
|
+
cli_utilities_1.log.debug(`Updating ${apiContent.length} labels`, this.importConfig.context);
|
|
115
144
|
const onSuccess = ({ response, apiData: { uid, name } = { uid: null, name: '' } }) => {
|
|
116
145
|
this.createdLabel.push(response);
|
|
117
|
-
|
|
146
|
+
cli_utilities_1.log.success(`Label '${name}' updated successfully`, this.importConfig.context);
|
|
147
|
+
cli_utilities_1.log.debug(`Label update completed: ${name} (${uid})`, this.importConfig.context);
|
|
118
148
|
};
|
|
119
149
|
const onReject = ({ error, apiData }) => {
|
|
120
|
-
|
|
150
|
+
cli_utilities_1.log.debug(`Label '${apiData === null || apiData === void 0 ? void 0 : apiData.name}' update failed`, this.importConfig.context);
|
|
151
|
+
(0, cli_utilities_1.handleAndLogError)(error, Object.assign(Object.assign({}, this.importConfig.context), { name: apiData === null || apiData === void 0 ? void 0 : apiData.name }), `Failed to update label '${apiData === null || apiData === void 0 ? void 0 : apiData.name}'`);
|
|
121
152
|
};
|
|
153
|
+
cli_utilities_1.log.debug(`Using concurrency limit for updates: ${this.importConfig.fetchConcurrency || 1}`, this.importConfig.context);
|
|
122
154
|
await this.makeConcurrentCall({
|
|
123
155
|
apiContent,
|
|
124
156
|
processName: 'update labels',
|
|
@@ -132,6 +164,10 @@ class Importlabels extends base_class_1.default {
|
|
|
132
164
|
concurrencyLimit: this.importConfig.fetchConcurrency || 1,
|
|
133
165
|
}, undefined, false);
|
|
134
166
|
}
|
|
167
|
+
else {
|
|
168
|
+
cli_utilities_1.log.debug('No labels to update', this.importConfig.context);
|
|
169
|
+
}
|
|
170
|
+
cli_utilities_1.log.debug('Labels update process completed', this.importConfig.context);
|
|
135
171
|
}
|
|
136
172
|
/**
|
|
137
173
|
* @method serializeUpdatelabels
|
|
@@ -142,29 +178,35 @@ class Importlabels extends base_class_1.default {
|
|
|
142
178
|
var _a, _b;
|
|
143
179
|
const { apiData: label } = apiOptions;
|
|
144
180
|
const labelUid = label.uid;
|
|
181
|
+
cli_utilities_1.log.debug(`Serializing label update: ${label.name} (${labelUid})`, this.importConfig.context);
|
|
145
182
|
if (this.labelUidMapper.hasOwnProperty(labelUid)) {
|
|
146
183
|
const newLabel = this.labelUidMapper[labelUid];
|
|
147
184
|
if (((_a = label === null || label === void 0 ? void 0 : label.parent) === null || _a === void 0 ? void 0 : _a.length) > 0) {
|
|
185
|
+
cli_utilities_1.log.debug(`Label '${label.name}' has ${label.parent.length} parent labels to update`, this.importConfig.context);
|
|
148
186
|
for (let i = 0; i < ((_b = label === null || label === void 0 ? void 0 : label.parent) === null || _b === void 0 ? void 0 : _b.length); i++) {
|
|
149
187
|
const parentUid = label.parent[i];
|
|
150
188
|
if (this.labelUidMapper.hasOwnProperty(parentUid)) {
|
|
151
189
|
const mappedLabel = this.labelUidMapper[parentUid];
|
|
152
190
|
label.parent[i] = mappedLabel.uid;
|
|
191
|
+
cli_utilities_1.log.debug(`Parent label mapping: ${parentUid} → ${mappedLabel.uid}`, this.importConfig.context);
|
|
153
192
|
}
|
|
154
193
|
}
|
|
155
194
|
const createdLabelRes = this.labelUidMapper[labelUid];
|
|
156
195
|
createdLabelRes.parent = label.parent;
|
|
157
196
|
apiOptions.apiData = createdLabelRes;
|
|
197
|
+
cli_utilities_1.log.debug(`Updated label '${label.name}' with parent references`, this.importConfig.context);
|
|
158
198
|
}
|
|
159
199
|
else {
|
|
200
|
+
cli_utilities_1.log.debug(`Label '${label.name}' has no parent labels, adding to created list`, this.importConfig.context);
|
|
160
201
|
apiOptions.entity = undefined;
|
|
161
202
|
this.createdLabel.push(newLabel);
|
|
162
203
|
}
|
|
163
204
|
}
|
|
164
205
|
else {
|
|
206
|
+
cli_utilities_1.log.debug(`Label '${label.name}' not found in UID mapper, skipping update`, this.importConfig.context);
|
|
165
207
|
apiOptions.entity = undefined;
|
|
166
208
|
}
|
|
167
209
|
return apiOptions;
|
|
168
210
|
}
|
|
169
211
|
}
|
|
170
|
-
exports.default =
|
|
212
|
+
exports.default = ImportLabels;
|