@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.
@@ -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
- return fs_1.promises.writeFile(ConfigManager.getScopeManifestPath(scope), JSON.stringify(man, null, 2));
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
- return fs_1.promises.writeFile(ConfigManager.getManifestPath(), JSON.stringify(man, null, 2));
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
- return fs_1.promises.writeFile(ConfigManager.getScopeManifestPath(scope), JSON.stringify(man, null, 2));
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
- const fullPath = path_1.default.join(parentPath, `${name}.${type}`);
85
- return await fs_1.promises.writeFile(fullPath, content);
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
- // Process metadata files separately
61
- const metadataFiles = [];
62
- const regularFiles = [];
63
- rec.files.forEach((file) => {
64
- if (file.name === "metaData" && file.type === "json") {
65
- metadataFiles.push(file);
66
- }
67
- else {
68
- regularFiles.push(file);
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 files with updated _lastUpdatedOn field
72
- const metadataPromises = metadataFiles.map(async (file) => {
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
- // Write regular files
76
- const regularPromises = regularFiles.map((file) => fileWrite(file, recPath));
77
- await Promise.all([...metadataPromises, ...regularPromises]);
78
- // Remove content from ALL files and exclude metadata from manifest
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
- console.log(e);
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) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tenonhq/sincronia-core",
3
- "version": "0.0.46",
3
+ "version": "0.0.47",
4
4
  "description": "Next-gen file syncer",
5
5
  "license": "GPL-3.0",
6
6
  "main": "./dist/index.js",