bitburner-studio 0.1.0

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,184 @@
1
+ import { promises as fs, watch } from 'node:fs';
2
+ import { Events } from '@netfeez/common';
3
+ import { File, Glob, Path } from '@netfeez/common-node';
4
+ export class Observer extends Events {
5
+ vFolder;
6
+ options;
7
+ watcher = null;
8
+ snapshot = null; // filename -> mtime
9
+ pollIntervalId = null;
10
+ globExec;
11
+ glob;
12
+ debounceDelay;
13
+ constructor(vFolder, options = {}) {
14
+ super();
15
+ this.vFolder = vFolder;
16
+ this.options = options;
17
+ const { glob = '**/*', debounceDelay = 500 } = options;
18
+ this.glob = glob;
19
+ this.debounceDelay = debounceDelay;
20
+ this.vFolder = Path.resolve(vFolder);
21
+ this.globExec = Glob.globToRegex(glob);
22
+ }
23
+ get observing() { return !!this.watcher; }
24
+ get target() { return this.vFolder; }
25
+ set target(folder) {
26
+ folder = Path.resolve(folder);
27
+ if (folder === this.vFolder)
28
+ return;
29
+ this.vFolder = folder;
30
+ if (!this.watcher)
31
+ return;
32
+ this.stop();
33
+ }
34
+ /**
35
+ * Starts the workspace observer by setting up a file system watcher on the specified workspace folder.
36
+ * The observer will monitor the folder for any changes, such as file creations, deletions, modifications, or renames.
37
+ * When a change is detected, the observer will trigger the appropriate events (create, delete, change, rename) with the relevant file paths.
38
+ * The observer also builds an initial snapshot of the workspace to track the state of files and their modification times for accurate change detection.
39
+ */
40
+ async start() {
41
+ if (this.watcher)
42
+ return;
43
+ const handler = Observer.debounce(this.changeHandler.bind(this), this.debounceDelay);
44
+ this.snapshot = await this.buildSnapshot();
45
+ try {
46
+ this.watcher = watch(this.target, { recursive: true }, (_, filename) => handler(filename));
47
+ this.watcher.on('error', () => { });
48
+ }
49
+ catch (err) {
50
+ this.watcher = watch(this.target, (_, filename) => handler(filename));
51
+ this.watcher.on('error', () => { });
52
+ this.pollIntervalId = setInterval(() => { void this.scan(this.target).catch(() => { }); }, 2000);
53
+ }
54
+ }
55
+ /**
56
+ * Stops the workspace observer by closing the file system watcher and clearing any existing snapshots.
57
+ * This will effectively stop monitoring the workspace folder for changes and prevent any further events from being triggered until the observer is started again.
58
+ */
59
+ stop() {
60
+ if (!this.watcher)
61
+ return;
62
+ this.watcher.close();
63
+ this.watcher = null;
64
+ this.snapshot = null;
65
+ if (this.pollIntervalId) {
66
+ clearInterval(this.pollIntervalId);
67
+ this.pollIntervalId = null;
68
+ }
69
+ }
70
+ /**
71
+ * Restarts the workspace observer by first stopping it and then starting it again. This can be useful if you want to reset the observer or apply changes to the workspace folder path without creating a new instance of the observer.
72
+ * The restart process will ensure that the observer is properly reinitialized and ready to monitor the workspace folder for changes.
73
+ */
74
+ async restart() {
75
+ this.stop();
76
+ await this.start();
77
+ }
78
+ /**
79
+ * Internal method that handles file system change events triggered by the watcher.
80
+ * This method is debounced to prevent excessive calls during rapid file changes.
81
+ * When a change is detected, it scans the workspace folder to compare the current state of files against the previously stored snapshot.
82
+ * It identifies added, removed, changed, and renamed files, and emits the corresponding events with the relevant file paths.
83
+ */
84
+ changeHandler(filename) {
85
+ if (filename && !this.globExec.test(filename))
86
+ return;
87
+ this.scan(this.target).catch(() => { });
88
+ }
89
+ /**
90
+ * Scans the workspace folder to build a snapshot of the current state of files and their modification times.
91
+ * It compares the current snapshot with the previous snapshot to identify any added, removed, changed, or renamed files.
92
+ * Based on the comparison, it emits the appropriate events (create, delete, change, rename) with the relevant file paths.
93
+ * @param folder - The folder to scan for files. This should be the root of the workspace being observed.
94
+ * @returns A promise that resolves when the scan is complete and events have been emitted for any detected changes.
95
+ */
96
+ async scan(folder) {
97
+ if (!this.snapshot)
98
+ this.snapshot = await this.buildSnapshot();
99
+ const previous = this.snapshot;
100
+ let current = new Map();
101
+ try {
102
+ current = await this.buildSnapshot();
103
+ }
104
+ catch {
105
+ for (const file of previous.keys())
106
+ this.emit('delete', file);
107
+ this.snapshot = new Map();
108
+ return;
109
+ }
110
+ const added = [];
111
+ const removed = [];
112
+ const changed = [];
113
+ for (const file of current.keys()) {
114
+ if (!previous.has(file))
115
+ added.push(file);
116
+ else if ((previous.get(file) ?? 0) !== (current.get(file) ?? 0))
117
+ changed.push(file);
118
+ }
119
+ for (const file of previous.keys()) {
120
+ if (!current.has(file))
121
+ removed.push(file);
122
+ }
123
+ if (added.length === 1 && removed.length === 1) {
124
+ const oldName = removed[0];
125
+ const newName = added[0];
126
+ const relativeOld = Path.diff(this.target, oldName);
127
+ const relativeNew = Path.diff(this.target, newName);
128
+ this.emit('rename', relativeOld, relativeNew);
129
+ }
130
+ else {
131
+ for (const file of added)
132
+ this.emit('create', Path.diff(this.target, file));
133
+ for (const file of removed)
134
+ this.emit('delete', Path.diff(this.target, file));
135
+ }
136
+ for (const change of changed)
137
+ this.emit('change', Path.diff(this.target, change));
138
+ this.snapshot = current;
139
+ }
140
+ /**
141
+ * Utility function to build a snapshot of the current state of the workspace by recursively scanning the specified folder and recording the modification time of each file.
142
+ * @param folder - The folder to scan for files. This should be the root of the workspace being observed.
143
+ * @return A promise that resolves to a snapshot, which is a Map where the keys are file paths (relative to the workspace root) and the values are the modification times of those files. This snapshot can be used to compare against future scans to detect changes in the workspace.
144
+ */
145
+ async buildSnapshot() {
146
+ const snapshot = new Map();
147
+ const target = Path.join(this.target, this.glob);
148
+ try {
149
+ await File.smartProcess(target, this.target, { concurrency: 16 }, async ({ src }) => {
150
+ try {
151
+ const stat = await fs.stat(src);
152
+ snapshot.set(src, stat.mtimeMs);
153
+ }
154
+ catch {
155
+ this.emit('warn', `Failed to stat file: ${src}`);
156
+ }
157
+ });
158
+ }
159
+ catch {
160
+ this.emit('warn', `Failed to build snapshot for folder: ${this.target}`);
161
+ }
162
+ // console.debug({ snapshot, target, exec: this.globExec, });
163
+ return snapshot;
164
+ }
165
+ /**
166
+ * Utility function to debounce calls to a function, ensuring that it is only called once within a specified time frame, even if it is triggered multiple times. This is particularly useful for handling rapid file system events without overwhelming the system with too many calls.
167
+ * @param action - The function to debounce.
168
+ * @param delay - The time frame in milliseconds during which the function should only be called once.
169
+ * @returns A debounced version of the input function.
170
+ */
171
+ static debounce(action, delay) {
172
+ let timeout = null;
173
+ return function (...args) {
174
+ if (timeout)
175
+ clearTimeout(timeout);
176
+ timeout = setTimeout(() => {
177
+ timeout = null;
178
+ action.apply(this, args);
179
+ }, delay);
180
+ };
181
+ }
182
+ }
183
+ export default Observer;
184
+ //# sourceMappingURL=Observer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Observer.js","sourceRoot":"","sources":["../../src/Workspace/Observer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,399 @@
1
+ import { Events, Time } from "@netfeez/common";
2
+ import { File, Glob, Path } from "@netfeez/common-node";
3
+ import Logger from "@netfeez/vterm";
4
+ import ts from 'typescript';
5
+ import Observer from "./Observer.js";
6
+ import Defaults from "./Default.js";
7
+ import { IS_VALID_FILENAME } from "../contract.js";
8
+ import { truncate } from "node:fs";
9
+ const logger = new Logger({ name: 'WSP' });
10
+ export class Workspace extends Events {
11
+ client;
12
+ static DEFAULT_TYPESCRIPT = true;
13
+ static DEFAULT_ROOT = '.workspace';
14
+ static DEFAULT_SHARED = 'shared';
15
+ static DEFAULT_SERVER = 'server';
16
+ static DEFAULT_BACKUP = 'backup';
17
+ static DEFAULT_DOWNLOAD = 'download';
18
+ config;
19
+ preBind;
20
+ paths;
21
+ /** Observers */
22
+ compilerObserver;
23
+ staticObserver;
24
+ tsWatcher = null;
25
+ constructor(client, config = {}) {
26
+ super();
27
+ this.client = client;
28
+ this.config = Workspace.normalizeConfig(config);
29
+ this.compilerObserver = new Observer(this.config.folders.shared, { glob: '**/*.js', debounceDelay: 1000 });
30
+ this.staticObserver = new Observer(this.config.folders.server, { glob: Workspace.staticGlob(this.config.typescript), debounceDelay: 1000 });
31
+ this.preBind = {
32
+ compiler: {
33
+ createFile: this.UpdateFile.bind(this, this.config.folders.shared),
34
+ updateFile: this.UpdateFile.bind(this, this.config.folders.shared),
35
+ deleteFile: this.DeleteFile.bind(this, this.config.folders.shared)
36
+ },
37
+ static: {
38
+ createFile: this.UpdateFile.bind(this, this.config.folders.server),
39
+ updateFile: this.UpdateFile.bind(this, this.config.folders.server),
40
+ deleteFile: this.DeleteFile.bind(this, this.config.folders.server)
41
+ }
42
+ };
43
+ }
44
+ /**
45
+ * Starts the TypeScript watcher to monitor changes in TypeScript files within the workspace.
46
+ * This method initializes a watch program using the TypeScript compiler API, which listens for changes to the tsconfig.json file and triggers recompilation when necessary.
47
+ * The watcher is set up with custom diagnostic handlers to log any errors or messages that occur during the compilation process.
48
+ * If the watcher is already running, this method will not create a new instance, ensuring that only one watcher is active at a time.
49
+ */
50
+ startTypeScriptWatcher() {
51
+ if (this.tsWatcher)
52
+ return;
53
+ const configPath = Path.join(this.config.folders.root, 'tsconfig.json');
54
+ const host = ts.createWatchCompilerHost(configPath, {
55
+ incremental: true,
56
+ tsBuildInfoFile: Path.join(this.config.folders.root, 'bin', '.tsbuildinfo')
57
+ }, ts.sys, ts.createEmitAndSemanticDiagnosticsBuilderProgram, diagnostic => logger.error('&C6' + diagnostic.messageText), diagnostic => logger.log('&C6' + diagnostic.messageText));
58
+ this.tsWatcher = ts.createWatchProgram(host);
59
+ }
60
+ /**
61
+ * Stops the TypeScript watcher if it is currently running.
62
+ * This method checks if the watcher instance exists and, if so, calls the close method to stop the watcher and then sets the instance to null.
63
+ * This ensures that the watcher is properly cleaned up and that resources are released when it is no longer needed.
64
+ */
65
+ stopTypeScriptWatcher() {
66
+ if (!this.tsWatcher)
67
+ return;
68
+ this.tsWatcher.close();
69
+ this.tsWatcher = null;
70
+ }
71
+ /**
72
+ * Sets up the workspace by creating necessary directories and files, and optionally creating a backup of the current workspace state.
73
+ * This method ensures that the workspace is properly initialized with the required structure and files, allowing for seamless operation when starting the workspace.
74
+ * The setup process includes creating directories for servers, shared files, and backups, as well as generating essential configuration files like tsconfig.json and package.json if they do not already exist.
75
+ * Additionally, it can fetch and save the latest NetScript.d.ts definitions from the BBClient to ensure that the workspace has up-to-date type definitions for development.
76
+ * @param options - An object containing options for setting up the workspace, including forceReset to clear existing directories, forceReloadDefinitions to fetch the latest type definitions, and backup to create a backup of the current workspace state before setup.
77
+ */
78
+ async setup(options = {}) {
79
+ const { forceReset = false, forceReloadDefinitions = false, backup = false } = options;
80
+ logger.log('&C6Setting up workspace');
81
+ if (forceReset) {
82
+ logger.warn('&C3Force reset enabled, clearing workspace directories...');
83
+ await File.remove(this.config.folders.root);
84
+ }
85
+ const dirs = [this.config.folders.server, this.config.folders.shared, this.config.folders.backup];
86
+ // dirs.push(
87
+ // ... await this.client.getAllServers()
88
+ // .then(servers => servers
89
+ // .filter(server => server.hasAdminRights)
90
+ // .map(server => Path.join(this.config.server, server.hostname))
91
+ // ).catch(() => [])
92
+ // );
93
+ for (const dir of dirs)
94
+ if (!await File.exists(dir)) {
95
+ await File.mkdir(dir, { recursive: true });
96
+ logger.log('&C2Created workspace directory:', dir);
97
+ }
98
+ const tsconfigPath = Path.join(this.config.folders.root, 'tsconfig.json');
99
+ const packagePath = Path.join(this.config.folders.root, 'package.json');
100
+ const gitignorePath = Path.join(this.config.folders.root, '.gitignore');
101
+ const definitionPath = Path.join(this.config.folders.root, 'bin', 'NetScript.d.ts');
102
+ if (!await File.exists(tsconfigPath)) {
103
+ const tsconfig = JSON.stringify(Defaults.TSCONFIG, null, 2);
104
+ await File.write(tsconfigPath, tsconfig, 'utf-8');
105
+ logger.log('&C2Created workspace tsconfig.json:', tsconfigPath);
106
+ }
107
+ if (!await File.exists(packagePath)) {
108
+ const pkg = JSON.stringify(Defaults.PACKAGE, null, 2);
109
+ await File.write(packagePath, pkg, 'utf-8');
110
+ logger.log('&C2Created workspace package.json:', packagePath);
111
+ }
112
+ if (!await File.exists(gitignorePath)) {
113
+ await File.copy(Path.relativeToMe(import.meta, '../../assets', '.gitignore'), gitignorePath);
114
+ logger.log('&C2Created workspace .gitignore:', gitignorePath);
115
+ }
116
+ if (!await File.exists(definitionPath) || forceReloadDefinitions) {
117
+ const definitions = await this.client.getDefinitionFile(true);
118
+ await File.write(definitionPath, definitions, 'utf-8');
119
+ logger.log('&C2Created workspace NetScript.d.ts:', definitionPath);
120
+ }
121
+ if (backup)
122
+ await this.createBackup();
123
+ logger.log('&C2Workspace setup complete');
124
+ }
125
+ /**
126
+ * Starts the workspace by setting up the necessary directories and files, binding the observers to their respective event handlers, and starting the file watching process for both the compiler and static observers.
127
+ * This method ensures that the workspace is properly initialized and ready to monitor file changes in the specified directories, allowing for seamless updates to files on the server when changes are detected in the local workspace.
128
+ */
129
+ async start(options = {}) {
130
+ await this.setup(options);
131
+ await this.sync();
132
+ if (this.config.typescript) {
133
+ if (this.config.autoWatch)
134
+ this.startTypeScriptWatcher();
135
+ Workspace.bindObserver(this.compilerObserver, this.preBind.compiler);
136
+ }
137
+ Workspace.bindObserver(this.staticObserver, this.preBind.static);
138
+ if (this.config.typescript)
139
+ await this.compilerObserver.start();
140
+ await this.staticObserver.start();
141
+ }
142
+ /**
143
+ * Stops the workspace by stopping both the compiler and static observers, and unbinding their event handlers.
144
+ * This method ensures that all file watching activities are halted and that the observers are properly cleaned up to prevent any further events from being processed.
145
+ * It is important to call this method when you want to shut down the workspace or when you need to reset the observers for any reason.
146
+ */
147
+ async stop() {
148
+ if (this.config.typescript) {
149
+ this.stopTypeScriptWatcher();
150
+ this.compilerObserver.stop();
151
+ Workspace.unbindObserver(this.compilerObserver, this.preBind.compiler);
152
+ }
153
+ this.staticObserver.stop();
154
+ Workspace.unbindObserver(this.staticObserver, this.preBind.static);
155
+ }
156
+ /**
157
+ * Synchronizes the workspace with the server by fetching the list of servers, synchronizing static files, and synchronizing shared files.
158
+ * This method ensures that the local workspace is up-to-date with the server's state, allowing for seamless development and file management.
159
+ * It retrieves the list of servers from the BBClient, then calls the syncStaticFiles and syncSharedFiles methods to synchronize the respective files between the local workspace and the server.
160
+ * Once the synchronization process is complete, it logs a message indicating that the workspace synchronization is complete.
161
+ */
162
+ async sync() {
163
+ logger.log('&C6Synchronizing workspace with server...');
164
+ const bkPath = await this.createBackup();
165
+ logger.log(`&C2Created backup of current workspace state at: &C3${bkPath}`);
166
+ const servers = await this.client.getAllServers();
167
+ await this.syncStaticFiles(...servers);
168
+ if (this.config.typescript)
169
+ await this.syncSharedFiles(...servers);
170
+ logger.log('&C2Workspace synchronization complete');
171
+ }
172
+ /**
173
+ * Synchronizes the static files between the local workspace and the server.
174
+ * This method is used to ensure that all static files are up-to-date on the server.
175
+ * @returns A promise that resolves when all static files have been synchronized.
176
+ */
177
+ async syncStaticFiles(...servers) {
178
+ const regex = Glob.globToRegex(Workspace.staticGlob(this.config.typescript));
179
+ for (const server of servers) {
180
+ if (!server.hasAdminRights)
181
+ continue;
182
+ const remoteFiles = await this.client.getFiles(server.hostname);
183
+ for (const { filename, content } of remoteFiles)
184
+ try {
185
+ const localPath = Path.join(this.config.folders.server, server.hostname, filename);
186
+ if (this.config.downloads) {
187
+ const downloadPath = Path.join(this.config.folders.download, server.hostname, filename);
188
+ await File.write(downloadPath, content, 'utf-8');
189
+ logger.log(`&C6Downloaded file from &C3${server.hostname}&C6 -> &C3${filename}`);
190
+ }
191
+ if (!regex.test(filename))
192
+ continue;
193
+ if (!await File.exists(localPath)) {
194
+ await File.write(localPath, content, 'utf-8');
195
+ logger.log(`&C6Downloaded file from &C3${server.hostname}&C6 -> &C3${filename}`);
196
+ continue;
197
+ }
198
+ const localContent = await File.read(localPath, 'utf-8');
199
+ if (localContent === content)
200
+ continue;
201
+ const stat = await this.client.getFileMetadata(server.hostname, filename);
202
+ const localStat = await File.stat(localPath);
203
+ if (stat.mtime > localStat.mtime.getTime()) {
204
+ await File.write(localPath, content, 'utf-8');
205
+ logger.log(`&C6Updated local file from &C3${server.hostname}&C6 -> &C3${filename}`);
206
+ }
207
+ else if (stat.mtime < localStat.mtime.getTime()) {
208
+ await this.client.updateFile(server.hostname, filename, localContent);
209
+ logger.log(`&C6Updated server file from &C3${server.hostname}&C6 -> &C3${filename}`);
210
+ }
211
+ else {
212
+ logger.warn(`&C3Conflict detected for file &C3${filename}&C3 on server &C3${server.hostname}&C3, but modification times are identical. No action taken.`);
213
+ }
214
+ }
215
+ catch (err) {
216
+ logger.warn(`&C3Failed to delete file on server &C3${server.hostname}&C6 -> &C3${filename}`, err);
217
+ }
218
+ }
219
+ }
220
+ /**
221
+ * Synchronizes the shared files between the local workspace and the server.
222
+ * This method is used to ensure that all shared files are up-to-date on the server.
223
+ * @returns A promise that resolves when all shared files have been synchronized.
224
+ */
225
+ async syncSharedFiles(...servers) {
226
+ for (const server of servers) {
227
+ if (!server.hasAdminRights)
228
+ continue;
229
+ const files = await this.client.getFileNames(server.hostname);
230
+ for (const file of files)
231
+ try {
232
+ const regex = Glob.globToRegex('**/*.js');
233
+ if (!regex.test(file))
234
+ continue;
235
+ await this.client.deleteFile(server.hostname, file);
236
+ logger.log(`&C6Deleted file on &C3${server.hostname}&C6 -> &C3${file}`);
237
+ }
238
+ catch (err) {
239
+ logger.warn(`&C3Failed to delete file on server &C3${server.hostname}&C6 -> &C3${file}`, err);
240
+ }
241
+ const searchShared = Path.join(this.config.folders.shared, server.hostname, '**/*.js');
242
+ const localSharedFiles = await File.glob(searchShared);
243
+ await this.loadFiles(localSharedFiles, this.config.folders.shared);
244
+ }
245
+ }
246
+ //
247
+ // ========== WORKSPACE OPERATIONS ==========
248
+ //
249
+ /**
250
+ * Loads a list of files into the workspace by reading their content from the file system and updating them on the server using the BBClient.
251
+ * The function takes an array of file paths and an optional base directory, reads the content of each file, retrieves the corresponding server and file information, and then sends an update request to the BBClient to update the file on the server.
252
+ * This method is used to synchronize local files with the server when starting the workspace or when manually triggering a synchronization.
253
+ * @param files - An array of file paths to be loaded into the workspace, which can be either absolute or relative paths.
254
+ * @param base - An optional base directory that can be used to resolve relative file paths. If provided, the file paths will be treated as relative to this base directory; if not provided, the file paths will be treated as absolute.
255
+ * @returns A promise that resolves when all files have been loaded and updated on the server.
256
+ */
257
+ async loadFiles(files, base = null) {
258
+ files = base === null ? files : files.map(file => Path.isAbsolute(file) ? Path.diff(base, file) : file);
259
+ for (const file of files)
260
+ try {
261
+ const path = base ? Path.join(base, file) : file;
262
+ const content = await File.read(path, 'utf-8');
263
+ const fileInfo = Workspace.serverFileInfo(file);
264
+ if (!fileInfo)
265
+ continue;
266
+ await this.client.updateFile(fileInfo.server, fileInfo.path, content);
267
+ logger.log(`&C6Loaded file on &C3${fileInfo.server}&C6 -> &C3${fileInfo.path}`);
268
+ }
269
+ catch (err) {
270
+ logger.warn(`&C3Failed to load file on server &C3${file}`, err);
271
+ }
272
+ }
273
+ /**
274
+ * Creates a backup of the current workspace.
275
+ * @returns A promise that resolves when the backup is complete.
276
+ */
277
+ async createBackup() {
278
+ const format = Time.format('{YYYY}-{MM}-{DD}/{HH}-{mm}-{ss}-{ms}');
279
+ const backup = await this.client.backup();
280
+ const ext = backup.binary ? 'gz' : 'json';
281
+ const encoding = backup.binary ? 'binary' : 'utf-8';
282
+ const path = Path.join(this.config.folders.backup, `${format}-${backup.identifier}.${ext}`);
283
+ await File.write(path, backup.save, encoding);
284
+ return path;
285
+ }
286
+ //
287
+ // ========== FILE EVENT HANDLERS ==========
288
+ //
289
+ /**
290
+ * Handles the update of a file in the workspace.
291
+ * This method is triggered when a file is changed or created in the observed directories.
292
+ * It validates the file path, retrieves the corresponding server and file information, reads the updated content from the file system, and then sends an update request to the BBClient to update the file on the server.
293
+ * If the file path is invalid or if there is an issue with retrieving the file information, it logs a warning message and does not proceed with the update.
294
+ * @param base - The base directory where the file is located (either the shared or server directory).
295
+ * @param path - The relative path of the file that was changed or created, which includes the server name and the file path on that server.
296
+ * @returns A promise that resolves when the file update process is complete.
297
+ */
298
+ async UpdateFile(base, path) {
299
+ if (!IS_VALID_FILENAME.test(path))
300
+ return void logger.warn('&C3Attempted to update file with invalid path:', path);
301
+ const file = Workspace.serverFileInfo(path);
302
+ if (!file)
303
+ return void logger.warn('&C3Attempted to update file with invalid path:', path);
304
+ const content = await File.read(Path.join(base, path), 'utf-8');
305
+ logger.log(`&C6Updating file on &C3${file.server}&C6 -> &C3${file.path}`);
306
+ return void await this.client.updateFile(file.server, file.path, content);
307
+ }
308
+ /**
309
+ * Handles the deletion of a file in the workspace.
310
+ * This method is triggered when a file is deleted in the observed directories.
311
+ * It validates the file path, retrieves the corresponding server and file information, and then sends a delete request to the BBClient to remove the file from the server.
312
+ * If the file path is invalid or if there is an issue with retrieving the file information, it logs a warning message and does not proceed with the deletion.
313
+ * @param base - The base directory where the file was located (either the shared or server directory).
314
+ * @param path - The relative path of the file that was deleted, which includes the server name and the file path on that server.
315
+ * @returns A promise that resolves when the file deletion process is complete.
316
+ */
317
+ async DeleteFile(base, path) {
318
+ if (!IS_VALID_FILENAME.test(path))
319
+ return void logger.warn('&C3Attempted to delete file with invalid path:', path);
320
+ const file = Workspace.serverFileInfo(path);
321
+ if (!file)
322
+ return void logger.warn('&C3Attempted to delete file with invalid path:', path);
323
+ logger.log(`&C6Deleting file on &C3${file.server}&C6 -> &C3${file.path}`);
324
+ return void await this.client.deleteFile(file.server, file.path);
325
+ }
326
+ //
327
+ // ========== HELPER METHODS ==========
328
+ //
329
+ /**
330
+ * Binds the provided observer to the specified event handlers defined in the ObserverBind object.
331
+ * This method sets up listeners for the 'change', 'create', and 'delete' events emitted by the observer, associating each event with its corresponding handler function from the ObserverBind object.
332
+ * By calling this method, you can ensure that the observer will trigger the appropriate actions when files are changed, created, or deleted within the workspace.
333
+ * @param observer - The Observer instance to bind event handlers to.
334
+ * @param bind - An object containing the event handler functions for 'change', 'create', and 'delete' events.
335
+ */
336
+ static bindObserver(observer, bind) {
337
+ observer.on('change', bind.updateFile);
338
+ observer.on('create', bind.createFile);
339
+ observer.on('delete', bind.deleteFile);
340
+ }
341
+ /**
342
+ * Unbinds the provided observer from the specified event handlers defined in the ObserverBind object.
343
+ * This method removes the listeners for the 'change', 'create', and 'delete' events emitted by the observer, disassociating each event from its corresponding handler function from the ObserverBind object.
344
+ * By calling this method, you can ensure that the observer will no longer trigger the associated actions when files are changed, created, or deleted within the workspace.
345
+ * @param observer - The Observer instance to unbind event handlers from.
346
+ * @param bind - An object containing the event handler functions for 'change', 'create', and 'delete' events that were previously bound to the observer.
347
+ */
348
+ static unbindObserver(observer, bind) {
349
+ observer.off('change', bind.updateFile);
350
+ observer.off('create', bind.createFile);
351
+ observer.off('delete', bind.deleteFile);
352
+ }
353
+ /**
354
+ * Parses a relative file path to extract the server name and the file path on that server.
355
+ * The function takes a relative path string as input, splits it into parts, and identifies the first part as the server name and the remaining parts as the file path.
356
+ * If the input path is valid and contains both a server name and a file path, it returns an object containing the server name and the file path.
357
+ * If the input path is invalid (e.g., missing server name or file path), it returns null.
358
+ * @param relative - A relative file path string that includes the server name and the file path, separated by slashes (e.g., "server1/path/to/file.txt").
359
+ * @returns An object containing the server name and the file path if the input is valid, or null if the input is invalid.
360
+ */
361
+ static serverFileInfo(relative) {
362
+ const parts = relative.split(/[\\/]/).filter(Boolean);
363
+ const [server, ...rest] = parts;
364
+ if (!server)
365
+ return null;
366
+ if (rest.length === 0)
367
+ return null;
368
+ return { server, path: rest.join('/') };
369
+ }
370
+ /**
371
+ * Normalizes the provided workspace configuration by applying default values for any missing properties and resolving the root path to an absolute path. The function takes a partial workspace configuration object as input and returns a complete workspace configuration object with all properties defined, ensuring that the workspace is set up with consistent and valid paths for its various directories.
372
+ * @param config - A partial workspace configuration object that may contain some or all of the properties needed to define the workspace configuration.
373
+ * @returns A complete workspace configuration object with all properties defined, including default values for any missing properties and an absolute path for the root directory.
374
+ */
375
+ static normalizeConfig(config) {
376
+ const { typescript = Workspace.DEFAULT_TYPESCRIPT, downloads = truncate, autoWatch = true, folders = {} } = config;
377
+ const { root = Workspace.DEFAULT_ROOT, server = Workspace.DEFAULT_SERVER, shared = Workspace.DEFAULT_SHARED, backup = Workspace.DEFAULT_BACKUP, download = Workspace.DEFAULT_DOWNLOAD } = folders;
378
+ const realRoot = Path.isAbsolute(root) ? root : Path.root(root);
379
+ return {
380
+ downloads,
381
+ typescript,
382
+ autoWatch,
383
+ folders: {
384
+ root: realRoot,
385
+ server: Path.isAbsolute(server) ? server : Path.join(realRoot, server),
386
+ shared: Path.isAbsolute(shared) ? shared : Path.join(realRoot, shared),
387
+ backup: Path.isAbsolute(backup) ? backup : Path.join(realRoot, backup),
388
+ download: Path.isAbsolute(download) ? download : Path.join(realRoot, download)
389
+ }
390
+ };
391
+ }
392
+ static staticGlob(typescript) {
393
+ return typescript
394
+ ? '**/*.{script,ns,txt,css,json}'
395
+ : '**/*.{script,ns,txt,css,json,js}';
396
+ }
397
+ }
398
+ export default Workspace;
399
+ //# sourceMappingURL=Workspace.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Workspace.js","sourceRoot":"","sources":["../../src/Workspace/Workspace.ts"],"names":[],"mappings":"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"}