@inforge/migrations-tools-cli 1.1.1 → 1.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +29 -0
- package/dist/index.js +83 -19
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -103,6 +103,35 @@ Select "Logs" to see recent operations with status, timestamps, and details.
|
|
|
103
103
|
|
|
104
104
|
All operations are logged to `.logs/operations.log` (JSON format, one per line).
|
|
105
105
|
|
|
106
|
+
## Debugging
|
|
107
|
+
|
|
108
|
+
### Debug Logs
|
|
109
|
+
|
|
110
|
+
When errors occur, detailed error information including stack traces and API request/response data is automatically logged to `.logs/debug.log`. The error message will show you the exact path to the debug log file.
|
|
111
|
+
|
|
112
|
+
**Example error message:**
|
|
113
|
+
```
|
|
114
|
+
Failed to apply changes: The requested resource does not exist
|
|
115
|
+
|
|
116
|
+
Error details logged to: /path/to/your/project/.logs/debug.log
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
### Enable Verbose Debug Logging
|
|
120
|
+
|
|
121
|
+
For more detailed troubleshooting, enable debug mode to see all API calls and internal operations:
|
|
122
|
+
|
|
123
|
+
```bash
|
|
124
|
+
DEBUG=true imigrate
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
This will log detailed information about:
|
|
128
|
+
- API queries and their results
|
|
129
|
+
- Request/response payloads
|
|
130
|
+
- Internal state changes
|
|
131
|
+
- Detailed error contexts
|
|
132
|
+
|
|
133
|
+
Debug logs are written in JSON format with timestamps and structured context for easy analysis.
|
|
134
|
+
|
|
106
135
|
## Safety Features
|
|
107
136
|
|
|
108
137
|
### Atomic Operations
|
package/dist/index.js
CHANGED
|
@@ -248,12 +248,15 @@ var BackupManager = class {
|
|
|
248
248
|
// src/core/logger.ts
|
|
249
249
|
import * as fs2 from "fs/promises";
|
|
250
250
|
import * as path2 from "path";
|
|
251
|
-
var Logger = class {
|
|
251
|
+
var Logger = class _Logger {
|
|
252
252
|
logDir;
|
|
253
253
|
logFile;
|
|
254
|
+
debugLogFile;
|
|
255
|
+
static debugEnabled = process.env.DEBUG === "true";
|
|
254
256
|
constructor(logDir = ".logs") {
|
|
255
257
|
this.logDir = logDir;
|
|
256
258
|
this.logFile = path2.join(logDir, "operations.log");
|
|
259
|
+
this.debugLogFile = path2.join(logDir, "debug.log");
|
|
257
260
|
}
|
|
258
261
|
async log(operation) {
|
|
259
262
|
await this.ensureLogDir();
|
|
@@ -277,6 +280,38 @@ var Logger = class {
|
|
|
277
280
|
const random = Math.random().toString(36).substring(2, 9);
|
|
278
281
|
return `op_${timestamp}${random}`;
|
|
279
282
|
}
|
|
283
|
+
async debug(message, context) {
|
|
284
|
+
await this.writeDebugLog("DEBUG", message, context);
|
|
285
|
+
}
|
|
286
|
+
async info(message, context) {
|
|
287
|
+
await this.writeDebugLog("INFO", message, context);
|
|
288
|
+
}
|
|
289
|
+
async error(message, error, context) {
|
|
290
|
+
const errorDetails = error ? {
|
|
291
|
+
message: error.message || String(error),
|
|
292
|
+
stack: error.stack,
|
|
293
|
+
details: error.response?.data || error.details || error
|
|
294
|
+
} : void 0;
|
|
295
|
+
await this.writeDebugLog("ERROR", message, context, errorDetails);
|
|
296
|
+
}
|
|
297
|
+
getDebugLogPath() {
|
|
298
|
+
return path2.resolve(this.debugLogFile);
|
|
299
|
+
}
|
|
300
|
+
async writeDebugLog(level, message, context, error) {
|
|
301
|
+
if (!_Logger.debugEnabled && level === "DEBUG") {
|
|
302
|
+
return;
|
|
303
|
+
}
|
|
304
|
+
await this.ensureLogDir();
|
|
305
|
+
const entry = {
|
|
306
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
307
|
+
level,
|
|
308
|
+
message,
|
|
309
|
+
...context && { context },
|
|
310
|
+
...error && { error }
|
|
311
|
+
};
|
|
312
|
+
const logLine = JSON.stringify(entry, null, 2) + "\n---\n";
|
|
313
|
+
await fs2.appendFile(this.debugLogFile, logLine, "utf-8");
|
|
314
|
+
}
|
|
280
315
|
async ensureLogDir() {
|
|
281
316
|
try {
|
|
282
317
|
await fs2.mkdir(this.logDir, { recursive: true });
|
|
@@ -427,6 +462,10 @@ var FlowsHandler = class {
|
|
|
427
462
|
|
|
428
463
|
// src/core/metadata/triggers.ts
|
|
429
464
|
var TriggersHandler = class {
|
|
465
|
+
logger;
|
|
466
|
+
constructor() {
|
|
467
|
+
this.logger = new Logger();
|
|
468
|
+
}
|
|
430
469
|
async fetch(connection, objectName) {
|
|
431
470
|
const query = `
|
|
432
471
|
SELECT Id, Name, TableEnumOrId, Status, NamespacePrefix
|
|
@@ -465,25 +504,39 @@ var TriggersHandler = class {
|
|
|
465
504
|
await this.updateStatus(connection, triggerNames, "Active");
|
|
466
505
|
}
|
|
467
506
|
async updateStatus(connection, triggerNames, status) {
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
const failures =
|
|
507
|
+
await this.logger.debug("TriggersHandler.updateStatus called", {
|
|
508
|
+
triggerNames,
|
|
509
|
+
status
|
|
510
|
+
});
|
|
511
|
+
try {
|
|
512
|
+
const updates = triggerNames.map((name) => ({
|
|
513
|
+
fullName: name,
|
|
514
|
+
status
|
|
515
|
+
}));
|
|
516
|
+
await this.logger.debug("Preparing Metadata API update", { updates });
|
|
517
|
+
const results = await connection.metadata.update("ApexTrigger", updates);
|
|
518
|
+
await this.logger.debug("Metadata API update results", {
|
|
519
|
+
results: Array.isArray(results) ? results : [results]
|
|
520
|
+
});
|
|
521
|
+
const resultArray = Array.isArray(results) ? results : [results];
|
|
522
|
+
const failures = resultArray.filter((r) => !r.success);
|
|
484
523
|
if (failures.length > 0) {
|
|
485
|
-
|
|
524
|
+
await this.logger.error("Some triggers failed to update", null, {
|
|
525
|
+
failures,
|
|
526
|
+
totalAttempted: resultArray.length
|
|
527
|
+
});
|
|
528
|
+
throw new Error(`Failed to update ${failures.length} trigger(s): ${JSON.stringify(failures)}`);
|
|
486
529
|
}
|
|
530
|
+
await this.logger.info("Successfully updated trigger status", {
|
|
531
|
+
triggerCount: triggerNames.length,
|
|
532
|
+
status
|
|
533
|
+
});
|
|
534
|
+
} catch (error) {
|
|
535
|
+
await this.logger.error("Error in updateStatus", error, {
|
|
536
|
+
triggerNames,
|
|
537
|
+
status
|
|
538
|
+
});
|
|
539
|
+
throw error;
|
|
487
540
|
}
|
|
488
541
|
}
|
|
489
542
|
};
|
|
@@ -1199,6 +1252,14 @@ Select items to toggle (Space to select, Enter to continue):`,
|
|
|
1199
1252
|
);
|
|
1200
1253
|
} catch (error) {
|
|
1201
1254
|
applySpinner.stop("Changes failed");
|
|
1255
|
+
await this.logger.error("Failed to apply changes in IndividualCommand", error, {
|
|
1256
|
+
org: org.alias,
|
|
1257
|
+
object: selectedObject,
|
|
1258
|
+
automationType,
|
|
1259
|
+
selectedFullNames,
|
|
1260
|
+
toActivate,
|
|
1261
|
+
toDeactivate
|
|
1262
|
+
});
|
|
1202
1263
|
await this.logger.log({
|
|
1203
1264
|
id: operationId,
|
|
1204
1265
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
@@ -1212,7 +1273,10 @@ Select items to toggle (Space to select, Enter to continue):`,
|
|
|
1212
1273
|
backupPath,
|
|
1213
1274
|
error: error.message
|
|
1214
1275
|
});
|
|
1215
|
-
this.
|
|
1276
|
+
const debugLogPath = this.logger.getDebugLogPath();
|
|
1277
|
+
this.prompts.error(`Failed to apply changes: ${error.message}
|
|
1278
|
+
|
|
1279
|
+
Error details logged to: ${debugLogPath}`);
|
|
1216
1280
|
throw error;
|
|
1217
1281
|
}
|
|
1218
1282
|
}
|
package/package.json
CHANGED