fauxnix-cli 0.2.1 → 0.4.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/README.md +203 -199
- package/dist/ast.d.ts +9 -2
- package/dist/ast.js +12 -2
- package/dist/cli.js +13 -13
- package/dist/commands/archive.js +5 -5
- package/dist/commands/files.js +28 -39
- package/dist/commands/net.js +8 -5
- package/dist/commands/sysinfo.js +1317 -53
- package/dist/commands/text-filters.js +2 -4
- package/dist/commands/text-io.js +22 -24
- package/dist/encoding.d.ts +9 -0
- package/dist/encoding.js +19 -0
- package/dist/executor.js +230 -108
- package/dist/mcp.js +1 -1
- package/dist/parser.d.ts +2 -0
- package/dist/parser.js +425 -16
- package/dist/registry.js +10 -0
- package/dist/translator.d.ts +39 -5
- package/dist/translator.js +547 -31
- package/package.json +1 -1
package/dist/commands/files.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { wordToString } from '../ast.js';
|
|
2
2
|
import { parseWords, psStr } from '../registry.js';
|
|
3
|
-
import { exprOfWord, operandExpr } from '../translator.js';
|
|
3
|
+
import { argListExpr, exprOfWord, operandExpr } from '../translator.js';
|
|
4
4
|
/* ------------------------------------------------------------------ */
|
|
5
5
|
/* Shared PS snippets */
|
|
6
6
|
/* ------------------------------------------------------------------ */
|
|
@@ -45,9 +45,7 @@ const PS_HSIZE_FN = [
|
|
|
45
45
|
].join('\n');
|
|
46
46
|
/** Operand Words → PS array expression of string exprs. */
|
|
47
47
|
function psArray(words, fn = operandExpr) {
|
|
48
|
-
|
|
49
|
-
return '@()';
|
|
50
|
-
return '@(' + words.map(fn).join(', ') + ')';
|
|
48
|
+
return argListExpr(words, fn);
|
|
51
49
|
}
|
|
52
50
|
/* ------------------------------------------------------------------ */
|
|
53
51
|
/* ls */
|
|
@@ -63,7 +61,7 @@ const ls = (args) => {
|
|
|
63
61
|
const sortByTime = flags.has('t');
|
|
64
62
|
const sortBySize = flags.has('S');
|
|
65
63
|
const reverse = flags.has('r');
|
|
66
|
-
const targets = operandWords.length ? operandWords
|
|
64
|
+
const targets = operandWords.length ? argListExpr(operandWords) : "@('.')";
|
|
67
65
|
return [
|
|
68
66
|
PS_GLOB_FN,
|
|
69
67
|
PS_FTIME_FN,
|
|
@@ -84,7 +82,7 @@ const ls = (args) => {
|
|
|
84
82
|
' }',
|
|
85
83
|
' return $n',
|
|
86
84
|
'}',
|
|
87
|
-
'$fx_targets =
|
|
85
|
+
'$fx_targets = ' + targets,
|
|
88
86
|
'$fx_all = @()',
|
|
89
87
|
'foreach ($fx_t in $fx_targets) {',
|
|
90
88
|
' foreach ($fx_g in (fx-glob $fx_t)) {',
|
|
@@ -126,12 +124,10 @@ const cp = (args) => {
|
|
|
126
124
|
const { flags, longs, operandWords } = parseWords(args);
|
|
127
125
|
const recurse = flags.has('r') || flags.has('R') || longs.has('--recursive');
|
|
128
126
|
const verbose = flags.has('v') || longs.has('--verbose');
|
|
129
|
-
const srcs = psArray(operandWords.slice(0, -1));
|
|
130
|
-
const dst = operandWords.length >= 2 ? operandExpr(operandWords[operandWords.length - 1]) : "''";
|
|
131
127
|
return [
|
|
132
128
|
PS_GLOB_FN,
|
|
133
|
-
'$
|
|
134
|
-
|
|
129
|
+
'$fx_all = ' + argListExpr(operandWords),
|
|
130
|
+
"if ($fx_all.Count -lt 2) { $fx_srcs = @(); $fx_dst = '' } else { $fx_dst = [string]$fx_all[$fx_all.Count - 1]; $fx_srcs = @($fx_all[0..($fx_all.Count - 2)]) }",
|
|
135
131
|
"if ($fx_srcs.Count -eq 0) { [Console]::Error.WriteLine('cp: missing file operand'); $script:fx_exit = 1 }",
|
|
136
132
|
"elseif ($fx_dst -eq '') { [Console]::Error.WriteLine('cp: missing destination file operand'); $script:fx_exit = 1 }",
|
|
137
133
|
'else {',
|
|
@@ -154,12 +150,10 @@ const cp = (args) => {
|
|
|
154
150
|
const mv = (args) => {
|
|
155
151
|
const { flags, longs, operandWords } = parseWords(args);
|
|
156
152
|
const verbose = flags.has('v') || longs.has('--verbose');
|
|
157
|
-
const srcs = psArray(operandWords.slice(0, -1));
|
|
158
|
-
const dst = operandWords.length >= 2 ? operandExpr(operandWords[operandWords.length - 1]) : "''";
|
|
159
153
|
return [
|
|
160
154
|
PS_GLOB_FN,
|
|
161
|
-
'$
|
|
162
|
-
|
|
155
|
+
'$fx_all = ' + argListExpr(operandWords),
|
|
156
|
+
"if ($fx_all.Count -lt 2) { $fx_srcs = @(); $fx_dst = '' } else { $fx_dst = [string]$fx_all[$fx_all.Count - 1]; $fx_srcs = @($fx_all[0..($fx_all.Count - 2)]) }",
|
|
163
157
|
"if ($fx_srcs.Count -eq 0) { [Console]::Error.WriteLine('mv: missing file operand'); $script:fx_exit = 1 }",
|
|
164
158
|
"elseif ($fx_dst -eq '') { [Console]::Error.WriteLine('mv: missing destination file operand'); $script:fx_exit = 1 }",
|
|
165
159
|
'elseif ($fx_srcs.Count -gt 1 -and -not (Test-Path -LiteralPath $fx_dst -PathType Container)) { [Console]::Error.WriteLine("mv: target \'" + $fx_dst + "\' is not a directory"); $script:fx_exit = 1 }',
|
|
@@ -274,13 +268,11 @@ const mktemp = (args) => {
|
|
|
274
268
|
const ln = (args) => {
|
|
275
269
|
const { flags, operandWords } = parseWords(args);
|
|
276
270
|
const sym = flags.has('s');
|
|
277
|
-
const src = operandWords.length >= 2 ? operandExpr(operandWords[0]) : "''";
|
|
278
|
-
const dst = operandWords.length >= 2 ? operandExpr(operandWords[1]) : "''";
|
|
279
271
|
const kind = sym ? 'SymbolicLink' : 'HardLink';
|
|
280
272
|
const label = sym ? 'symbolic link' : 'hard link';
|
|
281
273
|
return [
|
|
282
|
-
'$
|
|
283
|
-
'$fx_dst = '
|
|
274
|
+
'$fx_ops = ' + argListExpr(operandWords),
|
|
275
|
+
"if ($fx_ops.Count -lt 2) { $fx_src = ''; $fx_dst = '' } else { $fx_src = [string]$fx_ops[0]; $fx_dst = [string]$fx_ops[1] }",
|
|
284
276
|
"if ($fx_src -eq '' -or $fx_dst -eq '') { [Console]::Error.WriteLine('ln: missing file operand'); $script:fx_exit = 1 }",
|
|
285
277
|
'else {',
|
|
286
278
|
' if (Test-Path -LiteralPath $fx_dst -PathType Container) { $fx_dst = Join-Path $fx_dst (Split-Path $fx_src -Leaf) }',
|
|
@@ -321,29 +313,28 @@ const realpath = (args) => {
|
|
|
321
313
|
/* basename / dirname */
|
|
322
314
|
/* ------------------------------------------------------------------ */
|
|
323
315
|
const basename = (args) => {
|
|
324
|
-
if (args.length === 2) {
|
|
325
|
-
return [
|
|
326
|
-
'$fx_p = ' + exprOfWord(args[0]),
|
|
327
|
-
'$fx_sfx = ' + exprOfWord(args[1]),
|
|
328
|
-
"$fx_n = [IO.Path]::GetFileName(($fx_p.TrimEnd('/')).TrimEnd('\\'))",
|
|
329
|
-
"if ($fx_n -eq '') { $fx_n = '/' }",
|
|
330
|
-
"if ($fx_sfx -ne '' -and $fx_n.EndsWith($fx_sfx) -and ($fx_n.Length -gt $fx_sfx.Length)) { $fx_n = $fx_n.Substring(0, $fx_n.Length - $fx_sfx.Length) }",
|
|
331
|
-
'$fx_n',
|
|
332
|
-
].join('\n');
|
|
333
|
-
}
|
|
334
316
|
return [
|
|
335
|
-
'$fx_ps =
|
|
317
|
+
'$fx_ps = ' + argListExpr(args, exprOfWord),
|
|
336
318
|
"if ($fx_ps.Count -eq 0) { [Console]::Error.WriteLine('basename: missing operand'); $script:fx_exit = 1 }",
|
|
337
|
-
'
|
|
319
|
+
'elseif ($fx_ps.Count -eq 2) {',
|
|
320
|
+
' $fx_p = [string]$fx_ps[0]',
|
|
321
|
+
' $fx_sfx = [string]$fx_ps[1]',
|
|
338
322
|
" $fx_n = [IO.Path]::GetFileName(($fx_p.TrimEnd('/')).TrimEnd('\\'))",
|
|
339
323
|
" if ($fx_n -eq '') { $fx_n = '/' }",
|
|
324
|
+
" if ($fx_sfx -ne '' -and $fx_n.EndsWith($fx_sfx) -and ($fx_n.Length -gt $fx_sfx.Length)) { $fx_n = $fx_n.Substring(0, $fx_n.Length - $fx_sfx.Length) }",
|
|
340
325
|
' $fx_n',
|
|
326
|
+
'} else {',
|
|
327
|
+
' foreach ($fx_p in $fx_ps) {',
|
|
328
|
+
" $fx_n = [IO.Path]::GetFileName(($fx_p.TrimEnd('/')).TrimEnd('\\'))",
|
|
329
|
+
" if ($fx_n -eq '') { $fx_n = '/' }",
|
|
330
|
+
' $fx_n',
|
|
331
|
+
' }',
|
|
341
332
|
'}',
|
|
342
333
|
].join('\n');
|
|
343
334
|
};
|
|
344
335
|
const dirname = (args) => {
|
|
345
336
|
return [
|
|
346
|
-
'$fx_ps =
|
|
337
|
+
'$fx_ps = ' + argListExpr(args, exprOfWord),
|
|
347
338
|
"if ($fx_ps.Count -eq 0) { [Console]::Error.WriteLine('dirname: missing operand'); $script:fx_exit = 1 }",
|
|
348
339
|
'foreach ($fx_p in $fx_ps) {',
|
|
349
340
|
" $fx_n = ($fx_p.TrimEnd('/')).TrimEnd('\\')",
|
|
@@ -428,7 +419,7 @@ const du = (args) => {
|
|
|
428
419
|
const { flags, longs, operandWords } = parseWords(args, [], ['--max-depth']);
|
|
429
420
|
const sum = flags.has('s') || longs.has('--summarize');
|
|
430
421
|
const human = flags.has('h') || longs.has('--human-readable');
|
|
431
|
-
const targets = operandWords.length ? operandWords
|
|
422
|
+
const targets = operandWords.length ? argListExpr(operandWords) : "@('.')";
|
|
432
423
|
return [
|
|
433
424
|
PS_HSIZE_FN,
|
|
434
425
|
'function fx-size($p) {',
|
|
@@ -436,7 +427,7 @@ const du = (args) => {
|
|
|
436
427
|
' Get-ChildItem -LiteralPath $p -Recurse -Force -File -ErrorAction SilentlyContinue | ForEach-Object { $t += $_.Length }',
|
|
437
428
|
' return [math]::Ceiling($t / 1KB)',
|
|
438
429
|
'}',
|
|
439
|
-
'$fx_ts =
|
|
430
|
+
'$fx_ts = ' + targets,
|
|
440
431
|
'foreach ($fx_t in $fx_ts) {',
|
|
441
432
|
' if (-not (Test-Path -LiteralPath $fx_t)) { [Console]::Error.WriteLine("du: cannot access \'" + $fx_t + "\': No such file or directory"); $script:fx_exit = 1; continue }',
|
|
442
433
|
' if (' + (sum ? '$true' : '$false') + ') {',
|
|
@@ -500,7 +491,7 @@ const find = (args) => {
|
|
|
500
491
|
const sizeExpr = extractValue(preds, ['-size']);
|
|
501
492
|
const mtimeExpr = extractValue(preds, ['-mtime']);
|
|
502
493
|
const wantDelete = preds.includes('-delete');
|
|
503
|
-
const paths = pathWords.length ? pathWords
|
|
494
|
+
const paths = pathWords.length ? argListExpr(pathWords) : "@('.')";
|
|
504
495
|
const conditions = [];
|
|
505
496
|
if (namePat !== null)
|
|
506
497
|
conditions.push("($fx_i.Name -like '" + likeOf(namePat) + "')");
|
|
@@ -516,7 +507,7 @@ const find = (args) => {
|
|
|
516
507
|
const sizeCond = sizeOf(sizeExpr);
|
|
517
508
|
const mtimeCond = mtimeOf(mtimeExpr);
|
|
518
509
|
return [
|
|
519
|
-
'$fx_paths =
|
|
510
|
+
'$fx_paths = ' + paths,
|
|
520
511
|
'foreach ($fx_p in $fx_paths) {',
|
|
521
512
|
' if (-not (Test-Path -LiteralPath $fx_p)) { [Console]::Error.WriteLine("find: \'" + $fx_p + "\': No such file or directory"); $script:fx_exit = 1; continue }',
|
|
522
513
|
' $fx_root = (Get-Item -LiteralPath $fx_p -Force).FullName',
|
|
@@ -632,13 +623,11 @@ const diff = (args) => {
|
|
|
632
623
|
const unified = flags.has('u') || flags.has('U');
|
|
633
624
|
const brief = flags.has('q') || flags.has('brief');
|
|
634
625
|
void unified;
|
|
635
|
-
const a = operandWords.length > 0 ? operandExpr(operandWords[0]) : "''";
|
|
636
|
-
const b = operandWords.length > 1 ? operandExpr(operandWords[1]) : "''";
|
|
637
626
|
return [
|
|
638
627
|
PS_READTEXT_FN,
|
|
639
628
|
'function fx-dr($x, $y) { if ($x -eq $y) { return [string]$x } else { return ([string]$x) + \',\' + ([string]$y) } }',
|
|
640
|
-
'$
|
|
641
|
-
'$fx_b = '
|
|
629
|
+
'$fx_ops = ' + argListExpr(operandWords),
|
|
630
|
+
"if ($fx_ops.Count -lt 2) { $fx_a = ''; $fx_b = '' } else { $fx_a = [string]$fx_ops[0]; $fx_b = [string]$fx_ops[1] }",
|
|
642
631
|
"if ($fx_a -eq '' -or $fx_b -eq '') { [Console]::Error.WriteLine('diff: missing operand'); $script:fx_exit = 2 }",
|
|
643
632
|
'elseif (-not (Test-Path -LiteralPath $fx_a)) { [Console]::Error.WriteLine("diff: " + $fx_a + ": No such file or directory"); $script:fx_exit = 2 }',
|
|
644
633
|
'elseif (-not (Test-Path -LiteralPath $fx_b)) { [Console]::Error.WriteLine("diff: " + $fx_b + ": No such file or directory"); $script:fx_exit = 2 }',
|
package/dist/commands/net.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { wordToString } from '../ast.js';
|
|
2
2
|
import { parseWords, psErr, psStr } from '../registry.js';
|
|
3
|
-
import { exprOfWord, literalOfWord, operandExpr } from '../translator.js';
|
|
3
|
+
import { argListExpr, exprOfWord, literalOfWord, operandExpr } from '../translator.js';
|
|
4
4
|
/* ------------------------------------------------------------------ */
|
|
5
5
|
/* Shared PS snippets */
|
|
6
6
|
/* ------------------------------------------------------------------ */
|
|
@@ -94,7 +94,7 @@ const curl = (args) => {
|
|
|
94
94
|
// refuses private/loopback URLs before the process is even started.
|
|
95
95
|
return [
|
|
96
96
|
PS_NETGUARD_FNS,
|
|
97
|
-
|
|
97
|
+
'$fx_args = ' + argListExpr(args, exprOfWord),
|
|
98
98
|
'$fx_bad = $false',
|
|
99
99
|
"foreach ($fx_a in $fx_args) { if (fx-netguard 'curl' $fx_a) { $fx_bad = $true } }",
|
|
100
100
|
'if ($fx_bad) { $script:fx_exit = 1 }',
|
|
@@ -212,11 +212,11 @@ function mapWgetArgs(args) {
|
|
|
212
212
|
return { margs, sawOutput, urls };
|
|
213
213
|
}
|
|
214
214
|
const wget = (args) => {
|
|
215
|
-
const orig = args.map(exprOfWord);
|
|
215
|
+
const orig = args.map((w) => exprOfWord(w));
|
|
216
216
|
const mapped = mapWgetArgs(args);
|
|
217
217
|
return [
|
|
218
218
|
PS_NETGUARD_FNS,
|
|
219
|
-
'$fx_args =
|
|
219
|
+
'$fx_args = ' + argListExpr(args, exprOfWord),
|
|
220
220
|
'$fx_margs = @(' + mapped.margs.join(', ') + ')',
|
|
221
221
|
'$fx_bad = $false',
|
|
222
222
|
"foreach ($fx_a in $fx_args) { if (fx-netguard 'wget' $fx_a) { $fx_bad = $true } }",
|
|
@@ -456,7 +456,10 @@ const ifconfig = (args) => {
|
|
|
456
456
|
/* ------------------------------------------------------------------ */
|
|
457
457
|
/* nslookup / dig / host */
|
|
458
458
|
/* ------------------------------------------------------------------ */
|
|
459
|
-
const nslookup = (args) =>
|
|
459
|
+
const nslookup = (args) => [
|
|
460
|
+
'$fx_args = ' + argListExpr(args, exprOfWord),
|
|
461
|
+
nativeCall('nslookup.exe', '$fx_args'),
|
|
462
|
+
].join('\n');
|
|
460
463
|
const dig = (args) => {
|
|
461
464
|
const raw = args.map(wordToString);
|
|
462
465
|
let short = false;
|