@magentrix-corp/magentrix-cli 1.3.16 → 1.3.17

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 (68) hide show
  1. package/LICENSE +25 -25
  2. package/README.md +1166 -1166
  3. package/actions/autopublish.old.js +293 -293
  4. package/actions/config.js +182 -182
  5. package/actions/create.js +466 -466
  6. package/actions/help.js +164 -164
  7. package/actions/iris/buildStage.js +874 -874
  8. package/actions/iris/delete.js +256 -256
  9. package/actions/iris/dev.js +391 -391
  10. package/actions/iris/index.js +6 -6
  11. package/actions/iris/link.js +375 -375
  12. package/actions/iris/recover.js +268 -268
  13. package/actions/main.js +80 -80
  14. package/actions/publish.js +1420 -1420
  15. package/actions/pull.js +684 -684
  16. package/actions/setup.js +148 -148
  17. package/actions/status.js +17 -17
  18. package/actions/update.js +248 -248
  19. package/bin/magentrix.js +393 -393
  20. package/package.json +55 -55
  21. package/utils/assetPaths.js +158 -158
  22. package/utils/autopublishLock.js +77 -77
  23. package/utils/cacher.js +206 -206
  24. package/utils/cli/checkInstanceUrl.js +76 -74
  25. package/utils/cli/helpers/compare.js +282 -282
  26. package/utils/cli/helpers/ensureApiKey.js +63 -63
  27. package/utils/cli/helpers/ensureCredentials.js +68 -68
  28. package/utils/cli/helpers/ensureInstanceUrl.js +75 -75
  29. package/utils/cli/writeRecords.js +262 -262
  30. package/utils/compare.js +135 -135
  31. package/utils/compress.js +17 -17
  32. package/utils/config.js +527 -527
  33. package/utils/debug.js +144 -144
  34. package/utils/diagnostics/testPublishLogic.js +96 -96
  35. package/utils/diff.js +49 -49
  36. package/utils/downloadAssets.js +291 -291
  37. package/utils/filetag.js +115 -115
  38. package/utils/hash.js +14 -14
  39. package/utils/iris/backup.js +411 -411
  40. package/utils/iris/builder.js +541 -541
  41. package/utils/iris/config-reader.js +664 -664
  42. package/utils/iris/deleteHelper.js +150 -150
  43. package/utils/iris/errors.js +537 -537
  44. package/utils/iris/linker.js +601 -601
  45. package/utils/iris/lock.js +360 -360
  46. package/utils/iris/validation.js +360 -360
  47. package/utils/iris/validator.js +281 -281
  48. package/utils/iris/zipper.js +248 -248
  49. package/utils/logger.js +291 -291
  50. package/utils/magentrix/api/assets.js +220 -220
  51. package/utils/magentrix/api/auth.js +107 -107
  52. package/utils/magentrix/api/createEntity.js +61 -61
  53. package/utils/magentrix/api/deleteEntity.js +55 -55
  54. package/utils/magentrix/api/iris.js +251 -251
  55. package/utils/magentrix/api/meqlQuery.js +36 -36
  56. package/utils/magentrix/api/retrieveEntity.js +86 -86
  57. package/utils/magentrix/api/updateEntity.js +66 -66
  58. package/utils/magentrix/fetch.js +168 -168
  59. package/utils/merge.js +22 -22
  60. package/utils/permissionError.js +70 -70
  61. package/utils/preferences.js +40 -40
  62. package/utils/progress.js +469 -469
  63. package/utils/spinner.js +43 -43
  64. package/utils/template.js +52 -52
  65. package/utils/updateFileBase.js +121 -121
  66. package/utils/workspaces.js +108 -108
  67. package/vars/config.js +11 -11
  68. package/vars/global.js +50 -50
package/utils/logger.js CHANGED
@@ -1,291 +1,291 @@
1
- import fs from 'fs';
2
- import path from 'path';
3
- import chalk from 'chalk';
4
- import Config from './config.js';
5
- import inquirer from 'inquirer';
6
-
7
- const config = new Config();
8
-
9
- /**
10
- * Logger utility for tracking errors, warnings, and operations during pull/publish.
11
- * Logs are stored in .magentrix/logs/ directory.
12
- */
13
-
14
- export class Logger {
15
- constructor(operationName = 'operation') {
16
- this.operationName = operationName;
17
- this.logDir = '.magentrix/logs';
18
- this.timestamp = new Date().toISOString().replace(/[:.]/g, '-').split('.')[0];
19
- this.logFile = path.join(this.logDir, `${operationName}-${this.timestamp}.log`);
20
- this.errors = [];
21
- this.warnings = [];
22
- this.infos = [];
23
- this.loggingEnabled = null; // Will be determined on first write
24
-
25
- // Check if logging is enabled in config
26
- this.checkLoggingPreference();
27
- }
28
-
29
- /**
30
- * Check user's logging preference from config
31
- */
32
- checkLoggingPreference() {
33
- const preference = config.read('saveLogs', { global: true });
34
-
35
- if (preference !== undefined && preference !== null) {
36
- this.loggingEnabled = preference === true || preference === 'true';
37
- }
38
- // If undefined, we'll prompt on first write
39
- }
40
-
41
- /**
42
- * Prompt user about logging preference (only once)
43
- */
44
- async promptLoggingPreference() {
45
- console.log('');
46
- console.log(chalk.cyan('📋 Log File Settings'));
47
- console.log(chalk.gray('Magentrix CLI can save detailed operation logs for debugging.'));
48
- console.log('');
49
-
50
- const answer = await inquirer.prompt([
51
- {
52
- type: 'confirm',
53
- name: 'saveLogs',
54
- message: 'Would you like to save operation logs to files?',
55
- default: true
56
- }
57
- ]);
58
-
59
- this.loggingEnabled = answer.saveLogs;
60
- config.save('saveLogs', answer.saveLogs, { global: true });
61
-
62
- if (answer.saveLogs) {
63
- console.log(chalk.green('✓ Logs will be saved to .magentrix/logs/'));
64
- } else {
65
- console.log(chalk.gray('Logs disabled. You can enable them anytime with: magentrix config set logs true'));
66
- }
67
- console.log('');
68
- }
69
-
70
- /**
71
- * Initialize log file if logging is enabled
72
- */
73
- async initLogFile() {
74
- if (this.loggingEnabled === null) {
75
- // First time - prompt user
76
- await this.promptLoggingPreference();
77
- }
78
-
79
- if (this.loggingEnabled) {
80
- // Ensure log directory exists
81
- if (!fs.existsSync(this.logDir)) {
82
- fs.mkdirSync(this.logDir, { recursive: true });
83
- }
84
-
85
- // Initialize log file
86
- this.writeToFile(`=== ${this.operationName.toUpperCase()} LOG ===`);
87
- this.writeToFile(`Started: ${new Date().toISOString()}`);
88
- this.writeToFile(`Working Directory: ${process.cwd()}`);
89
- this.writeToFile('');
90
- }
91
- }
92
-
93
- /**
94
- * Write a line to the log file (internal method)
95
- */
96
- writeToFile(message) {
97
- if (this.loggingEnabled) {
98
- fs.appendFileSync(this.logFile, message + '\n');
99
- }
100
- }
101
-
102
- /**
103
- * Log an info message
104
- */
105
- info(message, details = null) {
106
- const timestamp = new Date().toISOString();
107
- const entry = { timestamp, level: 'INFO', message, details };
108
- this.infos.push(entry);
109
-
110
- this.writeToFile(`[${timestamp}] INFO: ${message}`);
111
- if (details) {
112
- this.writeToFile(` Details: ${typeof details === 'object' ? JSON.stringify(details, null, 2) : details}`);
113
- }
114
- }
115
-
116
- /**
117
- * Log a warning message
118
- */
119
- warning(message, details = null) {
120
- const timestamp = new Date().toISOString();
121
- const entry = { timestamp, level: 'WARNING', message, details };
122
- this.warnings.push(entry);
123
-
124
- this.writeToFile(`[${timestamp}] WARNING: ${message}`);
125
- if (details) {
126
- this.writeToFile(` Details: ${typeof details === 'object' ? JSON.stringify(details, null, 2) : details}`);
127
- }
128
- }
129
-
130
- /**
131
- * Log an error message
132
- * @param {string} message - Error message
133
- * @param {Error|null} error - Error object
134
- * @param {object|null} details - Additional details
135
- * @param {string|null} hint - Helpful hint for resolving the error
136
- */
137
- error(message, error = null, details = null, hint = null) {
138
- const timestamp = new Date().toISOString();
139
- const entry = {
140
- timestamp,
141
- level: 'ERROR',
142
- message,
143
- error: error ? error.toString() : null,
144
- stack: error?.stack || null,
145
- details,
146
- hint
147
- };
148
- this.errors.push(entry);
149
-
150
- this.writeToFile(`[${timestamp}] ERROR: ${message}`);
151
- if (error) {
152
- this.writeToFile(` Error: ${error.toString()}`);
153
- if (error.stack) {
154
- this.writeToFile(` Stack: ${error.stack}`);
155
- }
156
- }
157
- if (details) {
158
- this.writeToFile(` Details: ${typeof details === 'object' ? JSON.stringify(details, null, 2) : details}`);
159
- }
160
- }
161
-
162
- /**
163
- * Get a summary of the log
164
- */
165
- getSummary() {
166
- return {
167
- errors: this.errors.length,
168
- warnings: this.warnings.length,
169
- infos: this.infos.length,
170
- logFile: this.logFile
171
- };
172
- }
173
-
174
- /**
175
- * Get the most recent errors (for preview)
176
- */
177
- getRecentErrors(count = 3) {
178
- return this.errors.slice(-count);
179
- }
180
-
181
- /**
182
- * Get the most recent warnings (for preview)
183
- */
184
- getRecentWarnings(count = 3) {
185
- return this.warnings.slice(-count);
186
- }
187
-
188
- /**
189
- * Display a summary to the console
190
- */
191
- displaySummary() {
192
- const summary = this.getSummary();
193
-
194
- if (summary.errors > 0 || summary.warnings > 0) {
195
- console.log('');
196
- console.log(chalk.bold('Issues Summary:'));
197
-
198
- if (summary.errors > 0) {
199
- console.log(chalk.red(` ✗ ${summary.errors} error(s)`));
200
-
201
- // Show preview of recent errors
202
- const recentErrors = this.getRecentErrors(3);
203
- recentErrors.forEach((err, idx) => {
204
- console.log(chalk.red(` ${idx + 1}. ${err.message}`));
205
- if (err.hint) {
206
- console.log(chalk.yellow(` ${err.hint}`));
207
- }
208
- });
209
-
210
- if (summary.errors > 3) {
211
- console.log(chalk.gray(` ... and ${summary.errors - 3} more`));
212
- }
213
- }
214
-
215
- if (summary.warnings > 0) {
216
- console.log(chalk.yellow(` ⚠ ${summary.warnings} warning(s)`));
217
-
218
- // Show preview of recent warnings
219
- const recentWarnings = this.getRecentWarnings(2);
220
- recentWarnings.forEach((warn, idx) => {
221
- console.log(chalk.yellow(` ${idx + 1}. ${warn.message}`));
222
- });
223
-
224
- if (summary.warnings > 2) {
225
- console.log(chalk.gray(` ... and ${summary.warnings - 2} more`));
226
- }
227
- }
228
-
229
- // Only show log file path if logging is enabled
230
- if (this.loggingEnabled) {
231
- console.log('');
232
- console.log(chalk.cyan(`📄 Full log: ${chalk.white(summary.logFile)}`));
233
- console.log(chalk.gray(` View with: cat ${summary.logFile}`));
234
- }
235
- console.log('');
236
- }
237
- }
238
-
239
- /**
240
- * Finalize the log file
241
- */
242
- close() {
243
- this.writeToFile('');
244
- this.writeToFile(`Completed: ${new Date().toISOString()}`);
245
- this.writeToFile(`Summary: ${this.errors.length} errors, ${this.warnings.length} warnings, ${this.infos.length} info messages`);
246
- this.writeToFile('=== END LOG ===');
247
- }
248
-
249
- /**
250
- * Clean up old log files (keep only last N logs)
251
- */
252
- static cleanupOldLogs(keepCount = 10) {
253
- const logDir = '.magentrix/logs';
254
-
255
- if (!fs.existsSync(logDir)) {
256
- return;
257
- }
258
-
259
- try {
260
- const files = fs.readdirSync(logDir)
261
- .filter(f => f.endsWith('.log'))
262
- .map(f => ({
263
- name: f,
264
- path: path.join(logDir, f),
265
- time: fs.statSync(path.join(logDir, f)).mtime.getTime()
266
- }))
267
- .sort((a, b) => b.time - a.time); // Sort by newest first
268
-
269
- // Delete files beyond keepCount
270
- if (files.length > keepCount) {
271
- const toDelete = files.slice(keepCount);
272
- toDelete.forEach(file => {
273
- try {
274
- fs.unlinkSync(file.path);
275
- } catch (err) {
276
- // Ignore errors when deleting old logs
277
- }
278
- });
279
- }
280
- } catch (err) {
281
- // Ignore errors in cleanup
282
- }
283
- }
284
- }
285
-
286
- /**
287
- * Create a logger instance for an operation
288
- */
289
- export function createLogger(operationName) {
290
- return new Logger(operationName);
291
- }
1
+ import fs from 'fs';
2
+ import path from 'path';
3
+ import chalk from 'chalk';
4
+ import Config from './config.js';
5
+ import inquirer from 'inquirer';
6
+
7
+ const config = new Config();
8
+
9
+ /**
10
+ * Logger utility for tracking errors, warnings, and operations during pull/publish.
11
+ * Logs are stored in .magentrix/logs/ directory.
12
+ */
13
+
14
+ export class Logger {
15
+ constructor(operationName = 'operation') {
16
+ this.operationName = operationName;
17
+ this.logDir = '.magentrix/logs';
18
+ this.timestamp = new Date().toISOString().replace(/[:.]/g, '-').split('.')[0];
19
+ this.logFile = path.join(this.logDir, `${operationName}-${this.timestamp}.log`);
20
+ this.errors = [];
21
+ this.warnings = [];
22
+ this.infos = [];
23
+ this.loggingEnabled = null; // Will be determined on first write
24
+
25
+ // Check if logging is enabled in config
26
+ this.checkLoggingPreference();
27
+ }
28
+
29
+ /**
30
+ * Check user's logging preference from config
31
+ */
32
+ checkLoggingPreference() {
33
+ const preference = config.read('saveLogs', { global: true });
34
+
35
+ if (preference !== undefined && preference !== null) {
36
+ this.loggingEnabled = preference === true || preference === 'true';
37
+ }
38
+ // If undefined, we'll prompt on first write
39
+ }
40
+
41
+ /**
42
+ * Prompt user about logging preference (only once)
43
+ */
44
+ async promptLoggingPreference() {
45
+ console.log('');
46
+ console.log(chalk.cyan('📋 Log File Settings'));
47
+ console.log(chalk.gray('Magentrix CLI can save detailed operation logs for debugging.'));
48
+ console.log('');
49
+
50
+ const answer = await inquirer.prompt([
51
+ {
52
+ type: 'confirm',
53
+ name: 'saveLogs',
54
+ message: 'Would you like to save operation logs to files?',
55
+ default: true
56
+ }
57
+ ]);
58
+
59
+ this.loggingEnabled = answer.saveLogs;
60
+ config.save('saveLogs', answer.saveLogs, { global: true });
61
+
62
+ if (answer.saveLogs) {
63
+ console.log(chalk.green('✓ Logs will be saved to .magentrix/logs/'));
64
+ } else {
65
+ console.log(chalk.gray('Logs disabled. You can enable them anytime with: magentrix config set logs true'));
66
+ }
67
+ console.log('');
68
+ }
69
+
70
+ /**
71
+ * Initialize log file if logging is enabled
72
+ */
73
+ async initLogFile() {
74
+ if (this.loggingEnabled === null) {
75
+ // First time - prompt user
76
+ await this.promptLoggingPreference();
77
+ }
78
+
79
+ if (this.loggingEnabled) {
80
+ // Ensure log directory exists
81
+ if (!fs.existsSync(this.logDir)) {
82
+ fs.mkdirSync(this.logDir, { recursive: true });
83
+ }
84
+
85
+ // Initialize log file
86
+ this.writeToFile(`=== ${this.operationName.toUpperCase()} LOG ===`);
87
+ this.writeToFile(`Started: ${new Date().toISOString()}`);
88
+ this.writeToFile(`Working Directory: ${process.cwd()}`);
89
+ this.writeToFile('');
90
+ }
91
+ }
92
+
93
+ /**
94
+ * Write a line to the log file (internal method)
95
+ */
96
+ writeToFile(message) {
97
+ if (this.loggingEnabled) {
98
+ fs.appendFileSync(this.logFile, message + '\n');
99
+ }
100
+ }
101
+
102
+ /**
103
+ * Log an info message
104
+ */
105
+ info(message, details = null) {
106
+ const timestamp = new Date().toISOString();
107
+ const entry = { timestamp, level: 'INFO', message, details };
108
+ this.infos.push(entry);
109
+
110
+ this.writeToFile(`[${timestamp}] INFO: ${message}`);
111
+ if (details) {
112
+ this.writeToFile(` Details: ${typeof details === 'object' ? JSON.stringify(details, null, 2) : details}`);
113
+ }
114
+ }
115
+
116
+ /**
117
+ * Log a warning message
118
+ */
119
+ warning(message, details = null) {
120
+ const timestamp = new Date().toISOString();
121
+ const entry = { timestamp, level: 'WARNING', message, details };
122
+ this.warnings.push(entry);
123
+
124
+ this.writeToFile(`[${timestamp}] WARNING: ${message}`);
125
+ if (details) {
126
+ this.writeToFile(` Details: ${typeof details === 'object' ? JSON.stringify(details, null, 2) : details}`);
127
+ }
128
+ }
129
+
130
+ /**
131
+ * Log an error message
132
+ * @param {string} message - Error message
133
+ * @param {Error|null} error - Error object
134
+ * @param {object|null} details - Additional details
135
+ * @param {string|null} hint - Helpful hint for resolving the error
136
+ */
137
+ error(message, error = null, details = null, hint = null) {
138
+ const timestamp = new Date().toISOString();
139
+ const entry = {
140
+ timestamp,
141
+ level: 'ERROR',
142
+ message,
143
+ error: error ? error.toString() : null,
144
+ stack: error?.stack || null,
145
+ details,
146
+ hint
147
+ };
148
+ this.errors.push(entry);
149
+
150
+ this.writeToFile(`[${timestamp}] ERROR: ${message}`);
151
+ if (error) {
152
+ this.writeToFile(` Error: ${error.toString()}`);
153
+ if (error.stack) {
154
+ this.writeToFile(` Stack: ${error.stack}`);
155
+ }
156
+ }
157
+ if (details) {
158
+ this.writeToFile(` Details: ${typeof details === 'object' ? JSON.stringify(details, null, 2) : details}`);
159
+ }
160
+ }
161
+
162
+ /**
163
+ * Get a summary of the log
164
+ */
165
+ getSummary() {
166
+ return {
167
+ errors: this.errors.length,
168
+ warnings: this.warnings.length,
169
+ infos: this.infos.length,
170
+ logFile: this.logFile
171
+ };
172
+ }
173
+
174
+ /**
175
+ * Get the most recent errors (for preview)
176
+ */
177
+ getRecentErrors(count = 3) {
178
+ return this.errors.slice(-count);
179
+ }
180
+
181
+ /**
182
+ * Get the most recent warnings (for preview)
183
+ */
184
+ getRecentWarnings(count = 3) {
185
+ return this.warnings.slice(-count);
186
+ }
187
+
188
+ /**
189
+ * Display a summary to the console
190
+ */
191
+ displaySummary() {
192
+ const summary = this.getSummary();
193
+
194
+ if (summary.errors > 0 || summary.warnings > 0) {
195
+ console.log('');
196
+ console.log(chalk.bold('Issues Summary:'));
197
+
198
+ if (summary.errors > 0) {
199
+ console.log(chalk.red(` ✗ ${summary.errors} error(s)`));
200
+
201
+ // Show preview of recent errors
202
+ const recentErrors = this.getRecentErrors(3);
203
+ recentErrors.forEach((err, idx) => {
204
+ console.log(chalk.red(` ${idx + 1}. ${err.message}`));
205
+ if (err.hint) {
206
+ console.log(chalk.yellow(` ${err.hint}`));
207
+ }
208
+ });
209
+
210
+ if (summary.errors > 3) {
211
+ console.log(chalk.gray(` ... and ${summary.errors - 3} more`));
212
+ }
213
+ }
214
+
215
+ if (summary.warnings > 0) {
216
+ console.log(chalk.yellow(` ⚠ ${summary.warnings} warning(s)`));
217
+
218
+ // Show preview of recent warnings
219
+ const recentWarnings = this.getRecentWarnings(2);
220
+ recentWarnings.forEach((warn, idx) => {
221
+ console.log(chalk.yellow(` ${idx + 1}. ${warn.message}`));
222
+ });
223
+
224
+ if (summary.warnings > 2) {
225
+ console.log(chalk.gray(` ... and ${summary.warnings - 2} more`));
226
+ }
227
+ }
228
+
229
+ // Only show log file path if logging is enabled
230
+ if (this.loggingEnabled) {
231
+ console.log('');
232
+ console.log(chalk.cyan(`📄 Full log: ${chalk.white(summary.logFile)}`));
233
+ console.log(chalk.gray(` View with: cat ${summary.logFile}`));
234
+ }
235
+ console.log('');
236
+ }
237
+ }
238
+
239
+ /**
240
+ * Finalize the log file
241
+ */
242
+ close() {
243
+ this.writeToFile('');
244
+ this.writeToFile(`Completed: ${new Date().toISOString()}`);
245
+ this.writeToFile(`Summary: ${this.errors.length} errors, ${this.warnings.length} warnings, ${this.infos.length} info messages`);
246
+ this.writeToFile('=== END LOG ===');
247
+ }
248
+
249
+ /**
250
+ * Clean up old log files (keep only last N logs)
251
+ */
252
+ static cleanupOldLogs(keepCount = 10) {
253
+ const logDir = '.magentrix/logs';
254
+
255
+ if (!fs.existsSync(logDir)) {
256
+ return;
257
+ }
258
+
259
+ try {
260
+ const files = fs.readdirSync(logDir)
261
+ .filter(f => f.endsWith('.log'))
262
+ .map(f => ({
263
+ name: f,
264
+ path: path.join(logDir, f),
265
+ time: fs.statSync(path.join(logDir, f)).mtime.getTime()
266
+ }))
267
+ .sort((a, b) => b.time - a.time); // Sort by newest first
268
+
269
+ // Delete files beyond keepCount
270
+ if (files.length > keepCount) {
271
+ const toDelete = files.slice(keepCount);
272
+ toDelete.forEach(file => {
273
+ try {
274
+ fs.unlinkSync(file.path);
275
+ } catch (err) {
276
+ // Ignore errors when deleting old logs
277
+ }
278
+ });
279
+ }
280
+ } catch (err) {
281
+ // Ignore errors in cleanup
282
+ }
283
+ }
284
+ }
285
+
286
+ /**
287
+ * Create a logger instance for an operation
288
+ */
289
+ export function createLogger(operationName) {
290
+ return new Logger(operationName);
291
+ }