@ecmaos/coreutils 0.2.1 → 0.3.1

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 (150) hide show
  1. package/.turbo/turbo-build.log +1 -1
  2. package/CHANGELOG.md +37 -0
  3. package/LICENSE +1 -1
  4. package/dist/commands/cal.js +2 -2
  5. package/dist/commands/cal.js.map +1 -1
  6. package/dist/commands/cat.js +2 -2
  7. package/dist/commands/cd.js +2 -2
  8. package/dist/commands/chmod.d.ts.map +1 -1
  9. package/dist/commands/chmod.js +16 -11
  10. package/dist/commands/chmod.js.map +1 -1
  11. package/dist/commands/cp.js +2 -2
  12. package/dist/commands/cp.js.map +1 -1
  13. package/dist/commands/cron.d.ts +4 -0
  14. package/dist/commands/cron.d.ts.map +1 -0
  15. package/dist/commands/cron.js +439 -0
  16. package/dist/commands/cron.js.map +1 -0
  17. package/dist/commands/date.js +2 -2
  18. package/dist/commands/date.js.map +1 -1
  19. package/dist/commands/echo.js +2 -2
  20. package/dist/commands/echo.js.map +1 -1
  21. package/dist/commands/false.js +2 -2
  22. package/dist/commands/fetch.d.ts +4 -0
  23. package/dist/commands/fetch.d.ts.map +1 -0
  24. package/dist/commands/fetch.js +210 -0
  25. package/dist/commands/fetch.js.map +1 -0
  26. package/dist/commands/format.d.ts +4 -0
  27. package/dist/commands/format.d.ts.map +1 -0
  28. package/dist/commands/format.js +178 -0
  29. package/dist/commands/format.js.map +1 -0
  30. package/dist/commands/hash.d.ts +4 -0
  31. package/dist/commands/hash.d.ts.map +1 -0
  32. package/dist/commands/hash.js +200 -0
  33. package/dist/commands/hash.js.map +1 -0
  34. package/dist/commands/head.js +2 -2
  35. package/dist/commands/id.js +2 -2
  36. package/dist/commands/id.js.map +1 -1
  37. package/dist/commands/less.d.ts.map +1 -1
  38. package/dist/commands/less.js +53 -2
  39. package/dist/commands/less.js.map +1 -1
  40. package/dist/commands/ls.d.ts.map +1 -1
  41. package/dist/commands/ls.js +41 -15
  42. package/dist/commands/ls.js.map +1 -1
  43. package/dist/commands/man.d.ts +4 -0
  44. package/dist/commands/man.d.ts.map +1 -0
  45. package/dist/commands/man.js +564 -0
  46. package/dist/commands/man.js.map +1 -0
  47. package/dist/commands/mkdir.js +2 -2
  48. package/dist/commands/mkdir.js.map +1 -1
  49. package/dist/commands/mktemp.d.ts +4 -0
  50. package/dist/commands/mktemp.d.ts.map +1 -0
  51. package/dist/commands/mktemp.js +229 -0
  52. package/dist/commands/mktemp.js.map +1 -0
  53. package/dist/commands/nc.js +2 -2
  54. package/dist/commands/nc.js.map +1 -1
  55. package/dist/commands/open.d.ts +4 -0
  56. package/dist/commands/open.d.ts.map +1 -0
  57. package/dist/commands/open.js +74 -0
  58. package/dist/commands/open.js.map +1 -0
  59. package/dist/commands/passkey.js +3 -3
  60. package/dist/commands/play.d.ts +4 -0
  61. package/dist/commands/play.d.ts.map +1 -0
  62. package/dist/commands/play.js +231 -0
  63. package/dist/commands/play.js.map +1 -0
  64. package/dist/commands/pwd.js +2 -2
  65. package/dist/commands/pwd.js.map +1 -1
  66. package/dist/commands/rm.d.ts.map +1 -1
  67. package/dist/commands/rm.js +57 -12
  68. package/dist/commands/rm.js.map +1 -1
  69. package/dist/commands/rmdir.js +2 -2
  70. package/dist/commands/rmdir.js.map +1 -1
  71. package/dist/commands/sockets.js +1 -1
  72. package/dist/commands/stat.d.ts.map +1 -1
  73. package/dist/commands/stat.js +37 -15
  74. package/dist/commands/stat.js.map +1 -1
  75. package/dist/commands/tail.js +2 -2
  76. package/dist/commands/tar.d.ts +4 -0
  77. package/dist/commands/tar.d.ts.map +1 -0
  78. package/dist/commands/tar.js +743 -0
  79. package/dist/commands/tar.js.map +1 -0
  80. package/dist/commands/touch.js +2 -2
  81. package/dist/commands/touch.js.map +1 -1
  82. package/dist/commands/true.js +2 -2
  83. package/dist/commands/unzip.d.ts +4 -0
  84. package/dist/commands/unzip.d.ts.map +1 -0
  85. package/dist/commands/unzip.js +443 -0
  86. package/dist/commands/unzip.js.map +1 -0
  87. package/dist/commands/user.js +1 -1
  88. package/dist/commands/video.d.ts +4 -0
  89. package/dist/commands/video.d.ts.map +1 -0
  90. package/dist/commands/video.js +250 -0
  91. package/dist/commands/video.js.map +1 -0
  92. package/dist/commands/view.d.ts +4 -0
  93. package/dist/commands/view.d.ts.map +1 -0
  94. package/dist/commands/view.js +488 -0
  95. package/dist/commands/view.js.map +1 -0
  96. package/dist/commands/web.d.ts +4 -0
  97. package/dist/commands/web.d.ts.map +1 -0
  98. package/dist/commands/web.js +348 -0
  99. package/dist/commands/web.js.map +1 -0
  100. package/dist/commands/whoami.js +2 -2
  101. package/dist/commands/whoami.js.map +1 -1
  102. package/dist/commands/zip.d.ts +4 -0
  103. package/dist/commands/zip.d.ts.map +1 -0
  104. package/dist/commands/zip.js +264 -0
  105. package/dist/commands/zip.js.map +1 -0
  106. package/dist/index.d.ts +14 -0
  107. package/dist/index.d.ts.map +1 -1
  108. package/dist/index.js +44 -2
  109. package/dist/index.js.map +1 -1
  110. package/package.json +7 -4
  111. package/src/commands/cal.ts +2 -2
  112. package/src/commands/cat.ts +2 -2
  113. package/src/commands/cd.ts +2 -2
  114. package/src/commands/chmod.ts +19 -11
  115. package/src/commands/cp.ts +2 -2
  116. package/src/commands/cron.ts +499 -0
  117. package/src/commands/date.ts +2 -2
  118. package/src/commands/echo.ts +2 -2
  119. package/src/commands/false.ts +2 -2
  120. package/src/commands/fetch.ts +205 -0
  121. package/src/commands/format.ts +204 -0
  122. package/src/commands/hash.ts +215 -0
  123. package/src/commands/head.ts +2 -2
  124. package/src/commands/id.ts +2 -2
  125. package/src/commands/less.ts +50 -2
  126. package/src/commands/ls.ts +40 -14
  127. package/src/commands/man.ts +651 -0
  128. package/src/commands/mkdir.ts +2 -2
  129. package/src/commands/mktemp.ts +235 -0
  130. package/src/commands/nc.ts +2 -2
  131. package/src/commands/open.ts +84 -0
  132. package/src/commands/passkey.ts +3 -3
  133. package/src/commands/play.ts +249 -0
  134. package/src/commands/pwd.ts +2 -2
  135. package/src/commands/rm.ts +54 -12
  136. package/src/commands/rmdir.ts +2 -2
  137. package/src/commands/sockets.ts +1 -1
  138. package/src/commands/stat.ts +44 -16
  139. package/src/commands/tail.ts +2 -2
  140. package/src/commands/tar.ts +780 -0
  141. package/src/commands/touch.ts +2 -2
  142. package/src/commands/true.ts +2 -2
  143. package/src/commands/unzip.ts +517 -0
  144. package/src/commands/user.ts +1 -1
  145. package/src/commands/video.ts +267 -0
  146. package/src/commands/view.ts +526 -0
  147. package/src/commands/web.ts +377 -0
  148. package/src/commands/whoami.ts +2 -2
  149. package/src/commands/zip.ts +319 -0
  150. package/src/index.ts +44 -2
@@ -7,7 +7,9 @@ function printUsage(process: Process | undefined, terminal: Terminal): void {
7
7
  const usage = `Usage: rm [OPTION]... FILE...
8
8
  Remove (unlink) the FILE(s).
9
9
 
10
- --help display this help and exit`
10
+ -f, --force ignore nonexistent files and arguments, never prompt
11
+ -r, -R, --recursive remove directories and their contents recursively
12
+ --help display this help and exit`
11
13
  writelnStderr(process, terminal, usage)
12
14
  }
13
15
 
@@ -32,10 +34,32 @@ export function createCommand(kernel: Kernel, shell: Shell, terminal: Terminal):
32
34
  return 0
33
35
  }
34
36
 
37
+ let recursive = false
38
+ let force = false
35
39
  const pathArray: string[] = []
40
+
36
41
  for (const arg of argv) {
37
42
  if (arg.startsWith('-') && arg !== '--') {
38
- if (arg !== '-f' && arg !== '-r' && arg !== '-rf' && arg !== '-fr') {
43
+ // Handle combined flags like -rf, -fr, -rR, etc.
44
+ if (arg === '--recursive' || arg === '-R') {
45
+ recursive = true
46
+ } else if (arg === '--force') {
47
+ force = true
48
+ } else if (arg.length > 1) {
49
+ // Parse individual flags in combined options like -rf
50
+ for (let i = 1; i < arg.length; i++) {
51
+ const flag = arg[i]
52
+ if (flag === 'r' || flag === 'R') {
53
+ recursive = true
54
+ } else if (flag === 'f') {
55
+ force = true
56
+ } else {
57
+ await writelnStderr(process, terminal, `rm: invalid option -- '${flag}'`)
58
+ await writelnStderr(process, terminal, "Try 'rm --help' for more information.")
59
+ return 1
60
+ }
61
+ }
62
+ } else {
39
63
  await writelnStderr(process, terminal, `rm: invalid option -- '${arg.slice(1)}'`)
40
64
  await writelnStderr(process, terminal, "Try 'rm --help' for more information.")
41
65
  return 1
@@ -104,24 +128,42 @@ export function createCommand(kernel: Kernel, shell: Shell, terminal: Terminal):
104
128
 
105
129
  for (const target of expandedPaths) {
106
130
  if (!target || typeof target !== 'string') {
107
- await writelnStderr(process, terminal, `rm: ${String(target)}: No such file or directory`)
108
- hasError = true
131
+ if (!force) {
132
+ await writelnStderr(process, terminal, `rm: ${String(target)}: No such file or directory`)
133
+ hasError = true
134
+ }
109
135
  continue
110
136
  }
111
137
 
112
138
  const fullPath = path.resolve(shell.cwd, target)
113
139
 
114
140
  try {
115
- const stat = await shell.context.fs.promises.stat(fullPath)
116
- if (stat.isDirectory()) {
117
- await shell.context.fs.promises.rmdir(fullPath)
118
- } else {
119
- await shell.context.fs.promises.unlink(fullPath)
141
+ // Check if it's a directory to validate recursive flag requirement
142
+ try {
143
+ const stat = await shell.context.fs.promises.stat(fullPath)
144
+ if (stat.isDirectory() && !recursive) {
145
+ await writelnStderr(process, terminal, `rm: ${target}: is a directory`)
146
+ hasError = true
147
+ continue
148
+ }
149
+ } catch (statError) {
150
+ // If stat fails, the file might not exist
151
+ // If force is enabled, we'll try to remove it anyway (rm will handle it)
152
+ // If force is not enabled, we'll let rm handle the error
120
153
  }
154
+
155
+ // Use fs.promises.rm with appropriate options
156
+ await shell.context.fs.promises.rm(fullPath, {
157
+ recursive: recursive,
158
+ force: force
159
+ })
121
160
  } catch (error) {
122
- const errorMessage = error instanceof Error ? error.message : String(error)
123
- await writelnStderr(process, terminal, `rm: ${target}: ${errorMessage}`)
124
- hasError = true
161
+ // If force is enabled, ignore errors
162
+ if (!force) {
163
+ const errorMessage = error instanceof Error ? error.message : String(error)
164
+ await writelnStderr(process, terminal, `rm: ${target}: ${errorMessage}`)
165
+ hasError = true
166
+ }
125
167
  }
126
168
  }
127
169
 
@@ -1,14 +1,14 @@
1
1
  import path from 'path'
2
2
  import type { Kernel, Process, Shell, Terminal } from '@ecmaos/types'
3
3
  import { TerminalCommand } from '../shared/terminal-command.js'
4
- import { writelnStdout, writelnStderr } from '../shared/helpers.js'
4
+ import { writelnStderr } from '../shared/helpers.js'
5
5
 
6
6
  function printUsage(process: Process | undefined, terminal: Terminal): void {
7
7
  const usage = `Usage: rmdir [OPTION]... DIRECTORY...
8
8
  Remove the DIRECTORY(ies), if they are empty.
9
9
 
10
10
  --help display this help and exit`
11
- writelnStdout(process, terminal, usage)
11
+ writelnStderr(process, terminal, usage)
12
12
  }
13
13
 
14
14
  export function createCommand(kernel: Kernel, shell: Shell, terminal: Terminal): TerminalCommand {
@@ -26,7 +26,7 @@ Examples:
26
26
  sockets create https://example.com:443 -t webtransport
27
27
  sockets close abc-123-def-456
28
28
  sockets show abc-123-def-456`
29
- writelnStdout(process, terminal, usage)
29
+ writelnStderr(process, terminal, usage)
30
30
  }
31
31
 
32
32
  function findConnectionById(kernel: Kernel, id: string): SocketConnection | undefined {
@@ -3,14 +3,14 @@ import chalk from 'chalk'
3
3
  import * as zipjs from '@zip.js/zip.js'
4
4
  import type { Kernel, Process, Shell, Terminal } from '@ecmaos/types'
5
5
  import { TerminalCommand } from '../shared/terminal-command.js'
6
- import { writelnStdout } from '../shared/helpers.js'
6
+ import { writelnStdout, writelnStderr } from '../shared/helpers.js'
7
7
 
8
8
  function printUsage(process: Process | undefined, terminal: Terminal): void {
9
9
  const usage = `Usage: stat [OPTION]... FILE...
10
10
  Display file or file system status.
11
11
 
12
12
  --help display this help and exit`
13
- writelnStdout(process, terminal, usage)
13
+ writelnStderr(process, terminal, usage)
14
14
  }
15
15
 
16
16
  export function createCommand(kernel: Kernel, shell: Shell, terminal: Terminal): TerminalCommand {
@@ -28,22 +28,50 @@ export function createCommand(kernel: Kernel, shell: Shell, terminal: Terminal):
28
28
  return 0
29
29
  }
30
30
 
31
- const argPath = argv.length > 0 && argv[0] && !argv[0].startsWith('-') ? argv[0] : shell.cwd
32
- const fullPath = argPath ? path.resolve(shell.cwd, argPath) : shell.cwd
33
- const stats = await shell.context.fs.promises.stat(fullPath)
34
- await writelnStdout(process, terminal, JSON.stringify(stats, null, 2))
35
-
36
- const extension = path.extname(fullPath)
37
- if (extension === '.zip') {
38
- const blob = new Blob([new Uint8Array(await shell.context.fs.promises.readFile(fullPath))])
39
- const zipReader = new zipjs.ZipReader(new zipjs.BlobReader(blob))
40
- const entries = await zipReader.getEntries()
41
- await writelnStdout(process, terminal, chalk.bold('\nZIP Entries:'))
42
- for (const entry of entries) {
43
- await writelnStdout(process, terminal, `${chalk.blue(entry.filename)} (${entry.uncompressedSize} bytes)`)
31
+ // Filter out options/flags and get target paths
32
+ const targets = argv.length > 0
33
+ ? argv.filter(arg => !arg.startsWith('-'))
34
+ : [shell.cwd]
35
+
36
+ if (targets.length === 0) {
37
+ targets.push(shell.cwd)
38
+ }
39
+
40
+ let hasError = false
41
+
42
+ for (const target of targets) {
43
+ const fullPath = path.resolve(shell.cwd, target)
44
+
45
+ try {
46
+ const stats = await shell.context.fs.promises.stat(fullPath)
47
+
48
+ if (targets.length > 1) {
49
+ await writelnStdout(process, terminal, `${target}:`)
50
+ }
51
+ await writelnStdout(process, terminal, JSON.stringify(stats, null, 2))
52
+
53
+ const extension = path.extname(fullPath)
54
+ if (extension === '.zip') {
55
+ const blob = new Blob([new Uint8Array(await shell.context.fs.promises.readFile(fullPath))])
56
+ const zipReader = new zipjs.ZipReader(new zipjs.BlobReader(blob))
57
+ const entries = await zipReader.getEntries()
58
+ await writelnStdout(process, terminal, chalk.bold('\nZIP Entries:'))
59
+ for (const entry of entries) {
60
+ await writelnStdout(process, terminal, `${chalk.blue(entry.filename)} (${entry.uncompressedSize} bytes)`)
61
+ }
62
+ }
63
+
64
+ if (targets.length > 1) {
65
+ await writelnStdout(process, terminal, '')
66
+ }
67
+ } catch (error) {
68
+ const errorMessage = error instanceof Error ? error.message : String(error)
69
+ await writelnStderr(process, terminal, `stat: ${target}: ${errorMessage}`)
70
+ hasError = true
44
71
  }
45
72
  }
46
- return 0
73
+
74
+ return hasError ? 1 : 0
47
75
  }
48
76
  })
49
77
  }
@@ -2,7 +2,7 @@ import path from 'path'
2
2
  import type { Kernel, Process, Shell, Terminal } from '@ecmaos/types'
3
3
  import { TerminalEvents } from '@ecmaos/types'
4
4
  import { TerminalCommand } from '../shared/terminal-command.js'
5
- import { writelnStdout } from '../shared/helpers.js'
5
+ import { writelnStderr } from '../shared/helpers.js'
6
6
 
7
7
  function printUsage(process: Process | undefined, terminal: Terminal): void {
8
8
  const usage = `Usage: tail [OPTION]... [FILE]...
@@ -10,7 +10,7 @@ Print the last 10 lines of each FILE to standard output.
10
10
 
11
11
  -n, -nNUMBER print the last NUMBER lines instead of 10
12
12
  --help display this help and exit`
13
- writelnStdout(process, terminal, usage)
13
+ writelnStderr(process, terminal, usage)
14
14
  }
15
15
 
16
16
  export function createCommand(kernel: Kernel, shell: Shell, terminal: Terminal): TerminalCommand {