@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.
Files changed (61) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +115 -0
  3. package/bin/dev.cmd +3 -0
  4. package/bin/dev.js +6 -0
  5. package/bin/run.cmd +3 -0
  6. package/bin/run.js +7 -0
  7. package/lib/commands/cm/stacks/import-setup.d.ts +10 -0
  8. package/lib/commands/cm/stacks/import-setup.js +53 -0
  9. package/lib/config/index.d.ts +3 -0
  10. package/lib/config/index.js +77 -0
  11. package/lib/import/import-setup.d.ts +32 -0
  12. package/lib/import/import-setup.js +112 -0
  13. package/lib/import/index.d.ts +1 -0
  14. package/lib/import/index.js +8 -0
  15. package/lib/import/modules/assets.d.ts +27 -0
  16. package/lib/import/modules/assets.js +102 -0
  17. package/lib/import/modules/base-setup.d.ts +37 -0
  18. package/lib/import/modules/base-setup.js +183 -0
  19. package/lib/import/modules/content-types.d.ts +6 -0
  20. package/lib/import/modules/content-types.js +20 -0
  21. package/lib/import/modules/custom-roles.d.ts +0 -0
  22. package/lib/import/modules/custom-roles.js +0 -0
  23. package/lib/import/modules/entries.d.ts +6 -0
  24. package/lib/import/modules/entries.js +20 -0
  25. package/lib/import/modules/extensions.d.ts +20 -0
  26. package/lib/import/modules/extensions.js +61 -0
  27. package/lib/import/modules/global-fields.d.ts +0 -0
  28. package/lib/import/modules/global-fields.js +0 -0
  29. package/lib/import/modules/index.d.ts +0 -0
  30. package/lib/import/modules/index.js +0 -0
  31. package/lib/import/modules/marketplace-apps.d.ts +26 -0
  32. package/lib/import/modules/marketplace-apps.js +81 -0
  33. package/lib/import/modules/taxonomies.d.ts +53 -0
  34. package/lib/import/modules/taxonomies.js +141 -0
  35. package/lib/types/default-config.d.ts +55 -0
  36. package/lib/types/default-config.js +2 -0
  37. package/lib/types/import-config.d.ts +55 -0
  38. package/lib/types/import-config.js +2 -0
  39. package/lib/types/index.d.ts +115 -0
  40. package/lib/types/index.js +2 -0
  41. package/lib/utils/backup-handler.d.ts +2 -0
  42. package/lib/utils/backup-handler.js +61 -0
  43. package/lib/utils/common-helper.d.ts +0 -0
  44. package/lib/utils/common-helper.js +0 -0
  45. package/lib/utils/file-helper.d.ts +15 -0
  46. package/lib/utils/file-helper.js +144 -0
  47. package/lib/utils/import-config-handler.d.ts +3 -0
  48. package/lib/utils/import-config-handler.js +91 -0
  49. package/lib/utils/index.d.ts +7 -0
  50. package/lib/utils/index.js +16 -0
  51. package/lib/utils/interactive.d.ts +3 -0
  52. package/lib/utils/interactive.js +38 -0
  53. package/lib/utils/log.d.ts +12 -0
  54. package/lib/utils/log.js +31 -0
  55. package/lib/utils/logger.d.ts +8 -0
  56. package/lib/utils/logger.js +157 -0
  57. package/lib/utils/login-handler.d.ts +8 -0
  58. package/lib/utils/login-handler.js +53 -0
  59. package/messages/index.json +1 -0
  60. package/oclif.manifest.json +56 -0
  61. 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
+ [![License](https://img.shields.io/npm/l/@contentstack/cli)](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
@@ -0,0 +1,3 @@
1
+ @echo off
2
+
3
+ node "%~dp0\dev" %*
package/bin/dev.js ADDED
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env node_modules/.bin/ts-node
2
+ // eslint-disable-next-line node/shebang, unicorn/prefer-top-level-await
3
+ (async () => {
4
+ const oclif = await import('@oclif/core');
5
+ await oclif.execute({ development: true, dir: __dirname });
6
+ })();
package/bin/run.cmd ADDED
@@ -0,0 +1,3 @@
1
+ @echo off
2
+
3
+ node "%~dp0\run" %*
package/bin/run.js ADDED
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env node
2
+
3
+ // eslint-disable-next-line unicorn/prefer-top-level-await
4
+ (async () => {
5
+ const oclif = await import('@oclif/core');
6
+ await oclif.execute({ development: false, dir: __dirname });
7
+ })();
@@ -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,3 @@
1
+ import { DefaultConfig } from '../types';
2
+ declare const config: DefaultConfig;
3
+ export default config;
@@ -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
+ }