@contentstack/cli-cm-clone 2.0.0-beta.2 → 2.0.0-beta.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/package.json +6 -9
- package/src/commands/cm/stacks/clone.js +87 -28
- package/src/lib/util/clone-handler.js +132 -24
- package/src/lib/util/log.js +0 -105
package/README.md
CHANGED
|
@@ -16,7 +16,7 @@ $ npm install -g @contentstack/cli-cm-clone
|
|
|
16
16
|
$ csdx COMMAND
|
|
17
17
|
running command...
|
|
18
18
|
$ csdx (--version)
|
|
19
|
-
@contentstack/cli-cm-clone/2.0.0-beta.
|
|
19
|
+
@contentstack/cli-cm-clone/2.0.0-beta.2 darwin-arm64 node-v22.14.0
|
|
20
20
|
$ csdx --help [COMMAND]
|
|
21
21
|
USAGE
|
|
22
22
|
$ csdx COMMAND
|
package/package.json
CHANGED
|
@@ -1,27 +1,24 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@contentstack/cli-cm-clone",
|
|
3
3
|
"description": "Contentstack stack clone plugin",
|
|
4
|
-
"version": "2.0.0-beta.
|
|
4
|
+
"version": "2.0.0-beta.3",
|
|
5
5
|
"author": "Contentstack",
|
|
6
6
|
"bugs": "https://github.com/rohitmishra209/cli-cm-clone/issues",
|
|
7
7
|
"dependencies": {
|
|
8
8
|
"@colors/colors": "^1.6.0",
|
|
9
|
-
"@contentstack/cli-cm-export": "~2.0.0-beta.
|
|
10
|
-
"@contentstack/cli-cm-import": "~2.0.0-beta.
|
|
11
|
-
"@contentstack/cli-command": "~1.
|
|
9
|
+
"@contentstack/cli-cm-export": "~2.0.0-beta.3",
|
|
10
|
+
"@contentstack/cli-cm-import": "~2.0.0-beta.3",
|
|
11
|
+
"@contentstack/cli-command": "~1.7.0",
|
|
12
12
|
"@contentstack/cli-utilities": "~1.15.0",
|
|
13
13
|
"@oclif/core": "^4.3.0",
|
|
14
14
|
"@oclif/plugin-help": "^6.2.28",
|
|
15
15
|
"chalk": "^4.1.2",
|
|
16
|
-
"inquirer": "8.2.
|
|
17
|
-
"inquirer-search-checkbox": "^1.0.0",
|
|
18
|
-
"inquirer-search-list": "^1.2.6",
|
|
16
|
+
"inquirer": "8.2.7",
|
|
19
17
|
"lodash": "^4.17.21",
|
|
20
18
|
"merge": "^2.1.1",
|
|
21
19
|
"ora": "^5.4.1",
|
|
22
20
|
"prompt": "^1.3.0",
|
|
23
|
-
"rimraf": "^
|
|
24
|
-
"winston": "^3.17.0"
|
|
21
|
+
"rimraf": "^6.1.0"
|
|
25
22
|
},
|
|
26
23
|
"devDependencies": {
|
|
27
24
|
"@oclif/test": "^4.1.13",
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
const { Command } = require('@contentstack/cli-command');
|
|
2
|
-
const { configHandler, flags, isAuthenticated, managementSDKClient } = require('@contentstack/cli-utilities');
|
|
2
|
+
const { configHandler, flags, isAuthenticated, managementSDKClient, log, handleAndLogError } = require('@contentstack/cli-utilities');
|
|
3
3
|
const { CloneHandler } = require('../../../lib/util/clone-handler');
|
|
4
4
|
const path = require('path');
|
|
5
5
|
const { rimraf } = require('rimraf');
|
|
@@ -9,6 +9,44 @@ const { readdirSync, readFileSync } = require('fs');
|
|
|
9
9
|
let config = {};
|
|
10
10
|
|
|
11
11
|
class StackCloneCommand extends Command {
|
|
12
|
+
/**
|
|
13
|
+
* Determine authentication method based on user preference
|
|
14
|
+
*/
|
|
15
|
+
determineAuthenticationMethod(sourceManagementTokenAlias, destinationManagementTokenAlias) {
|
|
16
|
+
// Track authentication method
|
|
17
|
+
let authenticationMethod = 'unknown';
|
|
18
|
+
|
|
19
|
+
// Determine authentication method based on user preference
|
|
20
|
+
if (sourceManagementTokenAlias || destinationManagementTokenAlias) {
|
|
21
|
+
authenticationMethod = 'Management Token';
|
|
22
|
+
} else if (isAuthenticated()) {
|
|
23
|
+
// Check if user is authenticated via OAuth
|
|
24
|
+
const isOAuthUser = configHandler.get('authorisationType') === 'OAUTH' || false;
|
|
25
|
+
if (isOAuthUser) {
|
|
26
|
+
authenticationMethod = 'OAuth';
|
|
27
|
+
} else {
|
|
28
|
+
authenticationMethod = 'Basic Auth';
|
|
29
|
+
}
|
|
30
|
+
} else {
|
|
31
|
+
authenticationMethod = 'Basic Auth';
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
return authenticationMethod;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Create clone context object for logging
|
|
39
|
+
*/
|
|
40
|
+
createCloneContext(authenticationMethod) {
|
|
41
|
+
return {
|
|
42
|
+
command: this.context?.info?.command || 'cm:stacks:clone',
|
|
43
|
+
module: 'clone',
|
|
44
|
+
email: configHandler.get('email') || '',
|
|
45
|
+
sessionId: this.context?.sessionId || '',
|
|
46
|
+
authenticationMethod: authenticationMethod || 'Basic Auth',
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
|
|
12
50
|
async run() {
|
|
13
51
|
try {
|
|
14
52
|
let self = this;
|
|
@@ -31,14 +69,27 @@ class StackCloneCommand extends Command {
|
|
|
31
69
|
|
|
32
70
|
const handleClone = async () => {
|
|
33
71
|
const listOfTokens = configHandler.get('tokens');
|
|
72
|
+
const authenticationMethod = this.determineAuthenticationMethod(
|
|
73
|
+
sourceManagementTokenAlias,
|
|
74
|
+
destinationManagementTokenAlias,
|
|
75
|
+
);
|
|
76
|
+
const cloneContext = this.createCloneContext(authenticationMethod);
|
|
77
|
+
log.debug('Starting clone operation setup', cloneContext);
|
|
34
78
|
|
|
35
79
|
if (externalConfigPath) {
|
|
80
|
+
log.debug(`Loading external configuration from: ${externalConfigPath}`, cloneContext);
|
|
36
81
|
let externalConfig = readFileSync(externalConfigPath, 'utf-8');
|
|
37
82
|
externalConfig = JSON.parse(externalConfig);
|
|
38
83
|
config = merge.recursive(config, externalConfig);
|
|
39
84
|
}
|
|
40
85
|
config.forceStopMarketplaceAppsPrompt = yes;
|
|
41
86
|
config.skipAudit = cloneCommandFlags['skip-audit'];
|
|
87
|
+
log.debug('Clone configuration prepared', {
|
|
88
|
+
...cloneContext,
|
|
89
|
+
cloneType: config.cloneType,
|
|
90
|
+
skipAudit: config.skipAudit,
|
|
91
|
+
forceStopMarketplaceAppsPrompt: config.forceStopMarketplaceAppsPrompt
|
|
92
|
+
});
|
|
42
93
|
|
|
43
94
|
if (cloneType) {
|
|
44
95
|
config.cloneType = cloneType;
|
|
@@ -67,15 +118,18 @@ class StackCloneCommand extends Command {
|
|
|
67
118
|
if (sourceManagementTokenAlias && listOfTokens[sourceManagementTokenAlias]) {
|
|
68
119
|
config.source_alias = sourceManagementTokenAlias;
|
|
69
120
|
config.source_stack = listOfTokens[sourceManagementTokenAlias].apiKey;
|
|
121
|
+
log.debug(`Using source token alias: ${sourceManagementTokenAlias}`, cloneContext);
|
|
70
122
|
} else if (sourceManagementTokenAlias) {
|
|
71
|
-
|
|
123
|
+
log.warn(`Provided source token alias (${sourceManagementTokenAlias}) not found in your config.!`, cloneContext);
|
|
72
124
|
}
|
|
73
125
|
if (destinationManagementTokenAlias && listOfTokens[destinationManagementTokenAlias]) {
|
|
74
126
|
config.destination_alias = destinationManagementTokenAlias;
|
|
75
127
|
config.target_stack = listOfTokens[destinationManagementTokenAlias].apiKey;
|
|
128
|
+
log.debug(`Using destination token alias: ${destinationManagementTokenAlias}`, cloneContext);
|
|
76
129
|
} else if (destinationManagementTokenAlias) {
|
|
77
|
-
|
|
130
|
+
log.warn(
|
|
78
131
|
`Provided destination token alias (${destinationManagementTokenAlias}) not found in your config.!`,
|
|
132
|
+
cloneContext,
|
|
79
133
|
);
|
|
80
134
|
}
|
|
81
135
|
if (importWebhookStatus) {
|
|
@@ -83,18 +137,23 @@ class StackCloneCommand extends Command {
|
|
|
83
137
|
}
|
|
84
138
|
|
|
85
139
|
const managementAPIClient = await managementSDKClient(config);
|
|
140
|
+
log.debug('Management API client initialized successfully', cloneContext);
|
|
86
141
|
|
|
87
|
-
|
|
88
|
-
this.
|
|
142
|
+
log.debug(`Content directory path: ${pathdir}`, cloneContext);
|
|
143
|
+
await this.removeContentDirIfNotEmptyBeforeClone(pathdir, cloneContext); // NOTE remove if folder not empty before clone
|
|
144
|
+
this.registerCleanupOnInterrupt(pathdir, cloneContext);
|
|
89
145
|
|
|
90
146
|
config.auth_token = configHandler.get('authtoken');
|
|
91
147
|
config.host = this.cmaHost;
|
|
92
148
|
config.cdn = this.cdaHost;
|
|
93
149
|
config.pathDir = pathdir;
|
|
150
|
+
config.cloneContext = cloneContext;
|
|
151
|
+
log.debug('Clone configuration finalized', cloneContext);
|
|
94
152
|
const cloneHandler = new CloneHandler(config);
|
|
95
153
|
cloneHandler.setClient(managementAPIClient);
|
|
154
|
+
log.debug('Starting clone operation', cloneContext);
|
|
96
155
|
cloneHandler.execute().catch((error) => {
|
|
97
|
-
|
|
156
|
+
handleAndLogError(error, cloneContext);
|
|
98
157
|
});
|
|
99
158
|
};
|
|
100
159
|
|
|
@@ -103,7 +162,7 @@ class StackCloneCommand extends Command {
|
|
|
103
162
|
if (isAuthenticated()) {
|
|
104
163
|
handleClone();
|
|
105
164
|
} else {
|
|
106
|
-
|
|
165
|
+
log.error('Log in to execute this command,csdx auth:login', cloneContext);
|
|
107
166
|
this.exit(1);
|
|
108
167
|
}
|
|
109
168
|
} else {
|
|
@@ -112,76 +171,76 @@ class StackCloneCommand extends Command {
|
|
|
112
171
|
} else if (isAuthenticated()) {
|
|
113
172
|
handleClone();
|
|
114
173
|
} else {
|
|
115
|
-
|
|
174
|
+
log.error('Please login to execute this command, csdx auth:login', cloneContext);
|
|
116
175
|
this.exit(1);
|
|
117
176
|
}
|
|
118
177
|
} catch (error) {
|
|
119
178
|
if (error) {
|
|
120
|
-
await this.cleanUp(pathdir);
|
|
121
|
-
|
|
122
|
-
console.log(error.message || error);
|
|
179
|
+
await this.cleanUp(pathdir, null, cloneContext);
|
|
180
|
+
log.error('Stack clone command failed', { ...cloneContext, error: error?.message || error });
|
|
123
181
|
}
|
|
124
182
|
}
|
|
125
183
|
}
|
|
126
184
|
|
|
127
185
|
|
|
128
186
|
|
|
129
|
-
async removeContentDirIfNotEmptyBeforeClone(dir) {
|
|
187
|
+
async removeContentDirIfNotEmptyBeforeClone(dir, cloneContext) {
|
|
130
188
|
try {
|
|
189
|
+
log.debug('Checking if content directory is empty', { ...cloneContext, dir });
|
|
131
190
|
const dirNotEmpty = readdirSync(dir).length;
|
|
132
191
|
|
|
133
192
|
if (dirNotEmpty) {
|
|
134
|
-
|
|
193
|
+
log.debug('Content directory is not empty, cleaning up', { ...cloneContext, dir });
|
|
194
|
+
await this.cleanUp(dir, null, cloneContext);
|
|
135
195
|
}
|
|
136
196
|
} catch (error) {
|
|
137
197
|
const omit = ['ENOENT']; // NOTE add emittable error codes in the array
|
|
138
198
|
|
|
139
199
|
if (!omit.includes(error.code)) {
|
|
140
|
-
|
|
200
|
+
log.error('Error checking content directory', { ...cloneContext, error: error?.message, code: error.code });
|
|
141
201
|
}
|
|
142
202
|
}
|
|
143
203
|
}
|
|
144
204
|
|
|
145
|
-
async cleanUp(pathDir, message) {
|
|
205
|
+
async cleanUp(pathDir, message, cloneContext) {
|
|
146
206
|
try {
|
|
207
|
+
log.debug('Starting cleanup', { ...cloneContext, pathDir });
|
|
147
208
|
await rimraf(pathDir);
|
|
148
209
|
if (message) {
|
|
149
|
-
|
|
150
|
-
console.log(message);
|
|
210
|
+
log.info(message, cloneContext);
|
|
151
211
|
}
|
|
212
|
+
log.debug('Cleanup completed', { ...cloneContext, pathDir });
|
|
152
213
|
} catch (err) {
|
|
153
214
|
if (err) {
|
|
154
|
-
|
|
215
|
+
log.debug('Cleaning up', cloneContext);
|
|
155
216
|
const skipCodeArr = ['ENOENT', 'EBUSY', 'EPERM', 'EMFILE', 'ENOTEMPTY'];
|
|
156
217
|
|
|
157
218
|
if (skipCodeArr.includes(err.code)) {
|
|
219
|
+
log.debug('Cleanup error code is in skip list, exiting', { ...cloneContext, code: err?.code });
|
|
158
220
|
process.exit();
|
|
159
221
|
}
|
|
160
222
|
}
|
|
161
223
|
}
|
|
162
224
|
}
|
|
163
225
|
|
|
164
|
-
registerCleanupOnInterrupt(pathDir) {
|
|
226
|
+
registerCleanupOnInterrupt(pathDir, cloneContext) {
|
|
165
227
|
const interrupt = ['SIGINT', 'SIGQUIT', 'SIGTERM'];
|
|
166
228
|
const exceptions = ['unhandledRejection', 'uncaughtException'];
|
|
167
229
|
|
|
168
230
|
const cleanUp = async (exitOrError) => {
|
|
169
231
|
if (exitOrError) {
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
// eslint-disable-next-line no-console
|
|
174
|
-
console.log('done');
|
|
175
|
-
// eslint-disable-next-line no-process-exit
|
|
232
|
+
log.debug('Cleaning up on interrupt', cloneContext);
|
|
233
|
+
await this.cleanUp(pathDir, null, cloneContext);
|
|
234
|
+
log.info('Cleanup done', cloneContext);
|
|
176
235
|
|
|
177
236
|
if (exitOrError instanceof Promise) {
|
|
178
237
|
exitOrError.catch((error) => {
|
|
179
|
-
|
|
238
|
+
log.error('Error during cleanup', { ...cloneContext, error: (error && error?.message) || '' });
|
|
180
239
|
});
|
|
181
240
|
} else if (exitOrError.message) {
|
|
182
|
-
|
|
241
|
+
log.error('Cleanup error', { ...cloneContext, error: exitOrError?.message });
|
|
183
242
|
} else if (exitOrError.errorMessage) {
|
|
184
|
-
|
|
243
|
+
log.error('Cleanup error', { ...cloneContext, error: exitOrError?.errorMessage });
|
|
185
244
|
}
|
|
186
245
|
|
|
187
246
|
if (exitOrError === true) process.exit();
|
|
@@ -21,7 +21,7 @@ const {
|
|
|
21
21
|
Clone,
|
|
22
22
|
HandleBranchCommand,
|
|
23
23
|
} = require('../helpers/command-helpers');
|
|
24
|
-
const { configHandler, getBranchFromAlias } = require('@contentstack/cli-utilities');
|
|
24
|
+
const { configHandler, getBranchFromAlias, log } = require('@contentstack/cli-utilities');
|
|
25
25
|
|
|
26
26
|
let client = {};
|
|
27
27
|
let config;
|
|
@@ -76,6 +76,7 @@ class CloneHandler {
|
|
|
76
76
|
cloneCommand = new Clone();
|
|
77
77
|
this.pathDir = opt.pathDir;
|
|
78
78
|
process.stdin.setMaxListeners(50);
|
|
79
|
+
log.debug('Initializing CloneHandler', config.cloneContext, { pathDir: opt.pathDir, cloneType: opt.cloneType });
|
|
79
80
|
}
|
|
80
81
|
setClient(managementSDKClient) {
|
|
81
82
|
client = managementSDKClient;
|
|
@@ -84,19 +85,24 @@ class CloneHandler {
|
|
|
84
85
|
handleOrgSelection(options = {}) {
|
|
85
86
|
return new Promise(async (resolve, reject) => {
|
|
86
87
|
const { msg = '', isSource = true } = options || {};
|
|
88
|
+
log.debug('Handling organization selection', config.cloneContext);
|
|
87
89
|
const orgList = await this.getOrganizationChoices(msg).catch(reject);
|
|
88
90
|
|
|
89
|
-
|
|
90
|
-
|
|
91
|
+
if (orgList) {
|
|
92
|
+
log.debug(`Found ${orgList.choices?.length || 0} organization(s) to choose from`, config.cloneContext);
|
|
93
|
+
const orgSelected = await inquirer.prompt(orgList);
|
|
94
|
+
log.debug(`Organization selected: ${orgSelected.Organization}`, config.cloneContext);
|
|
91
95
|
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
96
|
+
if (isSource) {
|
|
97
|
+
config.sourceOrg = orgUidList[orgSelected.Organization];
|
|
98
|
+
log.debug(`Source organization UID: ${config.sourceOrg}`, config.cloneContext);
|
|
99
|
+
} else {
|
|
100
|
+
config.targetOrg = orgUidList[orgSelected.Organization];
|
|
101
|
+
log.debug(`Target organization UID: ${config.targetOrg}`, config.cloneContext);
|
|
102
|
+
}
|
|
97
103
|
|
|
98
|
-
|
|
99
|
-
|
|
104
|
+
resolve(orgSelected);
|
|
105
|
+
}
|
|
100
106
|
});
|
|
101
107
|
}
|
|
102
108
|
|
|
@@ -104,13 +110,16 @@ class CloneHandler {
|
|
|
104
110
|
return new Promise(async (resolve, reject) => {
|
|
105
111
|
try {
|
|
106
112
|
const { org = {}, msg = '', isSource = true } = options || {};
|
|
113
|
+
log.debug('Handling stack selection', config.cloneContext, { isSource, orgName: org.Organization, msg });
|
|
107
114
|
|
|
108
115
|
const stackList = await this.getStack(org, msg, isSource).catch(reject);
|
|
109
116
|
|
|
110
117
|
if (stackList) {
|
|
111
118
|
this.displayBackOptionMessage();
|
|
112
119
|
|
|
120
|
+
log.debug(`Found ${stackList.choices?.length || 0} stack(s) to choose from`, config.cloneContext);
|
|
113
121
|
const selectedStack = await inquirer.prompt(stackList);
|
|
122
|
+
log.debug(`Stack selected: ${selectedStack.stack}`, config.cloneContext);
|
|
114
123
|
if (this.executingCommand != 1) {
|
|
115
124
|
return reject();
|
|
116
125
|
}
|
|
@@ -118,9 +127,11 @@ class CloneHandler {
|
|
|
118
127
|
config.sourceStackName = selectedStack.stack;
|
|
119
128
|
master_locale = masterLocaleList[selectedStack.stack];
|
|
120
129
|
config.source_stack = stackUidList[selectedStack.stack];
|
|
130
|
+
log.debug(`Source stack configured`, config.cloneContext);
|
|
121
131
|
} else {
|
|
122
132
|
config.target_stack = stackUidList[selectedStack.stack];
|
|
123
133
|
config.destinationStackName = selectedStack.stack;
|
|
134
|
+
log.debug(`Target stack configured`, config.cloneContext);
|
|
124
135
|
}
|
|
125
136
|
|
|
126
137
|
resolve(selectedStack);
|
|
@@ -136,6 +147,7 @@ class CloneHandler {
|
|
|
136
147
|
return new Promise(async (resolve, reject) => {
|
|
137
148
|
let spinner;
|
|
138
149
|
try {
|
|
150
|
+
log.debug('Handling branch selection', config.cloneContext, { isSource, returnBranch, stackApiKey: isSource ? config.source_stack : config.target_stack });
|
|
139
151
|
const stackAPIClient = client.stack({
|
|
140
152
|
api_key: isSource ? config.source_stack : config.target_stack,
|
|
141
153
|
management_token: config.management_token,
|
|
@@ -143,22 +155,27 @@ class CloneHandler {
|
|
|
143
155
|
|
|
144
156
|
// NOTE validate if source branch is exist
|
|
145
157
|
if (isSource && config.sourceStackBranch) {
|
|
158
|
+
log.debug('Validating source branch exists', { ...config.cloneContext, branch: config.sourceStackBranch });
|
|
146
159
|
await this.validateIfBranchExist(stackAPIClient, true);
|
|
147
160
|
return resolve();
|
|
148
161
|
} else if(isSource && config.sourceStackBranchAlias) {
|
|
162
|
+
log.debug('Resolving source branch alias', { ...config.cloneContext, alias: config.sourceStackBranchAlias });
|
|
149
163
|
await this.resolveBranchAliases(true);
|
|
150
164
|
return resolve();
|
|
151
165
|
}
|
|
152
166
|
|
|
153
167
|
// NOTE Validate target branch is exist
|
|
154
168
|
if (!isSource && config.targetStackBranch) {
|
|
169
|
+
log.debug('Validating target branch exists', { ...config.cloneContext, branch: config.targetStackBranch });
|
|
155
170
|
await this.validateIfBranchExist(stackAPIClient, false);
|
|
156
171
|
return resolve();
|
|
157
172
|
} else if (!isSource && config.targetStackBranchAlias) {
|
|
173
|
+
log.debug('Resolving target branch alias', { ...config.cloneContext, alias: config.targetStackBranchAlias });
|
|
158
174
|
await this.resolveBranchAliases();
|
|
159
175
|
return resolve();
|
|
160
176
|
}
|
|
161
177
|
spinner = ora('Fetching Branches').start();
|
|
178
|
+
log.debug(`Querying branches for stack: ${isSource ? config.source_stack : config.target_stack}`, config.cloneContext);
|
|
162
179
|
const result = await stackAPIClient
|
|
163
180
|
.branch()
|
|
164
181
|
.query()
|
|
@@ -167,6 +184,7 @@ class CloneHandler {
|
|
|
167
184
|
.catch((_err) => {});
|
|
168
185
|
|
|
169
186
|
const condition = result && Array.isArray(result) && result.length > 0;
|
|
187
|
+
log.debug(`Found ${result?.length || 0} branch(es)`, config.cloneContext);
|
|
170
188
|
|
|
171
189
|
// NOTE if want to get only list of branches (Pass param -> returnBranch = true )
|
|
172
190
|
if (returnBranch) {
|
|
@@ -185,8 +203,10 @@ class CloneHandler {
|
|
|
185
203
|
}
|
|
186
204
|
if (isSource) {
|
|
187
205
|
config.sourceStackBranch = branch;
|
|
206
|
+
log.debug(`Source branch selected: ${branch}`, config.cloneContext);
|
|
188
207
|
} else {
|
|
189
208
|
config.targetStackBranch = branch;
|
|
209
|
+
log.debug(`Target branch selected: ${branch}`, config.cloneContext);
|
|
190
210
|
}
|
|
191
211
|
} else {
|
|
192
212
|
spinner.succeed('No branches found.!');
|
|
@@ -196,7 +216,6 @@ class CloneHandler {
|
|
|
196
216
|
}
|
|
197
217
|
} catch (e) {
|
|
198
218
|
if (spinner) spinner.fail();
|
|
199
|
-
console.error(e && e.message);
|
|
200
219
|
return reject(e);
|
|
201
220
|
}
|
|
202
221
|
});
|
|
@@ -210,6 +229,7 @@ class CloneHandler {
|
|
|
210
229
|
};
|
|
211
230
|
try {
|
|
212
231
|
const branch = isSource ? config.sourceStackBranch : config.targetStackBranch;
|
|
232
|
+
log.debug('Validating branch existence', config.cloneContext);
|
|
213
233
|
spinner = ora(`Validation if ${isSource ? 'source' : 'target'} branch exist.!`).start();
|
|
214
234
|
const isBranchExist = await stackAPIClient
|
|
215
235
|
.branch(branch)
|
|
@@ -217,8 +237,10 @@ class CloneHandler {
|
|
|
217
237
|
.then((data) => data);
|
|
218
238
|
|
|
219
239
|
if (isBranchExist && typeof isBranchExist === 'object') {
|
|
240
|
+
log.debug('Branch validation successful', config.cloneContext);
|
|
220
241
|
completeSpinner(`${isSource ? 'Source' : 'Target'} branch verified.!`);
|
|
221
242
|
} else {
|
|
243
|
+
log.error('Branch not found', config.cloneContext);
|
|
222
244
|
completeSpinner(`${isSource ? 'Source' : 'Target'} branch not found.!`, 'fail');
|
|
223
245
|
process.exit();
|
|
224
246
|
}
|
|
@@ -247,8 +269,10 @@ class CloneHandler {
|
|
|
247
269
|
return new Promise(async (resolve, reject) => {
|
|
248
270
|
let keyPressHandler;
|
|
249
271
|
try {
|
|
272
|
+
log.debug('Starting clone execution', { ...config.cloneContext, sourceStack: config.source_stack, targetStack: config.target_stack });
|
|
250
273
|
if (!config.source_stack) {
|
|
251
274
|
const orgMsg = 'Choose an organization where your source stack exists:';
|
|
275
|
+
log.debug('Source stack not provided, prompting for organization', config.cloneContext);
|
|
252
276
|
this.setExectingCommand(0);
|
|
253
277
|
this.removeBackKeyPressHandler();
|
|
254
278
|
const org = await cloneCommand.execute(new HandleOrgCommand({ msg: orgMsg, isSource: true }, this));
|
|
@@ -278,17 +302,21 @@ class CloneHandler {
|
|
|
278
302
|
return reject('Org not found.');
|
|
279
303
|
}
|
|
280
304
|
} else {
|
|
305
|
+
log.debug('Source stack provided, proceeding with branch selection and export', config.cloneContext);
|
|
281
306
|
this.setExectingCommand(2);
|
|
282
307
|
await this.handleBranchSelection({ api_key: config.sourceStack });
|
|
308
|
+
log.debug('Starting export operation', config.cloneContext);
|
|
283
309
|
const exportRes = await cloneCommand.execute(new HandleExportCommand(null, this));
|
|
284
310
|
await cloneCommand.execute(new SetBranchCommand(null, this));
|
|
285
311
|
|
|
286
312
|
if (exportRes) {
|
|
313
|
+
log.debug('Export completed, proceeding with destination setup', config.cloneContext);
|
|
287
314
|
this.executeDestination().catch((error) => {
|
|
288
315
|
return reject(error);
|
|
289
316
|
});
|
|
290
317
|
}
|
|
291
318
|
}
|
|
319
|
+
log.debug('Clone execution completed successfully', config.cloneContext);
|
|
292
320
|
return resolve();
|
|
293
321
|
} catch (error) {
|
|
294
322
|
return reject(error);
|
|
@@ -327,10 +355,12 @@ class CloneHandler {
|
|
|
327
355
|
|
|
328
356
|
async executeExport() {
|
|
329
357
|
try {
|
|
358
|
+
log.debug('Executing export operation', config.cloneContext);
|
|
330
359
|
const exportRes = await cloneCommand.execute(new HandleExportCommand(null, this));
|
|
331
360
|
await cloneCommand.execute(new SetBranchCommand(null, this));
|
|
332
361
|
|
|
333
362
|
if (exportRes) {
|
|
363
|
+
log.debug('Export operation completed, proceeding with destination', config.cloneContext);
|
|
334
364
|
this.executeDestination().catch(() => {
|
|
335
365
|
throw '';
|
|
336
366
|
});
|
|
@@ -346,8 +376,10 @@ class CloneHandler {
|
|
|
346
376
|
return new Promise(async (resolve, reject) => {
|
|
347
377
|
let keyPressHandler;
|
|
348
378
|
try {
|
|
379
|
+
log.debug('Executing destination setup', config.cloneContext);
|
|
349
380
|
let canCreateStack = false;
|
|
350
381
|
if (!config.target_stack) {
|
|
382
|
+
log.debug('Target stack not provided, prompting for stack creation', config.cloneContext);
|
|
351
383
|
canCreateStack = await inquirer.prompt(stackCreationConfirmation);
|
|
352
384
|
}
|
|
353
385
|
|
|
@@ -397,6 +429,7 @@ class CloneHandler {
|
|
|
397
429
|
await this.executeBranchDestinationPrompt(params);
|
|
398
430
|
}
|
|
399
431
|
|
|
432
|
+
log.debug('Destination setup completed successfully', config.cloneContext);
|
|
400
433
|
return resolve();
|
|
401
434
|
} catch (error) {
|
|
402
435
|
reject(error);
|
|
@@ -469,10 +502,12 @@ class CloneHandler {
|
|
|
469
502
|
choices: [],
|
|
470
503
|
};
|
|
471
504
|
return new Promise(async (resolve, reject) => {
|
|
505
|
+
log.debug('Fetching organization choices', config.cloneContext);
|
|
472
506
|
const spinner = ora('Fetching Organization').start();
|
|
473
507
|
try {
|
|
474
508
|
let organizations;
|
|
475
509
|
const configOrgUid = configHandler.get('oauthOrgUid');
|
|
510
|
+
log.debug('Getting organizations', config.cloneContext, { hasConfigOrgUid: !!configOrgUid });
|
|
476
511
|
|
|
477
512
|
if (configOrgUid) {
|
|
478
513
|
organizations = await client.organization(configOrgUid).fetch();
|
|
@@ -481,6 +516,7 @@ class CloneHandler {
|
|
|
481
516
|
}
|
|
482
517
|
|
|
483
518
|
spinner.succeed('Fetched Organization');
|
|
519
|
+
log.debug('Fetched organizations', config.cloneContext);
|
|
484
520
|
for (const element of organizations.items || [organizations]) {
|
|
485
521
|
orgUidList[element.name] = element.uid;
|
|
486
522
|
orgChoice.choices.push(element.name);
|
|
@@ -501,12 +537,15 @@ class CloneHandler {
|
|
|
501
537
|
message: stkMessage !== undefined ? stkMessage : 'Select the stack',
|
|
502
538
|
choices: [],
|
|
503
539
|
};
|
|
540
|
+
log.debug('Fetching stacks', config.cloneContext);
|
|
504
541
|
const spinner = ora('Fetching stacks').start();
|
|
505
542
|
try {
|
|
506
543
|
const organization_uid = orgUidList[answer.Organization];
|
|
544
|
+
log.debug('Querying stacks for organization', config.cloneContext, { organizationUid: organization_uid });
|
|
507
545
|
const stackList = client.stack().query({ organization_uid }).find();
|
|
508
546
|
stackList
|
|
509
547
|
.then((stacklist) => {
|
|
548
|
+
log.debug('Fetched stacks', config.cloneContext, { count: stacklist.items ? stacklist.items.length : 0 });
|
|
510
549
|
for (const element of stacklist.items) {
|
|
511
550
|
stackUidList[element.name] = element.api_key;
|
|
512
551
|
masterLocaleList[element.name] = element.master_locale;
|
|
@@ -530,9 +569,11 @@ class CloneHandler {
|
|
|
530
569
|
return new Promise(async (resolve, reject) => {
|
|
531
570
|
try {
|
|
532
571
|
const { orgUid } = options;
|
|
572
|
+
log.debug('Creating new stack', config.cloneContext, { orgUid, masterLocale: master_locale, stackName: config.stackName });
|
|
533
573
|
this.displayBackOptionMessage();
|
|
534
574
|
let inputvalue;
|
|
535
575
|
if (!config.stackName) {
|
|
576
|
+
log.debug('Stack name not provided, prompting user', config.cloneContext);
|
|
536
577
|
prompt.start();
|
|
537
578
|
prompt.message = '';
|
|
538
579
|
this.setCreateNewStackPrompt(prompt);
|
|
@@ -542,17 +583,24 @@ class CloneHandler {
|
|
|
542
583
|
inputvalue = { stack: config.stackName };
|
|
543
584
|
}
|
|
544
585
|
if (this.executingCommand === 0 || !inputvalue) {
|
|
586
|
+
log.debug('Stack creation cancelled or invalid input', config.cloneContext);
|
|
545
587
|
return reject();
|
|
546
588
|
}
|
|
547
589
|
|
|
548
590
|
let stack = { name: inputvalue.stack, master_locale: master_locale };
|
|
591
|
+
log.debug('Creating stack with configuration', config.cloneContext);
|
|
549
592
|
const spinner = ora('Creating New stack').start();
|
|
593
|
+
log.debug('Sending stack creation API request', config.cloneContext);
|
|
550
594
|
let newStack = client.stack().create({ stack }, { organization_uid: orgUid });
|
|
551
595
|
newStack
|
|
552
596
|
.then((result) => {
|
|
597
|
+
log.debug('Stack created successfully', config.cloneContext, {
|
|
598
|
+
stackName: result.name,
|
|
599
|
+
});
|
|
553
600
|
spinner.succeed('New Stack created Successfully name as ' + result.name);
|
|
554
601
|
config.target_stack = result.api_key;
|
|
555
602
|
config.destinationStackName = result.name;
|
|
603
|
+
log.debug('Target stack configuration updated', config.cloneContext);
|
|
556
604
|
return resolve(result);
|
|
557
605
|
})
|
|
558
606
|
.catch((error) => {
|
|
@@ -589,12 +637,15 @@ class CloneHandler {
|
|
|
589
637
|
|
|
590
638
|
async resolveBranchAliases(isSource = false) {
|
|
591
639
|
try {
|
|
640
|
+
log.debug('Resolving branch aliases', { ...config.cloneContext, isSource, alias: isSource ? config.sourceStackBranchAlias : config.targetStackBranchAlias });
|
|
592
641
|
if (isSource) {
|
|
593
642
|
const sourceStack = client.stack({ api_key: config.source_stack });
|
|
594
643
|
config.sourceStackBranch = await getBranchFromAlias(sourceStack, config.sourceStackBranchAlias);
|
|
644
|
+
log.debug('Source branch alias resolved', { ...config.cloneContext, alias: config.sourceStackBranchAlias, branch: config.sourceStackBranch });
|
|
595
645
|
} else {
|
|
596
646
|
const targetStack = client.stack({ api_key: config.target_stack });
|
|
597
647
|
config.targetStackBranch = await getBranchFromAlias(targetStack, config.targetStackBranchAlias);
|
|
648
|
+
log.debug('Target branch alias resolved', { ...config.cloneContext, alias: config.targetStackBranchAlias, branch: config.targetStackBranch });
|
|
598
649
|
}
|
|
599
650
|
} catch (error) {
|
|
600
651
|
throw error;
|
|
@@ -604,6 +655,7 @@ class CloneHandler {
|
|
|
604
655
|
async cloneTypeSelection() {
|
|
605
656
|
console.clear();
|
|
606
657
|
return new Promise(async (resolve, reject) => {
|
|
658
|
+
log.debug('Starting clone type selection', config.cloneContext);
|
|
607
659
|
const choices = [
|
|
608
660
|
'Structure (all modules except entries & assets)',
|
|
609
661
|
'Structure with content (all modules including entries & assets)',
|
|
@@ -619,83 +671,139 @@ class CloneHandler {
|
|
|
619
671
|
let successMsg;
|
|
620
672
|
let selectedValue = {};
|
|
621
673
|
config['data'] = path.join(__dirname.split('src')[0], 'contents', config.sourceStackBranch || '');
|
|
674
|
+
log.debug(`Clone data directory: ${config['data']}`, config.cloneContext);
|
|
622
675
|
|
|
623
676
|
if (!config.cloneType) {
|
|
677
|
+
log.debug('Clone type not specified, prompting user for selection', config.cloneContext);
|
|
624
678
|
selectedValue = await inquirer.prompt(cloneTypeSelection);
|
|
679
|
+
} else {
|
|
680
|
+
log.debug(`Using pre-configured clone type: ${config.cloneType}`, config.cloneContext);
|
|
625
681
|
}
|
|
626
682
|
|
|
627
683
|
if (config.cloneType === 'a' || selectedValue.type === 'Structure (all modules except entries & assets)') {
|
|
628
684
|
config['modules'] = structureList;
|
|
629
685
|
successMsg = 'Stack clone Structure completed';
|
|
686
|
+
log.debug(`Clone type: Structure only. Modules to clone: ${structureList.join(', ')}`, config.cloneContext);
|
|
630
687
|
} else {
|
|
631
688
|
successMsg = 'Stack clone completed with structure and content';
|
|
689
|
+
log.debug('Clone type: Structure with content (all modules)', config.cloneContext);
|
|
632
690
|
}
|
|
633
691
|
|
|
634
692
|
this.cmdImport()
|
|
635
|
-
.then(() =>
|
|
693
|
+
.then(() => {
|
|
694
|
+
log.debug('Clone type selection and import completed successfully', config.cloneContext);
|
|
695
|
+
resolve(successMsg);
|
|
696
|
+
})
|
|
636
697
|
.catch(reject);
|
|
637
698
|
});
|
|
638
699
|
}
|
|
639
700
|
|
|
640
701
|
async cmdExport() {
|
|
641
702
|
return new Promise((resolve, reject) => {
|
|
703
|
+
log.debug('Preparing export command', { ...config.cloneContext, sourceStack: config.source_stack, cloneType: config.cloneType });
|
|
642
704
|
// Creating export specific config by merging external configurations
|
|
643
705
|
let exportConfig = Object.assign({}, cloneDeep(config), { ...config?.export });
|
|
644
706
|
delete exportConfig.import;
|
|
645
707
|
delete exportConfig.export;
|
|
646
708
|
|
|
647
|
-
const
|
|
709
|
+
const exportDir = __dirname.split('src')[0] + 'contents';
|
|
710
|
+
log.debug(`Export directory: ${exportDir}`, config.cloneContext);
|
|
711
|
+
const cmd = ['-k', exportConfig.source_stack, '-d', exportDir];
|
|
712
|
+
|
|
648
713
|
if (exportConfig.cloneType === 'a') {
|
|
649
714
|
exportConfig.filteredModules = ['stack'].concat(structureList);
|
|
715
|
+
log.debug(`Filtered modules for structure-only export: ${exportConfig.filteredModules.join(', ')}`, config.cloneContext);
|
|
650
716
|
}
|
|
651
717
|
|
|
652
718
|
if (exportConfig.source_alias) {
|
|
653
719
|
cmd.push('-a', exportConfig.source_alias);
|
|
720
|
+
log.debug(`Using source alias: ${exportConfig.source_alias}`, config.cloneContext);
|
|
654
721
|
}
|
|
655
722
|
if (exportConfig.sourceStackBranch) {
|
|
656
723
|
cmd.push('--branch', exportConfig.sourceStackBranch);
|
|
724
|
+
log.debug(`Using source branch: ${exportConfig.sourceStackBranch}`, config.cloneContext);
|
|
657
725
|
}
|
|
658
726
|
|
|
659
|
-
if (exportConfig.forceStopMarketplaceAppsPrompt)
|
|
727
|
+
if (exportConfig.forceStopMarketplaceAppsPrompt) {
|
|
728
|
+
cmd.push('-y');
|
|
729
|
+
log.debug('Force stop marketplace apps prompt enabled', config.cloneContext);
|
|
730
|
+
}
|
|
660
731
|
|
|
732
|
+
const configFilePath = path.join(__dirname, 'dummyConfig.json');
|
|
661
733
|
cmd.push('-c');
|
|
662
|
-
cmd.push(
|
|
663
|
-
|
|
664
|
-
|
|
734
|
+
cmd.push(configFilePath);
|
|
735
|
+
log.debug(`Writing export config to: ${configFilePath}`, config.cloneContext);
|
|
736
|
+
|
|
737
|
+
fs.writeFileSync(configFilePath, JSON.stringify(exportConfig));
|
|
738
|
+
log.debug('Export command prepared', config.cloneContext, {
|
|
739
|
+
cmd: cmd.join(' '),
|
|
740
|
+
exportDir,
|
|
741
|
+
sourceStack: exportConfig.source_stack,
|
|
742
|
+
branch: exportConfig.sourceStackBranch
|
|
743
|
+
});
|
|
744
|
+
log.debug('Running export command', config.cloneContext, { cmd });
|
|
665
745
|
let exportData = exportCmd.run(cmd);
|
|
666
|
-
exportData.then(() =>
|
|
746
|
+
exportData.then(() => {
|
|
747
|
+
log.debug('Export command completed successfully', config.cloneContext);
|
|
748
|
+
resolve(true);
|
|
749
|
+
}).catch((error) => {
|
|
750
|
+
reject(error);
|
|
751
|
+
});
|
|
667
752
|
});
|
|
668
753
|
}
|
|
669
754
|
|
|
670
755
|
async cmdImport() {
|
|
671
756
|
return new Promise(async (resolve, _reject) => {
|
|
757
|
+
log.debug('Preparing import command', { ...config.cloneContext, targetStack: config.target_stack, targetBranch: config.targetStackBranch });
|
|
672
758
|
// Creating export specific config by merging external configurations
|
|
673
759
|
let importConfig = Object.assign({}, cloneDeep(config), { ...config?.import });
|
|
674
760
|
delete importConfig.import;
|
|
675
761
|
delete importConfig.export;
|
|
676
762
|
|
|
677
|
-
const
|
|
763
|
+
const configFilePath = path.join(__dirname, 'dummyConfig.json');
|
|
764
|
+
const cmd = ['-c', configFilePath];
|
|
678
765
|
|
|
679
766
|
if (importConfig.destination_alias) {
|
|
680
767
|
cmd.push('-a', importConfig.destination_alias);
|
|
768
|
+
log.debug(`Using destination alias: ${importConfig.destination_alias}`, config.cloneContext);
|
|
681
769
|
}
|
|
682
770
|
if (!importConfig.data && importConfig.sourceStackBranch) {
|
|
683
|
-
|
|
771
|
+
const dataPath = path.join(importConfig.pathDir, importConfig.sourceStackBranch);
|
|
772
|
+
cmd.push('-d', dataPath);
|
|
773
|
+
log.debug(`Import data path: ${dataPath}`, config.cloneContext);
|
|
684
774
|
}
|
|
685
775
|
if (importConfig.targetStackBranch) {
|
|
686
776
|
cmd.push('--branch', importConfig.targetStackBranch);
|
|
777
|
+
log.debug(`Using target branch: ${importConfig.targetStackBranch}`, config.cloneContext);
|
|
687
778
|
}
|
|
688
779
|
if (importConfig.importWebhookStatus) {
|
|
689
780
|
cmd.push('--import-webhook-status', importConfig.importWebhookStatus);
|
|
781
|
+
log.debug(`Import webhook status: ${importConfig.importWebhookStatus}`, config.cloneContext);
|
|
690
782
|
}
|
|
691
783
|
|
|
692
|
-
if (importConfig.skipAudit)
|
|
784
|
+
if (importConfig.skipAudit) {
|
|
785
|
+
cmd.push('--skip-audit');
|
|
786
|
+
log.debug('Skip audit flag enabled', config.cloneContext);
|
|
787
|
+
}
|
|
693
788
|
|
|
694
|
-
if (importConfig.forceStopMarketplaceAppsPrompt)
|
|
789
|
+
if (importConfig.forceStopMarketplaceAppsPrompt) {
|
|
790
|
+
cmd.push('-y');
|
|
791
|
+
log.debug('Force stop marketplace apps prompt enabled', config.cloneContext);
|
|
792
|
+
}
|
|
695
793
|
|
|
696
|
-
|
|
794
|
+
log.debug(`Writing import config to: ${configFilePath}`, config.cloneContext);
|
|
795
|
+
fs.writeFileSync(configFilePath, JSON.stringify(importConfig));
|
|
796
|
+
log.debug('Import command prepared', config.cloneContext, {
|
|
797
|
+
cmd: cmd.join(' '),
|
|
798
|
+
targetStack: importConfig.target_stack,
|
|
799
|
+
targetBranch: importConfig.targetStackBranch,
|
|
800
|
+
dataPath: importConfig.data || path.join(importConfig.pathDir, importConfig.sourceStackBranch)
|
|
801
|
+
});
|
|
802
|
+
log.debug('Running import command', config.cloneContext, { cmd });
|
|
697
803
|
await importCmd.run(cmd);
|
|
698
|
-
|
|
804
|
+
log.debug('Import command completed successfully', config.cloneContext);
|
|
805
|
+
log.debug('Clearing import config file', config.cloneContext);
|
|
806
|
+
fs.writeFileSync(configFilePath, JSON.stringify({}));
|
|
699
807
|
return resolve();
|
|
700
808
|
});
|
|
701
809
|
}
|
package/src/lib/util/log.js
DELETED
|
@@ -1,105 +0,0 @@
|
|
|
1
|
-
/*!
|
|
2
|
-
* Contentstack Import
|
|
3
|
-
* Copyright (c) 2024 Contentstack LLC
|
|
4
|
-
* MIT Licensed
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
var winston = require('winston');
|
|
8
|
-
var path = require('path');
|
|
9
|
-
var mkdirp = require('mkdirp');
|
|
10
|
-
const { pathValidator, sanitizePath } = require('@contentstack/cli-utilities');
|
|
11
|
-
var slice = Array.prototype.slice;
|
|
12
|
-
|
|
13
|
-
function returnString(args) {
|
|
14
|
-
var returnStr = '';
|
|
15
|
-
if (args && args.length) {
|
|
16
|
-
returnStr = args
|
|
17
|
-
.map(function (item) {
|
|
18
|
-
if (item && typeof item === 'object') {
|
|
19
|
-
return JSON.stringify(item);
|
|
20
|
-
}
|
|
21
|
-
return item;
|
|
22
|
-
})
|
|
23
|
-
.join(' ')
|
|
24
|
-
.trim();
|
|
25
|
-
}
|
|
26
|
-
return returnStr;
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
var myCustomLevels = {
|
|
30
|
-
levels: {
|
|
31
|
-
error: 0,
|
|
32
|
-
warn: 1,
|
|
33
|
-
info: 2,
|
|
34
|
-
debug: 3,
|
|
35
|
-
},
|
|
36
|
-
colors: {
|
|
37
|
-
info: 'blue',
|
|
38
|
-
debug: 'green',
|
|
39
|
-
warn: 'yellow',
|
|
40
|
-
error: 'red',
|
|
41
|
-
},
|
|
42
|
-
};
|
|
43
|
-
|
|
44
|
-
function init(_logPath, logfileName) {
|
|
45
|
-
var logsDir = pathValidator(path.resolve(sanitizePath(_logPath), 'logs', 'import'));
|
|
46
|
-
// Create dir if doesn't already exist
|
|
47
|
-
mkdirp.sync(logsDir);
|
|
48
|
-
var logPath = path.join(sanitizePath(logsDir), pathValidator(sanitizePath(logfileName)) + '.log');
|
|
49
|
-
|
|
50
|
-
var transports = [
|
|
51
|
-
new winston.transports.File({
|
|
52
|
-
filename: logPath,
|
|
53
|
-
maxFiles: 20,
|
|
54
|
-
maxsize: 1000000,
|
|
55
|
-
tailable: true,
|
|
56
|
-
json: true,
|
|
57
|
-
}),
|
|
58
|
-
];
|
|
59
|
-
|
|
60
|
-
transports.push(new winston.transports.Console());
|
|
61
|
-
|
|
62
|
-
var logger = winston.createLogger({
|
|
63
|
-
transports: transports,
|
|
64
|
-
levels: myCustomLevels.levels,
|
|
65
|
-
});
|
|
66
|
-
|
|
67
|
-
return {
|
|
68
|
-
log: function () {
|
|
69
|
-
var args = slice.call(arguments);
|
|
70
|
-
var logString = returnString(args);
|
|
71
|
-
if (logString) {
|
|
72
|
-
logger.log('info', logString);
|
|
73
|
-
}
|
|
74
|
-
},
|
|
75
|
-
warn: function () {
|
|
76
|
-
var args = slice.call(arguments);
|
|
77
|
-
var logString = returnString(args);
|
|
78
|
-
if (logString) {
|
|
79
|
-
logger.log('warn', logString);
|
|
80
|
-
}
|
|
81
|
-
},
|
|
82
|
-
error: function () {
|
|
83
|
-
var args = slice.call(arguments);
|
|
84
|
-
var logString = returnString(args);
|
|
85
|
-
if (logString) {
|
|
86
|
-
logger.log('error', logString);
|
|
87
|
-
}
|
|
88
|
-
},
|
|
89
|
-
debug: function () {
|
|
90
|
-
var args = slice.call(arguments);
|
|
91
|
-
var logString = returnString(args);
|
|
92
|
-
if (logString) {
|
|
93
|
-
logger.log('debug', logString);
|
|
94
|
-
}
|
|
95
|
-
},
|
|
96
|
-
};
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
exports.addlogs = async (config, message, type) => {
|
|
100
|
-
if (type !== 'error') {
|
|
101
|
-
init(config.oldPath, type).log(message);
|
|
102
|
-
} else {
|
|
103
|
-
init(config.oldPath, type).error(message);
|
|
104
|
-
}
|
|
105
|
-
};
|