@tenonhq/sincronia-core 0.0.19 → 0.0.22
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/MultiScopeWatcher.js +311 -0
- package/dist/allScopesCommands.js +84 -19
- package/dist/commander.js +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,311 @@
|
|
|
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", "chokidar", "./logMessages", "lodash", "./FileUtils", "./appUtils", "./Logger", "path", "./config"], factory);
|
|
44
|
+
}
|
|
45
|
+
})(function (require, exports) {
|
|
46
|
+
"use strict";
|
|
47
|
+
var __syncRequire = typeof module === "object" && typeof module.exports === "object";
|
|
48
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
49
|
+
exports.multiScopeWatcher = void 0;
|
|
50
|
+
exports.startMultiScopeWatching = startMultiScopeWatching;
|
|
51
|
+
exports.stopMultiScopeWatching = stopMultiScopeWatching;
|
|
52
|
+
const chokidar_1 = __importDefault(require("chokidar"));
|
|
53
|
+
const logMessages_1 = require("./logMessages");
|
|
54
|
+
const lodash_1 = require("lodash");
|
|
55
|
+
const FileUtils_1 = require("./FileUtils");
|
|
56
|
+
const appUtils_1 = require("./appUtils");
|
|
57
|
+
const Logger_1 = require("./Logger");
|
|
58
|
+
const path = __importStar(require("path"));
|
|
59
|
+
const ConfigManager = __importStar(require("./config"));
|
|
60
|
+
const DEBOUNCE_MS = 300;
|
|
61
|
+
class MultiScopeWatcherManager {
|
|
62
|
+
constructor() {
|
|
63
|
+
this.scopeWatchers = new Map();
|
|
64
|
+
this.updateSetCheckInterval = null;
|
|
65
|
+
}
|
|
66
|
+
async startWatchingAllScopes() {
|
|
67
|
+
try {
|
|
68
|
+
// Load configuration
|
|
69
|
+
await ConfigManager.loadConfigs();
|
|
70
|
+
const config = ConfigManager.getConfig();
|
|
71
|
+
if (!config.scopes) {
|
|
72
|
+
Logger_1.logger.error("No scopes defined in sinc.config.js");
|
|
73
|
+
throw new Error("No scopes defined in configuration");
|
|
74
|
+
}
|
|
75
|
+
const scopes = Object.keys(config.scopes);
|
|
76
|
+
Logger_1.logger.info(`Starting multi-scope watch for ${scopes.length} scopes: ${scopes.join(", ")}`);
|
|
77
|
+
// Start watching each scope
|
|
78
|
+
for (const scopeName of scopes) {
|
|
79
|
+
const scopeConfig = config.scopes[scopeName];
|
|
80
|
+
let sourceDirectory;
|
|
81
|
+
if (typeof scopeConfig === "object" && scopeConfig.sourceDirectory) {
|
|
82
|
+
sourceDirectory = path.resolve(ConfigManager.getRootDir(), scopeConfig.sourceDirectory);
|
|
83
|
+
}
|
|
84
|
+
else {
|
|
85
|
+
// Default to src/{scope} if no sourceDirectory specified
|
|
86
|
+
sourceDirectory = path.resolve(ConfigManager.getRootDir(), "src", scopeName);
|
|
87
|
+
}
|
|
88
|
+
this.startWatchingScope(scopeName, sourceDirectory);
|
|
89
|
+
}
|
|
90
|
+
// Start periodic update set checking
|
|
91
|
+
this.startUpdateSetMonitoring();
|
|
92
|
+
Logger_1.logger.success("✅ Multi-scope watch started successfully!");
|
|
93
|
+
Logger_1.logger.info("Watching for file changes across all scopes...");
|
|
94
|
+
Logger_1.logger.info("Press Ctrl+C to stop watching\n");
|
|
95
|
+
}
|
|
96
|
+
catch (error) {
|
|
97
|
+
Logger_1.logger.error("Failed to start multi-scope watch: " + error);
|
|
98
|
+
throw error;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
startWatchingScope(scopeName, sourceDirectory) {
|
|
102
|
+
Logger_1.logger.info(`Setting up watcher for scope ${scopeName} in ${sourceDirectory}`);
|
|
103
|
+
const watcher = chokidar_1.default.watch(sourceDirectory, {
|
|
104
|
+
persistent: true,
|
|
105
|
+
ignoreInitial: true,
|
|
106
|
+
awaitWriteFinish: {
|
|
107
|
+
stabilityThreshold: 300,
|
|
108
|
+
pollInterval: 100
|
|
109
|
+
}
|
|
110
|
+
});
|
|
111
|
+
const scopeWatcher = {
|
|
112
|
+
scope: scopeName,
|
|
113
|
+
watcher: watcher,
|
|
114
|
+
pushQueue: [],
|
|
115
|
+
sourceDirectory: sourceDirectory
|
|
116
|
+
};
|
|
117
|
+
// Create a debounced processor for this scope
|
|
118
|
+
const processQueue = (0, lodash_1.debounce)(async () => {
|
|
119
|
+
await this.processScopeQueue(scopeWatcher);
|
|
120
|
+
}, DEBOUNCE_MS);
|
|
121
|
+
watcher.on("change", (filePath) => {
|
|
122
|
+
Logger_1.logger.info(`[${scopeName}] File changed: ${path.relative(sourceDirectory, filePath)}`);
|
|
123
|
+
scopeWatcher.pushQueue.push(filePath);
|
|
124
|
+
processQueue();
|
|
125
|
+
});
|
|
126
|
+
watcher.on("add", (filePath) => {
|
|
127
|
+
Logger_1.logger.info(`[${scopeName}] File added: ${path.relative(sourceDirectory, filePath)}`);
|
|
128
|
+
scopeWatcher.pushQueue.push(filePath);
|
|
129
|
+
processQueue();
|
|
130
|
+
});
|
|
131
|
+
watcher.on("error", (error) => {
|
|
132
|
+
Logger_1.logger.error(`[${scopeName}] Watcher error: ${error.message}`);
|
|
133
|
+
});
|
|
134
|
+
this.scopeWatchers.set(scopeName, scopeWatcher);
|
|
135
|
+
}
|
|
136
|
+
async processScopeQueue(scopeWatcher) {
|
|
137
|
+
if (scopeWatcher.pushQueue.length === 0)
|
|
138
|
+
return;
|
|
139
|
+
const toProcess = Array.from(new Set([...scopeWatcher.pushQueue]));
|
|
140
|
+
scopeWatcher.pushQueue = [];
|
|
141
|
+
Logger_1.logger.info(`[${scopeWatcher.scope}] Processing ${toProcess.length} file(s)...`);
|
|
142
|
+
try {
|
|
143
|
+
// First, switch to the correct scope
|
|
144
|
+
await this.switchToScope(scopeWatcher.scope);
|
|
145
|
+
// Process the files
|
|
146
|
+
const fileContexts = toProcess
|
|
147
|
+
.map(FileUtils_1.getFileContextFromPath)
|
|
148
|
+
.filter((ctx) => !!ctx);
|
|
149
|
+
if (fileContexts.length === 0) {
|
|
150
|
+
Logger_1.logger.warn(`[${scopeWatcher.scope}] No valid file contexts found`);
|
|
151
|
+
return;
|
|
152
|
+
}
|
|
153
|
+
const buildables = (0, appUtils_1.groupAppFiles)(fileContexts);
|
|
154
|
+
const updateResults = await (0, appUtils_1.pushFiles)(buildables);
|
|
155
|
+
updateResults.forEach((res, index) => {
|
|
156
|
+
if (index < fileContexts.length) {
|
|
157
|
+
(0, logMessages_1.logFilePush)(fileContexts[index], res);
|
|
158
|
+
}
|
|
159
|
+
});
|
|
160
|
+
Logger_1.logger.success(`[${scopeWatcher.scope}] Successfully pushed ${updateResults.length} file(s)`);
|
|
161
|
+
}
|
|
162
|
+
catch (error) {
|
|
163
|
+
Logger_1.logger.error(`[${scopeWatcher.scope}] Error processing queue: ${error}`);
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
async switchToScope(scopeName) {
|
|
167
|
+
try {
|
|
168
|
+
const { defaultClient, unwrapSNResponse } = await (__syncRequire ? Promise.resolve().then(() => __importStar(require("./snClient"))) : new Promise((resolve_1, reject_1) => { require(["./snClient"], resolve_1, reject_1); }).then(__importStar));
|
|
169
|
+
const client = defaultClient();
|
|
170
|
+
// Get the scope ID
|
|
171
|
+
const scopeResponse = await unwrapSNResponse(client.getScopeId(scopeName));
|
|
172
|
+
if (!scopeResponse || !Array.isArray(scopeResponse) || scopeResponse.length === 0 || !scopeResponse[0].sys_id) {
|
|
173
|
+
throw new Error(`Scope ${scopeName} not found`);
|
|
174
|
+
}
|
|
175
|
+
// Get user sys_id
|
|
176
|
+
const userResponse = await unwrapSNResponse(client.getUserSysId());
|
|
177
|
+
if (!userResponse || !Array.isArray(userResponse) || userResponse.length === 0 || !userResponse[0].sys_id) {
|
|
178
|
+
throw new Error("Could not get user sys_id");
|
|
179
|
+
}
|
|
180
|
+
// Get current app preference
|
|
181
|
+
const prefResponse = await unwrapSNResponse(client.getCurrentAppUserPrefSysId(userResponse[0].sys_id));
|
|
182
|
+
if (prefResponse && Array.isArray(prefResponse) && prefResponse.length > 0 && prefResponse[0].sys_id) {
|
|
183
|
+
// Update existing preference
|
|
184
|
+
await client.updateCurrentAppUserPref(scopeResponse[0].sys_id, prefResponse[0].sys_id);
|
|
185
|
+
}
|
|
186
|
+
else {
|
|
187
|
+
// Create new preference
|
|
188
|
+
await client.createCurrentAppUserPref(scopeResponse[0].sys_id, userResponse[0].sys_id);
|
|
189
|
+
}
|
|
190
|
+
Logger_1.logger.debug(`Switched to scope: ${scopeName}`);
|
|
191
|
+
}
|
|
192
|
+
catch (error) {
|
|
193
|
+
Logger_1.logger.error(`Failed to switch to scope ${scopeName}: ${error}`);
|
|
194
|
+
throw error;
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
async startUpdateSetMonitoring() {
|
|
198
|
+
// Check update sets immediately on start
|
|
199
|
+
await this.checkAllUpdateSets();
|
|
200
|
+
// Then check every 30 seconds
|
|
201
|
+
this.updateSetCheckInterval = setInterval(async () => {
|
|
202
|
+
await this.checkAllUpdateSets();
|
|
203
|
+
}, 30000);
|
|
204
|
+
}
|
|
205
|
+
async checkAllUpdateSets() {
|
|
206
|
+
try {
|
|
207
|
+
const { defaultClient, unwrapSNResponse } = await (__syncRequire ? Promise.resolve().then(() => __importStar(require("./snClient"))) : new Promise((resolve_2, reject_2) => { require(["./snClient"], resolve_2, reject_2); }).then(__importStar));
|
|
208
|
+
const client = defaultClient();
|
|
209
|
+
const config = ConfigManager.getConfig();
|
|
210
|
+
if (!config.scopes)
|
|
211
|
+
return;
|
|
212
|
+
const scopes = Object.keys(config.scopes);
|
|
213
|
+
Logger_1.logger.info("\n" + "=".repeat(60));
|
|
214
|
+
Logger_1.logger.info("Update Set Status Check");
|
|
215
|
+
Logger_1.logger.info("=".repeat(60));
|
|
216
|
+
for (const scopeName of scopes) {
|
|
217
|
+
try {
|
|
218
|
+
// Switch to scope to check its update set
|
|
219
|
+
await this.switchToScope(scopeName);
|
|
220
|
+
// Get user sys_id
|
|
221
|
+
const userResponse = await unwrapSNResponse(client.getUserSysId());
|
|
222
|
+
if (!userResponse || !Array.isArray(userResponse) || userResponse.length === 0 || !userResponse[0].sys_id) {
|
|
223
|
+
Logger_1.logger.warn(`[${scopeName}] Could not get user information`);
|
|
224
|
+
continue;
|
|
225
|
+
}
|
|
226
|
+
// Get current update set preference
|
|
227
|
+
const updateSetPref = await unwrapSNResponse(client.getCurrentUpdateSetUserPref(userResponse[0].sys_id));
|
|
228
|
+
if (updateSetPref && Array.isArray(updateSetPref) && updateSetPref.length > 0 && updateSetPref[0].value) {
|
|
229
|
+
// Get update set details
|
|
230
|
+
const updateSetId = updateSetPref[0].value;
|
|
231
|
+
const updateSetDetails = await this.getUpdateSetDetails(updateSetId);
|
|
232
|
+
if (updateSetDetails) {
|
|
233
|
+
const isDefault = updateSetDetails.name === "Default" ||
|
|
234
|
+
updateSetDetails.name.toLowerCase().includes("default");
|
|
235
|
+
if (isDefault) {
|
|
236
|
+
Logger_1.logger.warn(`⚠️ [${scopeName}] Currently in DEFAULT update set!`);
|
|
237
|
+
}
|
|
238
|
+
else {
|
|
239
|
+
Logger_1.logger.info(`✅ [${scopeName}] Update Set: ${updateSetDetails.name}`);
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
else {
|
|
243
|
+
Logger_1.logger.info(`[${scopeName}] Update Set ID: ${updateSetId}`);
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
else {
|
|
247
|
+
Logger_1.logger.warn(`⚠️ [${scopeName}] No update set selected or in DEFAULT`);
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
catch (error) {
|
|
251
|
+
Logger_1.logger.error(`[${scopeName}] Error checking update set: ${error}`);
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
Logger_1.logger.info("=".repeat(60) + "\n");
|
|
255
|
+
}
|
|
256
|
+
catch (error) {
|
|
257
|
+
Logger_1.logger.error(`Error during update set monitoring: ${error}`);
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
async getUpdateSetDetails(updateSetId) {
|
|
261
|
+
try {
|
|
262
|
+
const { defaultClient } = await (__syncRequire ? Promise.resolve().then(() => __importStar(require("./snClient"))) : new Promise((resolve_3, reject_3) => { require(["./snClient"], resolve_3, reject_3); }).then(__importStar));
|
|
263
|
+
const client = defaultClient();
|
|
264
|
+
// Create axios client directly to get update set details
|
|
265
|
+
const axios = (await (__syncRequire ? Promise.resolve().then(() => __importStar(require("axios"))) : new Promise((resolve_4, reject_4) => { require(["axios"], resolve_4, reject_4); }).then(__importStar))).default;
|
|
266
|
+
const { SN_USER = "", SN_PASSWORD = "", SN_INSTANCE = "" } = process.env;
|
|
267
|
+
const axiosClient = axios.create({
|
|
268
|
+
auth: {
|
|
269
|
+
username: SN_USER,
|
|
270
|
+
password: SN_PASSWORD
|
|
271
|
+
},
|
|
272
|
+
baseURL: SN_INSTANCE
|
|
273
|
+
});
|
|
274
|
+
const response = await axiosClient.get(`/api/now/table/sys_update_set/${updateSetId}`, {
|
|
275
|
+
params: {
|
|
276
|
+
sysparm_fields: "name,state,sys_id"
|
|
277
|
+
}
|
|
278
|
+
});
|
|
279
|
+
if (response.data && response.data.result) {
|
|
280
|
+
return response.data.result;
|
|
281
|
+
}
|
|
282
|
+
return null;
|
|
283
|
+
}
|
|
284
|
+
catch (error) {
|
|
285
|
+
Logger_1.logger.debug(`Could not get update set details: ${error}`);
|
|
286
|
+
return null;
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
stopWatching() {
|
|
290
|
+
// Stop all scope watchers
|
|
291
|
+
for (const [scopeName, scopeWatcher] of this.scopeWatchers) {
|
|
292
|
+
Logger_1.logger.info(`Stopping watcher for scope: ${scopeName}`);
|
|
293
|
+
scopeWatcher.watcher.close();
|
|
294
|
+
}
|
|
295
|
+
this.scopeWatchers.clear();
|
|
296
|
+
// Stop update set monitoring
|
|
297
|
+
if (this.updateSetCheckInterval) {
|
|
298
|
+
clearInterval(this.updateSetCheckInterval);
|
|
299
|
+
this.updateSetCheckInterval = null;
|
|
300
|
+
}
|
|
301
|
+
Logger_1.logger.info("All watchers stopped");
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
exports.multiScopeWatcher = new MultiScopeWatcherManager();
|
|
305
|
+
function startMultiScopeWatching() {
|
|
306
|
+
return exports.multiScopeWatcher.startWatchingAllScopes();
|
|
307
|
+
}
|
|
308
|
+
function stopMultiScopeWatching() {
|
|
309
|
+
exports.multiScopeWatcher.stopWatching();
|
|
310
|
+
}
|
|
311
|
+
});
|
|
@@ -37,15 +37,16 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
37
37
|
if (v !== undefined) module.exports = v;
|
|
38
38
|
}
|
|
39
39
|
else if (typeof define === "function" && define.amd) {
|
|
40
|
-
define(["require", "exports", "./Logger", "./config", "./
|
|
40
|
+
define(["require", "exports", "./Logger", "./config", "./snClient", "./commands", "path", "fs"], factory);
|
|
41
41
|
}
|
|
42
42
|
})(function (require, exports) {
|
|
43
43
|
"use strict";
|
|
44
|
+
var __syncRequire = typeof module === "object" && typeof module.exports === "object";
|
|
44
45
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
45
46
|
exports.initScopesCommand = initScopesCommand;
|
|
47
|
+
exports.watchAllScopesCommand = watchAllScopesCommand;
|
|
46
48
|
const Logger_1 = require("./Logger");
|
|
47
49
|
const ConfigManager = __importStar(require("./config"));
|
|
48
|
-
const fUtils = __importStar(require("./FileUtils"));
|
|
49
50
|
const snClient_1 = require("./snClient");
|
|
50
51
|
const commands_1 = require("./commands");
|
|
51
52
|
const path = __importStar(require("path"));
|
|
@@ -53,24 +54,62 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
53
54
|
const fsp = fs.promises;
|
|
54
55
|
// Custom function to process manifest with specific source directory
|
|
55
56
|
async function processManifestForScope(manifest, sourceDirectory, forceWrite = false) {
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
57
|
+
var _a;
|
|
58
|
+
try {
|
|
59
|
+
// Ensure the source directory exists
|
|
60
|
+
Logger_1.logger.info(`Creating source directory: ${sourceDirectory}`);
|
|
61
|
+
try {
|
|
62
|
+
await fsp.mkdir(sourceDirectory, { recursive: true });
|
|
63
|
+
Logger_1.logger.info(`Successfully created directory: ${sourceDirectory}`);
|
|
64
|
+
}
|
|
65
|
+
catch (dirError) {
|
|
66
|
+
Logger_1.logger.error(`Failed to create source directory ${sourceDirectory}: ${dirError}`);
|
|
67
|
+
throw dirError;
|
|
68
|
+
}
|
|
69
|
+
// Process each table in the manifest
|
|
70
|
+
const tables = manifest.tables || {};
|
|
71
|
+
const tableNames = Object.keys(tables);
|
|
72
|
+
Logger_1.logger.info(`Processing ${tableNames.length} tables`);
|
|
73
|
+
Logger_1.logger.debug(`Table names: ${tableNames.join(', ')}`);
|
|
74
|
+
for (const tableName of tableNames) {
|
|
75
|
+
const tableRecords = tables[tableName];
|
|
76
|
+
const tablePath = path.join(sourceDirectory, tableName);
|
|
77
|
+
// Process each record in the table
|
|
78
|
+
const recordNames = Object.keys(tableRecords.records || {});
|
|
79
|
+
Logger_1.logger.debug(`Processing ${recordNames.length} records in table ${tableName}`);
|
|
80
|
+
for (const recordName of recordNames) {
|
|
81
|
+
const record = tableRecords.records[recordName];
|
|
82
|
+
// Use the record's name property instead of the key for the directory name
|
|
83
|
+
const recordDirName = record.name || recordName;
|
|
84
|
+
const recordPath = path.join(tablePath, recordDirName);
|
|
85
|
+
Logger_1.logger.debug(`Processing record: ${recordDirName} with ${((_a = record.files) === null || _a === void 0 ? void 0 : _a.length) || 0} files`);
|
|
86
|
+
// Ensure the record directory exists
|
|
87
|
+
await fsp.mkdir(recordPath, { recursive: true });
|
|
88
|
+
// Process each file in the record
|
|
89
|
+
for (const file of record.files || []) {
|
|
90
|
+
const filePath = path.join(recordPath, `${file.name}.${file.type}`);
|
|
91
|
+
const fileContent = file.content || "";
|
|
92
|
+
// Ensure the parent directory exists before writing the file
|
|
93
|
+
const fileDir = path.dirname(filePath);
|
|
94
|
+
Logger_1.logger.debug(`Creating directory: ${fileDir}`);
|
|
95
|
+
await fsp.mkdir(fileDir, { recursive: true });
|
|
96
|
+
// Create the file
|
|
97
|
+
Logger_1.logger.debug(`Writing file: ${filePath}`);
|
|
98
|
+
try {
|
|
99
|
+
await fsp.writeFile(filePath, fileContent, 'utf8');
|
|
100
|
+
}
|
|
101
|
+
catch (writeError) {
|
|
102
|
+
Logger_1.logger.error(`Failed to write file ${filePath}: ${writeError}`);
|
|
103
|
+
throw writeError;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
72
106
|
}
|
|
73
107
|
}
|
|
108
|
+
Logger_1.logger.info(`Successfully processed files for ${sourceDirectory}`);
|
|
109
|
+
}
|
|
110
|
+
catch (error) {
|
|
111
|
+
Logger_1.logger.error(`Error in processManifestForScope: ${error}`);
|
|
112
|
+
throw error;
|
|
74
113
|
}
|
|
75
114
|
}
|
|
76
115
|
async function processScope(scopeName, scopeConfig) {
|
|
@@ -106,6 +145,7 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
106
145
|
const manifest = await (0, snClient_1.unwrapSNResponse)(client.getManifest(scopeName, config, true));
|
|
107
146
|
// Process the manifest to create local files in the correct directory
|
|
108
147
|
Logger_1.logger.info(`Processing manifest and creating local files for ${scopeName}...`);
|
|
148
|
+
Logger_1.logger.info(`Manifest has ${Object.keys((manifest === null || manifest === void 0 ? void 0 : manifest.tables) || {}).length} tables`);
|
|
109
149
|
await processManifestForScope(manifest, sourceDirectory, true);
|
|
110
150
|
// Create the scope-specific manifest structure
|
|
111
151
|
const scopeManifest = {
|
|
@@ -180,11 +220,36 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
180
220
|
}
|
|
181
221
|
Logger_1.logger.info(`Manifest written to: ${manifestPath}`);
|
|
182
222
|
Logger_1.logger.info("\nAll scope files have been downloaded to their respective source directories.");
|
|
183
|
-
Logger_1.logger.success("\nYou can now use 'npx sinc
|
|
223
|
+
Logger_1.logger.success("\nYou can now use 'npx sinc watchAllScopes' to start development mode!");
|
|
184
224
|
}
|
|
185
225
|
catch (e) {
|
|
186
226
|
Logger_1.logger.error("Error initializing scopes: " + e);
|
|
187
227
|
throw e;
|
|
188
228
|
}
|
|
189
229
|
}
|
|
230
|
+
async function watchAllScopesCommand(args) {
|
|
231
|
+
(0, commands_1.setLogLevel)(args);
|
|
232
|
+
try {
|
|
233
|
+
// First check if we have environment variables set
|
|
234
|
+
if (!process.env.SN_USER || !process.env.SN_PASSWORD || !process.env.SN_INSTANCE) {
|
|
235
|
+
Logger_1.logger.error("Missing ServiceNow credentials. Please ensure SN_USER, SN_PASSWORD, and SN_INSTANCE are set in your .env file");
|
|
236
|
+
throw new Error("ServiceNow credentials not configured");
|
|
237
|
+
}
|
|
238
|
+
// Import and start the multi-scope watcher
|
|
239
|
+
const { startMultiScopeWatching } = await (__syncRequire ? Promise.resolve().then(() => __importStar(require("./MultiScopeWatcher"))) : new Promise((resolve_1, reject_1) => { require(["./MultiScopeWatcher"], resolve_1, reject_1); }).then(__importStar));
|
|
240
|
+
// Start watching all scopes
|
|
241
|
+
await startMultiScopeWatching();
|
|
242
|
+
// Keep the process running
|
|
243
|
+
process.on("SIGINT", async () => {
|
|
244
|
+
Logger_1.logger.info("\nStopping multi-scope watch...");
|
|
245
|
+
const { stopMultiScopeWatching } = await (__syncRequire ? Promise.resolve().then(() => __importStar(require("./MultiScopeWatcher"))) : new Promise((resolve_2, reject_2) => { require(["./MultiScopeWatcher"], resolve_2, reject_2); }).then(__importStar));
|
|
246
|
+
stopMultiScopeWatching();
|
|
247
|
+
process.exit(0);
|
|
248
|
+
});
|
|
249
|
+
}
|
|
250
|
+
catch (error) {
|
|
251
|
+
Logger_1.logger.error("Failed to start multi-scope watch: " + error);
|
|
252
|
+
throw error;
|
|
253
|
+
}
|
|
254
|
+
}
|
|
190
255
|
});
|
package/dist/commander.js
CHANGED
|
@@ -61,6 +61,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
61
61
|
})
|
|
62
62
|
.command("init", "Provisions an initial project for you", sharedOptions, commands_1.initCommand)
|
|
63
63
|
.command("initScopes", "Provisions an initial project for the scopes defined in the config", sharedOptions, allScopesCommands_1.initScopesCommand)
|
|
64
|
+
.command("watchAllScopes", "Watch all scopes for file changes and display update set status", sharedOptions, allScopesCommands_1.watchAllScopesCommand)
|
|
64
65
|
.command("build", "Build application files locally", (cmdArgs) => {
|
|
65
66
|
cmdArgs.options({
|
|
66
67
|
...sharedOptions,
|