@contentstack/cli-cm-import 1.13.3 → 1.14.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/lib/commands/cm/stacks/import.js +3 -1
- package/lib/config/index.js +1 -5
- package/lib/import/module-importer.js +4 -0
- package/lib/import/modules/base-class.d.ts +1 -1
- package/lib/import/modules/base-class.js +25 -22
- package/lib/import/modules/content-types.d.ts +2 -0
- package/lib/import/modules/content-types.js +38 -0
- package/lib/import/modules/extensions.d.ts +4 -0
- package/lib/import/modules/extensions.js +27 -0
- package/lib/import/modules/taxonomies.d.ts +6 -27
- package/lib/import/modules/taxonomies.js +42 -128
- package/lib/types/default-config.d.ts +0 -5
- package/lib/types/import-config.d.ts +1 -0
- package/lib/types/index.d.ts +5 -5
- package/lib/utils/interactive.d.ts +0 -1
- package/lib/utils/interactive.js +1 -14
- package/lib/utils/marketplace-app-helper.js +5 -11
- package/lib/utils/taxonomies-helper.js +11 -2
- package/oclif.manifest.json +1 -1
- package/package.json +6 -6
package/README.md
CHANGED
|
@@ -47,7 +47,7 @@ $ npm install -g @contentstack/cli-cm-import
|
|
|
47
47
|
$ csdx COMMAND
|
|
48
48
|
running command...
|
|
49
49
|
$ csdx (--version)
|
|
50
|
-
@contentstack/cli-cm-import/1.
|
|
50
|
+
@contentstack/cli-cm-import/1.14.0 linux-x64 node-v18.19.1
|
|
51
51
|
$ csdx --help [COMMAND]
|
|
52
52
|
USAGE
|
|
53
53
|
$ csdx COMMAND
|
|
@@ -22,7 +22,9 @@ class ImportCommand extends cli_command_1.Command {
|
|
|
22
22
|
const moduleImporter = new import_1.ModuleImporter(managementAPIClient, importConfig);
|
|
23
23
|
const result = await moduleImporter.start();
|
|
24
24
|
if (!(result === null || result === void 0 ? void 0 : result.noSuccessMsg)) {
|
|
25
|
-
(0, utils_1.log)(importConfig,
|
|
25
|
+
(0, utils_1.log)(importConfig, importConfig.stackName
|
|
26
|
+
? `Successfully imported the content to the stack named ${importConfig.stackName} with the API key ${importConfig.apiKey} .`
|
|
27
|
+
: `The content has been imported to the stack ${importConfig.apiKey} successfully!`, 'success');
|
|
26
28
|
}
|
|
27
29
|
(0, utils_1.log)(importConfig, `The log has been stored at '${node_path_1.default.join(importConfig.backupDir, 'logs', 'import')}'`, 'success');
|
|
28
30
|
}
|
package/lib/config/index.js
CHANGED
|
@@ -18,6 +18,10 @@ class ModuleImporter {
|
|
|
18
18
|
this.importConfig = importConfig;
|
|
19
19
|
}
|
|
20
20
|
async start() {
|
|
21
|
+
if (!this.importConfig.management_token) {
|
|
22
|
+
const stackName = await this.stackAPIClient.fetch();
|
|
23
|
+
this.importConfig.stackName = stackName.name;
|
|
24
|
+
}
|
|
21
25
|
if (this.importConfig.branchName) {
|
|
22
26
|
await (0, utils_1.validateBranch)(this.stackAPIClient, this.importConfig, this.importConfig.branchName);
|
|
23
27
|
}
|
|
@@ -3,7 +3,7 @@ import { ImportConfig, ModuleClassParams } from '../../types';
|
|
|
3
3
|
export type AdditionalKeys = {
|
|
4
4
|
backupDir: string;
|
|
5
5
|
};
|
|
6
|
-
export type ApiModuleType = 'create-assets' | 'replace-assets' | 'publish-assets' | 'create-assets-folder' | 'create-extensions' | 'update-extensions' | 'create-locale' | 'update-locale' | 'create-gfs' | 'create-cts' | 'update-cts' | 'update-gfs' | 'create-environments' | 'create-labels' | 'update-labels' | 'create-webhooks' | 'create-workflows' | 'create-custom-role' | 'create-entries' | 'update-entries' | 'publish-entries' | 'delete-entries' | 'create-taxonomies' | 'create-terms';
|
|
6
|
+
export type ApiModuleType = 'create-assets' | 'replace-assets' | 'publish-assets' | 'create-assets-folder' | 'create-extensions' | 'update-extensions' | 'create-locale' | 'update-locale' | 'create-gfs' | 'create-cts' | 'update-cts' | 'update-gfs' | 'create-environments' | 'create-labels' | 'update-labels' | 'create-webhooks' | 'create-workflows' | 'create-custom-role' | 'create-entries' | 'update-entries' | 'publish-entries' | 'delete-entries' | 'create-taxonomies' | 'create-terms' | 'import-taxonomy';
|
|
7
7
|
export type ApiOptions = {
|
|
8
8
|
uid?: string;
|
|
9
9
|
url?: string;
|
|
@@ -122,6 +122,11 @@ class BaseClass {
|
|
|
122
122
|
additionalInfo,
|
|
123
123
|
apiData: includeParamOnCompletion ? apiData : undefined,
|
|
124
124
|
});
|
|
125
|
+
if (!apiData ||
|
|
126
|
+
(entity === 'publish-entries' && !apiData.entryUid) ||
|
|
127
|
+
(entity === 'update-extensions' && !apiData.uid)) {
|
|
128
|
+
return Promise.resolve();
|
|
129
|
+
}
|
|
125
130
|
switch (entity) {
|
|
126
131
|
case 'create-assets-folder':
|
|
127
132
|
return this.stack
|
|
@@ -154,6 +159,16 @@ class BaseClass {
|
|
|
154
159
|
.create({ extension: (0, omit_1.default)(apiData, ['uid']) })
|
|
155
160
|
.then(onSuccess)
|
|
156
161
|
.catch(onReject);
|
|
162
|
+
case 'update-extensions':
|
|
163
|
+
return this.stack
|
|
164
|
+
.extension(apiData.uid)
|
|
165
|
+
.fetch()
|
|
166
|
+
.then((extension) => {
|
|
167
|
+
extension.scope = apiData.scope;
|
|
168
|
+
return extension.update();
|
|
169
|
+
})
|
|
170
|
+
.then(onSuccess)
|
|
171
|
+
.catch(onReject);
|
|
157
172
|
case 'create-locale':
|
|
158
173
|
return this.stack
|
|
159
174
|
.locale()
|
|
@@ -169,14 +184,8 @@ class BaseClass {
|
|
|
169
184
|
case 'create-cts':
|
|
170
185
|
return this.stack.contentType().create(apiData).then(onSuccess).catch(onReject);
|
|
171
186
|
case 'update-cts':
|
|
172
|
-
if (!apiData) {
|
|
173
|
-
return Promise.resolve();
|
|
174
|
-
}
|
|
175
187
|
return apiData.update().then(onSuccess).catch(onReject);
|
|
176
188
|
case 'update-gfs':
|
|
177
|
-
if (!apiData) {
|
|
178
|
-
return Promise.resolve();
|
|
179
|
-
}
|
|
180
189
|
return apiData.update().then(onSuccess).catch(onReject);
|
|
181
190
|
case 'create-environments':
|
|
182
191
|
return this.stack
|
|
@@ -218,9 +227,6 @@ class BaseClass {
|
|
|
218
227
|
.then(onSuccess)
|
|
219
228
|
.catch(onReject);
|
|
220
229
|
case 'create-entries':
|
|
221
|
-
if (!apiData) {
|
|
222
|
-
return Promise.resolve();
|
|
223
|
-
}
|
|
224
230
|
if ((_a = additionalInfo[apiData === null || apiData === void 0 ? void 0 : apiData.uid]) === null || _a === void 0 ? void 0 : _a.isLocalized) {
|
|
225
231
|
return apiData.update({ locale: additionalInfo.locale }).then(onSuccess).catch(onReject);
|
|
226
232
|
}
|
|
@@ -231,14 +237,8 @@ class BaseClass {
|
|
|
231
237
|
.then(onSuccess)
|
|
232
238
|
.catch(onReject);
|
|
233
239
|
case 'update-entries':
|
|
234
|
-
if (!apiData) {
|
|
235
|
-
return Promise.resolve();
|
|
236
|
-
}
|
|
237
240
|
return apiData.update({ locale: additionalInfo.locale }).then(onSuccess).catch(onReject);
|
|
238
241
|
case 'publish-entries':
|
|
239
|
-
if (!apiData || !apiData.entryUid) {
|
|
240
|
-
return Promise.resolve();
|
|
241
|
-
}
|
|
242
242
|
return this.stack
|
|
243
243
|
.contentType(additionalInfo.cTUid)
|
|
244
244
|
.entry(apiData.entryUid)
|
|
@@ -258,14 +258,17 @@ class BaseClass {
|
|
|
258
258
|
case 'create-taxonomies':
|
|
259
259
|
return this.stack.taxonomy().create({ taxonomy: apiData }).then(onSuccess).catch(onReject);
|
|
260
260
|
case 'create-terms':
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
261
|
+
return this.stack
|
|
262
|
+
.taxonomy(apiData.taxonomy_uid)
|
|
263
|
+
.terms()
|
|
264
|
+
.create({ term: apiData })
|
|
265
|
+
.then(onSuccess)
|
|
266
|
+
.catch(onReject);
|
|
267
|
+
case 'import-taxonomy':
|
|
268
|
+
if (!apiData || !apiData.filePath) {
|
|
269
|
+
return Promise.resolve();
|
|
268
270
|
}
|
|
271
|
+
return this.stack.taxonomy(uid).import({ taxonomy: apiData.filePath }).then(onSuccess).catch(onReject);
|
|
269
272
|
default:
|
|
270
273
|
return Promise.resolve();
|
|
271
274
|
}
|
|
@@ -32,6 +32,7 @@ export default class ContentTypesImport extends BaseClass {
|
|
|
32
32
|
private gFsConfig;
|
|
33
33
|
private taxonomiesPath;
|
|
34
34
|
taxonomies: Record<string, unknown>;
|
|
35
|
+
private extPendingPath;
|
|
35
36
|
constructor({ importConfig, stackAPIClient }: ModuleClassParams);
|
|
36
37
|
start(): Promise<any>;
|
|
37
38
|
seedCTs(): Promise<any>;
|
|
@@ -55,4 +56,5 @@ export default class ContentTypesImport extends BaseClass {
|
|
|
55
56
|
* @returns {ApiOptions} ApiOptions
|
|
56
57
|
*/
|
|
57
58
|
serializeUpdateGFs(apiOptions: ApiOptions): ApiOptions;
|
|
59
|
+
updatePendingExtensions(): Promise<any>;
|
|
58
60
|
}
|
|
@@ -39,6 +39,7 @@ class ContentTypesImport extends base_class_1.default {
|
|
|
39
39
|
this.createdGFs = [];
|
|
40
40
|
this.pendingGFs = [];
|
|
41
41
|
this.taxonomiesPath = path.join(importConfig.data, 'mapper/taxonomies', 'success.json');
|
|
42
|
+
this.extPendingPath = path.join(importConfig.data, 'mapper', 'extensions', 'pending_extensions.js');
|
|
42
43
|
}
|
|
43
44
|
async start() {
|
|
44
45
|
/**
|
|
@@ -63,6 +64,9 @@ class ContentTypesImport extends base_class_1.default {
|
|
|
63
64
|
if (this.fieldRules.length > 0) {
|
|
64
65
|
await utils_1.fsUtil.writeFile(path.join(this.cTsFolderPath, 'field_rules_uid.json'), this.fieldRules);
|
|
65
66
|
}
|
|
67
|
+
(0, utils_1.log)(this.importConfig, 'Updating the extensions...', 'success');
|
|
68
|
+
await this.updatePendingExtensions();
|
|
69
|
+
(0, utils_1.log)(this.importConfig, 'Successfully updated the extensions.', 'success');
|
|
66
70
|
await this.updatePendingGFs().catch((error) => {
|
|
67
71
|
(0, utils_1.log)(this.importConfig, `Error while updating pending global field ${(0, utils_1.formatError)(error)}`, 'error');
|
|
68
72
|
});
|
|
@@ -190,5 +194,39 @@ class ContentTypesImport extends base_class_1.default {
|
|
|
190
194
|
apiOptions.apiData = globalFieldPayload;
|
|
191
195
|
return apiOptions;
|
|
192
196
|
}
|
|
197
|
+
async updatePendingExtensions() {
|
|
198
|
+
let apiContent = utils_1.fsUtil.readFile(this.extPendingPath);
|
|
199
|
+
if (apiContent.length === 0) {
|
|
200
|
+
(0, utils_1.log)(this.importConfig, `No extensions found to be updated.`, 'success');
|
|
201
|
+
return;
|
|
202
|
+
}
|
|
203
|
+
const onSuccess = ({ response, apiData: { uid, title } = { uid: null, title: '' } }) => {
|
|
204
|
+
(0, utils_1.log)(this.importConfig, `Successfully updated the '${response.title}' extension.`, 'success');
|
|
205
|
+
};
|
|
206
|
+
const onReject = ({ error, apiData }) => {
|
|
207
|
+
var _a;
|
|
208
|
+
const { uid } = apiData;
|
|
209
|
+
if ((_a = error === null || error === void 0 ? void 0 : error.errors) === null || _a === void 0 ? void 0 : _a.title) {
|
|
210
|
+
if (!this.importConfig.skipExisting) {
|
|
211
|
+
(0, utils_1.log)(this.importConfig, `Extension '${uid}' already exists.`, 'info');
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
else {
|
|
215
|
+
(0, utils_1.log)(this.importConfig, `Failed to update '${uid}' extension due to ${(0, utils_1.formatError)(error)}.`, 'error');
|
|
216
|
+
(0, utils_1.log)(this.importConfig, error, 'error');
|
|
217
|
+
}
|
|
218
|
+
};
|
|
219
|
+
return await this.makeConcurrentCall({
|
|
220
|
+
apiContent,
|
|
221
|
+
processName: 'update extensions',
|
|
222
|
+
apiParams: {
|
|
223
|
+
reject: onReject.bind(this),
|
|
224
|
+
resolve: onSuccess.bind(this),
|
|
225
|
+
entity: 'update-extensions',
|
|
226
|
+
includeParamOnCompletion: true,
|
|
227
|
+
},
|
|
228
|
+
concurrencyLimit: this.importConfig.concurrency || this.importConfig.fetchConcurrency || 1,
|
|
229
|
+
}, undefined, false);
|
|
230
|
+
}
|
|
193
231
|
}
|
|
194
232
|
exports.default = ContentTypesImport;
|
|
@@ -12,6 +12,8 @@ export default class ImportExtensions extends BaseClass {
|
|
|
12
12
|
private extSuccess;
|
|
13
13
|
private extFailed;
|
|
14
14
|
private existingExtensions;
|
|
15
|
+
private extPendingPath;
|
|
16
|
+
private extensionObject;
|
|
15
17
|
constructor({ importConfig, stackAPIClient }: ModuleClassParams);
|
|
16
18
|
/**
|
|
17
19
|
* @method start
|
|
@@ -25,4 +27,6 @@ export default class ImportExtensions extends BaseClass {
|
|
|
25
27
|
element: Record<string, string>;
|
|
26
28
|
isLastRequest: boolean;
|
|
27
29
|
}): Promise<unknown>;
|
|
30
|
+
getContentTypesInScope(): void;
|
|
31
|
+
updateUidExtension(): void;
|
|
28
32
|
}
|
|
@@ -16,10 +16,12 @@ class ImportExtensions extends base_class_1.default {
|
|
|
16
16
|
this.extUidMapperPath = (0, node_path_1.join)(this.mapperDirPath, 'uid-mapping.json');
|
|
17
17
|
this.extSuccessPath = (0, node_path_1.join)(this.mapperDirPath, 'success.json');
|
|
18
18
|
this.extFailsPath = (0, node_path_1.join)(this.mapperDirPath, 'fails.json');
|
|
19
|
+
this.extPendingPath = (0, node_path_1.join)(this.mapperDirPath, 'pending_extensions.js');
|
|
19
20
|
this.extFailed = [];
|
|
20
21
|
this.extSuccess = [];
|
|
21
22
|
this.existingExtensions = [];
|
|
22
23
|
this.extUidMapper = {};
|
|
24
|
+
this.extensionObject = [];
|
|
23
25
|
}
|
|
24
26
|
/**
|
|
25
27
|
* @method start
|
|
@@ -40,7 +42,12 @@ class ImportExtensions extends base_class_1.default {
|
|
|
40
42
|
this.extUidMapper = utils_1.fileHelper.fileExistsSync(this.extUidMapperPath)
|
|
41
43
|
? utils_1.fsUtil.readFile((0, node_path_1.join)(this.extUidMapperPath), true)
|
|
42
44
|
: {};
|
|
45
|
+
// Check whether the scope of an extension contains content-types in scope
|
|
46
|
+
// Remove the scope and store the scope with uid in pending extensions
|
|
47
|
+
this.getContentTypesInScope();
|
|
43
48
|
await this.importExtensions();
|
|
49
|
+
// Update the uid of the extension
|
|
50
|
+
this.updateUidExtension();
|
|
44
51
|
// Note: if any extensions present, then update it
|
|
45
52
|
if (this.importConfig.replaceExisting && this.existingExtensions.length > 0) {
|
|
46
53
|
await this.replaceExtensions().catch((error) => {
|
|
@@ -167,5 +174,25 @@ class ImportExtensions extends base_class_1.default {
|
|
|
167
174
|
}
|
|
168
175
|
});
|
|
169
176
|
}
|
|
177
|
+
getContentTypesInScope() {
|
|
178
|
+
const extension = (0, values_1.default)(this.extensions);
|
|
179
|
+
extension.forEach((ext) => {
|
|
180
|
+
var _a;
|
|
181
|
+
let ct = ((_a = ext === null || ext === void 0 ? void 0 : ext.scope) === null || _a === void 0 ? void 0 : _a.content_types) || [];
|
|
182
|
+
if ((ct.length === 1 && ct[0] !== '$all') || (ct === null || ct === void 0 ? void 0 : ct.length) > 1) {
|
|
183
|
+
(0, utils_1.log)(this.importConfig, `Removing the content-types ${ct.join(',')} from the extension ${ext.title} ...`, 'info');
|
|
184
|
+
const { uid, scope } = ext;
|
|
185
|
+
this.extensionObject.push({ uid, scope });
|
|
186
|
+
delete ext.scope;
|
|
187
|
+
this.extensions[ext.uid] = ext;
|
|
188
|
+
}
|
|
189
|
+
});
|
|
190
|
+
}
|
|
191
|
+
updateUidExtension() {
|
|
192
|
+
for (let i in this.extensionObject) {
|
|
193
|
+
this.extensionObject[i].uid = this.extUidMapper[this.extensionObject[i].uid];
|
|
194
|
+
}
|
|
195
|
+
utils_1.fsUtil.writeFile(this.extPendingPath, this.extensionObject);
|
|
196
|
+
}
|
|
170
197
|
}
|
|
171
198
|
exports.default = ImportExtensions;
|
|
@@ -7,17 +7,13 @@ export default class ImportTaxonomies extends BaseClass {
|
|
|
7
7
|
private taxFailsPath;
|
|
8
8
|
private taxonomiesConfig;
|
|
9
9
|
private taxonomies;
|
|
10
|
-
private termsFolderPath;
|
|
11
10
|
private termsMapperDirPath;
|
|
12
|
-
private termsConfig;
|
|
13
11
|
private termsSuccessPath;
|
|
14
12
|
private termsFailsPath;
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
terms: Record<string, any>;
|
|
20
|
-
taxonomyUIDs: string[];
|
|
13
|
+
createdTaxonomies: Record<string, unknown>;
|
|
14
|
+
failedTaxonomies: Record<string, unknown>;
|
|
15
|
+
createdTerms: Record<string, Record<string, unknown>>;
|
|
16
|
+
failedTerms: Record<string, Record<string, unknown>>;
|
|
21
17
|
constructor({ importConfig, stackAPIClient }: ModuleClassParams);
|
|
22
18
|
/**
|
|
23
19
|
* @method start
|
|
@@ -39,25 +35,8 @@ export default class ImportTaxonomies extends BaseClass {
|
|
|
39
35
|
serializeTaxonomy(apiOptions: ApiOptions): ApiOptions;
|
|
40
36
|
/**
|
|
41
37
|
* create taxonomies success and fail in (mapper/taxonomies)
|
|
42
|
-
* @method createTaxonomySuccessAndFailedFile
|
|
43
|
-
*/
|
|
44
|
-
createTaxonomySuccessAndFailedFile(): void;
|
|
45
|
-
/**
|
|
46
|
-
* create terms and enter success & failure related data into terms mapper file
|
|
47
|
-
* @method importTerms
|
|
48
|
-
* @async
|
|
49
|
-
* @returns {Promise<any>} Promise<any>
|
|
50
|
-
*/
|
|
51
|
-
importTerms(): Promise<any>;
|
|
52
|
-
/**
|
|
53
|
-
* @method serializeTerms
|
|
54
|
-
* @param {ApiOptions} apiOptions ApiOptions
|
|
55
|
-
* @returns {ApiOptions} ApiOptions
|
|
56
|
-
*/
|
|
57
|
-
serializeTerms(apiOptions: ApiOptions): ApiOptions;
|
|
58
|
-
/**
|
|
59
38
|
* create terms success and fail in (mapper/taxonomies/terms)
|
|
60
|
-
* @method
|
|
39
|
+
* @method createSuccessAndFailedFile
|
|
61
40
|
*/
|
|
62
|
-
|
|
41
|
+
createSuccessAndFailedFile(): void;
|
|
63
42
|
}
|
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
const tslib_1 = require("tslib");
|
|
4
|
-
const keys_1 = tslib_1.__importDefault(require("lodash/keys"));
|
|
5
|
-
const pick_1 = tslib_1.__importDefault(require("lodash/pick"));
|
|
6
4
|
const node_path_1 = require("node:path");
|
|
7
5
|
const values_1 = tslib_1.__importDefault(require("lodash/values"));
|
|
8
6
|
const isEmpty_1 = tslib_1.__importDefault(require("lodash/isEmpty"));
|
|
@@ -11,18 +9,14 @@ const utils_1 = require("../../utils");
|
|
|
11
9
|
class ImportTaxonomies extends base_class_1.default {
|
|
12
10
|
constructor({ importConfig, stackAPIClient }) {
|
|
13
11
|
super({ importConfig, stackAPIClient });
|
|
14
|
-
this.
|
|
15
|
-
this.
|
|
16
|
-
this.
|
|
17
|
-
this.
|
|
18
|
-
this.terms = [];
|
|
19
|
-
this.taxonomyUIDs = [];
|
|
12
|
+
this.createdTaxonomies = {};
|
|
13
|
+
this.failedTaxonomies = {};
|
|
14
|
+
this.createdTerms = {};
|
|
15
|
+
this.failedTerms = {};
|
|
20
16
|
this.taxonomiesConfig = importConfig.modules.taxonomies;
|
|
21
|
-
this.termsConfig = importConfig.modules.terms;
|
|
22
17
|
this.taxonomiesMapperDirPath = (0, node_path_1.join)(importConfig.backupDir, 'mapper', 'taxonomies');
|
|
23
18
|
this.termsMapperDirPath = (0, node_path_1.join)(this.taxonomiesMapperDirPath, 'terms');
|
|
24
19
|
this.taxonomiesFolderPath = (0, node_path_1.join)(importConfig.backupDir, this.taxonomiesConfig.dirName);
|
|
25
|
-
this.termsFolderPath = (0, node_path_1.join)(this.taxonomiesFolderPath, this.termsConfig.dirName);
|
|
26
20
|
this.taxSuccessPath = (0, node_path_1.join)(this.taxonomiesMapperDirPath, 'success.json');
|
|
27
21
|
this.taxFailsPath = (0, node_path_1.join)(this.taxonomiesMapperDirPath, 'fails.json');
|
|
28
22
|
this.termsSuccessPath = (0, node_path_1.join)(this.termsMapperDirPath, 'success.json');
|
|
@@ -45,16 +39,10 @@ class ImportTaxonomies extends base_class_1.default {
|
|
|
45
39
|
//Step 2 create taxonomies & terms mapper directory
|
|
46
40
|
await utils_1.fsUtil.makeDirectory(this.taxonomiesMapperDirPath);
|
|
47
41
|
await utils_1.fsUtil.makeDirectory(this.termsMapperDirPath);
|
|
48
|
-
//Step 3 import
|
|
42
|
+
// Step 3 import taxonomies
|
|
49
43
|
await this.importTaxonomies();
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
(0, utils_1.log)(this.importConfig, `No such file or directory - '${this.termsFolderPath}'`, 'error');
|
|
53
|
-
return;
|
|
54
|
-
}
|
|
55
|
-
//Step 4 import terms and create success & failure file
|
|
56
|
-
await this.importTerms();
|
|
57
|
-
this.createTermSuccessAndFailedFile();
|
|
44
|
+
//Step 4 create taxonomy & related terms success & failure file
|
|
45
|
+
this.createSuccessAndFailedFile();
|
|
58
46
|
(0, utils_1.log)(this.importConfig, 'Taxonomies imported successfully!', 'success');
|
|
59
47
|
}
|
|
60
48
|
/**
|
|
@@ -69,24 +57,25 @@ class ImportTaxonomies extends base_class_1.default {
|
|
|
69
57
|
return;
|
|
70
58
|
}
|
|
71
59
|
const apiContent = (0, values_1.default)(this.taxonomies);
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
const
|
|
75
|
-
this.
|
|
76
|
-
|
|
60
|
+
const onSuccess = ({ apiData }) => {
|
|
61
|
+
var _a;
|
|
62
|
+
const taxonomyUID = (_a = apiData === null || apiData === void 0 ? void 0 : apiData.taxonomy) === null || _a === void 0 ? void 0 : _a.uid;
|
|
63
|
+
this.createdTaxonomies[taxonomyUID] = apiData === null || apiData === void 0 ? void 0 : apiData.taxonomy;
|
|
64
|
+
this.createdTerms[taxonomyUID] = apiData === null || apiData === void 0 ? void 0 : apiData.terms;
|
|
65
|
+
(0, utils_1.log)(this.importConfig, `Taxonomy '${taxonomyUID}' imported successfully!`, 'success');
|
|
77
66
|
};
|
|
78
67
|
const onReject = ({ error, apiData }) => {
|
|
79
|
-
var _a;
|
|
80
|
-
const
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
this.
|
|
84
|
-
(0, utils_1.log)(this.importConfig, `Taxonomy '${uid}' failed to be import! ${err.errors.taxonomy}`, 'error');
|
|
68
|
+
var _a, _b, _c;
|
|
69
|
+
const taxonomyUID = (_a = apiData === null || apiData === void 0 ? void 0 : apiData.taxonomy) === null || _a === void 0 ? void 0 : _a.uid;
|
|
70
|
+
if ((error === null || error === void 0 ? void 0 : error.errorMessage) || (error === null || error === void 0 ? void 0 : error.message)) {
|
|
71
|
+
const errorMsg = (error === null || error === void 0 ? void 0 : error.errorMessage) || ((_b = error === null || error === void 0 ? void 0 : error.errors) === null || _b === void 0 ? void 0 : _b.taxonomy) || ((_c = error === null || error === void 0 ? void 0 : error.errors) === null || _c === void 0 ? void 0 : _c.term) || (error === null || error === void 0 ? void 0 : error.message);
|
|
72
|
+
(0, utils_1.log)(this.importConfig, `Taxonomy '${taxonomyUID}' failed to be import! ${errorMsg}`, 'error');
|
|
85
73
|
}
|
|
86
74
|
else {
|
|
87
|
-
this.
|
|
88
|
-
(0, utils_1.log)(this.importConfig, `Taxonomy '${uid}' failed to be import! ${(0, utils_1.formatError)(error)}`, 'error');
|
|
75
|
+
(0, utils_1.log)(this.importConfig, `Taxonomy '${taxonomyUID}' failed to be import! ${(0, utils_1.formatError)(error)}`, 'error');
|
|
89
76
|
}
|
|
77
|
+
this.failedTaxonomies[taxonomyUID] = apiData === null || apiData === void 0 ? void 0 : apiData.taxonomy;
|
|
78
|
+
this.failedTerms[taxonomyUID] = apiData === null || apiData === void 0 ? void 0 : apiData.terms;
|
|
90
79
|
};
|
|
91
80
|
await this.makeConcurrentCall({
|
|
92
81
|
apiContent,
|
|
@@ -95,7 +84,7 @@ class ImportTaxonomies extends base_class_1.default {
|
|
|
95
84
|
serializeData: this.serializeTaxonomy.bind(this),
|
|
96
85
|
reject: onReject,
|
|
97
86
|
resolve: onSuccess,
|
|
98
|
-
entity: '
|
|
87
|
+
entity: 'import-taxonomy',
|
|
99
88
|
includeParamOnCompletion: true,
|
|
100
89
|
},
|
|
101
90
|
concurrencyLimit: this.importConfig.concurrency || this.importConfig.fetchConcurrency || 1,
|
|
@@ -107,110 +96,35 @@ class ImportTaxonomies extends base_class_1.default {
|
|
|
107
96
|
* @returns {ApiOptions} ApiOptions
|
|
108
97
|
*/
|
|
109
98
|
serializeTaxonomy(apiOptions) {
|
|
110
|
-
const { apiData
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
* create taxonomies success and fail in (mapper/taxonomies)
|
|
116
|
-
* @method createTaxonomySuccessAndFailedFile
|
|
117
|
-
*/
|
|
118
|
-
createTaxonomySuccessAndFailedFile() {
|
|
119
|
-
if (this.taxonomiesSuccess !== undefined && !(0, isEmpty_1.default)(this.taxonomiesSuccess)) {
|
|
120
|
-
utils_1.fsUtil.writeFile(this.taxSuccessPath, this.taxonomiesSuccess);
|
|
121
|
-
}
|
|
122
|
-
if (this.taxonomiesFailed !== undefined && !(0, isEmpty_1.default)(this.taxonomiesFailed)) {
|
|
123
|
-
utils_1.fsUtil.writeFile(this.taxFailsPath, this.taxonomiesFailed);
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
/**
|
|
127
|
-
* create terms and enter success & failure related data into terms mapper file
|
|
128
|
-
* @method importTerms
|
|
129
|
-
* @async
|
|
130
|
-
* @returns {Promise<any>} Promise<any>
|
|
131
|
-
*/
|
|
132
|
-
async importTerms() {
|
|
133
|
-
var _a, _b;
|
|
134
|
-
if (!((_a = this.taxonomyUIDs) === null || _a === void 0 ? void 0 : _a.length)) {
|
|
135
|
-
return;
|
|
136
|
-
}
|
|
137
|
-
const onSuccess = ({ response, apiData: { taxonomy_uid } = { taxonomy_uid: null } }) => {
|
|
138
|
-
var _a;
|
|
139
|
-
const { uid } = response;
|
|
140
|
-
if (!((_a = this.termsSuccess) === null || _a === void 0 ? void 0 : _a[taxonomy_uid]))
|
|
141
|
-
this.termsSuccess[taxonomy_uid] = {};
|
|
142
|
-
this.termsSuccess[taxonomy_uid][uid] = (0, pick_1.default)(response, ['name']);
|
|
143
|
-
(0, utils_1.log)(this.importConfig, `Term '${uid}' imported successfully!`, 'success');
|
|
144
|
-
};
|
|
145
|
-
const onReject = ({ error, apiData }) => {
|
|
146
|
-
var _a, _b;
|
|
147
|
-
const { taxonomy_uid, uid } = apiData;
|
|
148
|
-
if (!((_a = this.termsFailed) === null || _a === void 0 ? void 0 : _a[taxonomy_uid]))
|
|
149
|
-
this.termsFailed[taxonomy_uid] = {};
|
|
150
|
-
const err = (error === null || error === void 0 ? void 0 : error.message) ? JSON.parse(error.message) : error;
|
|
151
|
-
if ((_b = err === null || err === void 0 ? void 0 : err.errors) === null || _b === void 0 ? void 0 : _b.term) {
|
|
152
|
-
this.termsFailed[taxonomy_uid][uid] = apiData;
|
|
153
|
-
(0, utils_1.log)(this.importConfig, `Term '${uid}' failed to be import! ${err.errors.term}`, 'error');
|
|
154
|
-
}
|
|
155
|
-
else {
|
|
156
|
-
this.termsFailed[taxonomy_uid][uid] = apiData;
|
|
157
|
-
(0, utils_1.log)(this.importConfig, `Term '${uid}' failed to be import! ${(0, utils_1.formatError)(error)}`, 'error');
|
|
158
|
-
}
|
|
159
|
-
};
|
|
160
|
-
for (const taxUID of this.taxonomyUIDs) {
|
|
161
|
-
//read terms from respective taxonomy
|
|
162
|
-
this.terms = utils_1.fsUtil.readFile((0, node_path_1.join)(this.termsFolderPath, `${taxUID}-${this.termsConfig.fileName}`), true);
|
|
163
|
-
if ((_b = this.terms) === null || _b === void 0 ? void 0 : _b.length) {
|
|
164
|
-
const apiContent = this.terms;
|
|
165
|
-
await this.makeConcurrentCall({
|
|
166
|
-
apiContent,
|
|
167
|
-
processName: 'import terms',
|
|
168
|
-
apiParams: {
|
|
169
|
-
serializeData: this.serializeTerms.bind(this),
|
|
170
|
-
reject: onReject,
|
|
171
|
-
resolve: onSuccess,
|
|
172
|
-
entity: 'create-terms',
|
|
173
|
-
includeParamOnCompletion: true,
|
|
174
|
-
},
|
|
175
|
-
concurrencyLimit: this.importConfig.concurrency || this.importConfig.fetchConcurrency || 1,
|
|
176
|
-
}, undefined, false);
|
|
177
|
-
}
|
|
178
|
-
}
|
|
179
|
-
}
|
|
180
|
-
/**
|
|
181
|
-
* @method serializeTerms
|
|
182
|
-
* @param {ApiOptions} apiOptions ApiOptions
|
|
183
|
-
* @returns {ApiOptions} ApiOptions
|
|
184
|
-
*/
|
|
185
|
-
serializeTerms(apiOptions) {
|
|
186
|
-
var _a, _b;
|
|
187
|
-
const { apiData: term } = apiOptions;
|
|
188
|
-
const { parent_uid, taxonomy_uid } = term;
|
|
189
|
-
//check whether parent term exists or not in taxonomy
|
|
190
|
-
if (parent_uid !== null) {
|
|
191
|
-
if (!((_b = (_a = this.termsSuccess) === null || _a === void 0 ? void 0 : _a[taxonomy_uid]) === null || _b === void 0 ? void 0 : _b[parent_uid])) {
|
|
192
|
-
(0, utils_1.log)(this.importConfig, `Parent term '${term === null || term === void 0 ? void 0 : term.parent_uid}' does not exist! Skipping '${term.uid}' creation to avoid further issues.`, 'info');
|
|
193
|
-
apiOptions.apiData = undefined;
|
|
194
|
-
}
|
|
195
|
-
else {
|
|
196
|
-
apiOptions.apiData = term;
|
|
197
|
-
}
|
|
99
|
+
const { apiData } = apiOptions;
|
|
100
|
+
const filePath = (0, node_path_1.join)(this.taxonomiesFolderPath, `${apiData === null || apiData === void 0 ? void 0 : apiData.uid}.json`);
|
|
101
|
+
if (utils_1.fileHelper.fileExistsSync(filePath)) {
|
|
102
|
+
const taxonomyDetails = utils_1.fsUtil.readFile(filePath, true);
|
|
103
|
+
apiOptions.apiData = { filePath, taxonomy: taxonomyDetails === null || taxonomyDetails === void 0 ? void 0 : taxonomyDetails.taxonomy, terms: taxonomyDetails === null || taxonomyDetails === void 0 ? void 0 : taxonomyDetails.terms };
|
|
198
104
|
}
|
|
199
105
|
else {
|
|
200
|
-
|
|
106
|
+
(0, utils_1.log)(this.importConfig, `No such file - ${filePath}`, 'error');
|
|
107
|
+
apiOptions.apiData = undefined;
|
|
201
108
|
}
|
|
202
109
|
return apiOptions;
|
|
203
110
|
}
|
|
204
111
|
/**
|
|
112
|
+
* create taxonomies success and fail in (mapper/taxonomies)
|
|
205
113
|
* create terms success and fail in (mapper/taxonomies/terms)
|
|
206
|
-
* @method
|
|
114
|
+
* @method createSuccessAndFailedFile
|
|
207
115
|
*/
|
|
208
|
-
|
|
209
|
-
if (this.
|
|
210
|
-
utils_1.fsUtil.writeFile(this.
|
|
116
|
+
createSuccessAndFailedFile() {
|
|
117
|
+
if (this.createdTaxonomies !== undefined && !(0, isEmpty_1.default)(this.createdTaxonomies)) {
|
|
118
|
+
utils_1.fsUtil.writeFile(this.taxSuccessPath, this.createdTaxonomies);
|
|
119
|
+
}
|
|
120
|
+
if (this.failedTaxonomies !== undefined && !(0, isEmpty_1.default)(this.failedTaxonomies)) {
|
|
121
|
+
utils_1.fsUtil.writeFile(this.taxFailsPath, this.failedTaxonomies);
|
|
122
|
+
}
|
|
123
|
+
if (this.createdTerms !== undefined && !(0, isEmpty_1.default)(this.createdTerms)) {
|
|
124
|
+
utils_1.fsUtil.writeFile(this.termsSuccessPath, this.createdTerms);
|
|
211
125
|
}
|
|
212
|
-
if (this.
|
|
213
|
-
utils_1.fsUtil.writeFile(this.termsFailsPath, this.
|
|
126
|
+
if (this.failedTerms !== undefined && !(0, isEmpty_1.default)(this.failedTerms)) {
|
|
127
|
+
utils_1.fsUtil.writeFile(this.termsFailsPath, this.failedTerms);
|
|
214
128
|
}
|
|
215
129
|
}
|
|
216
130
|
}
|
package/lib/types/index.d.ts
CHANGED
|
@@ -65,12 +65,12 @@ export interface TaxonomiesConfig {
|
|
|
65
65
|
fileName: string;
|
|
66
66
|
dependencies?: Modules[];
|
|
67
67
|
}
|
|
68
|
-
export interface TermsConfig {
|
|
69
|
-
dirName: string;
|
|
70
|
-
fileName: string;
|
|
71
|
-
dependencies?: Modules[];
|
|
72
|
-
}
|
|
73
68
|
export { default as DefaultConfig } from './default-config';
|
|
74
69
|
export { default as ImportConfig } from './import-config';
|
|
75
70
|
export * from './entries';
|
|
76
71
|
export * from './marketplace-app';
|
|
72
|
+
export type ExtensionType = {
|
|
73
|
+
uid: string;
|
|
74
|
+
scope: Record<string, unknown>;
|
|
75
|
+
title: string;
|
|
76
|
+
};
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
export declare const askContentDir: () => Promise<string>;
|
|
2
2
|
export declare const askAPIKey: () => Promise<string>;
|
|
3
|
-
export declare const askDeveloperHubUrl: (regionName: string) => Promise<string>;
|
|
4
3
|
export declare const askEncryptionKey: (defaultValue: unknown) => Promise<string>;
|
|
5
4
|
export declare const askAppName: (app: any, appSuffix: number) => Promise<string>;
|
|
6
5
|
export declare const getAppName: (name: string, appSuffix?: number) => string;
|
package/lib/utils/interactive.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.selectConfiguration = exports.getAppName = exports.askAppName = exports.askEncryptionKey = exports.
|
|
3
|
+
exports.selectConfiguration = exports.getAppName = exports.askAppName = exports.askEncryptionKey = exports.askAPIKey = exports.askContentDir = void 0;
|
|
4
4
|
const tslib_1 = require("tslib");
|
|
5
5
|
const cli_utilities_1 = require("@contentstack/cli-utilities");
|
|
6
6
|
const path = tslib_1.__importStar(require("path"));
|
|
@@ -23,19 +23,6 @@ const askAPIKey = async () => {
|
|
|
23
23
|
});
|
|
24
24
|
};
|
|
25
25
|
exports.askAPIKey = askAPIKey;
|
|
26
|
-
const askDeveloperHubUrl = async (regionName) => {
|
|
27
|
-
return await cli_utilities_1.cliux.inquire({
|
|
28
|
-
type: 'input',
|
|
29
|
-
name: 'name',
|
|
30
|
-
validate: (url) => {
|
|
31
|
-
if (!url)
|
|
32
|
-
return "Developer-hub URL can't be empty.";
|
|
33
|
-
return true;
|
|
34
|
-
},
|
|
35
|
-
message: `Enter the developer-hub base URL for the ${regionName} region -`,
|
|
36
|
-
});
|
|
37
|
-
};
|
|
38
|
-
exports.askDeveloperHubUrl = askDeveloperHubUrl;
|
|
39
26
|
const askEncryptionKey = async (defaultValue) => {
|
|
40
27
|
return await cli_utilities_1.cliux.inquire({
|
|
41
28
|
type: 'input',
|
|
@@ -11,8 +11,7 @@ const cli_utilities_1 = require("@contentstack/cli-utilities");
|
|
|
11
11
|
const logger_1 = require("./logger");
|
|
12
12
|
const log_1 = require("../utils/log");
|
|
13
13
|
const utils_1 = require("../utils");
|
|
14
|
-
const interactive_1 = require("
|
|
15
|
-
const interactive_2 = require("../utils/interactive");
|
|
14
|
+
const interactive_1 = require("../utils/interactive");
|
|
16
15
|
const getAllStackSpecificApps = async (config, skip = 0, listOfApps = []) => {
|
|
17
16
|
const appSdk = await (0, cli_utilities_1.marketplaceSDKClient)({
|
|
18
17
|
host: config.developerHubBaseUrl.split('://').pop(),
|
|
@@ -42,12 +41,7 @@ const getAllStackSpecificApps = async (config, skip = 0, listOfApps = []) => {
|
|
|
42
41
|
};
|
|
43
42
|
exports.getAllStackSpecificApps = getAllStackSpecificApps;
|
|
44
43
|
const getDeveloperHubUrl = async (config) => {
|
|
45
|
-
|
|
46
|
-
let developerHubBaseUrl = config.developerHubUrls[cma];
|
|
47
|
-
if (!developerHubBaseUrl) {
|
|
48
|
-
developerHubBaseUrl = await (0, interactive_1.askDeveloperHubUrl)(name);
|
|
49
|
-
}
|
|
50
|
-
return developerHubBaseUrl.startsWith('http') ? developerHubBaseUrl : `https://${developerHubBaseUrl}`;
|
|
44
|
+
return (0, cli_utilities_1.createDeveloperHubUrl)(config.host);
|
|
51
45
|
};
|
|
52
46
|
exports.getDeveloperHubUrl = getDeveloperHubUrl;
|
|
53
47
|
const getOrgUid = async (config) => {
|
|
@@ -77,8 +71,8 @@ const getConfirmationToCreateApps = async (privateApps, config) => {
|
|
|
77
71
|
exports.getConfirmationToCreateApps = getConfirmationToCreateApps;
|
|
78
72
|
const handleNameConflict = async (app, appSuffix, config) => {
|
|
79
73
|
const appName = config.forceStopMarketplaceAppsPrompt
|
|
80
|
-
? (0,
|
|
81
|
-
: await (0,
|
|
74
|
+
? (0, interactive_1.getAppName)(app.name, appSuffix)
|
|
75
|
+
: await (0, interactive_1.askAppName)(app, appSuffix);
|
|
82
76
|
app.name = appName;
|
|
83
77
|
return app;
|
|
84
78
|
};
|
|
@@ -124,7 +118,7 @@ const ifAppAlreadyExist = async (app, currentStackApp, config) => {
|
|
|
124
118
|
cli_utilities_1.cliux.print(`\nWARNING!!! The ${name} app already exists and it may have its own configuration. But the current app you install has its own configuration which is used internally to manage content.\n`, { color: 'yellow' });
|
|
125
119
|
const configOption = config.forceStopMarketplaceAppsPrompt
|
|
126
120
|
? 'Update it with the new configuration.'
|
|
127
|
-
: await (0,
|
|
121
|
+
: await (0, interactive_1.selectConfiguration)();
|
|
128
122
|
if (configOption === 'Exit') {
|
|
129
123
|
process.exit();
|
|
130
124
|
}
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.lookUpTerms = exports.lookUpTaxonomy = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
4
5
|
/**
|
|
5
6
|
* taxonomy lookup
|
|
6
7
|
*/
|
|
8
|
+
const find_1 = tslib_1.__importDefault(require("lodash/find"));
|
|
7
9
|
const _1 = require("./");
|
|
8
10
|
/**
|
|
9
11
|
* check and remove if referenced taxonomy doesn't exists in stack
|
|
@@ -66,7 +68,13 @@ const lookUpTerms = function (ctSchema, entry, taxonomiesAndTermData, importConf
|
|
|
66
68
|
if (ctSchema[index].data_type === 'taxonomy') {
|
|
67
69
|
const taxonomyFieldData = entry[ctSchema[index].uid];
|
|
68
70
|
const updatedTaxonomyData = verifyAndRemoveTerms(taxonomyFieldData, taxonomiesAndTermData, importConfig);
|
|
69
|
-
|
|
71
|
+
if (updatedTaxonomyData === null || updatedTaxonomyData === void 0 ? void 0 : updatedTaxonomyData.length) {
|
|
72
|
+
entry[ctSchema[index].uid] = updatedTaxonomyData;
|
|
73
|
+
}
|
|
74
|
+
else {
|
|
75
|
+
//Delete taxonomy from entry if taxonomy field removed from CT
|
|
76
|
+
delete entry[ctSchema[index].uid];
|
|
77
|
+
}
|
|
70
78
|
}
|
|
71
79
|
}
|
|
72
80
|
};
|
|
@@ -85,7 +93,8 @@ const verifyAndRemoveTerms = function (taxonomyFieldData, taxonomiesAndTermData,
|
|
|
85
93
|
const termUID = taxonomyData === null || taxonomyData === void 0 ? void 0 : taxonomyData.term_uid;
|
|
86
94
|
if (taxonomiesAndTermData === undefined ||
|
|
87
95
|
!taxonomiesAndTermData.hasOwnProperty(taxUID) ||
|
|
88
|
-
(taxonomiesAndTermData.hasOwnProperty(taxUID) &&
|
|
96
|
+
(taxonomiesAndTermData.hasOwnProperty(taxUID) &&
|
|
97
|
+
!(0, find_1.default)(taxonomiesAndTermData[taxUID], (term) => (term === null || term === void 0 ? void 0 : term.uid) === termUID))) {
|
|
89
98
|
// remove term from taxonomies field data with warning if respective term doesn't exists
|
|
90
99
|
(0, _1.log)(importConfig, `Term '${termUID}' does not exist. Removing it from taxonomy - '${taxUID}'`, 'warn');
|
|
91
100
|
taxonomyFieldData.splice(index, 1);
|
package/oclif.manifest.json
CHANGED
package/package.json
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@contentstack/cli-cm-import",
|
|
3
3
|
"description": "Contentstack CLI plugin to import content into stack",
|
|
4
|
-
"version": "1.
|
|
4
|
+
"version": "1.14.0",
|
|
5
5
|
"author": "Contentstack",
|
|
6
6
|
"bugs": "https://github.com/contentstack/cli/issues",
|
|
7
7
|
"dependencies": {
|
|
8
|
-
"@contentstack/cli-audit": "
|
|
8
|
+
"@contentstack/cli-audit": "~1.4.0",
|
|
9
9
|
"@contentstack/cli-command": "~1.2.16",
|
|
10
|
-
"@contentstack/cli-utilities": "~1.5.
|
|
11
|
-
"@contentstack/management": "~1.
|
|
10
|
+
"@contentstack/cli-utilities": "~1.5.12",
|
|
11
|
+
"@contentstack/management": "~1.15.3",
|
|
12
12
|
"@oclif/core": "^2.9.3",
|
|
13
13
|
"big-json": "^3.2.0",
|
|
14
14
|
"bluebird": "^3.7.2",
|
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
"winston": "^3.7.2"
|
|
26
26
|
},
|
|
27
27
|
"devDependencies": {
|
|
28
|
-
"@oclif/test": "^
|
|
28
|
+
"@oclif/test": "^2.5.6",
|
|
29
29
|
"@types/big-json": "^3.2.0",
|
|
30
30
|
"@types/bluebird": "^3.5.38",
|
|
31
31
|
"@types/chai": "^4.2.18",
|
|
@@ -46,7 +46,7 @@
|
|
|
46
46
|
"oclif": "^3.8.1",
|
|
47
47
|
"rimraf": "^2.7.1",
|
|
48
48
|
"sinon": "^11.1.1",
|
|
49
|
-
"tmp": "^0.2.
|
|
49
|
+
"tmp": "^0.2.2",
|
|
50
50
|
"ts-node": "^10.9.1",
|
|
51
51
|
"typescript": "^4.9.3"
|
|
52
52
|
},
|