@contentstack/cli-cm-import 1.25.0 → 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/base-class.js +11 -3
- package/lib/import/modules/content-types.js +79 -28
- 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 +86 -19
- 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/global-field-helper.js +1 -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
|
-
if ((_a = this.
|
|
64
|
+
if ((_a = this.pendingGFs) === null || _a === void 0 ? void 0 : _a.length) {
|
|
50
65
|
utils_1.fsUtil.writeFile(this.gFsPendingPath, this.pendingGFs);
|
|
51
|
-
|
|
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);
|
|
52
70
|
await this.updateGFs();
|
|
53
|
-
(
|
|
71
|
+
if ((_b = this.pendingGFs) === null || _b === void 0 ? void 0 : _b.length)
|
|
72
|
+
utils_1.fsUtil.writeFile(this.gFsPendingPath, this.pendingGFs);
|
|
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,23 +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);
|
|
189
|
+
cli_utilities_1.log.info(`Global field '${globalField.uid}' will be updated later`, this.importConfig.context);
|
|
190
|
+
return resolve(true);
|
|
136
191
|
}
|
|
192
|
+
cli_utilities_1.log.debug(`Fetching existing global field: ${globalField.uid}`, this.importConfig.context);
|
|
137
193
|
return this.stack
|
|
138
194
|
.globalField(globalField.uid, { api_version: '3.2' })
|
|
139
195
|
.fetch()
|
|
140
196
|
.then((response) => {
|
|
197
|
+
cli_utilities_1.log.debug(`Updating global field: ${globalField.uid}`, this.importConfig.context);
|
|
141
198
|
Object.assign(response, globalField);
|
|
142
199
|
return response.update();
|
|
143
200
|
})
|
|
144
201
|
.then((response) => {
|
|
202
|
+
cli_utilities_1.log.debug(`Global field update successful: ${globalField.uid}`, this.importConfig.context);
|
|
145
203
|
apiParams.resolve({
|
|
146
204
|
response,
|
|
147
205
|
apiData: globalField,
|
|
@@ -149,6 +207,7 @@ class ImportGlobalFields extends base_class_1.default {
|
|
|
149
207
|
resolve(true);
|
|
150
208
|
})
|
|
151
209
|
.catch((error) => {
|
|
210
|
+
cli_utilities_1.log.debug(`Global field update failed: ${globalField.uid}`, this.importConfig.context);
|
|
152
211
|
apiParams.reject({
|
|
153
212
|
error,
|
|
154
213
|
apiData: globalField,
|
|
@@ -158,21 +217,24 @@ class ImportGlobalFields extends base_class_1.default {
|
|
|
158
217
|
});
|
|
159
218
|
}
|
|
160
219
|
async replaceGFs() {
|
|
220
|
+
cli_utilities_1.log.debug(`Replacing ${this.existingGFs.length} existing global fields`, this.importConfig.context);
|
|
161
221
|
const onSuccess = ({ response: globalField, apiData }) => {
|
|
162
222
|
var _a, _b, _c;
|
|
163
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';
|
|
164
224
|
this.createdGFs.push(globalField);
|
|
165
225
|
this.gFsUidMapper[uid] = globalField;
|
|
166
226
|
utils_1.fsUtil.writeFile(this.gFsUidMapperPath, this.gFsUidMapper);
|
|
167
|
-
|
|
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);
|
|
168
229
|
};
|
|
169
230
|
const onReject = ({ error, apiData }) => {
|
|
170
231
|
var _a, _b, _c;
|
|
171
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';
|
|
172
|
-
|
|
173
|
-
(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`);
|
|
174
235
|
this.failedGFs.push({ uid });
|
|
175
236
|
};
|
|
237
|
+
cli_utilities_1.log.debug(`Using concurrency limit for replacement: ${this.importConfig.concurrency || this.importConfig.fetchConcurrency || 1}`, this.importConfig.context);
|
|
176
238
|
await this.makeConcurrentCall({
|
|
177
239
|
apiContent: this.existingGFs,
|
|
178
240
|
processName: 'Replace global fields',
|
|
@@ -185,6 +247,7 @@ class ImportGlobalFields extends base_class_1.default {
|
|
|
185
247
|
},
|
|
186
248
|
concurrencyLimit: this.importConfig.concurrency || this.importConfig.fetchConcurrency || 1,
|
|
187
249
|
}, undefined, false);
|
|
250
|
+
cli_utilities_1.log.debug('Global fields replacement process completed', this.importConfig.context);
|
|
188
251
|
}
|
|
189
252
|
/**
|
|
190
253
|
* @method serializeReplaceGFs
|
|
@@ -192,11 +255,15 @@ class ImportGlobalFields extends base_class_1.default {
|
|
|
192
255
|
* @returns {ApiOptions} ApiOptions
|
|
193
256
|
*/
|
|
194
257
|
serializeReplaceGFs(apiOptions) {
|
|
258
|
+
var _a, _b, _c;
|
|
195
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);
|
|
196
262
|
const globalFieldPayload = this.stack.globalField(globalField.uid, { api_version: '3.2' });
|
|
197
263
|
Object.assign(globalFieldPayload, (0, lodash_1.cloneDeep)(globalField), {
|
|
198
264
|
stackHeaders: globalFieldPayload.stackHeaders,
|
|
199
265
|
});
|
|
266
|
+
cli_utilities_1.log.debug(`Global field replacement serialization completed: ${uid}`, this.importConfig.context);
|
|
200
267
|
apiOptions.apiData = globalFieldPayload;
|
|
201
268
|
return apiOptions;
|
|
202
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;
|