@contentstack/cli-cm-import 1.11.1 → 1.12.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 +0 -1
- package/lib/import/module-importer.js +2 -11
- package/lib/import/modules/assets.d.ts +1 -0
- package/lib/import/modules/assets.js +33 -4
- package/lib/import/modules/entries.js +2 -3
- package/lib/utils/common-helper.d.ts +1 -0
- package/lib/utils/common-helper.js +16 -1
- package/lib/utils/import-config-handler.js +0 -3
- package/oclif.manifest.json +2 -5
- package/package.json +4 -2
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.12.0 linux-x64 node-v18.18.2
|
|
51
51
|
$ csdx --help [COMMAND]
|
|
52
52
|
USAGE
|
|
53
53
|
$ csdx COMMAND
|
|
@@ -113,7 +113,6 @@ ImportCommand.flags = {
|
|
|
113
113
|
'replace-existing': cli_utilities_1.flags.boolean({
|
|
114
114
|
required: false,
|
|
115
115
|
description: 'Replaces the existing module in the target stack.',
|
|
116
|
-
dependsOn: ['module'],
|
|
117
116
|
}),
|
|
118
117
|
'skip-existing': cli_utilities_1.flags.boolean({
|
|
119
118
|
required: false,
|
|
@@ -20,17 +20,8 @@ class ModuleImporter {
|
|
|
20
20
|
}
|
|
21
21
|
// Temporarily adding this api call to verify management token has read and write permissions
|
|
22
22
|
// TODO: CS-40354 - CLI | import rewrite | Migrate HTTP call to SDK call once fix is ready from SDK side
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
});
|
|
26
|
-
const { data } = await httpClient.post(`https://${this.importConfig.host}/v3/locales`, {
|
|
27
|
-
locale: {
|
|
28
|
-
name: 'English',
|
|
29
|
-
code: 'en-us',
|
|
30
|
-
},
|
|
31
|
-
});
|
|
32
|
-
if (data.error_code === 161) {
|
|
33
|
-
throw new Error(data.error_message);
|
|
23
|
+
if (this.importConfig.management_token) {
|
|
24
|
+
await (0, cli_utilities_1.addLocale)(this.importConfig.apiKey, this.importConfig.management_token, this.importConfig.host);
|
|
34
25
|
}
|
|
35
26
|
if (!this.importConfig.master_locale) {
|
|
36
27
|
let masterLocalResponse = await (0, utils_1.masterLocalDetails)(this.stackAPIClient);
|
|
@@ -10,6 +10,7 @@ const isEmpty_1 = tslib_1.__importDefault(require("lodash/isEmpty"));
|
|
|
10
10
|
const uniq_1 = tslib_1.__importDefault(require("lodash/uniq"));
|
|
11
11
|
const node_fs_1 = require("node:fs");
|
|
12
12
|
const includes_1 = tslib_1.__importDefault(require("lodash/includes"));
|
|
13
|
+
const uuid_1 = require("uuid");
|
|
13
14
|
const node_path_1 = require("node:path");
|
|
14
15
|
const cli_utilities_1 = require("@contentstack/cli-utilities");
|
|
15
16
|
const config_1 = tslib_1.__importDefault(require("../../config"));
|
|
@@ -184,6 +185,10 @@ class ImportAssets extends base_class_1.default {
|
|
|
184
185
|
if (asset.parent_uid) {
|
|
185
186
|
asset.parent_uid = this.assetsFolderMap[asset.parent_uid];
|
|
186
187
|
}
|
|
188
|
+
else if (this.importConfig.replaceExisting) {
|
|
189
|
+
// adds the root folder as parent for all assets in the root level
|
|
190
|
+
asset.parent_uid = this.assetsFolderMap[this.rootFolder.uid];
|
|
191
|
+
}
|
|
187
192
|
apiOptions.apiData = asset;
|
|
188
193
|
if (this.assetsUidMap[asset.uid] && this.assetConfig.importSameStructure) {
|
|
189
194
|
apiOptions.entity = 'replace-assets';
|
|
@@ -249,19 +254,43 @@ class ImportAssets extends base_class_1.default {
|
|
|
249
254
|
* @returns {Array<Record<string, any>>} Array<Record<string, any>>
|
|
250
255
|
*/
|
|
251
256
|
constructFolderImportOrder(folders) {
|
|
252
|
-
let
|
|
257
|
+
let parentUIds = [];
|
|
253
258
|
// NOTE: Read root folder
|
|
254
259
|
const importOrder = (0, filter_1.default)(folders, { parent_uid: null }).map(({ uid, name, parent_uid, created_at }) => {
|
|
255
|
-
|
|
260
|
+
parentUIds.push(uid);
|
|
256
261
|
return { uid, name, parent_uid, created_at };
|
|
257
262
|
});
|
|
258
|
-
while (!(0, isEmpty_1.default)(
|
|
263
|
+
while (!(0, isEmpty_1.default)(parentUIds)) {
|
|
259
264
|
// NOTE: Read nested folders every iteration until we find empty folders
|
|
260
|
-
|
|
265
|
+
parentUIds = (0, filter_1.default)(folders, ({ parent_uid }) => (0, includes_1.default)(parentUIds, parent_uid)).map(({ uid, name, parent_uid, created_at }) => {
|
|
261
266
|
importOrder.push({ uid, name, parent_uid, created_at });
|
|
262
267
|
return uid;
|
|
263
268
|
});
|
|
264
269
|
}
|
|
270
|
+
if (this.importConfig.replaceExisting) {
|
|
271
|
+
// Note: adds a root folder to distinguish latest asset uploads
|
|
272
|
+
// Todo: This temporary approach should be updated with asset and folder overwrite strategy, which follows
|
|
273
|
+
// folder overwrite
|
|
274
|
+
// 1. Create folder trees, 2. Export all target stack folders, 3.Match the source to target folders and create a list of existing folders
|
|
275
|
+
// 4. Replace existing folders
|
|
276
|
+
// Asset overwrite
|
|
277
|
+
// 1. Search asset with title + filename + type
|
|
278
|
+
// 2. if there are multiple assets fetched with same query, then check the parent uid against mapper created while importing folders
|
|
279
|
+
// 3. Replace matched assets
|
|
280
|
+
this.rootFolder = {
|
|
281
|
+
uid: (0, uuid_1.v4)(),
|
|
282
|
+
name: `Import-${(0, utils_1.formatDate)()}`,
|
|
283
|
+
parent_uid: null,
|
|
284
|
+
created_at: null,
|
|
285
|
+
};
|
|
286
|
+
(0, filter_1.default)(importOrder, (folder, index) => {
|
|
287
|
+
if (!folder.parent_uid) {
|
|
288
|
+
importOrder.splice(index, 1, Object.assign(Object.assign({}, folder), { parent_uid: this.rootFolder.uid }));
|
|
289
|
+
}
|
|
290
|
+
});
|
|
291
|
+
// NOTE: Adds root folder
|
|
292
|
+
importOrder.unshift(this.rootFolder);
|
|
293
|
+
}
|
|
265
294
|
return importOrder;
|
|
266
295
|
}
|
|
267
296
|
}
|
|
@@ -58,7 +58,7 @@ class EntriesImport extends base_class_1.default {
|
|
|
58
58
|
for (let entryRequestOption of entryRequestOptions) {
|
|
59
59
|
await this.createEntries(entryRequestOption);
|
|
60
60
|
}
|
|
61
|
-
if (this.importConfig.replaceExisting
|
|
61
|
+
if (this.importConfig.replaceExisting) {
|
|
62
62
|
// Note: Instead of using entryRequestOptions, we can prepare request options for replace, to avoid unnecessary operations
|
|
63
63
|
for (let entryRequestOption of entryRequestOptions) {
|
|
64
64
|
await this.replaceEntries(entryRequestOption).catch((error) => {
|
|
@@ -253,8 +253,7 @@ class EntriesImport extends base_class_1.default {
|
|
|
253
253
|
//Note: write existing entries into files to handler later
|
|
254
254
|
if (error.errorCode === 119) {
|
|
255
255
|
if (((_a = error === null || error === void 0 ? void 0 : error.errors) === null || _a === void 0 ? void 0 : _a.title) || ((_b = error === null || error === void 0 ? void 0 : error.errors) === null || _b === void 0 ? void 0 : _b.uid)) {
|
|
256
|
-
if (this.importConfig.replaceExisting
|
|
257
|
-
(0, lodash_1.indexOf)(this.importConfig.overwriteSupportedModules, 'entries') !== -1) {
|
|
256
|
+
if (this.importConfig.replaceExisting) {
|
|
258
257
|
entry.entryOldUid = uid;
|
|
259
258
|
entry.sourceEntryFilePath = path.join(basePath, additionalInfo.entryFileName); // stores source file path temporarily
|
|
260
259
|
existingEntriesFileHelper.writeIntoFile({ [uid]: entry }, { mapKeyVal: true });
|
|
@@ -18,3 +18,4 @@ export declare const executeTask: (tasks: unknown[], handler: (task: unknown) =>
|
|
|
18
18
|
concurrency: number;
|
|
19
19
|
}) => Promise<unknown[]>;
|
|
20
20
|
export declare const validateBranch: (stackAPIClient: any, config: ImportConfig, branch: any) => Promise<unknown>;
|
|
21
|
+
export declare const formatDate: (date?: Date) => string;
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* MIT Licensed
|
|
7
7
|
*/
|
|
8
8
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
-
exports.validateBranch = exports.executeTask = exports.formatError = exports.getConfig = exports.field_rules_update = exports.masterLocalDetails = exports.sanitizeStack = exports.buildAppConfig = exports.validateConfig = exports.initialization = void 0;
|
|
9
|
+
exports.formatDate = exports.validateBranch = exports.executeTask = exports.formatError = exports.getConfig = exports.field_rules_update = exports.masterLocalDetails = exports.sanitizeStack = exports.buildAppConfig = exports.validateConfig = exports.initialization = void 0;
|
|
10
10
|
const tslib_1 = require("tslib");
|
|
11
11
|
const _ = tslib_1.__importStar(require("lodash"));
|
|
12
12
|
const path = tslib_1.__importStar(require("path"));
|
|
@@ -231,3 +231,18 @@ const validateBranch = async (stackAPIClient, config, branch) => {
|
|
|
231
231
|
});
|
|
232
232
|
};
|
|
233
233
|
exports.validateBranch = validateBranch;
|
|
234
|
+
const formatDate = (date = new Date()) => {
|
|
235
|
+
// Format the date manually
|
|
236
|
+
const formattedDate = `${date.getFullYear()}-${(date.getMonth() + 1).toString().padStart(2, '0')}-${date
|
|
237
|
+
.getDate()
|
|
238
|
+
.toString()
|
|
239
|
+
.padStart(2, '0')}T${date.getHours().toString().padStart(2, '0')}-${date
|
|
240
|
+
.getMinutes()
|
|
241
|
+
.toString()
|
|
242
|
+
.padStart(2, '0')}-${date.getSeconds().toString().padStart(2, '0')}-${date
|
|
243
|
+
.getMilliseconds()
|
|
244
|
+
.toString()
|
|
245
|
+
.padStart(3, '0')}Z`;
|
|
246
|
+
return formattedDate;
|
|
247
|
+
};
|
|
248
|
+
exports.formatDate = formatDate;
|
|
@@ -77,9 +77,6 @@ const setupConfig = async (importCmdFlags) => {
|
|
|
77
77
|
config.target_stack = config.apiKey;
|
|
78
78
|
config.replaceExisting = importCmdFlags['replace-existing'];
|
|
79
79
|
config.skipExisting = importCmdFlags['skip-existing'];
|
|
80
|
-
if (config.replaceExisting && !(0, lodash_1.includes)(config.overwriteSupportedModules, config.moduleName)) {
|
|
81
|
-
throw new Error(`Failed to overwrite ${config.moduleName} module! Currently, with the import command, you can overwrite the following modules: ${config.overwriteSupportedModules.join(',')}`);
|
|
82
|
-
}
|
|
83
80
|
return config;
|
|
84
81
|
};
|
|
85
82
|
exports.default = setupConfig;
|
package/oclif.manifest.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "1.
|
|
2
|
+
"version": "1.12.0",
|
|
3
3
|
"commands": {
|
|
4
4
|
"cm:stacks:import": {
|
|
5
5
|
"id": "cm:stacks:import",
|
|
@@ -128,10 +128,7 @@
|
|
|
128
128
|
"type": "boolean",
|
|
129
129
|
"description": "Replaces the existing module in the target stack.",
|
|
130
130
|
"required": false,
|
|
131
|
-
"allowNo": false
|
|
132
|
-
"dependsOn": [
|
|
133
|
-
"module"
|
|
134
|
-
]
|
|
131
|
+
"allowNo": false
|
|
135
132
|
},
|
|
136
133
|
"skip-existing": {
|
|
137
134
|
"name": "skip-existing",
|
package/package.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
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.12.0",
|
|
5
5
|
"author": "Contentstack",
|
|
6
6
|
"bugs": "https://github.com/contentstack/cli/issues",
|
|
7
7
|
"dependencies": {
|
|
8
8
|
"@contentstack/cli-command": "~1.2.16",
|
|
9
|
-
"@contentstack/cli-utilities": "~1.5.
|
|
9
|
+
"@contentstack/cli-utilities": "~1.5.8",
|
|
10
10
|
"@contentstack/management": "~1.12.0",
|
|
11
11
|
"@oclif/core": "^2.9.3",
|
|
12
12
|
"axios": "^1.6.0",
|
|
@@ -21,6 +21,7 @@
|
|
|
21
21
|
"mkdirp": "^1.0.4",
|
|
22
22
|
"promise-limit": "^2.7.0",
|
|
23
23
|
"tslib": "^2.4.1",
|
|
24
|
+
"uuid": "^9.0.0",
|
|
24
25
|
"winston": "^3.7.2"
|
|
25
26
|
},
|
|
26
27
|
"devDependencies": {
|
|
@@ -34,6 +35,7 @@
|
|
|
34
35
|
"@types/node": "^14.14.32",
|
|
35
36
|
"@types/sinon": "^10.0.2",
|
|
36
37
|
"@types/tar": "^4.0.3",
|
|
38
|
+
"@types/uuid": "^9.0.7",
|
|
37
39
|
"@typescript-eslint/eslint-plugin": "^5.48.2",
|
|
38
40
|
"chai": "^4.2.0",
|
|
39
41
|
"eslint": "^8.18.0",
|