@contentstack/cli-cm-import-setup 1.0.0-beta.1
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 +21 -0
- package/README.md +115 -0
- package/bin/dev.cmd +3 -0
- package/bin/dev.js +6 -0
- package/bin/run.cmd +3 -0
- package/bin/run.js +7 -0
- package/lib/commands/cm/stacks/import-setup.d.ts +10 -0
- package/lib/commands/cm/stacks/import-setup.js +53 -0
- package/lib/config/index.d.ts +3 -0
- package/lib/config/index.js +77 -0
- package/lib/import/import-setup.d.ts +32 -0
- package/lib/import/import-setup.js +112 -0
- package/lib/import/index.d.ts +1 -0
- package/lib/import/index.js +8 -0
- package/lib/import/modules/assets.d.ts +27 -0
- package/lib/import/modules/assets.js +102 -0
- package/lib/import/modules/base-setup.d.ts +37 -0
- package/lib/import/modules/base-setup.js +183 -0
- package/lib/import/modules/content-types.d.ts +6 -0
- package/lib/import/modules/content-types.js +20 -0
- package/lib/import/modules/custom-roles.d.ts +0 -0
- package/lib/import/modules/custom-roles.js +0 -0
- package/lib/import/modules/entries.d.ts +6 -0
- package/lib/import/modules/entries.js +20 -0
- package/lib/import/modules/extensions.d.ts +20 -0
- package/lib/import/modules/extensions.js +61 -0
- package/lib/import/modules/global-fields.d.ts +0 -0
- package/lib/import/modules/global-fields.js +0 -0
- package/lib/import/modules/index.d.ts +0 -0
- package/lib/import/modules/index.js +0 -0
- package/lib/import/modules/marketplace-apps.d.ts +26 -0
- package/lib/import/modules/marketplace-apps.js +81 -0
- package/lib/import/modules/taxonomies.d.ts +53 -0
- package/lib/import/modules/taxonomies.js +141 -0
- package/lib/types/default-config.d.ts +55 -0
- package/lib/types/default-config.js +2 -0
- package/lib/types/import-config.d.ts +55 -0
- package/lib/types/import-config.js +2 -0
- package/lib/types/index.d.ts +115 -0
- package/lib/types/index.js +2 -0
- package/lib/utils/backup-handler.d.ts +2 -0
- package/lib/utils/backup-handler.js +61 -0
- package/lib/utils/common-helper.d.ts +0 -0
- package/lib/utils/common-helper.js +0 -0
- package/lib/utils/file-helper.d.ts +15 -0
- package/lib/utils/file-helper.js +144 -0
- package/lib/utils/import-config-handler.d.ts +3 -0
- package/lib/utils/import-config-handler.js +91 -0
- package/lib/utils/index.d.ts +7 -0
- package/lib/utils/index.js +16 -0
- package/lib/utils/interactive.d.ts +3 -0
- package/lib/utils/interactive.js +38 -0
- package/lib/utils/log.d.ts +12 -0
- package/lib/utils/log.js +31 -0
- package/lib/utils/logger.d.ts +8 -0
- package/lib/utils/logger.js +157 -0
- package/lib/utils/login-handler.d.ts +8 -0
- package/lib/utils/login-handler.js +53 -0
- package/messages/index.json +1 -0
- package/oclif.manifest.json +56 -0
- package/package.json +96 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024 Contentstack
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
@contentstack/cli-cm-import
|
|
2
|
+
|
|
3
|
+
It is Contentstack’s CLI plugin to import content in the stack. To learn how to export and import content in Contentstack, refer to the [Migration guide](https://www.contentstack.com/docs/developers/cli/migration/).
|
|
4
|
+
|
|
5
|
+
[](https://github.com/contentstack/cli/blob/main/LICENSE)it -m
|
|
6
|
+
|
|
7
|
+
<!-- toc -->
|
|
8
|
+
* [Usage](#usage)
|
|
9
|
+
* [Commands](#commands)
|
|
10
|
+
<!-- tocstop -->
|
|
11
|
+
|
|
12
|
+
For switching to EU region update the hosts at config/default.js
|
|
13
|
+
|
|
14
|
+
```js
|
|
15
|
+
{
|
|
16
|
+
host:'https://eu-api.contentstack.com/v3',
|
|
17
|
+
cdn: 'https://eu-cdn.contentstack.com/v3',
|
|
18
|
+
...
|
|
19
|
+
}
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
For switching to AZURE-NA region update the hosts at config/default.js
|
|
23
|
+
|
|
24
|
+
```js
|
|
25
|
+
{
|
|
26
|
+
host:'https://azure-na-api.contentstack.com/v3',
|
|
27
|
+
cdn: 'https://azure-na-cdn.contentstack.com/v3'
|
|
28
|
+
...
|
|
29
|
+
}
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
For switching to AZURE-EU region update the hosts at config/default.js
|
|
33
|
+
|
|
34
|
+
```js
|
|
35
|
+
{
|
|
36
|
+
host:'https://azure-eu-api.contentstack.com/v3',
|
|
37
|
+
cdn: 'https://azure-eu-cdn.contentstack.com/v3'
|
|
38
|
+
...
|
|
39
|
+
}
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
# Usage
|
|
43
|
+
|
|
44
|
+
<!-- usage -->
|
|
45
|
+
```sh-session
|
|
46
|
+
$ npm install -g @contentstack/cli-cm-import-setup
|
|
47
|
+
$ csdx COMMAND
|
|
48
|
+
running command...
|
|
49
|
+
$ csdx (--version)
|
|
50
|
+
@contentstack/cli-cm-import-setup/1.0.0-beta.1 linux-x64 node-v18.20.5
|
|
51
|
+
$ csdx --help [COMMAND]
|
|
52
|
+
USAGE
|
|
53
|
+
$ csdx COMMAND
|
|
54
|
+
...
|
|
55
|
+
```
|
|
56
|
+
<!-- usagestop -->
|
|
57
|
+
|
|
58
|
+
# Commands
|
|
59
|
+
|
|
60
|
+
<!-- commands -->
|
|
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-1)
|
|
63
|
+
|
|
64
|
+
## `csdx cm:stacks:import-setup [-k <value>] [-d <value>] [-a <value>] [--modules <value,value>]`
|
|
65
|
+
|
|
66
|
+
Import content from a stack
|
|
67
|
+
|
|
68
|
+
```
|
|
69
|
+
USAGE
|
|
70
|
+
$ csdx cm:stacks:import-setup [-k <value>] [-d <value>] [-a <value>] [--modules <value,value>]
|
|
71
|
+
|
|
72
|
+
FLAGS
|
|
73
|
+
-a, --alias=<value> alias of the management token
|
|
74
|
+
-d, --data-dir=<value> path and location where data is stored
|
|
75
|
+
-k, --stack-api-key=<value> API key of the target stack
|
|
76
|
+
--modules=<option> [optional] specific module name
|
|
77
|
+
<options: content-types|entries|both>
|
|
78
|
+
|
|
79
|
+
DESCRIPTION
|
|
80
|
+
Import content from a stack
|
|
81
|
+
|
|
82
|
+
ALIASES
|
|
83
|
+
$ csdx cm:import-setup
|
|
84
|
+
|
|
85
|
+
EXAMPLES
|
|
86
|
+
$ csdx cm:stacks:import-setup --stack-api-key <stack_api_key> --data-dir <path/of/export/destination/dir> --modules <module_name, module_name>
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
## `csdx cm:stacks:import-setup [-k <value>] [-d <value>] [-a <value>] [--modules <value,value>]`
|
|
90
|
+
|
|
91
|
+
Import content from a stack
|
|
92
|
+
|
|
93
|
+
```
|
|
94
|
+
USAGE
|
|
95
|
+
$ csdx cm:stacks:import-setup [-k <value>] [-d <value>] [-a <value>] [--modules <value,value>]
|
|
96
|
+
|
|
97
|
+
FLAGS
|
|
98
|
+
-a, --alias=<value> alias of the management token
|
|
99
|
+
-d, --data-dir=<value> path and location where data is stored
|
|
100
|
+
-k, --stack-api-key=<value> API key of the target stack
|
|
101
|
+
--modules=<option> [optional] specific module name
|
|
102
|
+
<options: content-types|entries|both>
|
|
103
|
+
|
|
104
|
+
DESCRIPTION
|
|
105
|
+
Import content from a stack
|
|
106
|
+
|
|
107
|
+
ALIASES
|
|
108
|
+
$ csdx cm:import-setup
|
|
109
|
+
|
|
110
|
+
EXAMPLES
|
|
111
|
+
$ csdx cm:stacks:import-setup --stack-api-key <stack_api_key> --data-dir <path/of/export/destination/dir> --modules <module_name, module_name>
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
_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)_
|
|
115
|
+
<!-- commandsstop -->
|
package/bin/dev.cmd
ADDED
package/bin/dev.js
ADDED
package/bin/run.cmd
ADDED
package/bin/run.js
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { Command } from '@contentstack/cli-command';
|
|
2
|
+
import { FlagInput } from '@contentstack/cli-utilities';
|
|
3
|
+
export default class ImportSetupCommand extends Command {
|
|
4
|
+
static description: string;
|
|
5
|
+
static examples: string[];
|
|
6
|
+
static flags: FlagInput;
|
|
7
|
+
static aliases: string[];
|
|
8
|
+
static usage: string;
|
|
9
|
+
run(): Promise<void>;
|
|
10
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const tslib_1 = require("tslib");
|
|
4
|
+
const node_path_1 = tslib_1.__importDefault(require("node:path"));
|
|
5
|
+
const cli_command_1 = require("@contentstack/cli-command");
|
|
6
|
+
const cli_utilities_1 = require("@contentstack/cli-utilities");
|
|
7
|
+
const utils_1 = require("../../../utils");
|
|
8
|
+
const import_1 = require("../../../import");
|
|
9
|
+
class ImportSetupCommand extends cli_command_1.Command {
|
|
10
|
+
async run() {
|
|
11
|
+
try {
|
|
12
|
+
const { flags } = await this.parse(ImportSetupCommand);
|
|
13
|
+
let importSetupConfig = await (0, utils_1.setupImportConfig)(flags);
|
|
14
|
+
// Note setting host to create cma client
|
|
15
|
+
importSetupConfig.host = this.cmaHost;
|
|
16
|
+
importSetupConfig.region = this.region;
|
|
17
|
+
importSetupConfig.developerHubBaseUrl = this.developerHubUrl;
|
|
18
|
+
const managementAPIClient = await (0, cli_utilities_1.managementSDKClient)(importSetupConfig);
|
|
19
|
+
const importSetup = new import_1.ImportSetup(importSetupConfig, managementAPIClient);
|
|
20
|
+
await importSetup.start();
|
|
21
|
+
(0, utils_1.log)(importSetupConfig, `Successfully created backup folder and mapper files for the stack with the API key ${importSetupConfig.apiKey}.`, 'success');
|
|
22
|
+
(0, utils_1.log)(importSetupConfig, `The backup folder created at '${(0, cli_utilities_1.pathValidator)(node_path_1.default.join(importSetupConfig.backupDir))}'`, 'success');
|
|
23
|
+
}
|
|
24
|
+
catch (error) {
|
|
25
|
+
(0, utils_1.log)({ data: '' }, `Failed to create backup folder and mapper files - ${(0, cli_utilities_1.formatError)(error)}`, 'error');
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
exports.default = ImportSetupCommand;
|
|
30
|
+
ImportSetupCommand.description = cli_utilities_1.messageHandler.parse('Import content from a stack');
|
|
31
|
+
ImportSetupCommand.examples = [
|
|
32
|
+
`csdx cm:stacks:import-setup --stack-api-key <stack_api_key> --data-dir <path/of/export/destination/dir> --modules <module_name, module_name>`,
|
|
33
|
+
];
|
|
34
|
+
ImportSetupCommand.flags = {
|
|
35
|
+
'stack-api-key': cli_utilities_1.flags.string({
|
|
36
|
+
char: 'k',
|
|
37
|
+
description: 'API key of the target stack',
|
|
38
|
+
}),
|
|
39
|
+
'data-dir': cli_utilities_1.flags.string({
|
|
40
|
+
char: 'd',
|
|
41
|
+
description: 'path and location where data is stored',
|
|
42
|
+
}),
|
|
43
|
+
alias: cli_utilities_1.flags.string({
|
|
44
|
+
char: 'a',
|
|
45
|
+
description: 'alias of the management token',
|
|
46
|
+
}),
|
|
47
|
+
modules: cli_utilities_1.flags.string({
|
|
48
|
+
options: ['content-types', 'entries', 'both'],
|
|
49
|
+
description: '[optional] specific module name',
|
|
50
|
+
}),
|
|
51
|
+
};
|
|
52
|
+
ImportSetupCommand.aliases = ['cm:import-setup'];
|
|
53
|
+
ImportSetupCommand.usage = 'cm:stacks:import-setup [-k <value>] [-d <value>] [-a <value>] [--modules <value,value>]';
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const config = {
|
|
4
|
+
// use below hosts for eu region
|
|
5
|
+
// host:'https://eu-api.contentstack.com/v3',
|
|
6
|
+
// use below hosts for azure-na region
|
|
7
|
+
// host:'https://azure-na-api.contentstack.com/v3',
|
|
8
|
+
// use below hosts for azure-eu region
|
|
9
|
+
// host:'https://azure-eu-api.contentstack.com/v3',
|
|
10
|
+
// use below hosts for gcp-na region
|
|
11
|
+
// host:'https://gcp-na-api.contentstack.com',
|
|
12
|
+
// pass locale, only to migrate entries from that locale
|
|
13
|
+
// not passing `locale` will migrate all the locales present
|
|
14
|
+
// locales: ['fr-fr'],
|
|
15
|
+
host: 'https://api.contentstack.io/v3',
|
|
16
|
+
developerHubBaseUrl: '',
|
|
17
|
+
modules: {
|
|
18
|
+
'custom-roles': {
|
|
19
|
+
dirName: 'custom-roles',
|
|
20
|
+
fileName: 'custom-roles.json',
|
|
21
|
+
dependencies: ['environments', 'entries'],
|
|
22
|
+
},
|
|
23
|
+
environments: {
|
|
24
|
+
dirName: 'environments',
|
|
25
|
+
fileName: 'environments.json',
|
|
26
|
+
},
|
|
27
|
+
extensions: {
|
|
28
|
+
dirName: 'extensions',
|
|
29
|
+
fileName: 'extensions.json',
|
|
30
|
+
},
|
|
31
|
+
assets: {
|
|
32
|
+
dirName: 'assets',
|
|
33
|
+
fileName: 'assets.json',
|
|
34
|
+
fetchConcurrency: 5,
|
|
35
|
+
},
|
|
36
|
+
'content-types': {
|
|
37
|
+
dirName: 'content_types',
|
|
38
|
+
fileName: 'content_types.json',
|
|
39
|
+
dependencies: ['extensions', 'marketplace-apps', 'taxonomies'],
|
|
40
|
+
},
|
|
41
|
+
entries: {
|
|
42
|
+
dirName: 'entries',
|
|
43
|
+
fileName: 'entries.json',
|
|
44
|
+
dependencies: ['assets', 'marketplace-apps', 'taxonomies'],
|
|
45
|
+
},
|
|
46
|
+
'global-fields': {
|
|
47
|
+
dirName: 'global_fields',
|
|
48
|
+
fileName: 'globalfields.json',
|
|
49
|
+
dependencies: ['marketplace-apps'],
|
|
50
|
+
},
|
|
51
|
+
'marketplace-apps': {
|
|
52
|
+
dirName: 'marketplace_apps',
|
|
53
|
+
fileName: 'marketplace_apps.json',
|
|
54
|
+
},
|
|
55
|
+
taxonomies: {
|
|
56
|
+
dirName: 'taxonomies',
|
|
57
|
+
fileName: 'taxonomies.json',
|
|
58
|
+
invalidKeys: [
|
|
59
|
+
'updated_at',
|
|
60
|
+
'created_by',
|
|
61
|
+
'updated_by',
|
|
62
|
+
'stackHeaders',
|
|
63
|
+
'urlPath',
|
|
64
|
+
'created_at',
|
|
65
|
+
'ancestors',
|
|
66
|
+
'update',
|
|
67
|
+
'delete',
|
|
68
|
+
'fetch',
|
|
69
|
+
'descendants',
|
|
70
|
+
'move',
|
|
71
|
+
'search',
|
|
72
|
+
],
|
|
73
|
+
},
|
|
74
|
+
},
|
|
75
|
+
fetchConcurrency: 5,
|
|
76
|
+
};
|
|
77
|
+
exports.default = config;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { ImportConfig } from '../types';
|
|
2
|
+
import { ContentstackClient } from '@contentstack/cli-utilities';
|
|
3
|
+
export default class ImportSetup {
|
|
4
|
+
protected config: ImportConfig;
|
|
5
|
+
private managementAPIClient;
|
|
6
|
+
private importConfig;
|
|
7
|
+
private stackAPIClient;
|
|
8
|
+
dependencyTree: {
|
|
9
|
+
[key: string]: string[];
|
|
10
|
+
};
|
|
11
|
+
constructor(config: ImportConfig, managementAPIClient: ContentstackClient);
|
|
12
|
+
/**
|
|
13
|
+
* Generate mapper logic
|
|
14
|
+
* This method generates dependency tree based on the selected modules
|
|
15
|
+
* @returns {Promise<Array<void | string>>}
|
|
16
|
+
*/
|
|
17
|
+
protected generateDependencyTree(): Promise<void>;
|
|
18
|
+
/**
|
|
19
|
+
* Run module imports based on the selected modules
|
|
20
|
+
* This method dynamically imports modules based on the selected modules
|
|
21
|
+
* and runs the start method of each module
|
|
22
|
+
* @returns {Promise<void>}
|
|
23
|
+
*/
|
|
24
|
+
protected runModuleImports(): Promise<void>;
|
|
25
|
+
/**
|
|
26
|
+
* Start the import setup process
|
|
27
|
+
* This method generates mapper logic and runs module imports
|
|
28
|
+
* based on the selected modules
|
|
29
|
+
* @returns {Promise<void>}
|
|
30
|
+
*/
|
|
31
|
+
start(): Promise<void>;
|
|
32
|
+
}
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
+
if (mod && mod.__esModule) return mod;
|
|
20
|
+
var result = {};
|
|
21
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
+
__setModuleDefault(result, mod);
|
|
23
|
+
return result;
|
|
24
|
+
};
|
|
25
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
|
+
const utils_1 = require("../utils");
|
|
27
|
+
const cli_utilities_1 = require("@contentstack/cli-utilities");
|
|
28
|
+
class ImportSetup {
|
|
29
|
+
constructor(config, managementAPIClient) {
|
|
30
|
+
this.dependencyTree = {};
|
|
31
|
+
this.config = config;
|
|
32
|
+
this.managementAPIClient = managementAPIClient;
|
|
33
|
+
this.stackAPIClient = this.managementAPIClient.stack({
|
|
34
|
+
api_key: this.config.apiKey,
|
|
35
|
+
management_token: this.config.management_token,
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Generate mapper logic
|
|
40
|
+
* This method generates dependency tree based on the selected modules
|
|
41
|
+
* @returns {Promise<Array<void | string>>}
|
|
42
|
+
*/
|
|
43
|
+
async generateDependencyTree() {
|
|
44
|
+
const getAllDependencies = (module, visited = new Set()) => {
|
|
45
|
+
var _a;
|
|
46
|
+
if (visited.has(module))
|
|
47
|
+
return [];
|
|
48
|
+
visited.add(module);
|
|
49
|
+
let dependencies = ((_a = this.config.modules[module]) === null || _a === void 0 ? void 0 : _a.dependencies) || [];
|
|
50
|
+
for (const dependency of dependencies) {
|
|
51
|
+
dependencies = dependencies.concat(getAllDependencies(dependency, visited));
|
|
52
|
+
}
|
|
53
|
+
return dependencies;
|
|
54
|
+
};
|
|
55
|
+
for (const module of this.config.selectedModules) {
|
|
56
|
+
const allDependencies = getAllDependencies(module);
|
|
57
|
+
this.dependencyTree[module] = Array.from(new Set(allDependencies));
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Run module imports based on the selected modules
|
|
62
|
+
* This method dynamically imports modules based on the selected modules
|
|
63
|
+
* and runs the start method of each module
|
|
64
|
+
* @returns {Promise<void>}
|
|
65
|
+
*/
|
|
66
|
+
async runModuleImports() {
|
|
67
|
+
var _a;
|
|
68
|
+
for (const moduleName in this.dependencyTree) {
|
|
69
|
+
try {
|
|
70
|
+
const modulePath = `./modules/${moduleName}`;
|
|
71
|
+
const { default: ModuleClass } = await (_a = modulePath, Promise.resolve().then(() => __importStar(require(_a))));
|
|
72
|
+
const modulePayload = {
|
|
73
|
+
config: this.config,
|
|
74
|
+
dependencies: this.dependencyTree[moduleName],
|
|
75
|
+
stackAPIClient: this.stackAPIClient,
|
|
76
|
+
};
|
|
77
|
+
const moduleInstance = new ModuleClass(modulePayload);
|
|
78
|
+
await moduleInstance.start();
|
|
79
|
+
}
|
|
80
|
+
catch (error) {
|
|
81
|
+
(0, utils_1.log)(this.config, `Error importing '${moduleName}': ${(0, cli_utilities_1.formatError)(error)}`, 'error');
|
|
82
|
+
throw error;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Start the import setup process
|
|
88
|
+
* This method generates mapper logic and runs module imports
|
|
89
|
+
* based on the selected modules
|
|
90
|
+
* @returns {Promise<void>}
|
|
91
|
+
*/
|
|
92
|
+
async start() {
|
|
93
|
+
try {
|
|
94
|
+
if (!this.config.management_token) {
|
|
95
|
+
const stackDetails = await this.stackAPIClient.fetch();
|
|
96
|
+
this.config.stackName = stackDetails.name;
|
|
97
|
+
this.config.org_uid = stackDetails.org_uid;
|
|
98
|
+
}
|
|
99
|
+
const backupDir = await (0, utils_1.backupHandler)(this.config);
|
|
100
|
+
if (backupDir) {
|
|
101
|
+
this.config.backupDir = backupDir;
|
|
102
|
+
}
|
|
103
|
+
await this.generateDependencyTree();
|
|
104
|
+
await this.runModuleImports();
|
|
105
|
+
}
|
|
106
|
+
catch (error) {
|
|
107
|
+
console.log(error);
|
|
108
|
+
throw error;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
exports.default = ImportSetup;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default as ImportSetup } from './import-setup';
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.ImportSetup = void 0;
|
|
7
|
+
var import_setup_1 = require("./import-setup");
|
|
8
|
+
Object.defineProperty(exports, "ImportSetup", { enumerable: true, get: function () { return __importDefault(import_setup_1).default; } });
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { ModuleClassParams } from '../../types';
|
|
2
|
+
import BaseImportSetup from './base-setup';
|
|
3
|
+
export default class AssetImportSetup extends BaseImportSetup {
|
|
4
|
+
private assetsFilePath;
|
|
5
|
+
private assetUidMapper;
|
|
6
|
+
private assetUrlMapper;
|
|
7
|
+
private duplicateAssets;
|
|
8
|
+
private assetsConfig;
|
|
9
|
+
private mapperDirPath;
|
|
10
|
+
private assetsFolderPath;
|
|
11
|
+
private assetUidMapperPath;
|
|
12
|
+
private assetUrlMapperPath;
|
|
13
|
+
private duplicateAssetPath;
|
|
14
|
+
constructor({ config, stackAPIClient, dependencies }: ModuleClassParams);
|
|
15
|
+
/**
|
|
16
|
+
* Start the asset import setup
|
|
17
|
+
* This method reads the assets from the content folder and generates a mapper file
|
|
18
|
+
* @returns {Promise<void>}
|
|
19
|
+
*/
|
|
20
|
+
start(): Promise<void>;
|
|
21
|
+
/**
|
|
22
|
+
* @method importAssets
|
|
23
|
+
* @param {boolean} isVersion boolean
|
|
24
|
+
* @returns {Promise<void>} Promise<void>
|
|
25
|
+
*/
|
|
26
|
+
fetchAndMapAssets(): Promise<void>;
|
|
27
|
+
}
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const tslib_1 = require("tslib");
|
|
4
|
+
const utils_1 = require("../../utils");
|
|
5
|
+
const path_1 = require("path");
|
|
6
|
+
const lodash_1 = require("lodash");
|
|
7
|
+
const cli_utilities_1 = require("@contentstack/cli-utilities");
|
|
8
|
+
const base_setup_1 = tslib_1.__importDefault(require("./base-setup"));
|
|
9
|
+
class AssetImportSetup extends base_setup_1.default {
|
|
10
|
+
constructor({ config, stackAPIClient, dependencies }) {
|
|
11
|
+
super({ config, stackAPIClient, dependencies });
|
|
12
|
+
this.assetsFolderPath = (0, path_1.join)((0, cli_utilities_1.sanitizePath)(this.config.contentDir), 'assets');
|
|
13
|
+
this.assetsFilePath = (0, path_1.join)((0, cli_utilities_1.sanitizePath)(this.config.contentDir), 'assets', 'assets.json');
|
|
14
|
+
this.assetsConfig = config.modules.assets;
|
|
15
|
+
this.mapperDirPath = (0, path_1.join)((0, cli_utilities_1.sanitizePath)(this.config.backupDir), 'mapper', 'assets');
|
|
16
|
+
this.assetUidMapperPath = (0, path_1.join)((0, cli_utilities_1.sanitizePath)(this.config.backupDir), 'mapper', 'assets', 'uid-mapping.json');
|
|
17
|
+
this.assetUrlMapperPath = (0, path_1.join)((0, cli_utilities_1.sanitizePath)(this.config.backupDir), 'mapper', 'assets', 'url-mapping.json');
|
|
18
|
+
this.duplicateAssetPath = (0, path_1.join)((0, cli_utilities_1.sanitizePath)(this.config.backupDir), 'mapper', 'assets', 'duplicate-assets.json');
|
|
19
|
+
this.assetUidMapper = {};
|
|
20
|
+
this.assetUrlMapper = {};
|
|
21
|
+
this.duplicateAssets = {};
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Start the asset import setup
|
|
25
|
+
* This method reads the assets from the content folder and generates a mapper file
|
|
26
|
+
* @returns {Promise<void>}
|
|
27
|
+
*/
|
|
28
|
+
async start() {
|
|
29
|
+
try {
|
|
30
|
+
utils_1.fsUtil.makeDirectory(this.mapperDirPath);
|
|
31
|
+
await this.fetchAndMapAssets();
|
|
32
|
+
(0, utils_1.log)(this.config, `Generated required setup files for asset`, 'success');
|
|
33
|
+
}
|
|
34
|
+
catch (error) {
|
|
35
|
+
(0, utils_1.log)(this.config, `Error generating asset mapper: ${(0, cli_utilities_1.formatError)(error)}`, 'error');
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* @method importAssets
|
|
40
|
+
* @param {boolean} isVersion boolean
|
|
41
|
+
* @returns {Promise<void>} Promise<void>
|
|
42
|
+
*/
|
|
43
|
+
async fetchAndMapAssets() {
|
|
44
|
+
const processName = 'mapping assets';
|
|
45
|
+
const indexFileName = 'assets.json';
|
|
46
|
+
const basePath = this.assetsFolderPath;
|
|
47
|
+
const fs = new cli_utilities_1.FsUtility({ basePath, indexFileName });
|
|
48
|
+
const indexer = fs.indexFileContent;
|
|
49
|
+
const indexerCount = (0, lodash_1.values)(indexer).length;
|
|
50
|
+
const onSuccess = ({ response: { items = [] } = {}, apiData: { uid, url, title } = undefined, }) => {
|
|
51
|
+
if (items.length === 1) {
|
|
52
|
+
this.assetUidMapper[uid] = items[0].uid;
|
|
53
|
+
this.assetUrlMapper[url] = items[0].url;
|
|
54
|
+
(0, utils_1.log)(this.config, `Mapped asset: '${title}'`, 'info');
|
|
55
|
+
}
|
|
56
|
+
else if (items.length > 1) {
|
|
57
|
+
this.duplicateAssets[uid] = items.map((asset) => {
|
|
58
|
+
return { uid: asset.uid, title: asset.title, url: asset.url };
|
|
59
|
+
});
|
|
60
|
+
(0, utils_1.log)(this.config, `Multiple assets found with title '${title}'`, 'info');
|
|
61
|
+
}
|
|
62
|
+
else {
|
|
63
|
+
(0, utils_1.log)(this.config, `Asset with title '${title}' not found in the stack!`, 'info');
|
|
64
|
+
}
|
|
65
|
+
};
|
|
66
|
+
const onReject = ({ error, apiData: { title } = undefined }) => {
|
|
67
|
+
(0, utils_1.log)(this.config, `${title} asset mapping failed.!`, 'error');
|
|
68
|
+
(0, utils_1.log)(this.config, (0, cli_utilities_1.formatError)(error), 'error');
|
|
69
|
+
};
|
|
70
|
+
/* eslint-disable @typescript-eslint/no-unused-vars, guard-for-in */
|
|
71
|
+
for (const index in indexer) {
|
|
72
|
+
const chunk = await fs.readChunkFiles.next().catch((error) => {
|
|
73
|
+
(0, utils_1.log)(this.config, error, 'error');
|
|
74
|
+
});
|
|
75
|
+
if (chunk) {
|
|
76
|
+
let apiContent = (0, lodash_1.orderBy)((0, lodash_1.values)(chunk), '_version');
|
|
77
|
+
await this.makeConcurrentCall({
|
|
78
|
+
apiContent,
|
|
79
|
+
processName,
|
|
80
|
+
indexerCount,
|
|
81
|
+
currentIndexer: +index,
|
|
82
|
+
apiParams: {
|
|
83
|
+
reject: onReject,
|
|
84
|
+
resolve: onSuccess,
|
|
85
|
+
entity: 'fetch-assets',
|
|
86
|
+
includeParamOnCompletion: true,
|
|
87
|
+
},
|
|
88
|
+
concurrencyLimit: this.assetsConfig.fetchConcurrency,
|
|
89
|
+
}, undefined);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
if (!(0, lodash_1.isEmpty)(this.assetUidMapper) || !(0, lodash_1.isEmpty)(this.assetUrlMapper)) {
|
|
93
|
+
utils_1.fsUtil.writeFile(this.assetUidMapperPath, this.assetUidMapper);
|
|
94
|
+
utils_1.fsUtil.writeFile(this.assetUrlMapperPath, this.assetUrlMapper);
|
|
95
|
+
}
|
|
96
|
+
if (!(0, lodash_1.isEmpty)(this.duplicateAssets)) {
|
|
97
|
+
utils_1.fsUtil.writeFile(this.duplicateAssetPath, this.duplicateAssets);
|
|
98
|
+
(0, utils_1.log)(this.config, `Duplicate asset files store here ${this.duplicateAssetPath}`, 'info');
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
exports.default = AssetImportSetup;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { ApiOptions, CustomPromiseHandler, EnvType, ImportConfig, ModuleClassParams } from '../../types';
|
|
2
|
+
export default class BaseImportSetup {
|
|
3
|
+
config: ImportConfig;
|
|
4
|
+
stackAPIClient: ModuleClassParams['stackAPIClient'];
|
|
5
|
+
dependencies: ModuleClassParams['dependencies'];
|
|
6
|
+
constructor({ config, stackAPIClient, dependencies }: ModuleClassParams);
|
|
7
|
+
setupDependencies(): Promise<void>;
|
|
8
|
+
/**
|
|
9
|
+
* @method delay
|
|
10
|
+
* @param {number} ms number
|
|
11
|
+
* @returns {Promise} Promise<void>
|
|
12
|
+
*/
|
|
13
|
+
delay(ms: number): Promise<void>;
|
|
14
|
+
/**
|
|
15
|
+
* @method makeConcurrentCall
|
|
16
|
+
* @param {Record<string, any>} env EnvType
|
|
17
|
+
* @param {CustomPromiseHandler} promisifyHandler CustomPromiseHandler
|
|
18
|
+
* @param {boolean} logBatchCompletionMsg boolean
|
|
19
|
+
* @returns {Promise} Promise<void>
|
|
20
|
+
*/
|
|
21
|
+
makeConcurrentCall(env: EnvType, promisifyHandler?: CustomPromiseHandler, logBatchCompletionMsg?: boolean): Promise<void>;
|
|
22
|
+
/**
|
|
23
|
+
* @method logMsgAndWaitIfRequired
|
|
24
|
+
* @param {string} processName string
|
|
25
|
+
* @param {number} start number
|
|
26
|
+
* @param {number} batchNo - number
|
|
27
|
+
* @returns {Promise} Promise<void>
|
|
28
|
+
*/
|
|
29
|
+
logMsgAndWaitIfRequired(processName: string, start: number, totelBatches: number, batchNo: number, logBatchCompletionMsg?: boolean, indexerCount?: number, currentIndexer?: number): Promise<void>;
|
|
30
|
+
/**
|
|
31
|
+
* @method makeAPICall
|
|
32
|
+
* @param {Record<string, any>} apiOptions - Api related params
|
|
33
|
+
* @param {Record<string, any>} isLastRequest - Boolean
|
|
34
|
+
* @return {Promise} Promise<void>
|
|
35
|
+
*/
|
|
36
|
+
makeAPICall(apiOptions: ApiOptions, isLastRequest?: boolean): Promise<void>;
|
|
37
|
+
}
|