command-stream 0.7.1 → 0.8.2

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/src/$.utils.mjs CHANGED
@@ -3,8 +3,11 @@ import path from 'path';
3
3
  const VERBOSE = process.env.COMMAND_STREAM_VERBOSE === 'true';
4
4
 
5
5
  export function trace(category, messageOrFunc) {
6
- if (!VERBOSE) return;
7
- const message = typeof messageOrFunc === 'function' ? messageOrFunc() : messageOrFunc;
6
+ if (!VERBOSE) {
7
+ return;
8
+ }
9
+ const message =
10
+ typeof messageOrFunc === 'function' ? messageOrFunc() : messageOrFunc;
8
11
  const timestamp = new Date().toISOString();
9
12
  console.error(`[TRACE ${timestamp}] [${category}] ${message}`);
10
13
  }
@@ -47,7 +50,10 @@ export const VirtualUtils = {
47
50
  if (minCount === 1) {
48
51
  return this.missingOperandError(commandName);
49
52
  } else {
50
- return this.invalidArgumentError(commandName, `requires at least ${minCount} arguments`);
53
+ return this.invalidArgumentError(
54
+ commandName,
55
+ `requires at least ${minCount} arguments`
56
+ );
51
57
  }
52
58
  }
53
59
  return null; // No error
@@ -58,7 +64,9 @@ export const VirtualUtils = {
58
64
  */
59
65
  resolvePath(filePath, cwd = null) {
60
66
  const basePath = cwd || process.cwd();
61
- return path.isAbsolute(filePath) ? filePath : path.resolve(basePath, filePath);
67
+ return path.isAbsolute(filePath)
68
+ ? filePath
69
+ : path.resolve(basePath, filePath);
62
70
  },
63
71
 
64
72
  /**
@@ -77,5 +85,5 @@ export const VirtualUtils = {
77
85
  */
78
86
  createAsyncWrapper(promiseFactory) {
79
87
  return new Promise(promiseFactory);
80
- }
81
- };
88
+ },
89
+ };
@@ -3,17 +3,19 @@ import { VirtualUtils } from '../$.utils.mjs';
3
3
 
4
4
  export default async function basename({ args }) {
5
5
  const argError = VirtualUtils.validateArgs(args, 1, 'basename');
6
- if (argError) return argError;
6
+ if (argError) {
7
+ return argError;
8
+ }
7
9
 
8
10
  const filePath = args[0];
9
11
  const suffix = args[1];
10
-
12
+
11
13
  let result = path.basename(filePath);
12
-
14
+
13
15
  // Remove suffix if provided and it matches
14
16
  if (suffix && result.endsWith(suffix)) {
15
17
  result = result.slice(0, -suffix.length);
16
18
  }
17
-
18
- return VirtualUtils.success(result + '\n');
19
- }
19
+
20
+ return VirtualUtils.success(`${result}\n`);
21
+ }
@@ -1,7 +1,13 @@
1
1
  import fs from 'fs';
2
2
  import { trace, VirtualUtils } from '../$.utils.mjs';
3
3
 
4
- export default async function cat({ args, stdin, cwd, isCancelled, abortSignal }) {
4
+ export default async function cat({
5
+ args,
6
+ stdin,
7
+ cwd,
8
+ isCancelled,
9
+ abortSignal,
10
+ }) {
5
11
  if (args.length === 0) {
6
12
  // Read from stdin if no files specified
7
13
  if (stdin !== undefined && stdin !== '') {
@@ -18,8 +24,11 @@ export default async function cat({ args, stdin, cwd, isCancelled, abortSignal }
18
24
  trace('VirtualCommand', () => `cat: cancelled while processing files`);
19
25
  return { code: 130, stdout: '', stderr: '' }; // SIGINT exit code
20
26
  }
21
-
22
- trace('VirtualCommand', () => `cat: reading file | ${JSON.stringify({ file }, null, 2)}`);
27
+
28
+ trace(
29
+ 'VirtualCommand',
30
+ () => `cat: reading file | ${JSON.stringify({ file }, null, 2)}`
31
+ );
23
32
  const resolvedPath = VirtualUtils.resolvePath(file, cwd);
24
33
  try {
25
34
  const content = fs.readFileSync(resolvedPath, 'utf8');
@@ -35,10 +44,18 @@ export default async function cat({ args, stdin, cwd, isCancelled, abortSignal }
35
44
  }
36
45
  }
37
46
  const output = outputs.join('');
38
- trace('VirtualCommand', () => `cat: success | ${JSON.stringify({ bytesRead: output.length }, null, 2)}`);
47
+ trace(
48
+ 'VirtualCommand',
49
+ () =>
50
+ `cat: success | ${JSON.stringify({ bytesRead: output.length }, null, 2)}`
51
+ );
39
52
  return VirtualUtils.success(output);
40
53
  } catch (error) {
41
- trace('VirtualCommand', () => `cat: unexpected error | ${JSON.stringify({ error: error.message }, null, 2)}`);
54
+ trace(
55
+ 'VirtualCommand',
56
+ () =>
57
+ `cat: unexpected error | ${JSON.stringify({ error: error.message }, null, 2)}`
58
+ );
42
59
  return VirtualUtils.error(`cat: ${error.message}`);
43
60
  }
44
- }
61
+ }
@@ -2,16 +2,25 @@ import { trace, VirtualUtils } from '../$.utils.mjs';
2
2
 
3
3
  export default async function cd({ args }) {
4
4
  const target = args[0] || process.env.HOME || process.env.USERPROFILE || '/';
5
- trace('VirtualCommand', () => `cd: changing directory | ${JSON.stringify({ target }, null, 2)}`);
5
+ trace(
6
+ 'VirtualCommand',
7
+ () => `cd: changing directory | ${JSON.stringify({ target }, null, 2)}`
8
+ );
6
9
 
7
10
  try {
8
11
  process.chdir(target);
9
12
  const newDir = process.cwd();
10
- trace('VirtualCommand', () => `cd: success | ${JSON.stringify({ newDir }, null, 2)}`);
13
+ trace(
14
+ 'VirtualCommand',
15
+ () => `cd: success | ${JSON.stringify({ newDir }, null, 2)}`
16
+ );
11
17
  // cd command should not output anything on success, just like real cd
12
18
  return VirtualUtils.success('');
13
19
  } catch (error) {
14
- trace('VirtualCommand', () => `cd: failed | ${JSON.stringify({ error: error.message }, null, 2)}`);
20
+ trace(
21
+ 'VirtualCommand',
22
+ () => `cd: failed | ${JSON.stringify({ error: error.message }, null, 2)}`
23
+ );
15
24
  return { stderr: `cd: ${error.message}\n`, code: 1 };
16
25
  }
17
- }
26
+ }
@@ -2,14 +2,19 @@ import fs from 'fs';
2
2
  import path from 'path';
3
3
  import { trace, VirtualUtils } from '../$.utils.mjs';
4
4
 
5
- export default async function cp({ args, stdin, cwd }) {
5
+ export default async function cp({ args, stdin: _stdin, cwd }) {
6
6
  const argError = VirtualUtils.validateArgs(args, 2, 'cp');
7
- if (argError) return VirtualUtils.invalidArgumentError('cp', 'missing destination file operand');
7
+ if (argError) {
8
+ return VirtualUtils.invalidArgumentError(
9
+ 'cp',
10
+ 'missing destination file operand'
11
+ );
12
+ }
8
13
 
9
14
  // Parse flags and paths
10
15
  const flags = new Set();
11
16
  const paths = [];
12
-
17
+
13
18
  for (const arg of args) {
14
19
  if (arg === '-r' || arg === '-R' || arg === '--recursive') {
15
20
  flags.add('r');
@@ -23,44 +28,48 @@ export default async function cp({ args, stdin, cwd }) {
23
28
  }
24
29
 
25
30
  if (paths.length < 2) {
26
- return VirtualUtils.invalidArgumentError('cp', 'missing destination file operand');
31
+ return VirtualUtils.invalidArgumentError(
32
+ 'cp',
33
+ 'missing destination file operand'
34
+ );
27
35
  }
28
36
 
29
37
  const recursive = flags.has('r') || flags.has('R');
30
38
  const sources = paths.slice(0, -1);
31
39
  const destination = paths[paths.length - 1];
32
-
40
+
33
41
  try {
34
42
  const destPath = VirtualUtils.resolvePath(destination, cwd);
35
43
  let destExists = false;
36
44
  let destIsDir = false;
37
-
45
+
38
46
  try {
39
47
  const destStats = fs.statSync(destPath);
40
48
  destExists = true;
41
49
  destIsDir = destStats.isDirectory();
42
50
  } catch (error) {
43
- if (error.code !== 'ENOENT') throw error;
51
+ if (error.code !== 'ENOENT') {
52
+ throw error;
53
+ }
44
54
  }
45
55
 
46
56
  // Copying multiple files requires destination to be a directory
47
57
  if (sources.length > 1 && destExists && !destIsDir) {
48
- return VirtualUtils.error(`cp: target '${destination}' is not a directory`);
58
+ return VirtualUtils.error(
59
+ `cp: target '${destination}' is not a directory`
60
+ );
49
61
  }
50
62
 
51
63
  // Helper function to copy directory recursively
52
64
  const copyRecursive = (src, dest) => {
53
65
  const stats = fs.statSync(src);
54
-
66
+
55
67
  if (stats.isDirectory()) {
56
68
  fs.mkdirSync(dest, { recursive: true });
57
69
  const entries = fs.readdirSync(src);
58
-
70
+
59
71
  for (const entry of entries) {
60
- copyRecursive(
61
- path.join(src, entry),
62
- path.join(dest, entry)
63
- );
72
+ copyRecursive(path.join(src, entry), path.join(dest, entry));
64
73
  }
65
74
  } else {
66
75
  fs.copyFileSync(src, dest);
@@ -69,11 +78,11 @@ export default async function cp({ args, stdin, cwd }) {
69
78
 
70
79
  for (const source of sources) {
71
80
  const sourcePath = VirtualUtils.resolvePath(source, cwd);
72
-
81
+
73
82
  try {
74
83
  const sourceStats = fs.statSync(sourcePath);
75
84
  let finalDestPath = destPath;
76
-
85
+
77
86
  if (destIsDir || (sources.length > 1 && !destExists)) {
78
87
  // Copying into a directory
79
88
  if (!destExists) {
@@ -83,30 +92,48 @@ export default async function cp({ args, stdin, cwd }) {
83
92
  }
84
93
  finalDestPath = path.join(destPath, path.basename(sourcePath));
85
94
  }
86
-
95
+
87
96
  if (sourceStats.isDirectory()) {
88
97
  if (!recursive) {
89
- return VirtualUtils.error(`cp: -r not specified; omitting directory '${source}'`);
98
+ return VirtualUtils.error(
99
+ `cp: -r not specified; omitting directory '${source}'`
100
+ );
90
101
  }
91
- trace('VirtualCommand', () => `cp: copying directory | ${JSON.stringify({ from: sourcePath, to: finalDestPath }, null, 2)}`);
102
+ trace(
103
+ 'VirtualCommand',
104
+ () =>
105
+ `cp: copying directory | ${JSON.stringify({ from: sourcePath, to: finalDestPath }, null, 2)}`
106
+ );
92
107
  copyRecursive(sourcePath, finalDestPath);
93
108
  } else {
94
- trace('VirtualCommand', () => `cp: copying file | ${JSON.stringify({ from: sourcePath, to: finalDestPath }, null, 2)}`);
109
+ trace(
110
+ 'VirtualCommand',
111
+ () =>
112
+ `cp: copying file | ${JSON.stringify({ from: sourcePath, to: finalDestPath }, null, 2)}`
113
+ );
95
114
  fs.copyFileSync(sourcePath, finalDestPath);
96
115
  }
97
-
98
116
  } catch (error) {
99
117
  if (error.code === 'ENOENT') {
100
- return VirtualUtils.error(`cp: cannot stat '${source}': No such file or directory`);
118
+ return VirtualUtils.error(
119
+ `cp: cannot stat '${source}': No such file or directory`
120
+ );
101
121
  }
102
122
  throw error;
103
123
  }
104
124
  }
105
-
106
- trace('VirtualCommand', () => `cp: success | ${JSON.stringify({ filesCopied: sources.length }, null, 2)}`);
125
+
126
+ trace(
127
+ 'VirtualCommand',
128
+ () =>
129
+ `cp: success | ${JSON.stringify({ filesCopied: sources.length }, null, 2)}`
130
+ );
107
131
  return VirtualUtils.success();
108
132
  } catch (error) {
109
- trace('VirtualCommand', () => `cp: error | ${JSON.stringify({ error: error.message }, null, 2)}`);
133
+ trace(
134
+ 'VirtualCommand',
135
+ () => `cp: error | ${JSON.stringify({ error: error.message }, null, 2)}`
136
+ );
110
137
  return VirtualUtils.error(`cp: ${error.message}`);
111
138
  }
112
- }
139
+ }
@@ -3,10 +3,12 @@ import { VirtualUtils } from '../$.utils.mjs';
3
3
 
4
4
  export default async function dirname({ args }) {
5
5
  const argError = VirtualUtils.validateArgs(args, 1, 'dirname');
6
- if (argError) return argError;
6
+ if (argError) {
7
+ return argError;
8
+ }
7
9
 
8
10
  const filePath = args[0];
9
11
  const result = path.dirname(filePath);
10
-
11
- return VirtualUtils.success(result + '\n');
12
- }
12
+
13
+ return VirtualUtils.success(`${result}\n`);
14
+ }
@@ -1,15 +1,22 @@
1
1
  import { trace, VirtualUtils } from '../$.utils.mjs';
2
2
 
3
3
  export default async function echo({ args }) {
4
- trace('VirtualCommand', () => `echo: processing | ${JSON.stringify({ argsCount: args.length }, null, 2)}`);
4
+ trace(
5
+ 'VirtualCommand',
6
+ () =>
7
+ `echo: processing | ${JSON.stringify({ argsCount: args.length }, null, 2)}`
8
+ );
5
9
 
6
10
  let output = args.join(' ');
7
11
  if (args.includes('-n')) {
8
12
  // Don't add newline
9
- trace('VirtualCommand', () => `BRANCH: echo => NO_NEWLINE | ${JSON.stringify({}, null, 2)}`);
10
- output = args.filter(arg => arg !== '-n').join(' ');
13
+ trace(
14
+ 'VirtualCommand',
15
+ () => `BRANCH: echo => NO_NEWLINE | ${JSON.stringify({}, null, 2)}`
16
+ );
17
+ output = args.filter((arg) => arg !== '-n').join(' ');
11
18
  } else {
12
19
  output += '\n';
13
20
  }
14
21
  return VirtualUtils.success(output);
15
- }
22
+ }
@@ -1,14 +1,14 @@
1
1
  import { VirtualUtils } from '../$.utils.mjs';
2
2
 
3
- export default async function env({ args, stdin, env }) {
3
+ export default async function env({ args, stdin: _stdin, env }) {
4
4
  if (args.length === 0) {
5
5
  // Use custom env if provided, otherwise use process.env
6
6
  const envVars = env || process.env;
7
- const output = Object.entries(envVars)
7
+ const output = `${Object.entries(envVars)
8
8
  .map(([key, value]) => `${key}=${value}`)
9
- .join('\n') + '\n';
9
+ .join('\n')}\n`;
10
10
  return VirtualUtils.success(output);
11
11
  }
12
12
  // TODO: Support setting environment variables for subsequent command
13
13
  return VirtualUtils.error('env: setting variables not yet supported');
14
- }
14
+ }
@@ -6,4 +6,4 @@ export default function createExitCommand(globalShellSettings) {
6
6
  }
7
7
  return { stdout: '', code };
8
8
  };
9
- }
9
+ }
@@ -1,3 +1,3 @@
1
1
  export default async function falseCommand() {
2
2
  return { stdout: '', code: 1 };
3
- }
3
+ }
@@ -2,12 +2,12 @@ import fs from 'fs';
2
2
  import path from 'path';
3
3
  import { trace, VirtualUtils } from '../$.utils.mjs';
4
4
 
5
- export default async function ls({ args, stdin, cwd }) {
5
+ export default async function ls({ args, stdin: _stdin, cwd }) {
6
6
  try {
7
7
  // Parse flags
8
8
  const flags = new Set();
9
9
  const paths = [];
10
-
10
+
11
11
  for (const arg of args) {
12
12
  if (arg.startsWith('-')) {
13
13
  for (const flag of arg.slice(1)) {
@@ -25,22 +25,26 @@ export default async function ls({ args, stdin, cwd }) {
25
25
 
26
26
  const showAll = flags.has('a');
27
27
  const longFormat = flags.has('l');
28
-
29
- trace('VirtualCommand', () => `ls: listing | ${JSON.stringify({ paths, flags: Array.from(flags) }, null, 2)}`);
28
+
29
+ trace(
30
+ 'VirtualCommand',
31
+ () =>
32
+ `ls: listing | ${JSON.stringify({ paths, flags: Array.from(flags) }, null, 2)}`
33
+ );
30
34
 
31
35
  const outputs = [];
32
-
36
+
33
37
  for (const targetPath of paths) {
34
38
  const resolvedPath = VirtualUtils.resolvePath(targetPath, cwd);
35
39
  const stats = fs.statSync(resolvedPath);
36
-
40
+
37
41
  if (stats.isDirectory()) {
38
42
  let entries = fs.readdirSync(resolvedPath);
39
-
43
+
40
44
  if (!showAll) {
41
- entries = entries.filter(e => !e.startsWith('.'));
45
+ entries = entries.filter((e) => !e.startsWith('.'));
42
46
  }
43
-
47
+
44
48
  if (longFormat) {
45
49
  for (const entry of entries) {
46
50
  const entryPath = path.join(resolvedPath, entry);
@@ -51,7 +55,7 @@ export default async function ls({ args, stdin, cwd }) {
51
55
  outputs.push(`${mode} 1 user group ${size} ${mtime} ${entry}\n`);
52
56
  }
53
57
  } else {
54
- outputs.push(entries.join('\n') + '\n');
58
+ outputs.push(`${entries.join('\n')}\n`);
55
59
  }
56
60
  } else {
57
61
  // Single file
@@ -62,18 +66,27 @@ export default async function ls({ args, stdin, cwd }) {
62
66
  const basename = path.basename(resolvedPath);
63
67
  outputs.push(`${mode} 1 user group ${size} ${mtime} ${basename}\n`);
64
68
  } else {
65
- outputs.push(path.basename(resolvedPath) + '\n');
69
+ outputs.push(`${path.basename(resolvedPath)}\n`);
66
70
  }
67
71
  }
68
72
  }
69
-
70
- trace('VirtualCommand', () => `ls: success | ${JSON.stringify({ entriesCount: outputs.length }, null, 2)}`);
73
+
74
+ trace(
75
+ 'VirtualCommand',
76
+ () =>
77
+ `ls: success | ${JSON.stringify({ entriesCount: outputs.length }, null, 2)}`
78
+ );
71
79
  return VirtualUtils.success(outputs.join(''));
72
80
  } catch (error) {
73
- trace('VirtualCommand', () => `ls: error | ${JSON.stringify({ error: error.message }, null, 2)}`);
81
+ trace(
82
+ 'VirtualCommand',
83
+ () => `ls: error | ${JSON.stringify({ error: error.message }, null, 2)}`
84
+ );
74
85
  if (error.code === 'ENOENT') {
75
- return VirtualUtils.error(`ls: ${args[0] || '.'}: No such file or directory`);
86
+ return VirtualUtils.error(
87
+ `ls: ${args[0] || '.'}: No such file or directory`
88
+ );
76
89
  }
77
90
  return VirtualUtils.error(`ls: ${error.message}`);
78
91
  }
79
- }
92
+ }
@@ -1,14 +1,16 @@
1
1
  import fs from 'fs';
2
2
  import { trace, VirtualUtils } from '../$.utils.mjs';
3
3
 
4
- export default async function mkdir({ args, stdin, cwd }) {
4
+ export default async function mkdir({ args, stdin: _stdin, cwd }) {
5
5
  const argError = VirtualUtils.validateArgs(args, 1, 'mkdir');
6
- if (argError) return argError;
6
+ if (argError) {
7
+ return argError;
8
+ }
7
9
 
8
10
  // Parse flags and paths
9
11
  const flags = new Set();
10
12
  const paths = [];
11
-
13
+
12
14
  for (const arg of args) {
13
15
  if (arg === '-p' || arg === '--parents') {
14
16
  flags.add('p');
@@ -26,20 +28,34 @@ export default async function mkdir({ args, stdin, cwd }) {
26
28
  }
27
29
 
28
30
  const recursive = flags.has('p');
29
-
31
+
30
32
  try {
31
33
  for (const dir of paths) {
32
34
  const resolvedPath = VirtualUtils.resolvePath(dir, cwd);
33
- trace('VirtualCommand', () => `mkdir: creating | ${JSON.stringify({ dir: resolvedPath, recursive }, null, 2)}`);
35
+ trace(
36
+ 'VirtualCommand',
37
+ () =>
38
+ `mkdir: creating | ${JSON.stringify({ dir: resolvedPath, recursive }, null, 2)}`
39
+ );
34
40
  fs.mkdirSync(resolvedPath, { recursive });
35
41
  }
36
- trace('VirtualCommand', () => `mkdir: success | ${JSON.stringify({ dirsCreated: paths.length }, null, 2)}`);
42
+ trace(
43
+ 'VirtualCommand',
44
+ () =>
45
+ `mkdir: success | ${JSON.stringify({ dirsCreated: paths.length }, null, 2)}`
46
+ );
37
47
  return VirtualUtils.success();
38
48
  } catch (error) {
39
- trace('VirtualCommand', () => `mkdir: error | ${JSON.stringify({ error: error.message }, null, 2)}`);
49
+ trace(
50
+ 'VirtualCommand',
51
+ () =>
52
+ `mkdir: error | ${JSON.stringify({ error: error.message }, null, 2)}`
53
+ );
40
54
  if (error.code === 'EEXIST') {
41
- return VirtualUtils.error(`mkdir: cannot create directory '${paths[0]}': File exists`);
55
+ return VirtualUtils.error(
56
+ `mkdir: cannot create directory '${paths[0]}': File exists`
57
+ );
42
58
  }
43
59
  return VirtualUtils.error(`mkdir: ${error.message}`);
44
60
  }
45
- }
61
+ }
@@ -2,14 +2,19 @@ import fs from 'fs';
2
2
  import path from 'path';
3
3
  import { trace, VirtualUtils } from '../$.utils.mjs';
4
4
 
5
- export default async function mv({ args, stdin, cwd }) {
5
+ export default async function mv({ args, stdin: _stdin, cwd }) {
6
6
  const argError = VirtualUtils.validateArgs(args, 2, 'mv');
7
- if (argError) return VirtualUtils.invalidArgumentError('mv', 'missing destination file operand');
7
+ if (argError) {
8
+ return VirtualUtils.invalidArgumentError(
9
+ 'mv',
10
+ 'missing destination file operand'
11
+ );
12
+ }
8
13
 
9
14
  // Parse flags and paths
10
15
  const flags = new Set();
11
16
  const paths = [];
12
-
17
+
13
18
  for (const arg of args) {
14
19
  if (arg.startsWith('-')) {
15
20
  for (const flag of arg.slice(1)) {
@@ -21,69 +26,92 @@ export default async function mv({ args, stdin, cwd }) {
21
26
  }
22
27
 
23
28
  if (paths.length < 2) {
24
- return VirtualUtils.invalidArgumentError('mv', 'missing destination file operand');
29
+ return VirtualUtils.invalidArgumentError(
30
+ 'mv',
31
+ 'missing destination file operand'
32
+ );
25
33
  }
26
34
 
27
35
  const force = flags.has('f');
28
36
  const sources = paths.slice(0, -1);
29
37
  const destination = paths[paths.length - 1];
30
-
38
+
31
39
  try {
32
40
  const destPath = VirtualUtils.resolvePath(destination, cwd);
33
41
  let destExists = false;
34
42
  let destIsDir = false;
35
-
43
+
36
44
  try {
37
45
  const destStats = fs.statSync(destPath);
38
46
  destExists = true;
39
47
  destIsDir = destStats.isDirectory();
40
48
  } catch (error) {
41
- if (error.code !== 'ENOENT') throw error;
49
+ if (error.code !== 'ENOENT') {
50
+ throw error;
51
+ }
42
52
  }
43
53
 
44
54
  // Moving multiple files requires destination to be a directory
45
55
  if (sources.length > 1 && destExists && !destIsDir) {
46
- return VirtualUtils.error(`mv: target '${destination}' is not a directory`);
56
+ return VirtualUtils.error(
57
+ `mv: target '${destination}' is not a directory`
58
+ );
47
59
  }
48
60
 
49
61
  for (const source of sources) {
50
62
  const sourcePath = VirtualUtils.resolvePath(source, cwd);
51
-
63
+
52
64
  try {
53
- const sourceStats = fs.statSync(sourcePath);
65
+ const _sourceStats = fs.statSync(sourcePath);
54
66
  let finalDestPath = destPath;
55
-
67
+
56
68
  if (destIsDir) {
57
69
  // Moving into a directory
58
70
  finalDestPath = path.join(destPath, path.basename(sourcePath));
59
71
  }
60
-
72
+
61
73
  // Check if destination exists and handle force flag
62
74
  if (!force) {
63
75
  try {
64
76
  fs.statSync(finalDestPath);
65
77
  // Destination exists and no force flag
66
- return VirtualUtils.error(`mv: cannot move '${source}': File exists`);
78
+ return VirtualUtils.error(
79
+ `mv: cannot move '${source}': File exists`
80
+ );
67
81
  } catch (error) {
68
- if (error.code !== 'ENOENT') throw error;
82
+ if (error.code !== 'ENOENT') {
83
+ throw error;
84
+ }
69
85
  }
70
86
  }
71
-
72
- trace('VirtualCommand', () => `mv: moving | ${JSON.stringify({ from: sourcePath, to: finalDestPath }, null, 2)}`);
87
+
88
+ trace(
89
+ 'VirtualCommand',
90
+ () =>
91
+ `mv: moving | ${JSON.stringify({ from: sourcePath, to: finalDestPath }, null, 2)}`
92
+ );
73
93
  fs.renameSync(sourcePath, finalDestPath);
74
-
75
94
  } catch (error) {
76
95
  if (error.code === 'ENOENT') {
77
- return VirtualUtils.error(`mv: cannot stat '${source}': No such file or directory`);
96
+ return VirtualUtils.error(
97
+ `mv: cannot stat '${source}': No such file or directory`
98
+ );
78
99
  }
79
100
  throw error;
80
101
  }
81
102
  }
82
-
83
- trace('VirtualCommand', () => `mv: success | ${JSON.stringify({ filesMoved: sources.length }, null, 2)}`);
103
+
104
+ trace(
105
+ 'VirtualCommand',
106
+ () =>
107
+ `mv: success | ${JSON.stringify({ filesMoved: sources.length }, null, 2)}`
108
+ );
84
109
  return VirtualUtils.success();
85
110
  } catch (error) {
86
- trace('VirtualCommand', () => `mv: error | ${JSON.stringify({ error: error.message }, null, 2)}`);
111
+ trace(
112
+ 'VirtualCommand',
113
+ () => `mv: error | ${JSON.stringify({ error: error.message }, null, 2)}`
114
+ );
87
115
  return VirtualUtils.error(`mv: ${error.message}`);
88
116
  }
89
- }
117
+ }