@contentstack/cli-migration 1.5.6 → 1.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -21,7 +21,7 @@ $ npm install -g @contentstack/cli-migration
21
21
  $ csdx COMMAND
22
22
  running command...
23
23
  $ csdx (--version)
24
- @contentstack/cli-migration/1.5.6 darwin-arm64 node-v21.6.2
24
+ @contentstack/cli-migration/1.6.0 darwin-arm64 node-v22.2.0
25
25
  $ csdx --help [COMMAND]
26
26
  USAGE
27
27
  $ csdx COMMAND
package/package.json CHANGED
@@ -1,11 +1,11 @@
1
1
  {
2
2
  "name": "@contentstack/cli-migration",
3
- "version": "1.5.6",
3
+ "version": "1.6.0",
4
4
  "author": "@contentstack",
5
5
  "bugs": "https://github.com/contentstack/cli/issues",
6
6
  "dependencies": {
7
- "@contentstack/cli-command": "~1.2.18",
8
- "@contentstack/cli-utilities": "~1.6.2",
7
+ "@contentstack/cli-command": "~1.2.19",
8
+ "@contentstack/cli-utilities": "~1.7.0",
9
9
  "async": "^3.2.4",
10
10
  "callsites": "^3.1.0",
11
11
  "cardinal": "^2.1.1",
@@ -66,4 +66,4 @@
66
66
  "cm:migration": "O-MGRTN"
67
67
  }
68
68
  }
69
- }
69
+ }
@@ -25,7 +25,7 @@ const {
25
25
  const { ApiError, SchemaValidator, MigrationError, FieldValidator } = require('../../../validators');
26
26
 
27
27
  // Utils
28
- const { map: _map, constants, safePromise, errorHelper } = require('../../../utils');
28
+ const { map: _map, constants, safePromise, errorHelper, installModules } = require('../../../utils');
29
29
  // Properties
30
30
  const { get, set, getMapInstance, resetMapInstance } = _map;
31
31
  const {
@@ -67,7 +67,7 @@ class MigrationCommand extends Command {
67
67
  this.exit();
68
68
  }
69
69
 
70
- if (!filePath) {
70
+ if (!filePath || !fs.existsSync(filePath)) {
71
71
  this.log('Please provide the migration script file path, use --file-path flag');
72
72
  this.exit();
73
73
  }
@@ -129,6 +129,11 @@ class MigrationCommand extends Command {
129
129
  set(MANAGEMENT_SDK, mapInstance, stackSDKInstance);
130
130
  set(MANAGEMENT_CLIENT, mapInstance, APIClient);
131
131
 
132
+ if (!(await installModules(filePath, multi))) {
133
+ this.log(`Error: Failed to install dependencies for the specified scripts.`);
134
+ process.exit(1);
135
+ }
136
+
132
137
  if (multi) {
133
138
  await this.execMultiFiles(filePath, mapInstance);
134
139
  } else {
@@ -17,4 +17,5 @@ module.exports = {
17
17
  getBatches: require('./get-batches'),
18
18
  autoRetry: require('./auto-retry'),
19
19
  contentstackSdk: require('./contentstack-sdk'),
20
+ installModules: require('./modules'),
20
21
  };
@@ -0,0 +1,134 @@
1
+ const fs = require('fs');
2
+ const { execSync } = require('child_process');
3
+ const path = require('path');
4
+ const { sanitizePath } = require('@contentstack/cli-utilities');
5
+ const os = require('os');
6
+ const { builtinModules } = require('module');
7
+
8
+ const internalModules = new Set(builtinModules);
9
+
10
+ function checkWritePermissionToDirectory(directory) {
11
+ try {
12
+ fs.accessSync(directory, fs.constants.W_OK);
13
+ return true;
14
+ } catch (err) {
15
+ console.log(`Permission Denied! You do not have the necessary write access for this directory.`);
16
+ return false;
17
+ }
18
+ }
19
+
20
+ function doesPackageJsonExist(directory) {
21
+ return fs.existsSync(path.join(sanitizePath(directory), 'package.json'));
22
+ }
23
+
24
+ function scanDirectory(directory) {
25
+ return fs.readdirSync(directory);
26
+ }
27
+
28
+ function scanFileForDependencies(directory, files) {
29
+ const dependencies = new Set();
30
+
31
+ files.forEach((file) => {
32
+ const filePath = path.join(sanitizePath(directory), sanitizePath(file));
33
+ if (path.extname(filePath) === '.js') {
34
+ const fileContent = fs.readFileSync(filePath, 'utf-8');
35
+ findModulesSync(fileContent).forEach((dep) => dependencies.add(dep));
36
+ }
37
+ });
38
+
39
+ return [...dependencies];
40
+ }
41
+
42
+ function createPackageJson(directory) {
43
+ const templateString = `{
44
+ "name": "MigrationPackage",
45
+ "version": "1.0.0",
46
+ "main": "",
47
+ "scripts": {},
48
+ "keywords": [],
49
+ "author": "",
50
+ "license": "ISC",
51
+ "description": ""
52
+ }`;
53
+
54
+ fs.writeFileSync(path.join(sanitizePath(directory), 'package.json'), templateString);
55
+ }
56
+
57
+ function installDependencies(dependencies, directory) {
58
+ const installedDependencies = new Set();
59
+
60
+ dependencies.forEach((dep) => {
61
+ if (!internalModules.has(dep)) {
62
+ const pkg = dep.startsWith('@') ? dep : dep.split('/')[0];
63
+ if (!installedDependencies.has(pkg)) {
64
+ executeShellCommand(`npm i ${pkg}`, directory);
65
+ installedDependencies.add(pkg);
66
+ }
67
+ }
68
+ });
69
+ }
70
+
71
+ function executeShellCommand(command, directory = '') {
72
+ try {
73
+ execSync(command, { stdio: 'inherit', cwd: directory });
74
+ console.log(`The '${command}' command has been executed successfully.`);
75
+ } catch (error) {
76
+ console.error(`Command execution failed. Error: ${error.message}`);
77
+ }
78
+ }
79
+
80
+ async function installModules(filePath, multiple) {
81
+ const files = multiple ? [] : [path.basename(filePath)];
82
+ const dirPath = multiple ? filePath : path.dirname(filePath);
83
+
84
+ if (checkWritePermissionToDirectory(dirPath)) {
85
+ if (multiple) {
86
+ files.push(...scanDirectory(dirPath));
87
+ }
88
+
89
+ if (files.length === 0) {
90
+ console.log(`Error: Could not locate files needed to create package.json. Exiting the process.`);
91
+ return true;
92
+ }
93
+
94
+ const dependencies = scanFileForDependencies(dirPath, files);
95
+
96
+ if (!doesPackageJsonExist(dirPath)) {
97
+ console.log(`package.json not found. Creating a new package.json...`);
98
+ createPackageJson(dirPath);
99
+ }
100
+
101
+ installDependencies(dependencies, dirPath);
102
+ } else {
103
+ console.log(`You don't have write permission to the directory`);
104
+ return false;
105
+ }
106
+
107
+ console.log(`All dependencies installed successfully.`);
108
+ return true;
109
+ }
110
+
111
+ function findModulesSync(data) {
112
+ try {
113
+ const requireRegex = /require\(['"`](.*?)['"`]\)/g;
114
+ const importRegex = /import\s+(?:(?:[\w*\s{},]*)\s+from\s+)?['"`](.*?)['"`]/g;
115
+
116
+ const modules = new Set();
117
+ let match;
118
+
119
+ while ((match = requireRegex.exec(data)) !== null) {
120
+ modules.add(match[1]);
121
+ }
122
+
123
+ while ((match = importRegex.exec(data)) !== null) {
124
+ modules.add(match[1]);
125
+ }
126
+
127
+ return [...modules];
128
+ } catch (error) {
129
+ console.error(`Error reading file: ${error.message}`);
130
+ return [];
131
+ }
132
+ }
133
+
134
+ module.exports = installModules;