@contentstack/cli-cm-import-setup 1.7.2 → 2.0.0-beta.2
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/LICENSE +1 -1
- package/README.md +4 -49
- package/lib/commands/cm/stacks/import-setup.d.ts +1 -0
- package/lib/commands/cm/stacks/import-setup.js +28 -11
- package/lib/import/import-setup.d.ts +19 -5
- package/lib/import/import-setup.js +27 -16
- package/lib/import/modules/assets.js +48 -16
- package/lib/import/modules/base-setup.d.ts +20 -7
- package/lib/import/modules/base-setup.js +48 -15
- package/lib/import/modules/content-types.js +27 -5
- package/lib/import/modules/entries.js +11 -4
- package/lib/import/modules/extensions.d.ts +3 -6
- package/lib/import/modules/extensions.js +39 -23
- package/lib/import/modules/global-fields.js +27 -5
- package/lib/import/modules/marketplace-apps.d.ts +3 -5
- package/lib/import/modules/marketplace-apps.js +40 -18
- package/lib/import/modules/taxonomies.d.ts +5 -7
- package/lib/import/modules/taxonomies.js +103 -61
- package/lib/types/import-config.d.ts +1 -1
- package/lib/types/index.d.ts +8 -1
- package/lib/utils/common-helper.d.ts +8 -1
- package/lib/utils/common-helper.js +6 -4
- package/lib/utils/constants.d.ts +39 -0
- package/lib/utils/constants.js +114 -0
- package/lib/utils/file-helper.d.ts +1 -1
- package/lib/utils/file-helper.js +4 -4
- package/lib/utils/import-config-handler.js +3 -8
- package/lib/utils/index.d.ts +1 -0
- package/lib/utils/index.js +6 -1
- package/lib/utils/log.js +1 -1
- package/lib/utils/logger.d.ts +1 -1
- package/lib/utils/logger.js +11 -16
- package/lib/utils/login-handler.d.ts +11 -2
- package/lib/utils/login-handler.js +12 -8
- package/oclif.manifest.json +3 -8
- package/package.json +5 -3
package/LICENSE
CHANGED
package/README.md
CHANGED
|
@@ -47,7 +47,7 @@ $ npm install -g @contentstack/cli-cm-import-setup
|
|
|
47
47
|
$ csdx COMMAND
|
|
48
48
|
running command...
|
|
49
49
|
$ csdx (--version)
|
|
50
|
-
@contentstack/cli-cm-import-setup/
|
|
50
|
+
@contentstack/cli-cm-import-setup/2.0.0-beta.2 linux-x64 node-v22.21.1
|
|
51
51
|
$ csdx --help [COMMAND]
|
|
52
52
|
USAGE
|
|
53
53
|
$ csdx COMMAND
|
|
@@ -59,44 +59,6 @@ USAGE
|
|
|
59
59
|
|
|
60
60
|
<!-- commands -->
|
|
61
61
|
* [`csdx cm:stacks:import-setup [-k <value>] [-d <value>] [-a <value>] [--modules <value,value>]`](#csdx-cmstacksimport-setup--k-value--d-value--a-value---modules-valuevalue)
|
|
62
|
-
* [`csdx cm:stacks:import-setup [-k <value>] [-d <value>] [-a <value>] [--modules <value,value>]`](#csdx-cmstacksimport-setup--k-value--d-value--a-value---modules-valuevalue)
|
|
63
|
-
|
|
64
|
-
## `csdx cm:stacks:import-setup [-k <value>] [-d <value>] [-a <value>] [--modules <value,value>]`
|
|
65
|
-
|
|
66
|
-
Helps to generate mappers and backup folder for importing (overwriting) specific modules
|
|
67
|
-
|
|
68
|
-
```
|
|
69
|
-
USAGE
|
|
70
|
-
$ csdx cm:import-setup cm:stacks:import-setup [-k <value>] [-d <value>] [-a <value>] [--modules <value,value>]
|
|
71
|
-
|
|
72
|
-
FLAGS
|
|
73
|
-
-B, --branch=<value> The name of the branch where you want to import your content. If you don't mention the
|
|
74
|
-
branch name, then by default the content will be imported to the main branch.
|
|
75
|
-
-a, --alias=<value> The management token of the destination stack where you will import the content.
|
|
76
|
-
-d, --data-dir=<value> The path or the location in your file system where the content, you intend to import, is
|
|
77
|
-
stored. For example, -d "C:\Users\Name\Desktop\cli\content". If the export folder has
|
|
78
|
-
branches involved, then the path should point till the particular branch. For example,
|
|
79
|
-
“-d "C:\Users\Name\Desktop\cli\content\branch_name"
|
|
80
|
-
-k, --stack-api-key=<value> API key of the target stack
|
|
81
|
-
--branch-alias=<value> Specify the branch alias where you want to import your content. If not specified, the
|
|
82
|
-
content is imported into the main branch by default.
|
|
83
|
-
--module=<option>... [optional] Specify the modules/module to import into the target stack. currently options
|
|
84
|
-
are global-fields, content-types, entries
|
|
85
|
-
<options: global-fields|content-types|entries>
|
|
86
|
-
|
|
87
|
-
DESCRIPTION
|
|
88
|
-
Helps to generate mappers and backup folder for importing (overwriting) specific modules
|
|
89
|
-
|
|
90
|
-
ALIASES
|
|
91
|
-
$ csdx cm:import-setup
|
|
92
|
-
|
|
93
|
-
EXAMPLES
|
|
94
|
-
$ csdx cm:stacks:import-setup --stack-api-key <target_stack_api_key> --data-dir <path/of/export/destination/dir> --modules <module_name, module_name>
|
|
95
|
-
|
|
96
|
-
$ csdx cm:stacks:import-setup -k <target_stack_api_key> -d <path/of/export/destination/dir> --modules <module_name, module_name>
|
|
97
|
-
|
|
98
|
-
$ csdx cm:stacks:import-setup -k <target_stack_api_key> -d <path/of/export/destination/dir> --modules <module_name, module_name> -b <branch_name>
|
|
99
|
-
```
|
|
100
62
|
|
|
101
63
|
## `csdx cm:stacks:import-setup [-k <value>] [-d <value>] [-a <value>] [--modules <value,value>]`
|
|
102
64
|
|
|
@@ -107,14 +69,14 @@ USAGE
|
|
|
107
69
|
$ csdx cm:stacks:import-setup [-k <value>] [-d <value>] [-a <value>] [--modules <value,value>]
|
|
108
70
|
|
|
109
71
|
FLAGS
|
|
110
|
-
-B, --branch=<value> The name of the branch where you want to import your content. If you don't mention the
|
|
111
|
-
branch name, then by default the content will be imported to the main branch.
|
|
112
72
|
-a, --alias=<value> The management token of the destination stack where you will import the content.
|
|
113
73
|
-d, --data-dir=<value> The path or the location in your file system where the content, you intend to import, is
|
|
114
74
|
stored. For example, -d "C:\Users\Name\Desktop\cli\content". If the export folder has
|
|
115
75
|
branches involved, then the path should point till the particular branch. For example,
|
|
116
76
|
“-d "C:\Users\Name\Desktop\cli\content\branch_name"
|
|
117
77
|
-k, --stack-api-key=<value> API key of the target stack
|
|
78
|
+
--branch=<value> The name of the branch where you want to import your content. If you don't mention the
|
|
79
|
+
branch name, then by default the content will be imported to the main branch.
|
|
118
80
|
--branch-alias=<value> Specify the branch alias where you want to import your content. If not specified, the
|
|
119
81
|
content is imported into the main branch by default.
|
|
120
82
|
--module=<option>... [optional] Specify the modules/module to import into the target stack. currently options
|
|
@@ -124,15 +86,8 @@ FLAGS
|
|
|
124
86
|
DESCRIPTION
|
|
125
87
|
Helps to generate mappers and backup folder for importing (overwriting) specific modules
|
|
126
88
|
|
|
127
|
-
ALIASES
|
|
128
|
-
$ csdx cm:import-setup
|
|
129
|
-
|
|
130
89
|
EXAMPLES
|
|
131
|
-
$ csdx cm:stacks:import-setup --stack-api-key <target_stack_api_key> --data-dir <path/of/export/destination/dir> --modules <module_name, module_name>
|
|
132
|
-
|
|
133
|
-
$ csdx cm:stacks:import-setup -k <target_stack_api_key> -d <path/of/export/destination/dir> --modules <module_name, module_name>
|
|
134
|
-
|
|
135
|
-
$ csdx cm:stacks:import-setup -k <target_stack_api_key> -d <path/of/export/destination/dir> --modules <module_name, module_name> -b <branch_name>
|
|
90
|
+
$ csdx cm:stacks:import-setup --stack-api-key <target_stack_api_key> --data-dir <path/of/export/destination/dir> --modules <module_name, module_name> --branch <branch_name>
|
|
136
91
|
```
|
|
137
92
|
|
|
138
93
|
_See code: [src/commands/cm/stacks/import-setup.ts](https://github.com/contentstack/cli/blob/main/packages/contentstack-import-setup/src/commands/cm/stacks/import-setup.ts)_
|
|
@@ -8,34 +8,53 @@ const utils_1 = require("../../../utils");
|
|
|
8
8
|
const import_1 = require("../../../import");
|
|
9
9
|
class ImportSetupCommand extends cli_command_1.Command {
|
|
10
10
|
async run() {
|
|
11
|
-
var _a, _b;
|
|
12
11
|
try {
|
|
13
12
|
const { flags } = await this.parse(ImportSetupCommand);
|
|
14
13
|
let importSetupConfig = await (0, utils_1.setupImportConfig)(flags);
|
|
15
14
|
// Prepare the context object
|
|
16
|
-
|
|
17
|
-
importSetupConfig.context = {
|
|
15
|
+
const context = this.createImportSetupContext(importSetupConfig.apiKey, importSetupConfig.authenticationMethod);
|
|
16
|
+
importSetupConfig.context = Object.assign({}, context);
|
|
18
17
|
// Note setting host to create cma client
|
|
19
18
|
importSetupConfig.host = this.cmaHost;
|
|
20
19
|
importSetupConfig.region = this.region;
|
|
21
20
|
importSetupConfig.developerHubBaseUrl = this.developerHubUrl;
|
|
21
|
+
if (flags.branch) {
|
|
22
|
+
cli_utilities_1.CLIProgressManager.initializeGlobalSummary(`IMPORT-SETUP-${flags.branch}`, flags.branch, `Setting up import for "${flags.branch}" branch...`);
|
|
23
|
+
}
|
|
24
|
+
else {
|
|
25
|
+
cli_utilities_1.CLIProgressManager.initializeGlobalSummary(`IMPORT-SETUP`, flags.branch, 'Setting up import...');
|
|
26
|
+
}
|
|
22
27
|
const managementAPIClient = await (0, cli_utilities_1.managementSDKClient)(importSetupConfig);
|
|
23
28
|
const importSetup = new import_1.ImportSetup(importSetupConfig, managementAPIClient);
|
|
24
29
|
await importSetup.start();
|
|
30
|
+
cli_utilities_1.CLIProgressManager.printGlobalSummary();
|
|
25
31
|
cli_utilities_1.log.success(`Backup folder and mapper files have been successfully created for the stack using the API key ${importSetupConfig.apiKey}.`, importSetupConfig.context);
|
|
26
32
|
cli_utilities_1.log.success(`The backup folder has been created at '${(0, cli_utilities_1.pathValidator)(node_path_1.default.join(importSetupConfig.backupDir))}'.`, importSetupConfig.context);
|
|
27
33
|
}
|
|
28
34
|
catch (error) {
|
|
35
|
+
cli_utilities_1.CLIProgressManager.printGlobalSummary();
|
|
29
36
|
(0, cli_utilities_1.handleAndLogError)(error);
|
|
30
37
|
}
|
|
31
38
|
}
|
|
39
|
+
// Create import setup context object
|
|
40
|
+
createImportSetupContext(apiKey, authenticationMethod, module) {
|
|
41
|
+
var _a, _b, _c;
|
|
42
|
+
return {
|
|
43
|
+
command: ((_b = (_a = this.context) === null || _a === void 0 ? void 0 : _a.info) === null || _b === void 0 ? void 0 : _b.command) || 'cm:stacks:import-setup',
|
|
44
|
+
module: module || '',
|
|
45
|
+
userId: cli_utilities_1.configHandler.get('userUid') || undefined,
|
|
46
|
+
email: cli_utilities_1.configHandler.get('email') || undefined,
|
|
47
|
+
sessionId: (_c = this.context) === null || _c === void 0 ? void 0 : _c.sessionId,
|
|
48
|
+
apiKey: apiKey || '',
|
|
49
|
+
orgId: cli_utilities_1.configHandler.get('oauthOrgUid') || '',
|
|
50
|
+
authenticationMethod: authenticationMethod || 'Basic Auth',
|
|
51
|
+
};
|
|
52
|
+
}
|
|
32
53
|
}
|
|
33
54
|
exports.default = ImportSetupCommand;
|
|
34
55
|
ImportSetupCommand.description = cli_utilities_1.messageHandler.parse('Helps to generate mappers and backup folder for importing (overwriting) specific modules');
|
|
35
56
|
ImportSetupCommand.examples = [
|
|
36
|
-
`csdx cm:stacks:import-setup --stack-api-key <target_stack_api_key> --data-dir <path/of/export/destination/dir> --modules <module_name, module_name>`,
|
|
37
|
-
`csdx cm:stacks:import-setup -k <target_stack_api_key> -d <path/of/export/destination/dir> --modules <module_name, module_name>`,
|
|
38
|
-
`csdx cm:stacks:import-setup -k <target_stack_api_key> -d <path/of/export/destination/dir> --modules <module_name, module_name> -b <branch_name>`,
|
|
57
|
+
`csdx cm:stacks:import-setup --stack-api-key <target_stack_api_key> --data-dir <path/of/export/destination/dir> --modules <module_name, module_name> --branch <branch_name>`,
|
|
39
58
|
];
|
|
40
59
|
ImportSetupCommand.flags = {
|
|
41
60
|
'stack-api-key': cli_utilities_1.flags.string({
|
|
@@ -56,15 +75,13 @@ ImportSetupCommand.flags = {
|
|
|
56
75
|
multiple: true,
|
|
57
76
|
}),
|
|
58
77
|
branch: cli_utilities_1.flags.string({
|
|
59
|
-
char: 'B',
|
|
60
78
|
description: "The name of the branch where you want to import your content. If you don't mention the branch name, then by default the content will be imported to the main branch.",
|
|
61
|
-
|
|
62
|
-
exclusive: ['branch-alias']
|
|
79
|
+
exclusive: ['branch-alias'],
|
|
63
80
|
}),
|
|
64
81
|
'branch-alias': cli_utilities_1.flags.string({
|
|
65
|
-
description:
|
|
82
|
+
description: 'Specify the branch alias where you want to import your content. If not specified, the content is imported into the main branch by default.',
|
|
66
83
|
exclusive: ['branch'],
|
|
67
84
|
}),
|
|
68
85
|
};
|
|
69
|
-
ImportSetupCommand.aliases = [
|
|
86
|
+
ImportSetupCommand.aliases = [];
|
|
70
87
|
ImportSetupCommand.usage = 'cm:stacks:import-setup [-k <value>] [-d <value>] [-a <value>] [--modules <value,value>]';
|
|
@@ -1,14 +1,28 @@
|
|
|
1
1
|
import { ImportConfig } from '../types';
|
|
2
|
-
import {
|
|
2
|
+
import { backupHandler as defaultBackupHandler, setupBranchConfig as defaultSetupBranchConfig } from '../utils';
|
|
3
|
+
import { ContentstackClient, log as defaultLog, handleAndLogError as defaultHandleAndLogError } from '@contentstack/cli-utilities';
|
|
4
|
+
/**
|
|
5
|
+
* Dependencies for ImportSetup - can be injected for testing
|
|
6
|
+
*/
|
|
7
|
+
export interface ImportSetupDeps {
|
|
8
|
+
backupHandler?: typeof defaultBackupHandler;
|
|
9
|
+
setupBranchConfig?: typeof defaultSetupBranchConfig;
|
|
10
|
+
log?: typeof defaultLog;
|
|
11
|
+
handleAndLogError?: typeof defaultHandleAndLogError;
|
|
12
|
+
}
|
|
3
13
|
export default class ImportSetup {
|
|
4
14
|
protected config: ImportConfig;
|
|
5
|
-
private managementAPIClient;
|
|
6
|
-
private importConfig;
|
|
7
|
-
private stackAPIClient;
|
|
15
|
+
private readonly managementAPIClient;
|
|
16
|
+
private readonly importConfig;
|
|
17
|
+
private readonly stackAPIClient;
|
|
8
18
|
dependencyTree: {
|
|
9
19
|
[key: string]: string[];
|
|
10
20
|
};
|
|
11
|
-
|
|
21
|
+
private readonly backupHandler;
|
|
22
|
+
private readonly setupBranchConfig;
|
|
23
|
+
private readonly log;
|
|
24
|
+
private readonly handleAndLogError;
|
|
25
|
+
constructor(config: ImportConfig, managementAPIClient: ContentstackClient, deps?: ImportSetupDeps);
|
|
12
26
|
/**
|
|
13
27
|
* Generate mapper logic
|
|
14
28
|
* This method generates dependency tree based on the selected modules
|
|
@@ -26,7 +26,8 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
26
26
|
const utils_1 = require("../utils");
|
|
27
27
|
const cli_utilities_1 = require("@contentstack/cli-utilities");
|
|
28
28
|
class ImportSetup {
|
|
29
|
-
constructor(config, managementAPIClient) {
|
|
29
|
+
constructor(config, managementAPIClient, deps = {}) {
|
|
30
|
+
var _a, _b, _c, _d;
|
|
30
31
|
this.dependencyTree = {};
|
|
31
32
|
this.config = config;
|
|
32
33
|
this.managementAPIClient = managementAPIClient;
|
|
@@ -34,6 +35,11 @@ class ImportSetup {
|
|
|
34
35
|
api_key: this.config.apiKey,
|
|
35
36
|
management_token: this.config.management_token,
|
|
36
37
|
});
|
|
38
|
+
// Use injected dependencies or defaults
|
|
39
|
+
this.backupHandler = (_a = deps.backupHandler) !== null && _a !== void 0 ? _a : utils_1.backupHandler;
|
|
40
|
+
this.setupBranchConfig = (_b = deps.setupBranchConfig) !== null && _b !== void 0 ? _b : utils_1.setupBranchConfig;
|
|
41
|
+
this.log = (_c = deps.log) !== null && _c !== void 0 ? _c : cli_utilities_1.log;
|
|
42
|
+
this.handleAndLogError = (_d = deps.handleAndLogError) !== null && _d !== void 0 ? _d : cli_utilities_1.handleAndLogError;
|
|
37
43
|
}
|
|
38
44
|
/**
|
|
39
45
|
* Generate mapper logic
|
|
@@ -49,7 +55,7 @@ class ImportSetup {
|
|
|
49
55
|
return [];
|
|
50
56
|
visited.add(module);
|
|
51
57
|
const dependencies = ((_a = this.config.modules[module]) === null || _a === void 0 ? void 0 : _a.dependencies) || [];
|
|
52
|
-
|
|
58
|
+
const allDeps = [...dependencies];
|
|
53
59
|
for (const dependency of dependencies) {
|
|
54
60
|
allDeps.push(...getAllDependencies(dependency));
|
|
55
61
|
}
|
|
@@ -61,7 +67,9 @@ class ImportSetup {
|
|
|
61
67
|
allDependencies = allDependencies.filter((dep) => !assignedDependencies.has(dep)); // Remove assigned ones
|
|
62
68
|
this.dependencyTree[module] = allDependencies;
|
|
63
69
|
// Mark these dependencies as assigned so they won't be included in later modules
|
|
64
|
-
|
|
70
|
+
for (const dep of allDependencies) {
|
|
71
|
+
assignedDependencies.add(dep);
|
|
72
|
+
}
|
|
65
73
|
}
|
|
66
74
|
}
|
|
67
75
|
/**
|
|
@@ -72,10 +80,13 @@ class ImportSetup {
|
|
|
72
80
|
*/
|
|
73
81
|
async runModuleImports() {
|
|
74
82
|
var _a;
|
|
75
|
-
|
|
83
|
+
this.log.debug('Starting module imports', { modules: Object.keys(this.dependencyTree) });
|
|
76
84
|
for (const moduleName in this.dependencyTree) {
|
|
77
85
|
try {
|
|
78
|
-
|
|
86
|
+
this.log.debug(`Importing module: ${moduleName}`, {
|
|
87
|
+
moduleName,
|
|
88
|
+
dependencies: this.dependencyTree[moduleName],
|
|
89
|
+
});
|
|
79
90
|
const modulePath = `./modules/${moduleName}`;
|
|
80
91
|
const { default: ModuleClass } = await (_a = modulePath, Promise.resolve().then(() => __importStar(require(_a))));
|
|
81
92
|
const modulePayload = {
|
|
@@ -85,14 +96,14 @@ class ImportSetup {
|
|
|
85
96
|
};
|
|
86
97
|
const moduleInstance = new ModuleClass(modulePayload);
|
|
87
98
|
await moduleInstance.start();
|
|
88
|
-
|
|
99
|
+
this.log.debug(`Module ${moduleName} imported successfully`);
|
|
89
100
|
}
|
|
90
101
|
catch (error) {
|
|
91
|
-
|
|
102
|
+
this.handleAndLogError(error, Object.assign(Object.assign({}, this.config.context), { moduleName }), `Error occurred while importing '${moduleName}'`);
|
|
92
103
|
throw error;
|
|
93
104
|
}
|
|
94
105
|
}
|
|
95
|
-
|
|
106
|
+
this.log.debug('All module imports completed');
|
|
96
107
|
}
|
|
97
108
|
/**
|
|
98
109
|
* Start the import setup process
|
|
@@ -107,21 +118,21 @@ class ImportSetup {
|
|
|
107
118
|
this.config.stackName = stackDetails.name;
|
|
108
119
|
this.config.org_uid = stackDetails.org_uid;
|
|
109
120
|
}
|
|
110
|
-
|
|
111
|
-
const backupDir = await
|
|
121
|
+
this.log.debug('Creating backup directory');
|
|
122
|
+
const backupDir = await this.backupHandler(this.config);
|
|
112
123
|
if (backupDir) {
|
|
113
124
|
this.config.backupDir = backupDir;
|
|
114
|
-
|
|
125
|
+
this.log.debug('Backup directory created', { backupDir });
|
|
115
126
|
}
|
|
116
|
-
|
|
117
|
-
await
|
|
118
|
-
|
|
127
|
+
this.log.debug('Setting up branch configuration');
|
|
128
|
+
await this.setupBranchConfig(this.config, this.stackAPIClient);
|
|
129
|
+
this.log.debug('Branch configuration completed', { branchName: this.config.branchName });
|
|
119
130
|
await this.generateDependencyTree();
|
|
120
131
|
await this.runModuleImports();
|
|
121
|
-
|
|
132
|
+
this.log.debug('Import setup process completed successfully');
|
|
122
133
|
}
|
|
123
134
|
catch (error) {
|
|
124
|
-
|
|
135
|
+
this.handleAndLogError(error, Object.assign({}, this.config.context), 'Import setup failed');
|
|
125
136
|
throw error;
|
|
126
137
|
}
|
|
127
138
|
}
|
|
@@ -6,10 +6,11 @@ const path_1 = require("path");
|
|
|
6
6
|
const lodash_1 = require("lodash");
|
|
7
7
|
const cli_utilities_1 = require("@contentstack/cli-utilities");
|
|
8
8
|
const base_setup_1 = tslib_1.__importDefault(require("./base-setup"));
|
|
9
|
+
const utils_2 = require("../../utils");
|
|
9
10
|
class AssetImportSetup extends base_setup_1.default {
|
|
10
11
|
constructor({ config, stackAPIClient, dependencies }) {
|
|
11
12
|
super({ config, stackAPIClient, dependencies });
|
|
12
|
-
this.
|
|
13
|
+
this.currentModuleName = utils_2.MODULE_NAMES[utils_2.MODULE_CONTEXTS.ASSETS];
|
|
13
14
|
this.assetsFolderPath = (0, path_1.join)((0, cli_utilities_1.sanitizePath)(this.config.contentDir), 'assets');
|
|
14
15
|
this.assetsFilePath = (0, path_1.join)((0, cli_utilities_1.sanitizePath)(this.config.contentDir), 'assets', 'assets.json');
|
|
15
16
|
this.assetsConfig = config.modules.assets;
|
|
@@ -27,18 +28,43 @@ class AssetImportSetup extends base_setup_1.default {
|
|
|
27
28
|
* @returns {Promise<void>}
|
|
28
29
|
*/
|
|
29
30
|
async start() {
|
|
31
|
+
var _a;
|
|
30
32
|
try {
|
|
33
|
+
const progress = this.createNestedProgress(this.currentModuleName);
|
|
34
|
+
// Analyze to get chunk count
|
|
35
|
+
const indexerCount = await this.withLoadingSpinner('ASSETS: Analyzing import data...', async () => {
|
|
36
|
+
const basePath = this.assetsFolderPath;
|
|
37
|
+
const fs = new cli_utilities_1.FsUtility({ basePath, indexFileName: 'assets.json' });
|
|
38
|
+
const indexer = fs.indexFileContent;
|
|
39
|
+
return (0, lodash_1.values)(indexer).length;
|
|
40
|
+
});
|
|
41
|
+
if (indexerCount === 0) {
|
|
42
|
+
(0, utils_1.log)(this.config, 'No assets found in the content folder.', 'info');
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
// Add processes - use a large number for total assets since we don't know exact count
|
|
46
|
+
// The progress will update as we process each asset
|
|
47
|
+
progress.addProcess(utils_2.PROCESS_NAMES.ASSETS_MAPPER_GENERATION, 1);
|
|
48
|
+
progress.addProcess(utils_2.PROCESS_NAMES.ASSETS_FETCH_AND_MAP, indexerCount * 10); // Estimate: ~10 assets per chunk
|
|
49
|
+
// Create mapper directory
|
|
50
|
+
progress
|
|
51
|
+
.startProcess(utils_2.PROCESS_NAMES.ASSETS_MAPPER_GENERATION)
|
|
52
|
+
.updateStatus(utils_2.PROCESS_STATUS.ASSETS_MAPPER_GENERATION.GENERATING, utils_2.PROCESS_NAMES.ASSETS_MAPPER_GENERATION);
|
|
31
53
|
utils_1.fsUtil.makeDirectory(this.mapperDirPath);
|
|
32
|
-
|
|
54
|
+
(_a = this.progressManager) === null || _a === void 0 ? void 0 : _a.tick(true, 'mapper directory created', null, utils_2.PROCESS_NAMES.ASSETS_MAPPER_GENERATION);
|
|
55
|
+
progress.completeProcess(utils_2.PROCESS_NAMES.ASSETS_MAPPER_GENERATION, true);
|
|
56
|
+
// Fetch and map assets
|
|
57
|
+
progress
|
|
58
|
+
.startProcess(utils_2.PROCESS_NAMES.ASSETS_FETCH_AND_MAP)
|
|
59
|
+
.updateStatus(utils_2.PROCESS_STATUS.ASSETS_FETCH_AND_MAP.FETCHING, utils_2.PROCESS_NAMES.ASSETS_FETCH_AND_MAP);
|
|
33
60
|
await this.fetchAndMapAssets();
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
});
|
|
38
|
-
cli_utilities_1.log.success(`The required setup files for the asset have been generated successfully.`);
|
|
61
|
+
progress.completeProcess(utils_2.PROCESS_NAMES.ASSETS_FETCH_AND_MAP, true);
|
|
62
|
+
this.completeProgress(true);
|
|
63
|
+
(0, utils_1.log)(this.config, `The required setup files for the asset have been generated successfully.`, 'success');
|
|
39
64
|
}
|
|
40
65
|
catch (error) {
|
|
41
|
-
(
|
|
66
|
+
this.completeProgress(false, (error === null || error === void 0 ? void 0 : error.message) || 'Assets mapper generation failed');
|
|
67
|
+
(0, utils_1.log)(this.config, `Error occurred while generating the asset mapper: ${(0, cli_utilities_1.formatError)(error)}.`, 'error');
|
|
42
68
|
}
|
|
43
69
|
}
|
|
44
70
|
/**
|
|
@@ -47,7 +73,6 @@ class AssetImportSetup extends base_setup_1.default {
|
|
|
47
73
|
* @returns {Promise<void>} Promise<void>
|
|
48
74
|
*/
|
|
49
75
|
async fetchAndMapAssets() {
|
|
50
|
-
cli_utilities_1.log.debug('Starting asset fetch and mapping', { assetsFolderPath: this.assetsFolderPath });
|
|
51
76
|
const processName = 'mapping assets';
|
|
52
77
|
const indexFileName = 'assets.json';
|
|
53
78
|
const basePath = this.assetsFolderPath;
|
|
@@ -55,31 +80,38 @@ class AssetImportSetup extends base_setup_1.default {
|
|
|
55
80
|
const indexer = fs.indexFileContent;
|
|
56
81
|
const indexerCount = (0, lodash_1.values)(indexer).length;
|
|
57
82
|
const onSuccess = ({ response: { items = [] } = {}, apiData: { uid, url, title } = undefined, }) => {
|
|
83
|
+
var _a, _b, _c;
|
|
58
84
|
if (items.length === 1) {
|
|
59
85
|
this.assetUidMapper[uid] = items[0].uid;
|
|
60
86
|
this.assetUrlMapper[url] = items[0].url;
|
|
61
|
-
|
|
87
|
+
(_a = this.progressManager) === null || _a === void 0 ? void 0 : _a.tick(true, `asset: ${title}`, null, utils_2.PROCESS_NAMES.ASSETS_FETCH_AND_MAP);
|
|
88
|
+
(0, utils_1.log)(this.config, `Mapped asset successfully: '${title}'`, 'info');
|
|
62
89
|
}
|
|
63
90
|
else if (items.length > 1) {
|
|
64
91
|
this.duplicateAssets[uid] = items.map((asset) => {
|
|
65
92
|
return { uid: asset.uid, title: asset.title, url: asset.url };
|
|
66
93
|
});
|
|
67
|
-
|
|
94
|
+
(_b = this.progressManager) === null || _b === void 0 ? void 0 : _b.tick(true, `asset: ${title} (duplicate)`, null, utils_2.PROCESS_NAMES.ASSETS_FETCH_AND_MAP);
|
|
95
|
+
(0, utils_1.log)(this.config, `Multiple assets found with the title '${title}'.`, 'info');
|
|
68
96
|
}
|
|
69
97
|
else {
|
|
70
|
-
|
|
98
|
+
(_c = this.progressManager) === null || _c === void 0 ? void 0 : _c.tick(false, `asset: ${title}`, 'Not found in stack', utils_2.PROCESS_NAMES.ASSETS_FETCH_AND_MAP);
|
|
99
|
+
(0, utils_1.log)(this.config, `Asset with title '${title}' not found in the stack!`, 'info');
|
|
71
100
|
}
|
|
72
101
|
};
|
|
73
102
|
const onReject = ({ error, apiData: { title } = undefined }) => {
|
|
74
|
-
|
|
103
|
+
var _a;
|
|
104
|
+
(_a = this.progressManager) === null || _a === void 0 ? void 0 : _a.tick(false, `asset: ${title}`, (0, cli_utilities_1.formatError)(error), utils_2.PROCESS_NAMES.ASSETS_FETCH_AND_MAP);
|
|
105
|
+
(0, utils_1.log)(this.config, `Failed to map the asset '${title}'.`, 'error');
|
|
106
|
+
(0, utils_1.log)(this.config, (0, cli_utilities_1.formatError)(error), 'error');
|
|
75
107
|
};
|
|
76
108
|
/* eslint-disable @typescript-eslint/no-unused-vars, guard-for-in */
|
|
77
109
|
for (const index in indexer) {
|
|
78
110
|
const chunk = await fs.readChunkFiles.next().catch((error) => {
|
|
79
|
-
|
|
111
|
+
(0, utils_1.log)(this.config, error, 'error');
|
|
80
112
|
});
|
|
81
113
|
if (chunk) {
|
|
82
|
-
|
|
114
|
+
const apiContent = (0, lodash_1.orderBy)((0, lodash_1.values)(chunk), '_version');
|
|
83
115
|
await this.makeConcurrentCall({
|
|
84
116
|
apiContent,
|
|
85
117
|
processName,
|
|
@@ -101,7 +133,7 @@ class AssetImportSetup extends base_setup_1.default {
|
|
|
101
133
|
}
|
|
102
134
|
if (!(0, lodash_1.isEmpty)(this.duplicateAssets)) {
|
|
103
135
|
utils_1.fsUtil.writeFile(this.duplicateAssetPath, this.duplicateAssets);
|
|
104
|
-
|
|
136
|
+
(0, utils_1.log)(this.config, `Duplicate asset files are stored at: ${this.duplicateAssetPath}.`, 'info');
|
|
105
137
|
}
|
|
106
138
|
}
|
|
107
139
|
}
|
|
@@ -1,15 +1,12 @@
|
|
|
1
|
-
import { ApiOptions, CustomPromiseHandler, EnvType, ImportConfig, ModuleClassParams
|
|
1
|
+
import { ApiOptions, CustomPromiseHandler, EnvType, ImportConfig, ModuleClassParams } from '../../types';
|
|
2
|
+
import { CLIProgressManager } from '@contentstack/cli-utilities';
|
|
2
3
|
export default class BaseImportSetup {
|
|
3
4
|
config: ImportConfig;
|
|
4
5
|
stackAPIClient: ModuleClassParams['stackAPIClient'];
|
|
5
6
|
dependencies: ModuleClassParams['dependencies'];
|
|
7
|
+
protected progressManager: CLIProgressManager | null;
|
|
8
|
+
protected currentModuleName: string;
|
|
6
9
|
constructor({ config, stackAPIClient, dependencies }: ModuleClassParams);
|
|
7
|
-
/**
|
|
8
|
-
* Set the module name in context directly
|
|
9
|
-
* @param module - Module name to set
|
|
10
|
-
* @returns {void}
|
|
11
|
-
*/
|
|
12
|
-
protected initializeContext(module?: Modules): void;
|
|
13
10
|
setupDependencies(): Promise<void>;
|
|
14
11
|
/**
|
|
15
12
|
* @method delay
|
|
@@ -40,4 +37,20 @@ export default class BaseImportSetup {
|
|
|
40
37
|
* @return {Promise} Promise<void>
|
|
41
38
|
*/
|
|
42
39
|
makeAPICall(apiOptions: ApiOptions, isLastRequest?: boolean): Promise<void>;
|
|
40
|
+
/**
|
|
41
|
+
* Create simple progress manager
|
|
42
|
+
*/
|
|
43
|
+
protected createSimpleProgress(moduleName: string, total?: number): CLIProgressManager;
|
|
44
|
+
/**
|
|
45
|
+
* Create nested progress manager
|
|
46
|
+
*/
|
|
47
|
+
protected createNestedProgress(moduleName: string): CLIProgressManager;
|
|
48
|
+
/**
|
|
49
|
+
* Complete progress manager
|
|
50
|
+
*/
|
|
51
|
+
protected completeProgress(success?: boolean, error?: string): void;
|
|
52
|
+
/**
|
|
53
|
+
* Show a loading spinner before initializing progress
|
|
54
|
+
*/
|
|
55
|
+
protected withLoadingSpinner<T>(message: string, action: () => Promise<T>): Promise<T>;
|
|
43
56
|
}
|
|
@@ -23,30 +23,21 @@ var __importStar = (this && this.__importStar) || function (mod) {
|
|
|
23
23
|
return result;
|
|
24
24
|
};
|
|
25
25
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
|
+
const utils_1 = require("../../utils");
|
|
26
27
|
const lodash_1 = require("lodash");
|
|
27
28
|
const cli_utilities_1 = require("@contentstack/cli-utilities");
|
|
28
29
|
class BaseImportSetup {
|
|
29
30
|
constructor({ config, stackAPIClient, dependencies }) {
|
|
31
|
+
this.progressManager = null;
|
|
32
|
+
this.currentModuleName = '';
|
|
30
33
|
this.config = config;
|
|
31
34
|
this.stackAPIClient = stackAPIClient;
|
|
32
35
|
this.dependencies = dependencies;
|
|
33
36
|
}
|
|
34
|
-
/**
|
|
35
|
-
* Set the module name in context directly
|
|
36
|
-
* @param module - Module name to set
|
|
37
|
-
* @returns {void}
|
|
38
|
-
*/
|
|
39
|
-
initializeContext(module) {
|
|
40
|
-
if (this.config.context && module) {
|
|
41
|
-
this.config.context.module = module;
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
37
|
async setupDependencies() {
|
|
45
38
|
var _a;
|
|
46
|
-
cli_utilities_1.log.debug('Setting up dependencies', { dependencies: this.dependencies });
|
|
47
39
|
for (const moduleName of this.dependencies) {
|
|
48
40
|
try {
|
|
49
|
-
cli_utilities_1.log.debug(`Importing dependency module: ${moduleName}`);
|
|
50
41
|
const modulePath = `./${moduleName}`;
|
|
51
42
|
const { default: ModuleClass } = await (_a = modulePath, Promise.resolve().then(() => __importStar(require(_a))));
|
|
52
43
|
const modulePayload = {
|
|
@@ -55,10 +46,9 @@ class BaseImportSetup {
|
|
|
55
46
|
};
|
|
56
47
|
const moduleInstance = new ModuleClass(modulePayload);
|
|
57
48
|
await moduleInstance.start();
|
|
58
|
-
cli_utilities_1.log.debug(`Dependency module ${moduleName} imported successfully`);
|
|
59
49
|
}
|
|
60
50
|
catch (error) {
|
|
61
|
-
(0,
|
|
51
|
+
(0, utils_1.log)(this.config, `Error importing '${moduleName}': ${error.message}`, 'error');
|
|
62
52
|
}
|
|
63
53
|
}
|
|
64
54
|
}
|
|
@@ -134,7 +124,7 @@ class BaseImportSetup {
|
|
|
134
124
|
// info: Batch No. 20 of import assets is complete
|
|
135
125
|
if (currentIndexer)
|
|
136
126
|
batchMsg += `Current chunk processing is (${currentIndexer}/${indexerCount})`;
|
|
137
|
-
|
|
127
|
+
(0, utils_1.log)(this.config, `Batch No. (${batchNo}/${totelBatches}) of ${processName} is complete`, 'success');
|
|
138
128
|
}
|
|
139
129
|
// if (this.config.modules.assets.displayExecutionTime) {
|
|
140
130
|
// console.log(
|
|
@@ -192,5 +182,48 @@ class BaseImportSetup {
|
|
|
192
182
|
return Promise.resolve();
|
|
193
183
|
}
|
|
194
184
|
}
|
|
185
|
+
/**
|
|
186
|
+
* Create simple progress manager
|
|
187
|
+
*/
|
|
188
|
+
createSimpleProgress(moduleName, total) {
|
|
189
|
+
var _a;
|
|
190
|
+
this.currentModuleName = moduleName;
|
|
191
|
+
const logConfig = cli_utilities_1.configHandler.get('log') || {};
|
|
192
|
+
const showConsoleLogs = (_a = logConfig.showConsoleLogs) !== null && _a !== void 0 ? _a : false;
|
|
193
|
+
this.progressManager = cli_utilities_1.CLIProgressManager.createSimple(moduleName, total, showConsoleLogs);
|
|
194
|
+
return this.progressManager;
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* Create nested progress manager
|
|
198
|
+
*/
|
|
199
|
+
createNestedProgress(moduleName) {
|
|
200
|
+
var _a;
|
|
201
|
+
this.currentModuleName = moduleName;
|
|
202
|
+
const logConfig = cli_utilities_1.configHandler.get('log') || {};
|
|
203
|
+
const showConsoleLogs = (_a = logConfig.showConsoleLogs) !== null && _a !== void 0 ? _a : false;
|
|
204
|
+
this.progressManager = cli_utilities_1.CLIProgressManager.createNested(moduleName, showConsoleLogs);
|
|
205
|
+
return this.progressManager;
|
|
206
|
+
}
|
|
207
|
+
/**
|
|
208
|
+
* Complete progress manager
|
|
209
|
+
*/
|
|
210
|
+
completeProgress(success = true, error) {
|
|
211
|
+
var _a;
|
|
212
|
+
(_a = this.progressManager) === null || _a === void 0 ? void 0 : _a.complete(success, error);
|
|
213
|
+
this.progressManager = null;
|
|
214
|
+
}
|
|
215
|
+
/**
|
|
216
|
+
* Show a loading spinner before initializing progress
|
|
217
|
+
*/
|
|
218
|
+
async withLoadingSpinner(message, action) {
|
|
219
|
+
var _a;
|
|
220
|
+
const logConfig = cli_utilities_1.configHandler.get('log') || {};
|
|
221
|
+
const showConsoleLogs = (_a = logConfig.showConsoleLogs) !== null && _a !== void 0 ? _a : false;
|
|
222
|
+
if (showConsoleLogs) {
|
|
223
|
+
// If console logs are enabled, don't show spinner, just execute the action
|
|
224
|
+
return await action();
|
|
225
|
+
}
|
|
226
|
+
return await cli_utilities_1.CLIProgressManager.withLoadingSpinner(message, action);
|
|
227
|
+
}
|
|
195
228
|
}
|
|
196
229
|
exports.default = BaseImportSetup;
|
|
@@ -1,20 +1,42 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
const tslib_1 = require("tslib");
|
|
4
|
+
const utils_1 = require("../../utils");
|
|
4
5
|
const base_setup_1 = tslib_1.__importDefault(require("./base-setup"));
|
|
5
|
-
const
|
|
6
|
+
const utils_2 = require("../../utils");
|
|
6
7
|
class ContentTypesImportSetup extends base_setup_1.default {
|
|
7
8
|
constructor(options) {
|
|
8
9
|
super(options);
|
|
9
|
-
this.
|
|
10
|
+
this.currentModuleName = utils_2.MODULE_NAMES[utils_2.MODULE_CONTEXTS.CONTENT_TYPES];
|
|
10
11
|
}
|
|
11
12
|
async start() {
|
|
13
|
+
var _a, _b, _c;
|
|
12
14
|
try {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
+
const progress = this.createNestedProgress(this.currentModuleName);
|
|
16
|
+
// Add processes
|
|
17
|
+
progress.addProcess(utils_2.PROCESS_NAMES.CONTENT_TYPES_DEPENDENCY_SETUP, ((_a = this.dependencies) === null || _a === void 0 ? void 0 : _a.length) || 0);
|
|
18
|
+
progress.addProcess(utils_2.PROCESS_NAMES.CONTENT_TYPES_MAPPER_GENERATION, 1);
|
|
19
|
+
// Setup dependencies
|
|
20
|
+
if (this.dependencies && this.dependencies.length > 0) {
|
|
21
|
+
progress
|
|
22
|
+
.startProcess(utils_2.PROCESS_NAMES.CONTENT_TYPES_DEPENDENCY_SETUP)
|
|
23
|
+
.updateStatus(utils_2.PROCESS_STATUS.CONTENT_TYPES_DEPENDENCY_SETUP.SETTING_UP, utils_2.PROCESS_NAMES.CONTENT_TYPES_DEPENDENCY_SETUP);
|
|
24
|
+
await this.setupDependencies();
|
|
25
|
+
(_b = this.progressManager) === null || _b === void 0 ? void 0 : _b.tick(true, 'dependencies setup', null, utils_2.PROCESS_NAMES.CONTENT_TYPES_DEPENDENCY_SETUP);
|
|
26
|
+
progress.completeProcess(utils_2.PROCESS_NAMES.CONTENT_TYPES_DEPENDENCY_SETUP, true);
|
|
27
|
+
}
|
|
28
|
+
// Mapper generation
|
|
29
|
+
progress
|
|
30
|
+
.startProcess(utils_2.PROCESS_NAMES.CONTENT_TYPES_MAPPER_GENERATION)
|
|
31
|
+
.updateStatus(utils_2.PROCESS_STATUS.CONTENT_TYPES_MAPPER_GENERATION.GENERATING, utils_2.PROCESS_NAMES.CONTENT_TYPES_MAPPER_GENERATION);
|
|
32
|
+
(_c = this.progressManager) === null || _c === void 0 ? void 0 : _c.tick(true, 'mapper generation', null, utils_2.PROCESS_NAMES.CONTENT_TYPES_MAPPER_GENERATION);
|
|
33
|
+
progress.completeProcess(utils_2.PROCESS_NAMES.CONTENT_TYPES_MAPPER_GENERATION, true);
|
|
34
|
+
this.completeProgress(true);
|
|
35
|
+
(0, utils_1.log)(this.config, `The required setup files for content types have been generated successfully.`, 'success');
|
|
15
36
|
}
|
|
16
37
|
catch (error) {
|
|
17
|
-
(
|
|
38
|
+
this.completeProgress(false, (error === null || error === void 0 ? void 0 : error.message) || 'Content types mapper generation failed');
|
|
39
|
+
(0, utils_1.log)(this.config, `Error occurred while generating the content type mapper: ${error.message}.`, 'error');
|
|
18
40
|
}
|
|
19
41
|
}
|
|
20
42
|
}
|