@tenonhq/sincronia-core 0.0.46 → 0.0.47
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/dist/FileLogger.js +219 -0
- package/dist/FileUtils.js +56 -6
- package/dist/appUtils.js +74 -18
- package/dist/bootstrap.js +3 -2
- package/dist/commands.js +31 -1
- package/dist/index.js +4 -1
- package/dist/snClient.js +83 -1
- package/package.json +1 -1
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
2
|
+
if (k2 === undefined) k2 = k;
|
|
3
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
4
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
5
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
6
|
+
}
|
|
7
|
+
Object.defineProperty(o, k2, desc);
|
|
8
|
+
}) : (function(o, m, k, k2) {
|
|
9
|
+
if (k2 === undefined) k2 = k;
|
|
10
|
+
o[k2] = m[k];
|
|
11
|
+
}));
|
|
12
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
13
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
14
|
+
}) : function(o, v) {
|
|
15
|
+
o["default"] = v;
|
|
16
|
+
});
|
|
17
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
18
|
+
var ownKeys = function(o) {
|
|
19
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
20
|
+
var ar = [];
|
|
21
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
22
|
+
return ar;
|
|
23
|
+
};
|
|
24
|
+
return ownKeys(o);
|
|
25
|
+
};
|
|
26
|
+
return function (mod) {
|
|
27
|
+
if (mod && mod.__esModule) return mod;
|
|
28
|
+
var result = {};
|
|
29
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
30
|
+
__setModuleDefault(result, mod);
|
|
31
|
+
return result;
|
|
32
|
+
};
|
|
33
|
+
})();
|
|
34
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
35
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
36
|
+
};
|
|
37
|
+
(function (factory) {
|
|
38
|
+
if (typeof module === "object" && typeof module.exports === "object") {
|
|
39
|
+
var v = factory(require, exports);
|
|
40
|
+
if (v !== undefined) module.exports = v;
|
|
41
|
+
}
|
|
42
|
+
else if (typeof define === "function" && define.amd) {
|
|
43
|
+
define(["require", "exports", "fs", "path", "chalk"], factory);
|
|
44
|
+
}
|
|
45
|
+
})(function (require, exports) {
|
|
46
|
+
"use strict";
|
|
47
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
48
|
+
exports.fileLogger = void 0;
|
|
49
|
+
exports.enableFileLogging = enableFileLogging;
|
|
50
|
+
const fs = __importStar(require("fs"));
|
|
51
|
+
const path = __importStar(require("path"));
|
|
52
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
53
|
+
class FileLogger {
|
|
54
|
+
constructor() {
|
|
55
|
+
this.logStream = null;
|
|
56
|
+
this.initialized = false;
|
|
57
|
+
// Initialize on first use
|
|
58
|
+
this.logFilePath = "";
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Initialize the file logger in the current working directory
|
|
62
|
+
*/
|
|
63
|
+
initialize() {
|
|
64
|
+
if (this.initialized)
|
|
65
|
+
return;
|
|
66
|
+
const timestamp = new Date().toISOString().replace(/[:.]/g, "-").slice(0, 19);
|
|
67
|
+
const logFileName = `sincronia-debug-${timestamp}.log`;
|
|
68
|
+
// Create log file in the current working directory (ServiceNow folder)
|
|
69
|
+
this.logFilePath = path.join(process.cwd(), logFileName);
|
|
70
|
+
try {
|
|
71
|
+
// Create or append to the log file
|
|
72
|
+
this.logStream = fs.createWriteStream(this.logFilePath, { flags: 'a' });
|
|
73
|
+
this.initialized = true;
|
|
74
|
+
// Write header to log file
|
|
75
|
+
this.writeToFile(`\n${"=".repeat(80)}`);
|
|
76
|
+
this.writeToFile(`Sincronia Debug Log - Started at ${new Date().toISOString()}`);
|
|
77
|
+
this.writeToFile(`Log file: ${this.logFilePath}`);
|
|
78
|
+
this.writeToFile(`Working directory: ${process.cwd()}`);
|
|
79
|
+
this.writeToFile(`${"=".repeat(80)}\n`);
|
|
80
|
+
// Also log to console
|
|
81
|
+
console.log(chalk_1.default.cyan(`📝 Debug logging enabled: ${this.logFilePath}`));
|
|
82
|
+
}
|
|
83
|
+
catch (error) {
|
|
84
|
+
console.error(chalk_1.default.red(`Failed to create log file: ${error}`));
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Write a message to the log file
|
|
89
|
+
*/
|
|
90
|
+
writeToFile(message) {
|
|
91
|
+
if (!this.initialized) {
|
|
92
|
+
this.initialize();
|
|
93
|
+
}
|
|
94
|
+
if (this.logStream && this.logStream.writable) {
|
|
95
|
+
const timestamp = new Date().toISOString();
|
|
96
|
+
this.logStream.write(`[${timestamp}] ${message}\n`);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Format a message for both console and file output
|
|
101
|
+
*/
|
|
102
|
+
formatMessage(level, message, ...args) {
|
|
103
|
+
let fullMessage = message;
|
|
104
|
+
// If there are additional arguments, stringify them
|
|
105
|
+
if (args.length > 0) {
|
|
106
|
+
const additionalInfo = args.map(arg => {
|
|
107
|
+
if (typeof arg === 'object') {
|
|
108
|
+
try {
|
|
109
|
+
return JSON.stringify(arg, null, 2);
|
|
110
|
+
}
|
|
111
|
+
catch {
|
|
112
|
+
return String(arg);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
return String(arg);
|
|
116
|
+
}).join(' ');
|
|
117
|
+
fullMessage = `${message} ${additionalInfo}`;
|
|
118
|
+
}
|
|
119
|
+
return fullMessage;
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Debug level logging - replaces console.log
|
|
123
|
+
*/
|
|
124
|
+
debug(message, ...args) {
|
|
125
|
+
const formattedMessage = this.formatMessage('DEBUG', message, ...args);
|
|
126
|
+
// Write to console (preserving original console.log behavior)
|
|
127
|
+
console.log(message, ...args);
|
|
128
|
+
// Write to file
|
|
129
|
+
this.writeToFile(`[DEBUG] ${formattedMessage}`);
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Info level logging
|
|
133
|
+
*/
|
|
134
|
+
info(message, ...args) {
|
|
135
|
+
const formattedMessage = this.formatMessage('INFO', message, ...args);
|
|
136
|
+
// Write to console with color
|
|
137
|
+
console.log(chalk_1.default.blue(message), ...args);
|
|
138
|
+
// Write to file
|
|
139
|
+
this.writeToFile(`[INFO] ${formattedMessage}`);
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* Warning level logging
|
|
143
|
+
*/
|
|
144
|
+
warn(message, ...args) {
|
|
145
|
+
const formattedMessage = this.formatMessage('WARN', message, ...args);
|
|
146
|
+
// Write to console with color
|
|
147
|
+
console.log(chalk_1.default.yellow(message), ...args);
|
|
148
|
+
// Write to file
|
|
149
|
+
this.writeToFile(`[WARN] ${formattedMessage}`);
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* Error level logging
|
|
153
|
+
*/
|
|
154
|
+
error(message, ...args) {
|
|
155
|
+
const formattedMessage = this.formatMessage('ERROR', message, ...args);
|
|
156
|
+
// Write to console with color
|
|
157
|
+
console.error(chalk_1.default.red(message), ...args);
|
|
158
|
+
// Write to file
|
|
159
|
+
this.writeToFile(`[ERROR] ${formattedMessage}`);
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* Success level logging
|
|
163
|
+
*/
|
|
164
|
+
success(message, ...args) {
|
|
165
|
+
const formattedMessage = this.formatMessage('SUCCESS', message, ...args);
|
|
166
|
+
// Write to console with color
|
|
167
|
+
console.log(chalk_1.default.green(message), ...args);
|
|
168
|
+
// Write to file
|
|
169
|
+
this.writeToFile(`[SUCCESS] ${formattedMessage}`);
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* Close the log file stream
|
|
173
|
+
*/
|
|
174
|
+
close() {
|
|
175
|
+
if (this.logStream) {
|
|
176
|
+
this.writeToFile(`\n${"=".repeat(80)}`);
|
|
177
|
+
this.writeToFile(`Log session ended at ${new Date().toISOString()}`);
|
|
178
|
+
this.writeToFile(`${"=".repeat(80)}\n`);
|
|
179
|
+
this.logStream.end();
|
|
180
|
+
this.logStream = null;
|
|
181
|
+
this.initialized = false;
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
/**
|
|
185
|
+
* Get the path to the current log file
|
|
186
|
+
*/
|
|
187
|
+
getLogFilePath() {
|
|
188
|
+
return this.logFilePath;
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
// Create singleton instance
|
|
192
|
+
const fileLogger = new FileLogger();
|
|
193
|
+
exports.fileLogger = fileLogger;
|
|
194
|
+
// Also export a function to replace console.log globally
|
|
195
|
+
function enableFileLogging() {
|
|
196
|
+
// Store original console.log
|
|
197
|
+
const originalConsoleLog = console.log;
|
|
198
|
+
// Override console.log to also write to file
|
|
199
|
+
console.log = function (...args) {
|
|
200
|
+
// Call original console.log
|
|
201
|
+
originalConsoleLog.apply(console, args);
|
|
202
|
+
// Also write to file
|
|
203
|
+
const message = args.map(arg => {
|
|
204
|
+
if (typeof arg === 'object') {
|
|
205
|
+
try {
|
|
206
|
+
return JSON.stringify(arg, null, 2);
|
|
207
|
+
}
|
|
208
|
+
catch {
|
|
209
|
+
return String(arg);
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
return String(arg);
|
|
213
|
+
}).join(' ');
|
|
214
|
+
fileLogger.debug(message);
|
|
215
|
+
};
|
|
216
|
+
// Log that file logging is enabled
|
|
217
|
+
fileLogger.info('File logging has been enabled for this session');
|
|
218
|
+
}
|
|
219
|
+
});
|
package/dist/FileUtils.js
CHANGED
|
@@ -40,7 +40,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
40
40
|
if (v !== undefined) module.exports = v;
|
|
41
41
|
}
|
|
42
42
|
else if (typeof define === "function" && define.amd) {
|
|
43
|
-
define(["require", "exports", "./constants", "fs", "path", "./config"], factory);
|
|
43
|
+
define(["require", "exports", "./constants", "fs", "path", "./config", "./FileLogger"], factory);
|
|
44
44
|
}
|
|
45
45
|
})(function (require, exports) {
|
|
46
46
|
"use strict";
|
|
@@ -50,6 +50,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
50
50
|
const fs_1 = __importStar(require("fs"));
|
|
51
51
|
const path_1 = __importDefault(require("path"));
|
|
52
52
|
const ConfigManager = __importStar(require("./config"));
|
|
53
|
+
const FileLogger_1 = require("./FileLogger");
|
|
53
54
|
const SNFileExists = (parentDirPath) => async (file) => {
|
|
54
55
|
try {
|
|
55
56
|
const files = await fs_1.promises.readdir(parentDirPath);
|
|
@@ -62,37 +63,86 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
62
63
|
};
|
|
63
64
|
exports.SNFileExists = SNFileExists;
|
|
64
65
|
const writeManifestFile = async (man, scope) => {
|
|
66
|
+
FileLogger_1.fileLogger.debug('\n--- writeManifestFile DEBUG ---');
|
|
67
|
+
FileLogger_1.fileLogger.debug('Scope:', scope || 'No scope (legacy)');
|
|
65
68
|
if (scope) {
|
|
66
69
|
// Write scope-specific manifest
|
|
67
|
-
|
|
70
|
+
const manifestPath = ConfigManager.getScopeManifestPath(scope);
|
|
71
|
+
FileLogger_1.fileLogger.debug('Writing scope-specific manifest to:', manifestPath);
|
|
72
|
+
return fs_1.promises.writeFile(manifestPath, JSON.stringify(man, null, 2));
|
|
68
73
|
}
|
|
69
74
|
// Write legacy single manifest
|
|
70
|
-
|
|
75
|
+
const manifestPath = ConfigManager.getManifestPath();
|
|
76
|
+
FileLogger_1.fileLogger.debug('Writing legacy manifest to:', manifestPath);
|
|
77
|
+
return fs_1.promises.writeFile(manifestPath, JSON.stringify(man, null, 2));
|
|
71
78
|
};
|
|
72
79
|
exports.writeManifestFile = writeManifestFile;
|
|
73
80
|
const writeScopeManifest = async (scope, man) => {
|
|
74
|
-
|
|
81
|
+
const manifestPath = ConfigManager.getScopeManifestPath(scope);
|
|
82
|
+
FileLogger_1.fileLogger.debug('\n--- writeScopeManifest DEBUG ---');
|
|
83
|
+
FileLogger_1.fileLogger.debug('Scope:', scope);
|
|
84
|
+
FileLogger_1.fileLogger.debug('Manifest path:', manifestPath);
|
|
85
|
+
FileLogger_1.fileLogger.debug('--- writeScopeManifest DEBUG END ---\n');
|
|
86
|
+
return fs_1.promises.writeFile(manifestPath, JSON.stringify(man, null, 2));
|
|
75
87
|
};
|
|
76
88
|
exports.writeScopeManifest = writeScopeManifest;
|
|
77
89
|
const writeSNFileCurry = (checkExists) => async (file, parentPath) => {
|
|
90
|
+
FileLogger_1.fileLogger.debug('\n--- writeSNFileCurry DEBUG ---');
|
|
91
|
+
FileLogger_1.fileLogger.debug('Check exists:', checkExists);
|
|
92
|
+
FileLogger_1.fileLogger.debug('Parent path:', parentPath);
|
|
93
|
+
FileLogger_1.fileLogger.debug('File to write:', {
|
|
94
|
+
name: file.name,
|
|
95
|
+
type: file.type,
|
|
96
|
+
hasContent: !!file.content,
|
|
97
|
+
contentLength: file.content ? file.content.length : 0
|
|
98
|
+
});
|
|
78
99
|
let { name, type, content = "" } = file;
|
|
79
100
|
// content can sometimes be null
|
|
80
101
|
if (!content) {
|
|
102
|
+
FileLogger_1.fileLogger.debug('Content is null/undefined, using empty string');
|
|
81
103
|
content = "";
|
|
82
104
|
}
|
|
105
|
+
const fullPath = path_1.default.join(parentPath, `${name}.${type}`);
|
|
106
|
+
FileLogger_1.fileLogger.debug('Full file path:', fullPath);
|
|
107
|
+
// Special logging for metadata files
|
|
108
|
+
if (name.toLowerCase().includes('metadata') || name.toLowerCase() === 'metadata') {
|
|
109
|
+
FileLogger_1.fileLogger.debug('*** METADATA FILE DETECTED ***');
|
|
110
|
+
FileLogger_1.fileLogger.debug(' Name:', name);
|
|
111
|
+
FileLogger_1.fileLogger.debug(' Type:', type);
|
|
112
|
+
FileLogger_1.fileLogger.debug(' Path:', fullPath);
|
|
113
|
+
FileLogger_1.fileLogger.debug(' Content preview:', content ? content.substring(0, 100) : 'NO CONTENT');
|
|
114
|
+
}
|
|
83
115
|
const write = async () => {
|
|
84
|
-
|
|
85
|
-
|
|
116
|
+
FileLogger_1.fileLogger.debug(`Writing file: ${fullPath}`);
|
|
117
|
+
try {
|
|
118
|
+
const result = await fs_1.promises.writeFile(fullPath, content);
|
|
119
|
+
FileLogger_1.fileLogger.debug(`✓ File written successfully: ${fullPath}`);
|
|
120
|
+
// Verify metaData.json was actually written
|
|
121
|
+
if (name.toLowerCase() === 'metadata' && type === 'json') {
|
|
122
|
+
const exists = await fs_1.promises.access(fullPath).then(() => true).catch(() => false);
|
|
123
|
+
FileLogger_1.fileLogger.debug(`*** METADATA FILE VERIFICATION: File exists on disk = ${exists} ***`);
|
|
124
|
+
}
|
|
125
|
+
return result;
|
|
126
|
+
}
|
|
127
|
+
catch (error) {
|
|
128
|
+
FileLogger_1.fileLogger.error(`✗ ERROR writing file ${fullPath}:`, error);
|
|
129
|
+
throw error;
|
|
130
|
+
}
|
|
86
131
|
};
|
|
87
132
|
if (checkExists) {
|
|
88
133
|
const exists = await (0, exports.SNFileExists)(parentPath)(file);
|
|
134
|
+
FileLogger_1.fileLogger.debug(`File exists check: ${exists}`);
|
|
89
135
|
if (!exists) {
|
|
90
136
|
await write();
|
|
91
137
|
}
|
|
138
|
+
else {
|
|
139
|
+
FileLogger_1.fileLogger.debug(`File already exists, skipping: ${fullPath}`);
|
|
140
|
+
}
|
|
92
141
|
}
|
|
93
142
|
else {
|
|
94
143
|
await write();
|
|
95
144
|
}
|
|
145
|
+
FileLogger_1.fileLogger.debug('--- writeSNFileCurry DEBUG END ---\n');
|
|
96
146
|
};
|
|
97
147
|
exports.writeSNFileCurry = writeSNFileCurry;
|
|
98
148
|
const createDirRecursively = async (path) => {
|
package/dist/appUtils.js
CHANGED
|
@@ -40,7 +40,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
40
40
|
if (v !== undefined) module.exports = v;
|
|
41
41
|
}
|
|
42
42
|
else if (typeof define === "function" && define.amd) {
|
|
43
|
-
define(["require", "exports", "path", "progress", "./FileUtils", "./config", "./constants", "./PluginManager", "./snClient", "./Logger", "./genericUtils"], factory);
|
|
43
|
+
define(["require", "exports", "path", "progress", "./FileUtils", "./config", "./constants", "./PluginManager", "./FileLogger", "./snClient", "./Logger", "./genericUtils"], factory);
|
|
44
44
|
}
|
|
45
45
|
})(function (require, exports) {
|
|
46
46
|
"use strict";
|
|
@@ -52,35 +52,62 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
52
52
|
const ConfigManager = __importStar(require("./config"));
|
|
53
53
|
const constants_1 = require("./constants");
|
|
54
54
|
const PluginManager_1 = __importDefault(require("./PluginManager"));
|
|
55
|
+
const FileLogger_1 = require("./FileLogger");
|
|
55
56
|
const snClient_1 = require("./snClient");
|
|
56
57
|
const Logger_1 = require("./Logger");
|
|
57
58
|
const genericUtils_1 = require("./genericUtils");
|
|
58
59
|
const processFilesInManRec = async (recPath, rec, forceWrite) => {
|
|
60
|
+
FileLogger_1.fileLogger.debug('\n=== processFilesInManRec DEBUG START ===');
|
|
61
|
+
FileLogger_1.fileLogger.debug('Processing record:', rec.name);
|
|
62
|
+
FileLogger_1.fileLogger.debug('Record path:', recPath);
|
|
63
|
+
FileLogger_1.fileLogger.debug('Force write:', forceWrite);
|
|
64
|
+
FileLogger_1.fileLogger.debug('Number of files in record:', rec.files.length);
|
|
65
|
+
FileLogger_1.fileLogger.debug('Files received:', rec.files.map(f => ({
|
|
66
|
+
name: f.name,
|
|
67
|
+
type: f.type,
|
|
68
|
+
hasContent: !!f.content,
|
|
69
|
+
contentLength: f.content ? f.content.length : 0
|
|
70
|
+
})));
|
|
71
|
+
// Check if any file is named metaData or similar
|
|
72
|
+
const metadataFileIncoming = rec.files.find(f => f.name.toLowerCase().includes('metadata') ||
|
|
73
|
+
f.name.toLowerCase().includes('meta'));
|
|
74
|
+
FileLogger_1.fileLogger.debug('Metadata file found in incoming files?', metadataFileIncoming ? 'YES' : 'NO');
|
|
75
|
+
if (metadataFileIncoming) {
|
|
76
|
+
FileLogger_1.fileLogger.debug('Found metadata file:', metadataFileIncoming);
|
|
77
|
+
}
|
|
59
78
|
const fileWrite = fUtils.writeSNFileCurry(forceWrite);
|
|
60
|
-
//
|
|
61
|
-
const
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
79
|
+
// Create metadata file with current timestamp
|
|
80
|
+
const metadataFile = {
|
|
81
|
+
name: "metaData",
|
|
82
|
+
type: "json",
|
|
83
|
+
content: JSON.stringify({
|
|
84
|
+
_lastUpdatedOn: new Date().toISOString()
|
|
85
|
+
}, null, 2)
|
|
86
|
+
};
|
|
87
|
+
FileLogger_1.fileLogger.debug('Creating metadata file:', {
|
|
88
|
+
name: metadataFile.name,
|
|
89
|
+
type: metadataFile.type,
|
|
90
|
+
content: metadataFile.content
|
|
70
91
|
});
|
|
71
|
-
// Write metadata
|
|
72
|
-
|
|
92
|
+
// Write metadata file first
|
|
93
|
+
FileLogger_1.fileLogger.debug('Writing metadata file to:', recPath);
|
|
94
|
+
await fileWrite(metadataFile, recPath);
|
|
95
|
+
FileLogger_1.fileLogger.debug('Metadata file write complete');
|
|
96
|
+
// Write regular files
|
|
97
|
+
FileLogger_1.fileLogger.debug('Writing', rec.files.length, 'regular files...');
|
|
98
|
+
const regularPromises = rec.files.map((file) => {
|
|
99
|
+
FileLogger_1.fileLogger.debug(` Writing file: ${file.name}.${file.type}`);
|
|
73
100
|
return fileWrite(file, recPath);
|
|
74
101
|
});
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
rec.files = regularFiles.map((file) => {
|
|
102
|
+
await Promise.all(regularPromises);
|
|
103
|
+
FileLogger_1.fileLogger.debug('All regular files written');
|
|
104
|
+
// Remove content from ALL files (metadata is not included in manifest)
|
|
105
|
+
rec.files = rec.files.map((file) => {
|
|
80
106
|
const fileCopy = { ...file };
|
|
81
107
|
delete fileCopy.content;
|
|
82
108
|
return fileCopy;
|
|
83
109
|
});
|
|
110
|
+
FileLogger_1.fileLogger.debug('=== processFilesInManRec DEBUG END ===\n');
|
|
84
111
|
};
|
|
85
112
|
const processRecsInManTable = async (tablePath, table, forceWrite) => {
|
|
86
113
|
const { records } = table;
|
|
@@ -106,31 +133,46 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
106
133
|
await Promise.all(tablePromises);
|
|
107
134
|
};
|
|
108
135
|
const processManifest = async (manifest, forceWrite = false) => {
|
|
136
|
+
FileLogger_1.fileLogger.debug('\n=== processManifest DEBUG START ===');
|
|
137
|
+
FileLogger_1.fileLogger.debug('Manifest scope:', manifest.scope);
|
|
138
|
+
FileLogger_1.fileLogger.debug('Force write:', forceWrite);
|
|
139
|
+
FileLogger_1.fileLogger.debug('Number of tables:', Object.keys(manifest.tables).length);
|
|
140
|
+
FileLogger_1.fileLogger.debug('Table names:', Object.keys(manifest.tables));
|
|
109
141
|
await processTablesInManifest(manifest.tables, forceWrite);
|
|
110
142
|
// Write to scope-specific manifest if scope is available
|
|
111
143
|
if (manifest.scope) {
|
|
144
|
+
FileLogger_1.fileLogger.debug('Writing scope-specific manifest for scope:', manifest.scope);
|
|
112
145
|
await fUtils.writeScopeManifest(manifest.scope, manifest);
|
|
113
146
|
}
|
|
114
147
|
else {
|
|
115
148
|
// Fall back to legacy single manifest
|
|
149
|
+
FileLogger_1.fileLogger.debug('Writing legacy single manifest');
|
|
116
150
|
await fUtils.writeFileForce(ConfigManager.getManifestPath(), JSON.stringify(manifest, null, 2));
|
|
117
151
|
}
|
|
152
|
+
FileLogger_1.fileLogger.debug('=== processManifest DEBUG END ===\n');
|
|
118
153
|
};
|
|
119
154
|
exports.processManifest = processManifest;
|
|
120
155
|
const syncManifest = async (scope) => {
|
|
121
156
|
try {
|
|
157
|
+
FileLogger_1.fileLogger.debug('\n=== syncManifest DEBUG START ===');
|
|
158
|
+
FileLogger_1.fileLogger.debug('Called with scope:', scope || 'undefined (will sync all scopes)');
|
|
122
159
|
const curManifest = await ConfigManager.getManifest();
|
|
123
160
|
if (!curManifest)
|
|
124
161
|
throw new Error("No manifest file loaded!");
|
|
125
162
|
// If a specific scope is provided, sync only that scope
|
|
126
163
|
if (scope) {
|
|
127
164
|
Logger_1.logger.info(`Downloading fresh manifest for scope: ${scope}...`);
|
|
165
|
+
FileLogger_1.fileLogger.debug('Getting client and config...');
|
|
128
166
|
const client = (0, snClient_1.defaultClient)();
|
|
129
167
|
const config = ConfigManager.getConfig();
|
|
168
|
+
FileLogger_1.fileLogger.debug('Fetching manifest from ServiceNow for scope:', scope);
|
|
130
169
|
const newManifest = await (0, snClient_1.unwrapSNResponse)(client.getManifest(scope, config));
|
|
170
|
+
FileLogger_1.fileLogger.debug('New manifest received. Tables:', Object.keys(newManifest.tables));
|
|
171
|
+
FileLogger_1.fileLogger.debug('Manifest scope:', newManifest.scope);
|
|
131
172
|
Logger_1.logger.info(`Writing manifest file for scope: ${scope}...`);
|
|
132
173
|
await fUtils.writeScopeManifest(scope, newManifest);
|
|
133
174
|
Logger_1.logger.info("Finding and creating missing files...");
|
|
175
|
+
FileLogger_1.fileLogger.debug('Processing missing files for the new manifest...');
|
|
134
176
|
await (0, exports.processMissingFiles)(newManifest);
|
|
135
177
|
// Update the in-memory manifest for this scope
|
|
136
178
|
if (typeof curManifest === "object" && !curManifest.tables) {
|
|
@@ -234,11 +276,25 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
234
276
|
exports.findMissingFiles = findMissingFiles;
|
|
235
277
|
const processMissingFiles = async (newManifest) => {
|
|
236
278
|
try {
|
|
279
|
+
FileLogger_1.fileLogger.debug('\n=== processMissingFiles DEBUG START ===');
|
|
237
280
|
const missing = await (0, exports.findMissingFiles)(newManifest);
|
|
281
|
+
FileLogger_1.fileLogger.debug('Missing files found:', JSON.stringify(missing, null, 2));
|
|
238
282
|
const { tableOptions = {} } = ConfigManager.getConfig();
|
|
239
283
|
const client = (0, snClient_1.defaultClient)();
|
|
284
|
+
FileLogger_1.fileLogger.debug('Fetching missing files from ServiceNow...');
|
|
240
285
|
const filesToProcess = await (0, snClient_1.unwrapSNResponse)(client.getMissingFiles(missing, tableOptions));
|
|
286
|
+
FileLogger_1.fileLogger.debug('Files to process from ServiceNow:');
|
|
287
|
+
Object.keys(filesToProcess).forEach(tableName => {
|
|
288
|
+
const table = filesToProcess[tableName];
|
|
289
|
+
FileLogger_1.fileLogger.debug(` Table: ${tableName}`);
|
|
290
|
+
Object.keys(table.records).forEach(recordName => {
|
|
291
|
+
const record = table.records[recordName];
|
|
292
|
+
FileLogger_1.fileLogger.debug(` Record: ${recordName}`);
|
|
293
|
+
FileLogger_1.fileLogger.debug(` Files: ${record.files.map(f => `${f.name}.${f.type}`).join(', ')}`);
|
|
294
|
+
});
|
|
295
|
+
});
|
|
241
296
|
await processTablesInManifest(filesToProcess, false);
|
|
297
|
+
FileLogger_1.fileLogger.debug('=== processMissingFiles DEBUG END ===\n');
|
|
242
298
|
}
|
|
243
299
|
catch (e) {
|
|
244
300
|
throw e;
|
package/dist/bootstrap.js
CHANGED
|
@@ -40,7 +40,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
40
40
|
if (v !== undefined) module.exports = v;
|
|
41
41
|
}
|
|
42
42
|
else if (typeof define === "function" && define.amd) {
|
|
43
|
-
define(["require", "exports", "dotenv", "./config"], factory);
|
|
43
|
+
define(["require", "exports", "dotenv", "./config", "./FileLogger"], factory);
|
|
44
44
|
}
|
|
45
45
|
})(function (require, exports) {
|
|
46
46
|
"use strict";
|
|
@@ -49,12 +49,13 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
49
49
|
exports.init = init;
|
|
50
50
|
const dotenv_1 = __importDefault(require("dotenv"));
|
|
51
51
|
const ConfigManager = __importStar(require("./config"));
|
|
52
|
+
const FileLogger_1 = require("./FileLogger");
|
|
52
53
|
async function init() {
|
|
53
54
|
try {
|
|
54
55
|
await ConfigManager.loadConfigs();
|
|
55
56
|
}
|
|
56
57
|
catch (e) {
|
|
57
|
-
|
|
58
|
+
FileLogger_1.fileLogger.error(String(e));
|
|
58
59
|
}
|
|
59
60
|
let path = ConfigManager.getEnvPath();
|
|
60
61
|
dotenv_1.default.config({
|
package/dist/commands.js
CHANGED
|
@@ -40,7 +40,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
40
40
|
if (v !== undefined) module.exports = v;
|
|
41
41
|
}
|
|
42
42
|
else if (typeof define === "function" && define.amd) {
|
|
43
|
-
define(["require", "exports", "./config", "./Watcher", "./appUtils", "./wizard", "./Logger", "./logMessages", "./snClient", "inquirer", "./gitUtils", "./FileUtils"], factory);
|
|
43
|
+
define(["require", "exports", "./config", "./Watcher", "./appUtils", "./wizard", "./Logger", "./FileLogger", "./logMessages", "./snClient", "inquirer", "./gitUtils", "./FileUtils"], factory);
|
|
44
44
|
}
|
|
45
45
|
})(function (require, exports) {
|
|
46
46
|
"use strict";
|
|
@@ -59,6 +59,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
59
59
|
const AppUtils = __importStar(require("./appUtils"));
|
|
60
60
|
const wizard_1 = require("./wizard");
|
|
61
61
|
const Logger_1 = require("./Logger");
|
|
62
|
+
const FileLogger_1 = require("./FileLogger");
|
|
62
63
|
const logMessages_1 = require("./logMessages");
|
|
63
64
|
const snClient_1 = require("./snClient");
|
|
64
65
|
const inquirer_1 = __importDefault(require("inquirer"));
|
|
@@ -102,13 +103,18 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
102
103
|
}
|
|
103
104
|
async function refreshCommand(args, log = true) {
|
|
104
105
|
setLogLevel(args);
|
|
106
|
+
FileLogger_1.fileLogger.debug('\n=== refreshCommand DEBUG START ===');
|
|
107
|
+
FileLogger_1.fileLogger.debug('Log parameter:', log);
|
|
108
|
+
FileLogger_1.fileLogger.debug('Args:', args);
|
|
105
109
|
scopeCheck(async () => {
|
|
106
110
|
try {
|
|
107
111
|
if (!log)
|
|
108
112
|
setLogLevel({ logLevel: "warn" });
|
|
113
|
+
FileLogger_1.fileLogger.debug('Calling syncManifest (no scope parameter - will sync all)');
|
|
109
114
|
await AppUtils.syncManifest();
|
|
110
115
|
Logger_1.logger.success("Refresh complete! ✅");
|
|
111
116
|
setLogLevel(args);
|
|
117
|
+
FileLogger_1.fileLogger.debug('=== refreshCommand DEBUG END ===\n');
|
|
112
118
|
}
|
|
113
119
|
catch (e) {
|
|
114
120
|
throw e;
|
|
@@ -174,6 +180,8 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
174
180
|
async function downloadCommand(args) {
|
|
175
181
|
setLogLevel(args);
|
|
176
182
|
try {
|
|
183
|
+
FileLogger_1.fileLogger.debug('\n=== downloadCommand DEBUG START ===');
|
|
184
|
+
FileLogger_1.fileLogger.debug('Command arguments:', args);
|
|
177
185
|
let answers = await inquirer_1.default.prompt([
|
|
178
186
|
{
|
|
179
187
|
type: "confirm",
|
|
@@ -186,12 +194,34 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
186
194
|
return;
|
|
187
195
|
}
|
|
188
196
|
Logger_1.logger.info("Downloading manifest and files...");
|
|
197
|
+
FileLogger_1.fileLogger.debug('Scope to download:', args.scope);
|
|
198
|
+
FileLogger_1.fileLogger.debug('Getting manifest WITH FILES (third param = true)');
|
|
189
199
|
const client = (0, snClient_1.defaultClient)();
|
|
190
200
|
const config = ConfigManager.getConfig();
|
|
201
|
+
FileLogger_1.fileLogger.debug('Calling getManifest with withFiles=true');
|
|
191
202
|
const man = await (0, snClient_1.unwrapSNResponse)(client.getManifest(args.scope, config, true));
|
|
203
|
+
FileLogger_1.fileLogger.debug('Manifest received from ServiceNow');
|
|
204
|
+
FileLogger_1.fileLogger.debug('Manifest has', Object.keys(man.tables).length, 'tables');
|
|
205
|
+
// Check for metadata files in the manifest
|
|
206
|
+
let metadataFileCount = 0;
|
|
207
|
+
Object.keys(man.tables).forEach(tableName => {
|
|
208
|
+
const table = man.tables[tableName];
|
|
209
|
+
Object.keys(table.records).forEach(recordName => {
|
|
210
|
+
const record = table.records[recordName];
|
|
211
|
+
const metaFile = record.files.find((f) => f.name.toLowerCase().includes('metadata') ||
|
|
212
|
+
f.name.toLowerCase().includes('meta'));
|
|
213
|
+
if (metaFile) {
|
|
214
|
+
metadataFileCount++;
|
|
215
|
+
FileLogger_1.fileLogger.debug(`Found metadata file in ${tableName}/${recordName}:`, metaFile);
|
|
216
|
+
}
|
|
217
|
+
});
|
|
218
|
+
});
|
|
219
|
+
FileLogger_1.fileLogger.debug('Total metadata files found in manifest:', metadataFileCount);
|
|
192
220
|
Logger_1.logger.info("Creating local files from manifest...");
|
|
221
|
+
FileLogger_1.fileLogger.debug('Calling processManifest with forceWrite=true');
|
|
193
222
|
await AppUtils.processManifest(man, true);
|
|
194
223
|
Logger_1.logger.success("Download complete ✅");
|
|
224
|
+
FileLogger_1.fileLogger.debug('=== downloadCommand DEBUG END ===\n');
|
|
195
225
|
}
|
|
196
226
|
catch (e) {
|
|
197
227
|
throw e;
|
package/dist/index.js
CHANGED
|
@@ -5,13 +5,16 @@
|
|
|
5
5
|
if (v !== undefined) module.exports = v;
|
|
6
6
|
}
|
|
7
7
|
else if (typeof define === "function" && define.amd) {
|
|
8
|
-
define(["require", "exports", "./bootstrap"], factory);
|
|
8
|
+
define(["require", "exports", "./bootstrap", "./FileLogger"], factory);
|
|
9
9
|
}
|
|
10
10
|
})(function (require, exports) {
|
|
11
11
|
"use strict";
|
|
12
12
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13
13
|
const bootstrap_1 = require("./bootstrap");
|
|
14
|
+
const FileLogger_1 = require("./FileLogger");
|
|
14
15
|
function main() {
|
|
16
|
+
// Initialize file logging as early as possible
|
|
17
|
+
FileLogger_1.fileLogger.info("Starting Sincronia...");
|
|
15
18
|
(0, bootstrap_1.init)();
|
|
16
19
|
}
|
|
17
20
|
main();
|
package/dist/snClient.js
CHANGED
|
@@ -7,7 +7,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
7
7
|
if (v !== undefined) module.exports = v;
|
|
8
8
|
}
|
|
9
9
|
else if (typeof define === "function" && define.amd) {
|
|
10
|
-
define(["require", "exports", "axios", "axios-rate-limit", "./genericUtils", "./Logger"], factory);
|
|
10
|
+
define(["require", "exports", "axios", "axios-rate-limit", "./genericUtils", "./Logger", "./FileLogger"], factory);
|
|
11
11
|
}
|
|
12
12
|
})(function (require, exports) {
|
|
13
13
|
"use strict";
|
|
@@ -18,6 +18,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
18
18
|
const axios_rate_limit_1 = __importDefault(require("axios-rate-limit"));
|
|
19
19
|
const genericUtils_1 = require("./genericUtils");
|
|
20
20
|
const Logger_1 = require("./Logger");
|
|
21
|
+
const FileLogger_1 = require("./FileLogger");
|
|
21
22
|
const retryOnErr = async (f, allowedRetries, msBetween = 0, onRetry) => {
|
|
22
23
|
try {
|
|
23
24
|
return await f();
|
|
@@ -169,11 +170,31 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
169
170
|
};
|
|
170
171
|
const getMissingFiles = (missingFiles, tableOptions) => {
|
|
171
172
|
const endpoint = `api/x_nuvo_sinc/sinc/bulkDownload`;
|
|
173
|
+
FileLogger_1.fileLogger.debug('\n=== getMissingFiles DEBUG ===');
|
|
174
|
+
FileLogger_1.fileLogger.debug('Fetching missing files from ServiceNow');
|
|
175
|
+
FileLogger_1.fileLogger.debug('Endpoint:', endpoint);
|
|
176
|
+
FileLogger_1.fileLogger.debug('Missing files request:', JSON.stringify(missingFiles, null, 2));
|
|
177
|
+
FileLogger_1.fileLogger.debug('Table options:', JSON.stringify(tableOptions, null, 2));
|
|
178
|
+
FileLogger_1.fileLogger.debug('=== getMissingFiles DEBUG END ===\n');
|
|
172
179
|
return client.post(endpoint, { missingFiles, tableOptions });
|
|
173
180
|
};
|
|
174
181
|
const getManifest = (scope, config, withFiles = false) => {
|
|
175
182
|
const endpoint = `api/x_nuvo_sinc/sinc/getManifest/${scope}`;
|
|
176
183
|
const { includes = {}, excludes = {}, tableOptions = {}, scopes = {}, } = config;
|
|
184
|
+
FileLogger_1.fileLogger.debug('\n=== getManifest DEBUG ===');
|
|
185
|
+
FileLogger_1.fileLogger.debug('Fetching manifest from ServiceNow');
|
|
186
|
+
FileLogger_1.fileLogger.debug('Endpoint:', endpoint);
|
|
187
|
+
FileLogger_1.fileLogger.debug('Scope:', scope);
|
|
188
|
+
FileLogger_1.fileLogger.debug('With files (should download file contents):', withFiles);
|
|
189
|
+
FileLogger_1.fileLogger.debug('Request body:', JSON.stringify({
|
|
190
|
+
includes,
|
|
191
|
+
excludes,
|
|
192
|
+
tableOptions,
|
|
193
|
+
withFiles,
|
|
194
|
+
getContents: withFiles
|
|
195
|
+
}, null, 2));
|
|
196
|
+
FileLogger_1.fileLogger.debug('IMPORTANT: withFiles=' + withFiles + ' means', withFiles ? 'DOWNLOAD file contents' : 'NO file contents (manifest only)');
|
|
197
|
+
FileLogger_1.fileLogger.debug('=== getManifest DEBUG END ===\n');
|
|
177
198
|
return client.post(endpoint, {
|
|
178
199
|
includes,
|
|
179
200
|
excludes,
|
|
@@ -239,6 +260,67 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
239
260
|
const unwrapSNResponse = async (clientPromise) => {
|
|
240
261
|
try {
|
|
241
262
|
const resp = await clientPromise;
|
|
263
|
+
// Debug logging for manifest responses
|
|
264
|
+
if (resp.config && resp.config.url && resp.config.url.includes('getManifest')) {
|
|
265
|
+
FileLogger_1.fileLogger.debug('\n=== unwrapSNResponse DEBUG (Manifest) ===');
|
|
266
|
+
FileLogger_1.fileLogger.debug('Response status:', resp.status);
|
|
267
|
+
FileLogger_1.fileLogger.debug('Response URL:', resp.config.url);
|
|
268
|
+
// Check structure of manifest response
|
|
269
|
+
const result = resp.data.result;
|
|
270
|
+
if (result && result.tables) {
|
|
271
|
+
const tables = result.tables;
|
|
272
|
+
FileLogger_1.fileLogger.debug('Tables in manifest:', Object.keys(tables));
|
|
273
|
+
// Sample first table and record to see file structure
|
|
274
|
+
const firstTable = Object.keys(tables)[0];
|
|
275
|
+
if (firstTable) {
|
|
276
|
+
const table = tables[firstTable];
|
|
277
|
+
const firstRecord = Object.keys(table.records)[0];
|
|
278
|
+
if (firstRecord) {
|
|
279
|
+
const record = table.records[firstRecord];
|
|
280
|
+
FileLogger_1.fileLogger.debug(`Sample record from ${firstTable}:`, {
|
|
281
|
+
name: record.name,
|
|
282
|
+
sys_id: record.sys_id,
|
|
283
|
+
files: record.files.map((f) => ({
|
|
284
|
+
name: f.name,
|
|
285
|
+
type: f.type,
|
|
286
|
+
hasContent: !!f.content
|
|
287
|
+
}))
|
|
288
|
+
});
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
FileLogger_1.fileLogger.debug('=== unwrapSNResponse DEBUG END ===\n');
|
|
293
|
+
}
|
|
294
|
+
// Debug logging for bulkDownload responses
|
|
295
|
+
if (resp.config && resp.config.url && resp.config.url.includes('bulkDownload')) {
|
|
296
|
+
FileLogger_1.fileLogger.debug('\n=== unwrapSNResponse DEBUG (BulkDownload) ===');
|
|
297
|
+
FileLogger_1.fileLogger.debug('Response status:', resp.status);
|
|
298
|
+
FileLogger_1.fileLogger.debug('Response URL:', resp.config.url);
|
|
299
|
+
const result = resp.data.result;
|
|
300
|
+
if (result) {
|
|
301
|
+
const tables = result;
|
|
302
|
+
FileLogger_1.fileLogger.debug('Tables in bulk download:', Object.keys(tables || {}));
|
|
303
|
+
// Log details of files received
|
|
304
|
+
if (tables) {
|
|
305
|
+
Object.keys(tables).forEach((tableName) => {
|
|
306
|
+
const table = tables[tableName];
|
|
307
|
+
FileLogger_1.fileLogger.debug(`Table: ${tableName}`);
|
|
308
|
+
if (table && table.records) {
|
|
309
|
+
Object.keys(table.records).forEach((recordName) => {
|
|
310
|
+
const record = table.records[recordName];
|
|
311
|
+
FileLogger_1.fileLogger.debug(` Record: ${recordName}`);
|
|
312
|
+
if (record && record.files) {
|
|
313
|
+
record.files.forEach((file) => {
|
|
314
|
+
FileLogger_1.fileLogger.debug(` File: ${file.name}.${file.type} (content: ${file.content ? file.content.length + ' chars' : 'null'})`);
|
|
315
|
+
});
|
|
316
|
+
}
|
|
317
|
+
});
|
|
318
|
+
}
|
|
319
|
+
});
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
FileLogger_1.fileLogger.debug('=== unwrapSNResponse DEBUG END ===\n');
|
|
323
|
+
}
|
|
242
324
|
return resp.data.result;
|
|
243
325
|
}
|
|
244
326
|
catch (e) {
|