@ecmaos/coreutils 0.4.2 → 0.5.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.
- package/.turbo/turbo-build.log +1 -1
- package/CHANGELOG.md +18 -0
- package/dist/commands/mount.js +18 -18
- package/dist/commands/xxd.d.ts +4 -0
- package/dist/commands/xxd.d.ts.map +1 -0
- package/dist/commands/xxd.js +144 -0
- package/dist/commands/xxd.js.map +1 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.js +3 -3
- package/package.json +2 -2
- package/src/commands/mount.ts +18 -18
- package/src/commands/{hex.ts → xxd.ts} +13 -13
- package/src/index.ts +3 -3
package/.turbo/turbo-build.log
CHANGED
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,23 @@
|
|
|
1
1
|
# @ecmaos/coreutils
|
|
2
2
|
|
|
3
|
+
## 0.5.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- ad7dc2e: add initfs.demo; fix bell flash; rename hex to xxd
|
|
8
|
+
|
|
9
|
+
### Patch Changes
|
|
10
|
+
|
|
11
|
+
- Updated dependencies [ad7dc2e]
|
|
12
|
+
- @ecmaos/types@0.7.2
|
|
13
|
+
|
|
14
|
+
## 0.4.3
|
|
15
|
+
|
|
16
|
+
### Patch Changes
|
|
17
|
+
|
|
18
|
+
- Updated dependencies [f332a2f]
|
|
19
|
+
- @ecmaos/types@0.7.1
|
|
20
|
+
|
|
3
21
|
## 0.4.2
|
|
4
22
|
|
|
5
23
|
### Patch Changes
|
package/dist/commands/mount.js
CHANGED
|
@@ -66,31 +66,31 @@ function printUsage(process, terminal) {
|
|
|
66
66
|
Mount a filesystem.
|
|
67
67
|
|
|
68
68
|
Options:
|
|
69
|
-
-t, --type TYPE filesystem type
|
|
70
|
-
-o, --options OPTS
|
|
69
|
+
-t, --type TYPE filesystem type
|
|
70
|
+
-o, --options OPTS mount options (comma-separated key=value pairs)
|
|
71
71
|
-a, --all mount all filesystems listed in /etc/fstab
|
|
72
72
|
-l, --list list all mounted filesystems
|
|
73
73
|
--help display this help and exit
|
|
74
74
|
|
|
75
75
|
Filesystem types:
|
|
76
|
-
fetch
|
|
77
|
-
indexeddb
|
|
78
|
-
webstorage
|
|
79
|
-
webaccess
|
|
80
|
-
memory
|
|
81
|
-
singlebuffer
|
|
82
|
-
zip
|
|
83
|
-
iso
|
|
84
|
-
googledrive
|
|
76
|
+
fetch mount a remote filesystem via HTTP fetch
|
|
77
|
+
indexeddb mount an IndexedDB-backed filesystem
|
|
78
|
+
webstorage mount a WebStorage-backed filesystem (localStorage or sessionStorage)
|
|
79
|
+
webaccess mount a filesystem using the File System Access API
|
|
80
|
+
memory mount an in-memory filesystem
|
|
81
|
+
singlebuffer mount a filesystem backed by a single buffer
|
|
82
|
+
zip mount a readonly filesystem from a zip archive (requires SOURCE file or URL)
|
|
83
|
+
iso mount a readonly filesystem from an ISO image (requires SOURCE file or URL)
|
|
84
|
+
googledrive mount a Google Drive filesystem (requires apiKey via -o apiKey, optionally clientId for OAuth)
|
|
85
85
|
|
|
86
86
|
Mount options:
|
|
87
|
-
baseUrl=URL
|
|
88
|
-
size=BYTES
|
|
89
|
-
storage=TYPE
|
|
90
|
-
apiKey=KEY
|
|
91
|
-
clientId=ID
|
|
92
|
-
scope=SCOPE
|
|
93
|
-
cacheTTL=SECONDS
|
|
87
|
+
baseUrl=URL base URL for fetch operations (fetch type)
|
|
88
|
+
size=BYTES buffer size in bytes for singlebuffer type (default: 1048576)
|
|
89
|
+
storage=TYPE storage type for webstorage (localStorage or sessionStorage, default: localStorage)
|
|
90
|
+
apiKey=KEY Google API key (googledrive type, required)
|
|
91
|
+
clientId=ID Google OAuth client ID (googledrive type, optional)
|
|
92
|
+
scope=SCOPE OAuth scope (googledrive type, default: https://www.googleapis.com/auth/drive)
|
|
93
|
+
cacheTTL=SECONDS cache TTL in seconds for cloud backends (optional)
|
|
94
94
|
|
|
95
95
|
Examples:
|
|
96
96
|
mount -l list all mounted filesystems
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"xxd.d.ts","sourceRoot":"","sources":["../../src/commands/xxd.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,EAAW,KAAK,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAA;AACrE,OAAO,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAA;AAY/D,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,QAAQ,GAAG,eAAe,CAiJ/F"}
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
import path from 'path';
|
|
2
|
+
import { TerminalCommand } from '../shared/terminal-command.js';
|
|
3
|
+
import { writelnStdout, writelnStderr } from '../shared/helpers.js';
|
|
4
|
+
function printUsage(process, terminal) {
|
|
5
|
+
const usage = `Usage: xxd [FILE]
|
|
6
|
+
Display file contents or stdin in hexadecimal format.
|
|
7
|
+
|
|
8
|
+
FILE the file to display (if omitted, reads from stdin)
|
|
9
|
+
--help display this help and exit`;
|
|
10
|
+
writelnStderr(process, terminal, usage);
|
|
11
|
+
}
|
|
12
|
+
export function createCommand(kernel, shell, terminal) {
|
|
13
|
+
return new TerminalCommand({
|
|
14
|
+
command: 'xxd',
|
|
15
|
+
description: 'Display file contents or stdin in hexadecimal format',
|
|
16
|
+
kernel,
|
|
17
|
+
shell,
|
|
18
|
+
terminal,
|
|
19
|
+
run: async (pid, argv) => {
|
|
20
|
+
const process = kernel.processes.get(pid);
|
|
21
|
+
if (!process)
|
|
22
|
+
return 1;
|
|
23
|
+
if (argv.length > 0 && (argv[0] === '--help' || argv[0] === '-h')) {
|
|
24
|
+
printUsage(process, terminal);
|
|
25
|
+
return 0;
|
|
26
|
+
}
|
|
27
|
+
const firstArg = argv.length > 0 ? argv[0] : undefined;
|
|
28
|
+
const filePath = firstArg !== undefined && !firstArg.startsWith('-') ? firstArg : undefined;
|
|
29
|
+
let data;
|
|
30
|
+
try {
|
|
31
|
+
if (!filePath) {
|
|
32
|
+
if (!process.stdin) {
|
|
33
|
+
await writelnStderr(process, terminal, 'Usage: xxd <file>');
|
|
34
|
+
await writelnStderr(process, terminal, ' or: <command> | xxd');
|
|
35
|
+
return 1;
|
|
36
|
+
}
|
|
37
|
+
if (process.stdinIsTTY) {
|
|
38
|
+
await writelnStderr(process, terminal, 'Usage: xxd <file>');
|
|
39
|
+
await writelnStderr(process, terminal, ' or: <command> | xxd');
|
|
40
|
+
return 1;
|
|
41
|
+
}
|
|
42
|
+
const reader = process.stdin.getReader();
|
|
43
|
+
const chunks = [];
|
|
44
|
+
try {
|
|
45
|
+
const first = await reader.read();
|
|
46
|
+
if (first.done && !first.value) {
|
|
47
|
+
await writelnStderr(process, terminal, 'Usage: xxd <file>');
|
|
48
|
+
await writelnStderr(process, terminal, ' or: <command> | xxd');
|
|
49
|
+
return 1;
|
|
50
|
+
}
|
|
51
|
+
if (first.value) {
|
|
52
|
+
chunks.push(first.value);
|
|
53
|
+
}
|
|
54
|
+
if (!first.done) {
|
|
55
|
+
while (true) {
|
|
56
|
+
const { done, value } = await reader.read();
|
|
57
|
+
if (done)
|
|
58
|
+
break;
|
|
59
|
+
if (value) {
|
|
60
|
+
chunks.push(value);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
finally {
|
|
66
|
+
reader.releaseLock();
|
|
67
|
+
}
|
|
68
|
+
const totalLength = chunks.reduce((sum, chunk) => sum + chunk.length, 0);
|
|
69
|
+
if (totalLength === 0) {
|
|
70
|
+
await writelnStderr(process, terminal, 'Usage: xxd <file>');
|
|
71
|
+
await writelnStderr(process, terminal, ' or: <command> | xxd');
|
|
72
|
+
return 1;
|
|
73
|
+
}
|
|
74
|
+
data = new Uint8Array(totalLength);
|
|
75
|
+
let offset = 0;
|
|
76
|
+
for (const chunk of chunks) {
|
|
77
|
+
data.set(chunk, offset);
|
|
78
|
+
offset += chunk.length;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
else {
|
|
82
|
+
const fullPath = path.resolve(shell.cwd, filePath);
|
|
83
|
+
const exists = await shell.context.fs.promises.exists(fullPath);
|
|
84
|
+
if (!exists) {
|
|
85
|
+
await writelnStderr(process, terminal, `xxd: ${filePath}: No such file or directory`);
|
|
86
|
+
return 1;
|
|
87
|
+
}
|
|
88
|
+
const stats = await shell.context.fs.promises.stat(fullPath);
|
|
89
|
+
if (stats.isDirectory()) {
|
|
90
|
+
await writelnStderr(process, terminal, `xxd: ${filePath}: Is a directory`);
|
|
91
|
+
return 1;
|
|
92
|
+
}
|
|
93
|
+
data = await shell.context.fs.promises.readFile(fullPath);
|
|
94
|
+
}
|
|
95
|
+
const bytesPerLine = 16;
|
|
96
|
+
for (let offset = 0; offset < data.length; offset += bytesPerLine) {
|
|
97
|
+
const lineBytes = data.slice(offset, offset + bytesPerLine);
|
|
98
|
+
const offsetHex = offset.toString(16).padStart(8, '0');
|
|
99
|
+
const hexGroups = [];
|
|
100
|
+
const asciiChars = [];
|
|
101
|
+
for (let i = 0; i < bytesPerLine; i++) {
|
|
102
|
+
if (i < lineBytes.length) {
|
|
103
|
+
const byte = lineBytes[i];
|
|
104
|
+
if (byte === undefined)
|
|
105
|
+
continue;
|
|
106
|
+
const hex = byte.toString(16).padStart(2, '0');
|
|
107
|
+
if (i % 2 === 0) {
|
|
108
|
+
hexGroups.push(hex);
|
|
109
|
+
}
|
|
110
|
+
else {
|
|
111
|
+
hexGroups[hexGroups.length - 1] += hex;
|
|
112
|
+
}
|
|
113
|
+
if (byte >= 32 && byte <= 126) {
|
|
114
|
+
asciiChars.push(String.fromCharCode(byte));
|
|
115
|
+
}
|
|
116
|
+
else {
|
|
117
|
+
asciiChars.push('.');
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
else {
|
|
121
|
+
if (i % 2 === 0) {
|
|
122
|
+
hexGroups.push(' ');
|
|
123
|
+
}
|
|
124
|
+
else {
|
|
125
|
+
hexGroups[hexGroups.length - 1] += ' ';
|
|
126
|
+
}
|
|
127
|
+
asciiChars.push(' ');
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
const hexString = hexGroups.join(' ').padEnd(47, ' ');
|
|
131
|
+
const asciiString = asciiChars.join('');
|
|
132
|
+
await writelnStdout(process, terminal, `${offsetHex}: ${hexString} ${asciiString}`);
|
|
133
|
+
}
|
|
134
|
+
return 0;
|
|
135
|
+
}
|
|
136
|
+
catch (error) {
|
|
137
|
+
const errorPath = filePath || 'stdin';
|
|
138
|
+
await writelnStderr(process, terminal, `xxd: ${errorPath}: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
|
139
|
+
return 1;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
//# sourceMappingURL=xxd.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"xxd.js","sourceRoot":"","sources":["../../src/commands/xxd.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -34,7 +34,7 @@ export { createCommand as createRmdir } from './commands/rmdir.js';
|
|
|
34
34
|
export { createCommand as createStat } from './commands/stat.js';
|
|
35
35
|
export { createCommand as createStrings } from './commands/strings.js';
|
|
36
36
|
export { createCommand as createTouch } from './commands/touch.js';
|
|
37
|
-
export { createCommand as
|
|
37
|
+
export { createCommand as createXxd } from './commands/xxd.js';
|
|
38
38
|
export { createCommand as createLess } from './commands/less.js';
|
|
39
39
|
export { createCommand as createMan } from './commands/man.js';
|
|
40
40
|
export { createCommand as createSed } from './commands/sed.js';
|
package/dist/index.js
CHANGED
|
@@ -37,7 +37,7 @@ import { createCommand as createRm } from './commands/rm.js';
|
|
|
37
37
|
import { createCommand as createRmdir } from './commands/rmdir.js';
|
|
38
38
|
import { createCommand as createStat } from './commands/stat.js';
|
|
39
39
|
import { createCommand as createTouch } from './commands/touch.js';
|
|
40
|
-
import { createCommand as
|
|
40
|
+
import { createCommand as createXxd } from './commands/xxd.js';
|
|
41
41
|
import { createCommand as createLess } from './commands/less.js';
|
|
42
42
|
import { createCommand as createMan } from './commands/man.js';
|
|
43
43
|
import { createCommand as createPasskey } from './commands/passkey.js';
|
|
@@ -125,7 +125,7 @@ export { createCommand as createRmdir } from './commands/rmdir.js';
|
|
|
125
125
|
export { createCommand as createStat } from './commands/stat.js';
|
|
126
126
|
export { createCommand as createStrings } from './commands/strings.js';
|
|
127
127
|
export { createCommand as createTouch } from './commands/touch.js';
|
|
128
|
-
export { createCommand as
|
|
128
|
+
export { createCommand as createXxd } from './commands/xxd.js';
|
|
129
129
|
export { createCommand as createLess } from './commands/less.js';
|
|
130
130
|
export { createCommand as createMan } from './commands/man.js';
|
|
131
131
|
export { createCommand as createSed } from './commands/sed.js';
|
|
@@ -208,7 +208,7 @@ export function createAllCommands(kernel, shell, terminal) {
|
|
|
208
208
|
stat: createStat(kernel, shell, terminal),
|
|
209
209
|
strings: createStrings(kernel, shell, terminal),
|
|
210
210
|
touch: createTouch(kernel, shell, terminal),
|
|
211
|
-
|
|
211
|
+
xxd: createXxd(kernel, shell, terminal),
|
|
212
212
|
less: createLess(kernel, shell, terminal),
|
|
213
213
|
man: createMan(kernel, shell, terminal),
|
|
214
214
|
passkey: createPasskey(kernel, shell, terminal),
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ecmaos/coreutils",
|
|
3
3
|
"description": "ecmaOS: Core utilities for the ecmaOS framework",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.5.0",
|
|
5
5
|
"license": "MIT+Apache-2.0",
|
|
6
6
|
"homepage": "https://ecmaos.sh",
|
|
7
7
|
"repository": "https://github.com/ecmaos/ecmaos",
|
|
@@ -40,7 +40,7 @@
|
|
|
40
40
|
"human-format": "^1.2.1",
|
|
41
41
|
"marked": "^17.0.1",
|
|
42
42
|
"modern-tar": "^0.7.3",
|
|
43
|
-
"@ecmaos/types": "^0.7.
|
|
43
|
+
"@ecmaos/types": "^0.7.2"
|
|
44
44
|
},
|
|
45
45
|
"devDependencies": {
|
|
46
46
|
"@types/ansi-escape-sequences": "^4.0.4",
|
package/src/commands/mount.ts
CHANGED
|
@@ -79,31 +79,31 @@ function printUsage(process: Process | undefined, terminal: Terminal): void {
|
|
|
79
79
|
Mount a filesystem.
|
|
80
80
|
|
|
81
81
|
Options:
|
|
82
|
-
-t, --type TYPE filesystem type
|
|
83
|
-
-o, --options OPTS
|
|
82
|
+
-t, --type TYPE filesystem type
|
|
83
|
+
-o, --options OPTS mount options (comma-separated key=value pairs)
|
|
84
84
|
-a, --all mount all filesystems listed in /etc/fstab
|
|
85
85
|
-l, --list list all mounted filesystems
|
|
86
86
|
--help display this help and exit
|
|
87
87
|
|
|
88
88
|
Filesystem types:
|
|
89
|
-
fetch
|
|
90
|
-
indexeddb
|
|
91
|
-
webstorage
|
|
92
|
-
webaccess
|
|
93
|
-
memory
|
|
94
|
-
singlebuffer
|
|
95
|
-
zip
|
|
96
|
-
iso
|
|
97
|
-
googledrive
|
|
89
|
+
fetch mount a remote filesystem via HTTP fetch
|
|
90
|
+
indexeddb mount an IndexedDB-backed filesystem
|
|
91
|
+
webstorage mount a WebStorage-backed filesystem (localStorage or sessionStorage)
|
|
92
|
+
webaccess mount a filesystem using the File System Access API
|
|
93
|
+
memory mount an in-memory filesystem
|
|
94
|
+
singlebuffer mount a filesystem backed by a single buffer
|
|
95
|
+
zip mount a readonly filesystem from a zip archive (requires SOURCE file or URL)
|
|
96
|
+
iso mount a readonly filesystem from an ISO image (requires SOURCE file or URL)
|
|
97
|
+
googledrive mount a Google Drive filesystem (requires apiKey via -o apiKey, optionally clientId for OAuth)
|
|
98
98
|
|
|
99
99
|
Mount options:
|
|
100
|
-
baseUrl=URL
|
|
101
|
-
size=BYTES
|
|
102
|
-
storage=TYPE
|
|
103
|
-
apiKey=KEY
|
|
104
|
-
clientId=ID
|
|
105
|
-
scope=SCOPE
|
|
106
|
-
cacheTTL=SECONDS
|
|
100
|
+
baseUrl=URL base URL for fetch operations (fetch type)
|
|
101
|
+
size=BYTES buffer size in bytes for singlebuffer type (default: 1048576)
|
|
102
|
+
storage=TYPE storage type for webstorage (localStorage or sessionStorage, default: localStorage)
|
|
103
|
+
apiKey=KEY Google API key (googledrive type, required)
|
|
104
|
+
clientId=ID Google OAuth client ID (googledrive type, optional)
|
|
105
|
+
scope=SCOPE OAuth scope (googledrive type, default: https://www.googleapis.com/auth/drive)
|
|
106
|
+
cacheTTL=SECONDS cache TTL in seconds for cloud backends (optional)
|
|
107
107
|
|
|
108
108
|
Examples:
|
|
109
109
|
mount -l list all mounted filesystems
|
|
@@ -4,7 +4,7 @@ import { TerminalCommand } from '../shared/terminal-command.js'
|
|
|
4
4
|
import { writelnStdout, writelnStderr } from '../shared/helpers.js'
|
|
5
5
|
|
|
6
6
|
function printUsage(process: Process | undefined, terminal: Terminal): void {
|
|
7
|
-
const usage = `Usage:
|
|
7
|
+
const usage = `Usage: xxd [FILE]
|
|
8
8
|
Display file contents or stdin in hexadecimal format.
|
|
9
9
|
|
|
10
10
|
FILE the file to display (if omitted, reads from stdin)
|
|
@@ -14,7 +14,7 @@ Display file contents or stdin in hexadecimal format.
|
|
|
14
14
|
|
|
15
15
|
export function createCommand(kernel: Kernel, shell: Shell, terminal: Terminal): TerminalCommand {
|
|
16
16
|
return new TerminalCommand({
|
|
17
|
-
command: '
|
|
17
|
+
command: 'xxd',
|
|
18
18
|
description: 'Display file contents or stdin in hexadecimal format',
|
|
19
19
|
kernel,
|
|
20
20
|
shell,
|
|
@@ -36,14 +36,14 @@ export function createCommand(kernel: Kernel, shell: Shell, terminal: Terminal):
|
|
|
36
36
|
try {
|
|
37
37
|
if (!filePath) {
|
|
38
38
|
if (!process.stdin) {
|
|
39
|
-
await writelnStderr(process, terminal, 'Usage:
|
|
40
|
-
await writelnStderr(process, terminal, ' or: <command> |
|
|
39
|
+
await writelnStderr(process, terminal, 'Usage: xxd <file>')
|
|
40
|
+
await writelnStderr(process, terminal, ' or: <command> | xxd')
|
|
41
41
|
return 1
|
|
42
42
|
}
|
|
43
43
|
|
|
44
44
|
if (process.stdinIsTTY) {
|
|
45
|
-
await writelnStderr(process, terminal, 'Usage:
|
|
46
|
-
await writelnStderr(process, terminal, ' or: <command> |
|
|
45
|
+
await writelnStderr(process, terminal, 'Usage: xxd <file>')
|
|
46
|
+
await writelnStderr(process, terminal, ' or: <command> | xxd')
|
|
47
47
|
return 1
|
|
48
48
|
}
|
|
49
49
|
|
|
@@ -54,8 +54,8 @@ export function createCommand(kernel: Kernel, shell: Shell, terminal: Terminal):
|
|
|
54
54
|
const first = await reader.read()
|
|
55
55
|
|
|
56
56
|
if (first.done && !first.value) {
|
|
57
|
-
await writelnStderr(process, terminal, 'Usage:
|
|
58
|
-
await writelnStderr(process, terminal, ' or: <command> |
|
|
57
|
+
await writelnStderr(process, terminal, 'Usage: xxd <file>')
|
|
58
|
+
await writelnStderr(process, terminal, ' or: <command> | xxd')
|
|
59
59
|
return 1
|
|
60
60
|
}
|
|
61
61
|
|
|
@@ -78,8 +78,8 @@ export function createCommand(kernel: Kernel, shell: Shell, terminal: Terminal):
|
|
|
78
78
|
|
|
79
79
|
const totalLength = chunks.reduce((sum, chunk) => sum + chunk.length, 0)
|
|
80
80
|
if (totalLength === 0) {
|
|
81
|
-
await writelnStderr(process, terminal, 'Usage:
|
|
82
|
-
await writelnStderr(process, terminal, ' or: <command> |
|
|
81
|
+
await writelnStderr(process, terminal, 'Usage: xxd <file>')
|
|
82
|
+
await writelnStderr(process, terminal, ' or: <command> | xxd')
|
|
83
83
|
return 1
|
|
84
84
|
}
|
|
85
85
|
|
|
@@ -94,13 +94,13 @@ export function createCommand(kernel: Kernel, shell: Shell, terminal: Terminal):
|
|
|
94
94
|
|
|
95
95
|
const exists = await shell.context.fs.promises.exists(fullPath)
|
|
96
96
|
if (!exists) {
|
|
97
|
-
await writelnStderr(process, terminal, `
|
|
97
|
+
await writelnStderr(process, terminal, `xxd: ${filePath}: No such file or directory`)
|
|
98
98
|
return 1
|
|
99
99
|
}
|
|
100
100
|
|
|
101
101
|
const stats = await shell.context.fs.promises.stat(fullPath)
|
|
102
102
|
if (stats.isDirectory()) {
|
|
103
|
-
await writelnStderr(process, terminal, `
|
|
103
|
+
await writelnStderr(process, terminal, `xxd: ${filePath}: Is a directory`)
|
|
104
104
|
return 1
|
|
105
105
|
}
|
|
106
106
|
|
|
@@ -152,7 +152,7 @@ export function createCommand(kernel: Kernel, shell: Shell, terminal: Terminal):
|
|
|
152
152
|
return 0
|
|
153
153
|
} catch (error) {
|
|
154
154
|
const errorPath = filePath || 'stdin'
|
|
155
|
-
await writelnStderr(process, terminal, `
|
|
155
|
+
await writelnStderr(process, terminal, `xxd: ${errorPath}: ${error instanceof Error ? error.message : 'Unknown error'}`)
|
|
156
156
|
return 1
|
|
157
157
|
}
|
|
158
158
|
}
|
package/src/index.ts
CHANGED
|
@@ -42,7 +42,7 @@ import { createCommand as createRm } from './commands/rm.js'
|
|
|
42
42
|
import { createCommand as createRmdir } from './commands/rmdir.js'
|
|
43
43
|
import { createCommand as createStat } from './commands/stat.js'
|
|
44
44
|
import { createCommand as createTouch } from './commands/touch.js'
|
|
45
|
-
import { createCommand as
|
|
45
|
+
import { createCommand as createXxd } from './commands/xxd.js'
|
|
46
46
|
import { createCommand as createLess } from './commands/less.js'
|
|
47
47
|
import { createCommand as createMan } from './commands/man.js'
|
|
48
48
|
import { createCommand as createPasskey } from './commands/passkey.js'
|
|
@@ -131,7 +131,7 @@ export { createCommand as createRmdir } from './commands/rmdir.js'
|
|
|
131
131
|
export { createCommand as createStat } from './commands/stat.js'
|
|
132
132
|
export { createCommand as createStrings } from './commands/strings.js'
|
|
133
133
|
export { createCommand as createTouch } from './commands/touch.js'
|
|
134
|
-
export { createCommand as
|
|
134
|
+
export { createCommand as createXxd } from './commands/xxd.js'
|
|
135
135
|
export { createCommand as createLess } from './commands/less.js'
|
|
136
136
|
export { createCommand as createMan } from './commands/man.js'
|
|
137
137
|
export { createCommand as createSed } from './commands/sed.js'
|
|
@@ -215,7 +215,7 @@ export function createAllCommands(kernel: Kernel, shell: Shell, terminal: Termin
|
|
|
215
215
|
stat: createStat(kernel, shell, terminal),
|
|
216
216
|
strings: createStrings(kernel, shell, terminal),
|
|
217
217
|
touch: createTouch(kernel, shell, terminal),
|
|
218
|
-
|
|
218
|
+
xxd: createXxd(kernel, shell, terminal),
|
|
219
219
|
less: createLess(kernel, shell, terminal),
|
|
220
220
|
man: createMan(kernel, shell, terminal),
|
|
221
221
|
passkey: createPasskey(kernel, shell, terminal),
|