@git.zone/tstest 3.1.8 → 3.2.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.
Files changed (32) hide show
  1. package/dist_ts/00_commitinfo_data.js +1 -1
  2. package/dist_ts/tstest.classes.migration.js +4 -4
  3. package/dist_ts/tstest.classes.runtime.bun.js +5 -5
  4. package/dist_ts/tstest.classes.runtime.chromium.js +12 -10
  5. package/dist_ts/tstest.classes.runtime.deno.js +7 -7
  6. package/dist_ts/tstest.classes.runtime.docker.js +2 -2
  7. package/dist_ts/tstest.classes.runtime.node.js +5 -5
  8. package/dist_ts/tstest.classes.tap.parser.js +6 -7
  9. package/dist_ts/tstest.classes.testdirectory.d.ts +1 -1
  10. package/dist_ts/tstest.classes.testdirectory.js +11 -12
  11. package/dist_ts/tstest.classes.tstest.js +32 -31
  12. package/dist_ts/tstest.plugins.d.ts +6 -3
  13. package/dist_ts/tstest.plugins.js +7 -4
  14. package/dist_ts_tapbundle_serverside/classes.tapnodetools.d.ts +30 -0
  15. package/dist_ts_tapbundle_serverside/classes.tapnodetools.js +100 -3
  16. package/dist_ts_tapbundle_serverside/classes.testfileprovider.js +3 -3
  17. package/dist_ts_tapbundle_serverside/plugins.d.ts +4 -1
  18. package/dist_ts_tapbundle_serverside/plugins.js +5 -2
  19. package/package.json +14 -13
  20. package/readme.hints.md +1 -1
  21. package/readme.md +273 -868
  22. package/ts/00_commitinfo_data.ts +1 -1
  23. package/ts/tstest.classes.migration.ts +3 -6
  24. package/ts/tstest.classes.runtime.bun.ts +4 -4
  25. package/ts/tstest.classes.runtime.chromium.ts +8 -12
  26. package/ts/tstest.classes.runtime.deno.ts +6 -6
  27. package/ts/tstest.classes.runtime.docker.ts +1 -1
  28. package/ts/tstest.classes.runtime.node.ts +4 -4
  29. package/ts/tstest.classes.tap.parser.ts +5 -7
  30. package/ts/tstest.classes.testdirectory.ts +19 -20
  31. package/ts/tstest.classes.tstest.ts +36 -41
  32. package/ts/tstest.plugins.ts +8 -3
@@ -3,6 +3,6 @@
3
3
  */
4
4
  export const commitinfo = {
5
5
  name: '@git.zone/tstest',
6
- version: '3.1.8',
6
+ version: '3.2.0',
7
7
  description: 'a test utility to run tests that match test/**/*.ts'
8
8
  }
@@ -111,10 +111,7 @@ export class Migration {
111
111
  * Find all legacy test files in the base directory
112
112
  */
113
113
  async findLegacyFiles(): Promise<string[]> {
114
- const files = await plugins.smartfile.fs.listFileTree(
115
- this.options.baseDir,
116
- this.options.pattern
117
- );
114
+ const files = plugins.fs.globSync(this.options.pattern, { cwd: this.options.baseDir }) as string[];
118
115
 
119
116
  const legacyFiles: string[] = [];
120
117
 
@@ -154,7 +151,7 @@ export class Migration {
154
151
  const newPath = plugins.path.join(dirName, newFileName);
155
152
 
156
153
  // Check if target file already exists
157
- if (await plugins.smartfile.fs.fileExists(newPath)) {
154
+ if (await plugins.smartfsInstance.file(newPath).exists()) {
158
155
  return {
159
156
  oldPath: filePath,
160
157
  newPath,
@@ -206,7 +203,7 @@ export class Migration {
206
203
  private async isGitRepository(dir: string): Promise<boolean> {
207
204
  try {
208
205
  const gitDir = plugins.path.join(dir, '.git');
209
- return await plugins.smartfile.fs.isDirectory(gitDir);
206
+ return await plugins.smartfsInstance.directory(gitDir).exists();
210
207
  } catch {
211
208
  return false;
212
209
  }
@@ -121,7 +121,7 @@ export class BunRuntimeAdapter extends RuntimeAdapter {
121
121
  // Check for 00init.ts file in test directory
122
122
  const testDir = plugins.path.dirname(testFile);
123
123
  const initFile = plugins.path.join(testDir, '00init.ts');
124
- const initFileExists = await plugins.smartfile.fs.fileExists(initFile);
124
+ const initFileExists = await plugins.smartfsInstance.file(initFile).exists();
125
125
 
126
126
  let runCommand = fullCommand;
127
127
  let loaderPath: string | null = null;
@@ -135,7 +135,7 @@ import '${absoluteInitFile.replace(/\\/g, '/')}';
135
135
  import '${absoluteTestFile.replace(/\\/g, '/')}';
136
136
  `;
137
137
  loaderPath = plugins.path.join(testDir, `.loader_${plugins.path.basename(testFile)}`);
138
- await plugins.smartfile.memory.toFs(loaderContent, loaderPath);
138
+ await plugins.smartfsInstance.file(loaderPath).write(loaderContent);
139
139
 
140
140
  // Rebuild command with loader file
141
141
  const loaderCommand = this.createCommand(loaderPath, mergedOptions);
@@ -148,8 +148,8 @@ import '${absoluteTestFile.replace(/\\/g, '/')}';
148
148
  if (loaderPath) {
149
149
  const cleanup = () => {
150
150
  try {
151
- if (plugins.smartfile.fs.fileExistsSync(loaderPath)) {
152
- plugins.smartfile.fs.removeSync(loaderPath);
151
+ if (plugins.fs.existsSync(loaderPath)) {
152
+ plugins.fs.rmSync(loaderPath, { force: true });
153
153
  }
154
154
  } catch (e) {
155
155
  // Ignore cleanup errors
@@ -107,7 +107,8 @@ export class ChromiumRuntimeAdapter extends RuntimeAdapter {
107
107
  const bundleFilePath = plugins.path.join(tsbundleCacheDirPath, bundleFileName);
108
108
 
109
109
  // lets bundle the test
110
- await plugins.smartfile.fs.ensureEmptyDir(tsbundleCacheDirPath);
110
+ try { await plugins.smartfsInstance.directory(tsbundleCacheDirPath).recursive().delete(); } catch (e) { /* may not exist */ }
111
+ await plugins.smartfsInstance.directory(tsbundleCacheDirPath).recursive().create();
111
112
  await this.tsbundleInstance.build(process.cwd(), testFile, bundleFilePath, {
112
113
  bundler: 'esbuild',
113
114
  });
@@ -116,15 +117,13 @@ export class ChromiumRuntimeAdapter extends RuntimeAdapter {
116
117
  const { httpPort, wsPort } = await this.findFreePorts();
117
118
 
118
119
  // lets create a server
119
- const server = new plugins.typedserver.servertools.Server({
120
+ const server = new plugins.typedserver.TypedServer({
120
121
  cors: true,
121
122
  port: httpPort,
123
+ serveDir: tsbundleCacheDirPath,
122
124
  });
123
- server.addRoute(
124
- '/test',
125
- new plugins.typedserver.servertools.Handler('GET', async (_req, res) => {
126
- res.type('.html');
127
- res.write(`
125
+ server.addRoute('/test', 'GET', async () => {
126
+ return new Response(`
128
127
  <html>
129
128
  <head>
130
129
  <script>
@@ -134,11 +133,8 @@ export class ChromiumRuntimeAdapter extends RuntimeAdapter {
134
133
  </head>
135
134
  <body></body>
136
135
  </html>
137
- `);
138
- res.end();
139
- })
140
- );
141
- server.addRoute('/*splat', new plugins.typedserver.servertools.HandlerStatic(tsbundleCacheDirPath));
136
+ `, { headers: { 'Content-Type': 'text/html' } });
137
+ });
142
138
  await server.start();
143
139
 
144
140
  // lets handle realtime comms
@@ -36,9 +36,9 @@ export class DenoRuntimeAdapter extends RuntimeAdapter {
36
36
  const denoJsonPath = plugins.path.join(process.cwd(), 'deno.json');
37
37
  const denoJsoncPath = plugins.path.join(process.cwd(), 'deno.jsonc');
38
38
 
39
- if (plugins.smartfile.fs.fileExistsSync(denoJsonPath)) {
39
+ if (plugins.fs.existsSync(denoJsonPath)) {
40
40
  configPath = denoJsonPath;
41
- } else if (plugins.smartfile.fs.fileExistsSync(denoJsoncPath)) {
41
+ } else if (plugins.fs.existsSync(denoJsoncPath)) {
42
42
  configPath = denoJsoncPath;
43
43
  }
44
44
 
@@ -173,7 +173,7 @@ export class DenoRuntimeAdapter extends RuntimeAdapter {
173
173
  // Check for 00init.ts file in test directory
174
174
  const testDir = plugins.path.dirname(testFile);
175
175
  const initFile = plugins.path.join(testDir, '00init.ts');
176
- const initFileExists = await plugins.smartfile.fs.fileExists(initFile);
176
+ const initFileExists = await plugins.smartfsInstance.file(initFile).exists();
177
177
 
178
178
  let runCommand = fullCommand;
179
179
  let loaderPath: string | null = null;
@@ -187,7 +187,7 @@ import '${absoluteInitFile.replace(/\\/g, '/')}';
187
187
  import '${absoluteTestFile.replace(/\\/g, '/')}';
188
188
  `;
189
189
  loaderPath = plugins.path.join(testDir, `.loader_${plugins.path.basename(testFile)}`);
190
- await plugins.smartfile.memory.toFs(loaderContent, loaderPath);
190
+ await plugins.smartfsInstance.file(loaderPath).write(loaderContent);
191
191
 
192
192
  // Rebuild command with loader file
193
193
  const loaderCommand = this.createCommand(loaderPath, mergedOptions);
@@ -200,8 +200,8 @@ import '${absoluteTestFile.replace(/\\/g, '/')}';
200
200
  if (loaderPath) {
201
201
  const cleanup = () => {
202
202
  try {
203
- if (plugins.smartfile.fs.fileExistsSync(loaderPath)) {
204
- plugins.smartfile.fs.removeSync(loaderPath);
203
+ if (plugins.fs.existsSync(loaderPath)) {
204
+ plugins.fs.rmSync(loaderPath, { force: true });
205
205
  }
206
206
  } catch (e) {
207
207
  // Ignore cleanup errors
@@ -102,7 +102,7 @@ export class DockerRuntimeAdapter extends RuntimeAdapter {
102
102
  }
103
103
 
104
104
  // Check if Dockerfile exists
105
- if (!await plugins.smartfile.fs.fileExists(dockerfilePath)) {
105
+ if (!await plugins.smartfsInstance.file(dockerfilePath).exists()) {
106
106
  throw new Error(
107
107
  `Dockerfile not found: ${dockerfilePath}\n` +
108
108
  `Expected Dockerfile for Docker test variant.`
@@ -123,7 +123,7 @@ export class NodeRuntimeAdapter extends RuntimeAdapter {
123
123
  // Check for 00init.ts file in test directory
124
124
  const testDir = plugins.path.dirname(testFile);
125
125
  const initFile = plugins.path.join(testDir, '00init.ts');
126
- const initFileExists = await plugins.smartfile.fs.fileExists(initFile);
126
+ const initFileExists = await plugins.smartfsInstance.file(initFile).exists();
127
127
 
128
128
  // Determine which file to run
129
129
  let fileToRun = testFile;
@@ -138,7 +138,7 @@ import '${absoluteInitFile.replace(/\\/g, '/')}';
138
138
  import '${absoluteTestFile.replace(/\\/g, '/')}';
139
139
  `;
140
140
  loaderPath = plugins.path.join(testDir, `.loader_${plugins.path.basename(testFile)}`);
141
- await plugins.smartfile.memory.toFs(loaderContent, loaderPath);
141
+ await plugins.smartfsInstance.file(loaderPath).write(loaderContent);
142
142
  fileToRun = loaderPath;
143
143
  }
144
144
 
@@ -150,8 +150,8 @@ import '${absoluteTestFile.replace(/\\/g, '/')}';
150
150
  if (loaderPath) {
151
151
  const cleanup = () => {
152
152
  try {
153
- if (plugins.smartfile.fs.fileExistsSync(loaderPath)) {
154
- plugins.smartfile.fs.removeSync(loaderPath);
153
+ if (plugins.fs.existsSync(loaderPath)) {
154
+ plugins.fs.rmSync(loaderPath, { force: true });
155
155
  }
156
156
  } catch (e) {
157
157
  // Ignore cleanup errors
@@ -497,12 +497,10 @@ export class TapParser {
497
497
  */
498
498
  private async handleSnapshot(snapshotData: { path: string; content: string; action: string }) {
499
499
  try {
500
- const smartfile = await import('@push.rocks/smartfile');
501
-
502
500
  if (snapshotData.action === 'compare') {
503
501
  // Try to read existing snapshot
504
502
  try {
505
- const existingSnapshot = await smartfile.fs.toStringSync(snapshotData.path);
503
+ const existingSnapshot = await plugins.smartfsInstance.file(snapshotData.path).encoding('utf8').read() as string;
506
504
  if (existingSnapshot !== snapshotData.content) {
507
505
  // Snapshot mismatch
508
506
  if (this.logger) {
@@ -520,8 +518,8 @@ export class TapParser {
520
518
  if (error.code === 'ENOENT') {
521
519
  // Snapshot doesn't exist, create it
522
520
  const dirPath = snapshotData.path.substring(0, snapshotData.path.lastIndexOf('/'));
523
- await smartfile.fs.ensureDir(dirPath);
524
- await smartfile.memory.toFs(snapshotData.content, snapshotData.path);
521
+ await plugins.smartfsInstance.directory(dirPath).recursive().create();
522
+ await plugins.smartfsInstance.file(snapshotData.path).write(snapshotData.content);
525
523
  if (this.logger) {
526
524
  this.logger.testConsoleOutput(`Snapshot created: ${snapshotData.path}`);
527
525
  }
@@ -532,8 +530,8 @@ export class TapParser {
532
530
  } else if (snapshotData.action === 'update') {
533
531
  // Update snapshot
534
532
  const dirPath = snapshotData.path.substring(0, snapshotData.path.lastIndexOf('/'));
535
- await smartfile.fs.ensureDir(dirPath);
536
- await smartfile.memory.toFs(snapshotData.content, snapshotData.path);
533
+ await plugins.smartfsInstance.directory(dirPath).recursive().create();
534
+ await plugins.smartfsInstance.file(snapshotData.path).write(snapshotData.content);
537
535
  if (this.logger) {
538
536
  this.logger.testConsoleOutput(`Snapshot updated: ${snapshotData.path}`);
539
537
  }
@@ -1,8 +1,10 @@
1
1
  import * as plugins from './tstest.plugins.js';
2
2
  import * as paths from './tstest.paths.js';
3
- import { SmartFile } from '@push.rocks/smartfile';
3
+ import { type SmartFile, SmartFileFactory } from '@push.rocks/smartfile';
4
4
  import { TestExecutionMode } from './index.js';
5
5
 
6
+ const smartFileFactory = SmartFileFactory.nodeFs();
7
+
6
8
  // tap related stuff
7
9
  import { TapCombinator } from './tstest.classes.tap.combinator.js';
8
10
  import { TapParser } from './tstest.classes.tap.parser.js';
@@ -45,28 +47,28 @@ export class TestDirectory {
45
47
  switch (this.executionMode) {
46
48
  case TestExecutionMode.FILE:
47
49
  // Single file mode
48
- const filePath = plugins.path.isAbsolute(this.testPath)
49
- ? this.testPath
50
+ const filePath = plugins.path.isAbsolute(this.testPath)
51
+ ? this.testPath
50
52
  : plugins.path.join(this.cwd, this.testPath);
51
-
52
- if (await plugins.smartfile.fs.fileExists(filePath)) {
53
- this.testfileArray = [await plugins.smartfile.SmartFile.fromFilePath(filePath)];
53
+
54
+ if (await plugins.smartfsInstance.file(filePath).exists()) {
55
+ this.testfileArray = [await smartFileFactory.fromFilePath(filePath)];
54
56
  } else {
55
57
  throw new Error(`Test file not found: ${filePath}`);
56
58
  }
57
59
  break;
58
60
 
59
61
  case TestExecutionMode.GLOB:
60
- // Glob pattern mode - use listFileTree which supports glob patterns
62
+ // Glob pattern mode - use Node.js fs.globSync for full glob support
61
63
  const globPattern = this.testPath;
62
- const matchedFiles = await plugins.smartfile.fs.listFileTree(this.cwd, globPattern);
63
-
64
+ const matchedFiles = plugins.fs.globSync(globPattern, { cwd: this.cwd });
65
+
64
66
  this.testfileArray = await Promise.all(
65
- matchedFiles.map(async (filePath) => {
66
- const absolutePath = plugins.path.isAbsolute(filePath)
67
- ? filePath
67
+ matchedFiles.map(async (filePath: string) => {
68
+ const absolutePath = plugins.path.isAbsolute(filePath)
69
+ ? filePath
68
70
  : plugins.path.join(this.cwd, filePath);
69
- return await plugins.smartfile.SmartFile.fromFilePath(absolutePath);
71
+ return await smartFileFactory.fromFilePath(absolutePath);
70
72
  })
71
73
  );
72
74
  break;
@@ -79,19 +81,16 @@ export class TestDirectory {
79
81
  const tsPattern = '**/test*.ts';
80
82
  const dockerPattern = '**/*.docker.sh';
81
83
 
82
- const [tsFiles, dockerFiles] = await Promise.all([
83
- plugins.smartfile.fs.listFileTree(dirPath, tsPattern),
84
- plugins.smartfile.fs.listFileTree(dirPath, dockerPattern),
85
- ]);
86
-
87
- const allTestFiles = [...tsFiles, ...dockerFiles];
84
+ const tsFiles = plugins.fs.globSync(tsPattern, { cwd: dirPath });
85
+ const dockerFiles = plugins.fs.globSync(dockerPattern, { cwd: dirPath });
86
+ const allTestFiles = [...tsFiles, ...dockerFiles] as string[];
88
87
 
89
88
  this.testfileArray = await Promise.all(
90
89
  allTestFiles.map(async (filePath) => {
91
90
  const absolutePath = plugins.path.isAbsolute(filePath)
92
91
  ? filePath
93
92
  : plugins.path.join(dirPath, filePath);
94
- return await plugins.smartfile.SmartFile.fromFilePath(absolutePath);
93
+ return await smartFileFactory.fromFilePath(absolutePath);
95
94
  })
96
95
  );
97
96
  break;
@@ -132,7 +132,7 @@ export class TsTest {
132
132
  }
133
133
 
134
134
  public async runWatch(ignorePatterns: string[] = []) {
135
- const smartchokInstance = new plugins.smartchok.Smartchok([this.testDir.cwd]);
135
+ const smartwatchInstance = new plugins.smartwatch.Smartwatch([this.testDir.cwd]);
136
136
 
137
137
  console.clear();
138
138
  this.logger.watchModeStart();
@@ -155,12 +155,12 @@ export class TsTest {
155
155
  };
156
156
 
157
157
  // Start watching before subscribing to events
158
- await smartchokInstance.start();
159
-
158
+ await smartwatchInstance.start();
159
+
160
160
  // Subscribe to file change events
161
- const changeObservable = await smartchokInstance.getObservableFor('change');
162
- const addObservable = await smartchokInstance.getObservableFor('add');
163
- const unlinkObservable = await smartchokInstance.getObservableFor('unlink');
161
+ const changeObservable = await smartwatchInstance.getObservableFor('change');
162
+ const addObservable = await smartwatchInstance.getObservableFor('add');
163
+ const unlinkObservable = await smartwatchInstance.getObservableFor('unlink');
164
164
 
165
165
  const handleFileChange = (changedPath: string) => {
166
166
  // Skip if path matches ignore patterns
@@ -194,7 +194,7 @@ export class TsTest {
194
194
  // Handle Ctrl+C to exit gracefully
195
195
  process.on('SIGINT', async () => {
196
196
  this.logger.watchModeStop();
197
- await smartchokInstance.stop();
197
+ await smartwatchInstance.stop();
198
198
  process.exit(0);
199
199
  });
200
200
 
@@ -316,8 +316,8 @@ export class TsTest {
316
316
  const initFile = plugins.path.join(testDir, '00init.ts');
317
317
  let runCommand = `tsrun ${fileNameArg}${tsrunOptions}`;
318
318
 
319
- const initFileExists = await plugins.smartfile.fs.fileExists(initFile);
320
-
319
+ const initFileExists = await plugins.smartfsInstance.file(initFile).exists();
320
+
321
321
  // If 00init.ts exists, run it first
322
322
  if (initFileExists) {
323
323
  // Create a temporary loader file that imports both 00init.ts and the test file
@@ -328,7 +328,7 @@ import '${absoluteInitFile.replace(/\\/g, '/')}';
328
328
  import '${absoluteTestFile.replace(/\\/g, '/')}';
329
329
  `;
330
330
  const loaderPath = plugins.path.join(testDir, `.loader_${plugins.path.basename(fileNameArg)}`);
331
- await plugins.smartfile.memory.toFs(loaderContent, loaderPath);
331
+ await plugins.smartfsInstance.file(loaderPath).write(loaderContent);
332
332
  runCommand = `tsrun ${loaderPath}${tsrunOptions}`;
333
333
  }
334
334
 
@@ -339,14 +339,14 @@ import '${absoluteTestFile.replace(/\\/g, '/')}';
339
339
  const loaderPath = plugins.path.join(testDir, `.loader_${plugins.path.basename(fileNameArg)}`);
340
340
  const cleanup = () => {
341
341
  try {
342
- if (plugins.smartfile.fs.fileExistsSync(loaderPath)) {
343
- plugins.smartfile.fs.removeSync(loaderPath);
342
+ if (plugins.fs.existsSync(loaderPath)) {
343
+ plugins.fs.rmSync(loaderPath, { force: true });
344
344
  }
345
345
  } catch (e) {
346
346
  // Ignore cleanup errors
347
347
  }
348
348
  };
349
-
349
+
350
350
  execResultStreaming.childProcess.on('exit', cleanup);
351
351
  execResultStreaming.childProcess.on('error', cleanup);
352
352
  }
@@ -445,7 +445,8 @@ import '${absoluteTestFile.replace(/\\/g, '/')}';
445
445
  const bundleFilePath = plugins.path.join(tsbundleCacheDirPath, bundleFileName);
446
446
 
447
447
  // lets bundle the test
448
- await plugins.smartfile.fs.ensureEmptyDir(tsbundleCacheDirPath);
448
+ try { await plugins.smartfsInstance.directory(tsbundleCacheDirPath).recursive().delete(); } catch (e) { /* may not exist */ }
449
+ await plugins.smartfsInstance.directory(tsbundleCacheDirPath).recursive().create();
449
450
  await this.tsbundleInstance.build(process.cwd(), fileNameArg, bundleFilePath, {
450
451
  bundler: 'esbuild',
451
452
  });
@@ -454,15 +455,13 @@ import '${absoluteTestFile.replace(/\\/g, '/')}';
454
455
  const { httpPort, wsPort } = await this.findFreePorts();
455
456
 
456
457
  // lets create a server
457
- const server = new plugins.typedserver.servertools.Server({
458
+ const server = new plugins.typedserver.TypedServer({
458
459
  cors: true,
459
460
  port: httpPort,
461
+ serveDir: tsbundleCacheDirPath,
460
462
  });
461
- server.addRoute(
462
- '/test',
463
- new plugins.typedserver.servertools.Handler('GET', async (_req, res) => {
464
- res.type('.html');
465
- res.write(`
463
+ server.addRoute('/test', 'GET', async () => {
464
+ return new Response(`
466
465
  <html>
467
466
  <head>
468
467
  <script>
@@ -472,11 +471,8 @@ import '${absoluteTestFile.replace(/\\/g, '/')}';
472
471
  </head>
473
472
  <body></body>
474
473
  </html>
475
- `);
476
- res.end();
477
- })
478
- );
479
- server.addRoute('/*splat', new plugins.typedserver.servertools.HandlerStatic(tsbundleCacheDirPath));
474
+ `, { headers: { 'Content-Type': 'text/html' } });
475
+ });
480
476
  await server.start();
481
477
 
482
478
  // lets handle realtime comms
@@ -640,34 +636,33 @@ import '${absoluteTestFile.replace(/\\/g, '/')}';
640
636
 
641
637
  try {
642
638
  // Delete 00err and 00diff directories if they exist
643
- if (plugins.smartfile.fs.isDirectorySync(errDir)) {
644
- plugins.smartfile.fs.removeSync(errDir);
639
+ if (plugins.fs.existsSync(errDir) && plugins.fs.statSync(errDir).isDirectory()) {
640
+ plugins.fs.rmSync(errDir, { recursive: true, force: true });
645
641
  }
646
- if (plugins.smartfile.fs.isDirectorySync(diffDir)) {
647
- plugins.smartfile.fs.removeSync(diffDir);
642
+ if (plugins.fs.existsSync(diffDir) && plugins.fs.statSync(diffDir).isDirectory()) {
643
+ plugins.fs.rmSync(diffDir, { recursive: true, force: true });
648
644
  }
649
-
645
+
650
646
  // Get all .log files in log directory (not in subdirectories)
651
- const files = await plugins.smartfile.fs.listFileTree(logDir, '*.log');
652
- const logFiles = files.filter((file: string) => !file.includes('/'));
653
-
647
+ const entries = await plugins.smartfsInstance.directory(logDir).filter('*.log').list();
648
+ const logFiles = entries.filter((entry) => entry.isFile).map((entry) => entry.name);
649
+
654
650
  if (logFiles.length === 0) {
655
651
  return;
656
652
  }
657
-
653
+
658
654
  // Ensure previous directory exists
659
- await plugins.smartfile.fs.ensureDir(previousDir);
660
-
655
+ await plugins.smartfsInstance.directory(previousDir).recursive().create();
656
+
661
657
  // Move each log file to previous directory
662
- for (const file of logFiles) {
663
- const filename = plugins.path.basename(file);
658
+ for (const filename of logFiles) {
664
659
  const sourcePath = plugins.path.join(logDir, filename);
665
660
  const destPath = plugins.path.join(previousDir, filename);
666
-
661
+
667
662
  try {
668
663
  // Copy file to new location and remove original
669
- await plugins.smartfile.fs.copy(sourcePath, destPath);
670
- await plugins.smartfile.fs.remove(sourcePath);
664
+ await plugins.smartfsInstance.file(sourcePath).copy(destPath);
665
+ await plugins.smartfsInstance.file(sourcePath).delete();
671
666
  } catch (error) {
672
667
  // Silently continue if a file can't be moved
673
668
  }
@@ -1,7 +1,8 @@
1
1
  // node native
2
+ import * as fs from 'fs';
2
3
  import * as path from 'path';
3
4
 
4
- export { path };
5
+ export { fs, path };
5
6
 
6
7
  // @apiglobal scope
7
8
  import * as typedserver from '@api.global/typedserver';
@@ -13,25 +14,29 @@ export {
13
14
  // @push.rocks scope
14
15
  import * as consolecolor from '@push.rocks/consolecolor';
15
16
  import * as smartbrowser from '@push.rocks/smartbrowser';
16
- import * as smartchok from '@push.rocks/smartchok';
17
17
  import * as smartdelay from '@push.rocks/smartdelay';
18
18
  import * as smartfile from '@push.rocks/smartfile';
19
+ import * as smartfs from '@push.rocks/smartfs';
20
+ const smartfsInstance = new smartfs.SmartFs(new smartfs.SmartFsProviderNode());
19
21
  import * as smartlog from '@push.rocks/smartlog';
20
22
  import * as smartnetwork from '@push.rocks/smartnetwork';
21
23
  import * as smartpromise from '@push.rocks/smartpromise';
22
24
  import * as smartshell from '@push.rocks/smartshell';
25
+ import * as smartwatch from '@push.rocks/smartwatch';
23
26
  import * as tapbundle from '../dist_ts_tapbundle/index.js';
24
27
 
25
28
  export {
26
29
  consolecolor,
27
30
  smartbrowser,
28
- smartchok,
29
31
  smartdelay,
30
32
  smartfile,
33
+ smartfs,
34
+ smartfsInstance,
31
35
  smartlog,
32
36
  smartnetwork,
33
37
  smartpromise,
34
38
  smartshell,
39
+ smartwatch,
35
40
  tapbundle,
36
41
  };
37
42