shell-dsl 0.0.6 → 0.0.8
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 +3 -1
- package/dist/cjs/index.cjs +14 -4
- package/dist/cjs/index.cjs.map +3 -3
- package/dist/cjs/package.json +1 -1
- package/dist/cjs/src/commands/awk/awk.cjs +276 -0
- package/dist/cjs/src/commands/awk/awk.cjs.map +10 -0
- package/dist/cjs/src/commands/break-continue/break-continue.cjs +56 -0
- package/dist/cjs/src/commands/break-continue/break-continue.cjs.map +10 -0
- package/dist/cjs/src/commands/cat/cat.cjs +57 -0
- package/dist/cjs/src/commands/cat/cat.cjs.map +10 -0
- package/dist/cjs/src/commands/cp/cp.cjs +126 -0
- package/dist/cjs/src/commands/cp/cp.cjs.map +10 -0
- package/dist/cjs/src/commands/echo/echo.cjs +50 -0
- package/dist/cjs/src/commands/echo/echo.cjs.map +10 -0
- package/dist/cjs/src/commands/find/find.cjs +251 -0
- package/dist/cjs/src/commands/find/find.cjs.map +10 -0
- package/dist/cjs/src/commands/grep/grep.cjs +510 -0
- package/dist/cjs/src/commands/grep/grep.cjs.map +10 -0
- package/dist/cjs/src/commands/head/head.cjs +95 -0
- package/dist/cjs/src/commands/head/head.cjs.map +10 -0
- package/dist/cjs/src/commands/index.cjs +136 -0
- package/dist/cjs/src/commands/index.cjs.map +10 -0
- package/dist/cjs/src/commands/ls/ls.cjs +119 -0
- package/dist/cjs/src/commands/ls/ls.cjs.map +10 -0
- package/dist/cjs/src/commands/mkdir/mkdir.cjs +64 -0
- package/dist/cjs/src/commands/mkdir/mkdir.cjs.map +10 -0
- package/dist/cjs/src/commands/mv/mv.cjs +118 -0
- package/dist/cjs/src/commands/mv/mv.cjs.map +10 -0
- package/dist/cjs/src/commands/pwd/pwd.cjs +41 -0
- package/dist/cjs/src/commands/pwd/pwd.cjs.map +10 -0
- package/dist/cjs/src/commands/rm/rm.cjs +82 -0
- package/dist/cjs/src/commands/rm/rm.cjs.map +10 -0
- package/dist/cjs/src/commands/sed/sed.cjs +218 -0
- package/dist/cjs/src/commands/sed/sed.cjs.map +10 -0
- package/dist/cjs/src/commands/sort/sort.cjs +105 -0
- package/dist/cjs/src/commands/sort/sort.cjs.map +10 -0
- package/dist/cjs/src/commands/tail/tail.cjs +95 -0
- package/dist/cjs/src/commands/tail/tail.cjs.map +10 -0
- package/dist/cjs/src/commands/tee/tee.cjs +65 -0
- package/dist/cjs/src/commands/tee/tee.cjs.map +10 -0
- package/dist/cjs/src/commands/test/test.cjs +148 -0
- package/dist/cjs/src/commands/test/test.cjs.map +10 -0
- package/dist/cjs/src/commands/touch/touch.cjs +70 -0
- package/dist/cjs/src/commands/touch/touch.cjs.map +10 -0
- package/dist/cjs/src/commands/tree/tree.cjs +161 -0
- package/dist/cjs/src/commands/tree/tree.cjs.map +10 -0
- package/dist/cjs/src/commands/true-false/true-false.cjs +43 -0
- package/dist/cjs/src/commands/true-false/true-false.cjs.map +10 -0
- package/dist/cjs/src/commands/uniq/uniq.cjs +116 -0
- package/dist/cjs/src/commands/uniq/uniq.cjs.map +10 -0
- package/dist/cjs/src/commands/wc/wc.cjs +116 -0
- package/dist/cjs/src/commands/wc/wc.cjs.map +10 -0
- package/dist/cjs/src/index.cjs +10 -2
- package/dist/cjs/src/index.cjs.map +3 -3
- package/dist/cjs/src/interpreter/index.cjs +4 -2
- package/dist/cjs/src/interpreter/index.cjs.map +3 -3
- package/dist/cjs/src/interpreter/interpreter.cjs +390 -2
- package/dist/cjs/src/interpreter/interpreter.cjs.map +3 -3
- package/dist/cjs/src/lexer/index.cjs +3 -2
- package/dist/cjs/src/lexer/index.cjs.map +3 -3
- package/dist/cjs/src/lexer/lexer.cjs +359 -8
- package/dist/cjs/src/lexer/lexer.cjs.map +3 -3
- package/dist/cjs/src/lexer/tokens.cjs +35 -2
- package/dist/cjs/src/lexer/tokens.cjs.map +3 -3
- package/dist/cjs/src/parser/ast.cjs +25 -1
- package/dist/cjs/src/parser/ast.cjs.map +3 -3
- package/dist/cjs/src/parser/index.cjs +7 -1
- package/dist/cjs/src/parser/index.cjs.map +3 -3
- package/dist/cjs/src/parser/parser.cjs +280 -8
- package/dist/cjs/src/parser/parser.cjs.map +3 -3
- package/dist/cjs/src/shell-dsl.cjs +2 -2
- package/dist/cjs/src/shell-dsl.cjs.map +3 -3
- package/dist/mjs/index.mjs +25 -5
- package/dist/mjs/index.mjs.map +3 -3
- package/dist/mjs/package.json +1 -1
- package/dist/mjs/src/commands/awk/awk.mjs +246 -0
- package/dist/mjs/src/commands/awk/awk.mjs.map +10 -0
- package/dist/mjs/src/commands/break-continue/break-continue.mjs +26 -0
- package/dist/mjs/src/commands/break-continue/break-continue.mjs.map +10 -0
- package/dist/mjs/src/commands/cat/cat.mjs +27 -0
- package/dist/mjs/src/commands/cat/cat.mjs.map +10 -0
- package/dist/mjs/src/commands/cp/cp.mjs +96 -0
- package/dist/mjs/src/commands/cp/cp.mjs.map +10 -0
- package/dist/mjs/src/commands/echo/echo.mjs +20 -0
- package/dist/mjs/src/commands/echo/echo.mjs.map +10 -0
- package/dist/mjs/src/commands/find/find.mjs +221 -0
- package/dist/mjs/src/commands/find/find.mjs.map +10 -0
- package/dist/mjs/src/commands/grep/grep.mjs +480 -0
- package/dist/mjs/src/commands/grep/grep.mjs.map +10 -0
- package/dist/mjs/src/commands/head/head.mjs +65 -0
- package/dist/mjs/src/commands/head/head.mjs.map +10 -0
- package/dist/mjs/src/commands/index.mjs +106 -0
- package/dist/mjs/src/commands/index.mjs.map +10 -0
- package/dist/mjs/src/commands/ls/ls.mjs +89 -0
- package/dist/mjs/src/commands/ls/ls.mjs.map +10 -0
- package/dist/mjs/src/commands/mkdir/mkdir.mjs +34 -0
- package/dist/mjs/src/commands/mkdir/mkdir.mjs.map +10 -0
- package/dist/mjs/src/commands/mv/mv.mjs +88 -0
- package/dist/mjs/src/commands/mv/mv.mjs.map +10 -0
- package/dist/mjs/src/commands/pwd/pwd.mjs +11 -0
- package/dist/mjs/src/commands/pwd/pwd.mjs.map +10 -0
- package/dist/mjs/src/commands/rm/rm.mjs +52 -0
- package/dist/mjs/src/commands/rm/rm.mjs.map +10 -0
- package/dist/mjs/src/commands/sed/sed.mjs +188 -0
- package/dist/mjs/src/commands/sed/sed.mjs.map +10 -0
- package/dist/mjs/src/commands/sort/sort.mjs +75 -0
- package/dist/mjs/src/commands/sort/sort.mjs.map +10 -0
- package/dist/mjs/src/commands/tail/tail.mjs +65 -0
- package/dist/mjs/src/commands/tail/tail.mjs.map +10 -0
- package/dist/mjs/src/commands/tee/tee.mjs +35 -0
- package/dist/mjs/src/commands/tee/tee.mjs.map +10 -0
- package/dist/mjs/src/commands/test/test.mjs +118 -0
- package/dist/mjs/src/commands/test/test.mjs.map +10 -0
- package/dist/mjs/src/commands/touch/touch.mjs +40 -0
- package/dist/mjs/src/commands/touch/touch.mjs.map +10 -0
- package/dist/mjs/src/commands/tree/tree.mjs +131 -0
- package/dist/mjs/src/commands/tree/tree.mjs.map +10 -0
- package/dist/mjs/src/commands/true-false/true-false.mjs +13 -0
- package/dist/mjs/src/commands/true-false/true-false.mjs.map +10 -0
- package/dist/mjs/src/commands/uniq/uniq.mjs +86 -0
- package/dist/mjs/src/commands/uniq/uniq.mjs.map +10 -0
- package/dist/mjs/src/commands/wc/wc.mjs +86 -0
- package/dist/mjs/src/commands/wc/wc.mjs.map +10 -0
- package/dist/mjs/src/index.mjs +18 -4
- package/dist/mjs/src/index.mjs.map +3 -3
- package/dist/mjs/src/interpreter/index.mjs +5 -3
- package/dist/mjs/src/interpreter/index.mjs.map +2 -2
- package/dist/mjs/src/interpreter/interpreter.mjs +390 -2
- package/dist/mjs/src/interpreter/interpreter.mjs.map +3 -3
- package/dist/mjs/src/lexer/index.mjs +4 -3
- package/dist/mjs/src/lexer/index.mjs.map +2 -2
- package/dist/mjs/src/lexer/lexer.mjs +359 -8
- package/dist/mjs/src/lexer/lexer.mjs.map +3 -3
- package/dist/mjs/src/lexer/tokens.mjs +35 -2
- package/dist/mjs/src/lexer/tokens.mjs.map +3 -3
- package/dist/mjs/src/parser/ast.mjs +25 -1
- package/dist/mjs/src/parser/ast.mjs.map +3 -3
- package/dist/mjs/src/parser/index.mjs +14 -2
- package/dist/mjs/src/parser/index.mjs.map +3 -3
- package/dist/mjs/src/parser/parser.mjs +280 -8
- package/dist/mjs/src/parser/parser.mjs.map +3 -3
- package/dist/mjs/src/shell-dsl.mjs +2 -2
- package/dist/mjs/src/shell-dsl.mjs.map +3 -3
- package/dist/types/index.d.ts +2 -2
- package/dist/types/src/commands/awk/awk.d.ts +2 -0
- package/dist/types/src/commands/break-continue/break-continue.d.ts +3 -0
- package/dist/types/src/commands/cat/cat.d.ts +2 -0
- package/dist/types/src/commands/cp/cp.d.ts +2 -0
- package/dist/types/src/commands/echo/echo.d.ts +2 -0
- package/dist/types/src/commands/find/find.d.ts +2 -0
- package/dist/types/src/commands/grep/grep.d.ts +2 -0
- package/dist/types/src/commands/head/head.d.ts +2 -0
- package/dist/types/src/commands/index.d.ts +25 -0
- package/dist/types/src/commands/ls/ls.d.ts +2 -0
- package/dist/types/src/commands/mkdir/mkdir.d.ts +2 -0
- package/dist/types/src/commands/mv/mv.d.ts +2 -0
- package/dist/types/src/commands/pwd/pwd.d.ts +2 -0
- package/dist/types/src/commands/rm/rm.d.ts +2 -0
- package/dist/types/src/commands/sed/sed.d.ts +2 -0
- package/dist/types/src/commands/sort/sort.d.ts +2 -0
- package/dist/types/src/commands/tail/tail.d.ts +2 -0
- package/dist/types/src/commands/tee/tee.d.ts +2 -0
- package/dist/types/{commands → src/commands/test}/test.d.ts +1 -1
- package/dist/types/src/commands/touch/touch.d.ts +2 -0
- package/dist/types/src/commands/tree/tree.d.ts +2 -0
- package/dist/types/{commands → src/commands/true-false}/true-false.d.ts +1 -1
- package/dist/types/src/commands/uniq/uniq.d.ts +2 -0
- package/dist/types/src/commands/wc/wc.d.ts +2 -0
- package/dist/types/src/index.d.ts +3 -3
- package/dist/types/src/interpreter/index.d.ts +1 -1
- package/dist/types/src/interpreter/interpreter.d.ts +18 -0
- package/dist/types/src/lexer/index.d.ts +2 -2
- package/dist/types/src/lexer/lexer.d.ts +16 -2
- package/dist/types/src/lexer/tokens.d.ts +20 -0
- package/dist/types/src/parser/ast.d.ts +47 -1
- package/dist/types/src/parser/index.d.ts +2 -2
- package/dist/types/src/parser/parser.d.ts +15 -0
- package/package.json +1 -1
- package/dist/types/commands/cat.d.ts +0 -2
- package/dist/types/commands/cp.d.ts +0 -2
- package/dist/types/commands/echo.d.ts +0 -2
- package/dist/types/commands/find.d.ts +0 -2
- package/dist/types/commands/grep.d.ts +0 -2
- package/dist/types/commands/head.d.ts +0 -2
- package/dist/types/commands/index.d.ts +0 -22
- package/dist/types/commands/ls.d.ts +0 -2
- package/dist/types/commands/mkdir.d.ts +0 -2
- package/dist/types/commands/mv.d.ts +0 -2
- package/dist/types/commands/pwd.d.ts +0 -2
- package/dist/types/commands/rm.d.ts +0 -2
- package/dist/types/commands/sort.d.ts +0 -2
- package/dist/types/commands/tail.d.ts +0 -2
- package/dist/types/commands/tee.d.ts +0 -2
- package/dist/types/commands/touch.d.ts +0 -2
- package/dist/types/commands/tree.d.ts +0 -2
- package/dist/types/commands/uniq.d.ts +0 -2
- package/dist/types/commands/wc.d.ts +0 -2
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../../src/commands/sed/sed.ts"],
|
|
4
|
+
"sourcesContent": [
|
|
5
|
+
"import type { Command } from \"../../types.mjs\";\n\ninterface SedCommand {\n type: \"s\" | \"d\" | \"p\";\n addressPattern?: RegExp;\n pattern?: RegExp;\n replacement?: string;\n globalFlag: boolean;\n printFlag: boolean;\n}\n\ninterface SedOptions {\n suppressOutput: boolean; // -n\n commands: SedCommand[];\n}\n\nfunction parseSubstitution(script: string): SedCommand | null {\n // Match s/pattern/replacement/flags format\n // Support different delimiters (first char after 's')\n const match = script.match(/^s(.)(.+?)\\1(.*?)\\1([gi]*)$/);\n if (!match) return null;\n\n const [, , patternStr, replacement, flags] = match;\n const globalFlag = flags!.includes(\"g\");\n const caseInsensitive = flags!.includes(\"i\");\n\n try {\n const regexFlags = caseInsensitive ? \"i\" : \"\";\n return {\n type: \"s\",\n pattern: new RegExp(patternStr!, regexFlags),\n replacement: replacement!,\n globalFlag,\n printFlag: false,\n };\n } catch {\n return null;\n }\n}\n\nfunction parseCommand(script: string): SedCommand | null {\n const trimmed = script.trim();\n\n // Check for address pattern (e.g., /foo/d or /foo/p)\n const addressMatch = trimmed.match(/^\\/(.+?)\\/([dp])$/);\n if (addressMatch) {\n const [, addressPatternStr, cmd] = addressMatch;\n try {\n return {\n type: cmd as \"d\" | \"p\",\n addressPattern: new RegExp(addressPatternStr!),\n globalFlag: false,\n printFlag: false,\n };\n } catch {\n return null;\n }\n }\n\n // Simple d or p command (applies to all lines)\n if (trimmed === \"d\") {\n return { type: \"d\", globalFlag: false, printFlag: false };\n }\n if (trimmed === \"p\") {\n return { type: \"p\", globalFlag: false, printFlag: false };\n }\n\n // Address pattern with substitution: /pattern/s/old/new/flags\n const addressSubMatch = trimmed.match(/^\\/(.+?)\\/s(.)(.+?)\\2(.*?)\\2([gi]*)$/);\n if (addressSubMatch) {\n const [, addressPatternStr, , patternStr, replacement, flags] = addressSubMatch;\n const globalFlag = flags!.includes(\"g\");\n const caseInsensitive = flags!.includes(\"i\");\n try {\n return {\n type: \"s\",\n addressPattern: new RegExp(addressPatternStr!),\n pattern: new RegExp(patternStr!, caseInsensitive ? \"i\" : \"\"),\n replacement: replacement!,\n globalFlag,\n printFlag: false,\n };\n } catch {\n return null;\n }\n }\n\n // Substitution command\n const subCmd = parseSubstitution(trimmed);\n if (subCmd) return subCmd;\n\n return null;\n}\n\nfunction parseArgs(args: string[]): { options: SedOptions; files: string[] } {\n const options: SedOptions = {\n suppressOutput: false,\n commands: [],\n };\n const files: string[] = [];\n\n let i = 0;\n while (i < args.length) {\n const arg = args[i]!;\n\n if (arg === \"-n\") {\n options.suppressOutput = true;\n i++;\n continue;\n }\n\n if (arg === \"-e\" && args[i + 1] !== undefined) {\n const cmd = parseCommand(args[i + 1]!);\n if (cmd) {\n options.commands.push(cmd);\n }\n i += 2;\n continue;\n }\n\n // Non-flag argument: either a script or a file\n if (!arg.startsWith(\"-\")) {\n if (options.commands.length === 0) {\n // First non-flag is the script\n const cmd = parseCommand(arg);\n if (cmd) {\n options.commands.push(cmd);\n }\n } else {\n // Subsequent non-flags are files\n files.push(arg);\n }\n }\n i++;\n }\n\n return { options, files };\n}\n\nfunction applySubstitution(line: string, cmd: SedCommand): string {\n if (!cmd.pattern) return line;\n\n if (cmd.globalFlag) {\n return line.replace(new RegExp(cmd.pattern.source, cmd.pattern.flags + \"g\"), cmd.replacement!);\n } else {\n return line.replace(cmd.pattern, cmd.replacement!);\n }\n}\n\nfunction processLine(\n line: string,\n commands: SedCommand[],\n suppressOutput: boolean\n): { output: string | null; deleted: boolean } {\n let currentLine = line;\n let deleted = false;\n let printed = false;\n\n for (const cmd of commands) {\n // Check address pattern first\n if (cmd.addressPattern && !cmd.addressPattern.test(currentLine)) {\n continue; // Skip this command if address doesn't match\n }\n\n switch (cmd.type) {\n case \"s\":\n currentLine = applySubstitution(currentLine, cmd);\n break;\n case \"d\":\n deleted = true;\n return { output: null, deleted: true };\n case \"p\":\n printed = true;\n break;\n }\n }\n\n if (deleted) {\n return { output: null, deleted: true };\n }\n\n if (suppressOutput) {\n // With -n, only output if explicitly printed\n return { output: printed ? currentLine : null, deleted: false };\n }\n\n // Without -n, always output (plus extra if printed)\n if (printed) {\n return { output: currentLine + \"\\n\" + currentLine, deleted: false };\n }\n return { output: currentLine, deleted: false };\n}\n\nexport const sed: Command = async (ctx) => {\n const { options, files } = parseArgs(ctx.args);\n\n if (options.commands.length === 0) {\n await ctx.stderr.writeText(\"sed: missing script\\n\");\n return 1;\n }\n\n const processContent = async (content: string): Promise<void> => {\n const lines = content.split(\"\\n\");\n // Handle trailing newline\n if (lines.length > 0 && lines[lines.length - 1] === \"\") {\n lines.pop();\n }\n\n for (const line of lines) {\n const { output } = processLine(line, options.commands, options.suppressOutput);\n if (output !== null) {\n await ctx.stdout.writeText(output + \"\\n\");\n }\n }\n };\n\n if (files.length === 0) {\n // Read from stdin\n const content = await ctx.stdin.text();\n await processContent(content);\n } else {\n // Read from files\n for (const file of files) {\n try {\n const path = ctx.fs.resolve(ctx.cwd, file);\n const content = await ctx.fs.readFile(path);\n await processContent(content.toString());\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n await ctx.stderr.writeText(`sed: ${file}: ${message}\\n`);\n return 1;\n }\n }\n }\n\n return 0;\n};\n"
|
|
6
|
+
],
|
|
7
|
+
"mappings": "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",
|
|
8
|
+
"debugId": "87CDDCAD5F22F55864756E2164756E21",
|
|
9
|
+
"names": []
|
|
10
|
+
}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
// src/commands/sort/sort.ts
|
|
2
|
+
var sort = async (ctx) => {
|
|
3
|
+
let reverse = false;
|
|
4
|
+
let numeric = false;
|
|
5
|
+
let unique = false;
|
|
6
|
+
const files = [];
|
|
7
|
+
for (const arg of ctx.args) {
|
|
8
|
+
if (arg === "-r") {
|
|
9
|
+
reverse = true;
|
|
10
|
+
} else if (arg === "-n") {
|
|
11
|
+
numeric = true;
|
|
12
|
+
} else if (arg === "-u") {
|
|
13
|
+
unique = true;
|
|
14
|
+
} else if (arg.startsWith("-")) {
|
|
15
|
+
for (const flag of arg.slice(1)) {
|
|
16
|
+
if (flag === "r")
|
|
17
|
+
reverse = true;
|
|
18
|
+
else if (flag === "n")
|
|
19
|
+
numeric = true;
|
|
20
|
+
else if (flag === "u")
|
|
21
|
+
unique = true;
|
|
22
|
+
}
|
|
23
|
+
} else {
|
|
24
|
+
files.push(arg);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
let allLines = [];
|
|
28
|
+
if (files.length === 0) {
|
|
29
|
+
for await (const line of ctx.stdin.lines()) {
|
|
30
|
+
allLines.push(line);
|
|
31
|
+
}
|
|
32
|
+
} else {
|
|
33
|
+
for (const file of files) {
|
|
34
|
+
try {
|
|
35
|
+
const path = ctx.fs.resolve(ctx.cwd, file);
|
|
36
|
+
const content = (await ctx.fs.readFile(path)).toString();
|
|
37
|
+
const lines = content.split(`
|
|
38
|
+
`);
|
|
39
|
+
if (lines[lines.length - 1] === "") {
|
|
40
|
+
lines.pop();
|
|
41
|
+
}
|
|
42
|
+
allLines.push(...lines);
|
|
43
|
+
} catch (err) {
|
|
44
|
+
await ctx.stderr.writeText(`sort: ${file}: No such file or directory
|
|
45
|
+
`);
|
|
46
|
+
return 1;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
if (numeric) {
|
|
51
|
+
allLines.sort((a, b) => {
|
|
52
|
+
const numA = parseFloat(a) || 0;
|
|
53
|
+
const numB = parseFloat(b) || 0;
|
|
54
|
+
return numA - numB;
|
|
55
|
+
});
|
|
56
|
+
} else {
|
|
57
|
+
allLines.sort();
|
|
58
|
+
}
|
|
59
|
+
if (reverse) {
|
|
60
|
+
allLines.reverse();
|
|
61
|
+
}
|
|
62
|
+
if (unique) {
|
|
63
|
+
allLines = [...new Set(allLines)];
|
|
64
|
+
}
|
|
65
|
+
for (const line of allLines) {
|
|
66
|
+
await ctx.stdout.writeText(line + `
|
|
67
|
+
`);
|
|
68
|
+
}
|
|
69
|
+
return 0;
|
|
70
|
+
};
|
|
71
|
+
export {
|
|
72
|
+
sort
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
//# debugId=1632C591A20B1AA964756E2164756E21
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../../src/commands/sort/sort.ts"],
|
|
4
|
+
"sourcesContent": [
|
|
5
|
+
"import type { Command } from \"../../types.mjs\";\n\nexport const sort: Command = async (ctx) => {\n let reverse = false;\n let numeric = false;\n let unique = false;\n const files: string[] = [];\n\n // Parse arguments\n for (const arg of ctx.args) {\n if (arg === \"-r\") {\n reverse = true;\n } else if (arg === \"-n\") {\n numeric = true;\n } else if (arg === \"-u\") {\n unique = true;\n } else if (arg.startsWith(\"-\")) {\n for (const flag of arg.slice(1)) {\n if (flag === \"r\") reverse = true;\n else if (flag === \"n\") numeric = true;\n else if (flag === \"u\") unique = true;\n }\n } else {\n files.push(arg);\n }\n }\n\n let allLines: string[] = [];\n\n if (files.length === 0) {\n // Read from stdin\n for await (const line of ctx.stdin.lines()) {\n allLines.push(line);\n }\n } else {\n for (const file of files) {\n try {\n const path = ctx.fs.resolve(ctx.cwd, file);\n const content = (await ctx.fs.readFile(path)).toString();\n const lines = content.split(\"\\n\");\n if (lines[lines.length - 1] === \"\") {\n lines.pop();\n }\n allLines.push(...lines);\n } catch (err) {\n await ctx.stderr.writeText(`sort: ${file}: No such file or directory\\n`);\n return 1;\n }\n }\n }\n\n // Sort\n if (numeric) {\n allLines.sort((a, b) => {\n const numA = parseFloat(a) || 0;\n const numB = parseFloat(b) || 0;\n return numA - numB;\n });\n } else {\n allLines.sort();\n }\n\n if (reverse) {\n allLines.reverse();\n }\n\n if (unique) {\n allLines = [...new Set(allLines)];\n }\n\n for (const line of allLines) {\n await ctx.stdout.writeText(line + \"\\n\");\n }\n\n return 0;\n};\n"
|
|
6
|
+
],
|
|
7
|
+
"mappings": ";AAEO,IAAM,OAAgB,OAAO,QAAQ;AAAA,EAC1C,IAAI,UAAU;AAAA,EACd,IAAI,UAAU;AAAA,EACd,IAAI,SAAS;AAAA,EACb,MAAM,QAAkB,CAAC;AAAA,EAGzB,WAAW,OAAO,IAAI,MAAM;AAAA,IAC1B,IAAI,QAAQ,MAAM;AAAA,MAChB,UAAU;AAAA,IACZ,EAAO,SAAI,QAAQ,MAAM;AAAA,MACvB,UAAU;AAAA,IACZ,EAAO,SAAI,QAAQ,MAAM;AAAA,MACvB,SAAS;AAAA,IACX,EAAO,SAAI,IAAI,WAAW,GAAG,GAAG;AAAA,MAC9B,WAAW,QAAQ,IAAI,MAAM,CAAC,GAAG;AAAA,QAC/B,IAAI,SAAS;AAAA,UAAK,UAAU;AAAA,QACvB,SAAI,SAAS;AAAA,UAAK,UAAU;AAAA,QAC5B,SAAI,SAAS;AAAA,UAAK,SAAS;AAAA,MAClC;AAAA,IACF,EAAO;AAAA,MACL,MAAM,KAAK,GAAG;AAAA;AAAA,EAElB;AAAA,EAEA,IAAI,WAAqB,CAAC;AAAA,EAE1B,IAAI,MAAM,WAAW,GAAG;AAAA,IAEtB,iBAAiB,QAAQ,IAAI,MAAM,MAAM,GAAG;AAAA,MAC1C,SAAS,KAAK,IAAI;AAAA,IACpB;AAAA,EACF,EAAO;AAAA,IACL,WAAW,QAAQ,OAAO;AAAA,MACxB,IAAI;AAAA,QACF,MAAM,OAAO,IAAI,GAAG,QAAQ,IAAI,KAAK,IAAI;AAAA,QACzC,MAAM,WAAW,MAAM,IAAI,GAAG,SAAS,IAAI,GAAG,SAAS;AAAA,QACvD,MAAM,QAAQ,QAAQ,MAAM;AAAA,CAAI;AAAA,QAChC,IAAI,MAAM,MAAM,SAAS,OAAO,IAAI;AAAA,UAClC,MAAM,IAAI;AAAA,QACZ;AAAA,QACA,SAAS,KAAK,GAAG,KAAK;AAAA,QACtB,OAAO,KAAK;AAAA,QACZ,MAAM,IAAI,OAAO,UAAU,SAAS;AAAA,CAAmC;AAAA,QACvE,OAAO;AAAA;AAAA,IAEX;AAAA;AAAA,EAIF,IAAI,SAAS;AAAA,IACX,SAAS,KAAK,CAAC,GAAG,MAAM;AAAA,MACtB,MAAM,OAAO,WAAW,CAAC,KAAK;AAAA,MAC9B,MAAM,OAAO,WAAW,CAAC,KAAK;AAAA,MAC9B,OAAO,OAAO;AAAA,KACf;AAAA,EACH,EAAO;AAAA,IACL,SAAS,KAAK;AAAA;AAAA,EAGhB,IAAI,SAAS;AAAA,IACX,SAAS,QAAQ;AAAA,EACnB;AAAA,EAEA,IAAI,QAAQ;AAAA,IACV,WAAW,CAAC,GAAG,IAAI,IAAI,QAAQ,CAAC;AAAA,EAClC;AAAA,EAEA,WAAW,QAAQ,UAAU;AAAA,IAC3B,MAAM,IAAI,OAAO,UAAU,OAAO;AAAA,CAAI;AAAA,EACxC;AAAA,EAEA,OAAO;AAAA;",
|
|
8
|
+
"debugId": "1632C591A20B1AA964756E2164756E21",
|
|
9
|
+
"names": []
|
|
10
|
+
}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
// src/commands/tail/tail.ts
|
|
2
|
+
var tail = async (ctx) => {
|
|
3
|
+
let numLines = 10;
|
|
4
|
+
const files = [];
|
|
5
|
+
for (let i = 0;i < ctx.args.length; i++) {
|
|
6
|
+
const arg = ctx.args[i];
|
|
7
|
+
if (arg === "-n" && ctx.args[i + 1]) {
|
|
8
|
+
numLines = parseInt(ctx.args[i + 1], 10);
|
|
9
|
+
i++;
|
|
10
|
+
} else if (arg.startsWith("-n")) {
|
|
11
|
+
numLines = parseInt(arg.slice(2), 10);
|
|
12
|
+
} else if (arg.startsWith("-") && /^\d+$/.test(arg.slice(1))) {
|
|
13
|
+
numLines = parseInt(arg.slice(1), 10);
|
|
14
|
+
} else if (!arg.startsWith("-")) {
|
|
15
|
+
files.push(arg);
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
if (isNaN(numLines) || numLines < 0) {
|
|
19
|
+
await ctx.stderr.writeText(`tail: invalid number of lines
|
|
20
|
+
`);
|
|
21
|
+
return 1;
|
|
22
|
+
}
|
|
23
|
+
const outputLines = async (content) => {
|
|
24
|
+
const lines = content.split(`
|
|
25
|
+
`);
|
|
26
|
+
if (lines[lines.length - 1] === "") {
|
|
27
|
+
lines.pop();
|
|
28
|
+
}
|
|
29
|
+
const toOutput = lines.slice(-numLines);
|
|
30
|
+
for (const line of toOutput) {
|
|
31
|
+
await ctx.stdout.writeText(line + `
|
|
32
|
+
`);
|
|
33
|
+
}
|
|
34
|
+
};
|
|
35
|
+
if (files.length === 0) {
|
|
36
|
+
const content = await ctx.stdin.text();
|
|
37
|
+
await outputLines(content);
|
|
38
|
+
} else {
|
|
39
|
+
for (let i = 0;i < files.length; i++) {
|
|
40
|
+
const file = files[i];
|
|
41
|
+
try {
|
|
42
|
+
if (files.length > 1) {
|
|
43
|
+
if (i > 0)
|
|
44
|
+
await ctx.stdout.writeText(`
|
|
45
|
+
`);
|
|
46
|
+
await ctx.stdout.writeText(`==> ${file} <==
|
|
47
|
+
`);
|
|
48
|
+
}
|
|
49
|
+
const path = ctx.fs.resolve(ctx.cwd, file);
|
|
50
|
+
const content = (await ctx.fs.readFile(path)).toString();
|
|
51
|
+
await outputLines(content);
|
|
52
|
+
} catch (err) {
|
|
53
|
+
await ctx.stderr.writeText(`tail: ${file}: No such file or directory
|
|
54
|
+
`);
|
|
55
|
+
return 1;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
return 0;
|
|
60
|
+
};
|
|
61
|
+
export {
|
|
62
|
+
tail
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
//# debugId=828D3CDC24D5272A64756E2164756E21
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../../src/commands/tail/tail.ts"],
|
|
4
|
+
"sourcesContent": [
|
|
5
|
+
"import type { Command } from \"../../types.mjs\";\n\nexport const tail: Command = async (ctx) => {\n let numLines = 10;\n const files: string[] = [];\n\n // Parse arguments\n for (let i = 0; i < ctx.args.length; i++) {\n const arg = ctx.args[i]!;\n if (arg === \"-n\" && ctx.args[i + 1]) {\n numLines = parseInt(ctx.args[i + 1]!, 10);\n i++;\n } else if (arg.startsWith(\"-n\")) {\n numLines = parseInt(arg.slice(2), 10);\n } else if (arg.startsWith(\"-\") && /^\\d+$/.test(arg.slice(1))) {\n numLines = parseInt(arg.slice(1), 10);\n } else if (!arg.startsWith(\"-\")) {\n files.push(arg);\n }\n }\n\n if (isNaN(numLines) || numLines < 0) {\n await ctx.stderr.writeText(\"tail: invalid number of lines\\n\");\n return 1;\n }\n\n const outputLines = async (content: string) => {\n const lines = content.split(\"\\n\");\n // Remove trailing empty line if present\n if (lines[lines.length - 1] === \"\") {\n lines.pop();\n }\n const toOutput = lines.slice(-numLines);\n for (const line of toOutput) {\n await ctx.stdout.writeText(line + \"\\n\");\n }\n };\n\n if (files.length === 0) {\n // Read from stdin\n const content = await ctx.stdin.text();\n await outputLines(content);\n } else {\n for (let i = 0; i < files.length; i++) {\n const file = files[i]!;\n try {\n if (files.length > 1) {\n if (i > 0) await ctx.stdout.writeText(\"\\n\");\n await ctx.stdout.writeText(`==> ${file} <==\\n`);\n }\n const path = ctx.fs.resolve(ctx.cwd, file);\n const content = (await ctx.fs.readFile(path)).toString();\n await outputLines(content);\n } catch (err) {\n await ctx.stderr.writeText(`tail: ${file}: No such file or directory\\n`);\n return 1;\n }\n }\n }\n\n return 0;\n};\n"
|
|
6
|
+
],
|
|
7
|
+
"mappings": ";AAEO,IAAM,OAAgB,OAAO,QAAQ;AAAA,EAC1C,IAAI,WAAW;AAAA,EACf,MAAM,QAAkB,CAAC;AAAA,EAGzB,SAAS,IAAI,EAAG,IAAI,IAAI,KAAK,QAAQ,KAAK;AAAA,IACxC,MAAM,MAAM,IAAI,KAAK;AAAA,IACrB,IAAI,QAAQ,QAAQ,IAAI,KAAK,IAAI,IAAI;AAAA,MACnC,WAAW,SAAS,IAAI,KAAK,IAAI,IAAK,EAAE;AAAA,MACxC;AAAA,IACF,EAAO,SAAI,IAAI,WAAW,IAAI,GAAG;AAAA,MAC/B,WAAW,SAAS,IAAI,MAAM,CAAC,GAAG,EAAE;AAAA,IACtC,EAAO,SAAI,IAAI,WAAW,GAAG,KAAK,QAAQ,KAAK,IAAI,MAAM,CAAC,CAAC,GAAG;AAAA,MAC5D,WAAW,SAAS,IAAI,MAAM,CAAC,GAAG,EAAE;AAAA,IACtC,EAAO,SAAI,CAAC,IAAI,WAAW,GAAG,GAAG;AAAA,MAC/B,MAAM,KAAK,GAAG;AAAA,IAChB;AAAA,EACF;AAAA,EAEA,IAAI,MAAM,QAAQ,KAAK,WAAW,GAAG;AAAA,IACnC,MAAM,IAAI,OAAO,UAAU;AAAA,CAAiC;AAAA,IAC5D,OAAO;AAAA,EACT;AAAA,EAEA,MAAM,cAAc,OAAO,YAAoB;AAAA,IAC7C,MAAM,QAAQ,QAAQ,MAAM;AAAA,CAAI;AAAA,IAEhC,IAAI,MAAM,MAAM,SAAS,OAAO,IAAI;AAAA,MAClC,MAAM,IAAI;AAAA,IACZ;AAAA,IACA,MAAM,WAAW,MAAM,MAAM,CAAC,QAAQ;AAAA,IACtC,WAAW,QAAQ,UAAU;AAAA,MAC3B,MAAM,IAAI,OAAO,UAAU,OAAO;AAAA,CAAI;AAAA,IACxC;AAAA;AAAA,EAGF,IAAI,MAAM,WAAW,GAAG;AAAA,IAEtB,MAAM,UAAU,MAAM,IAAI,MAAM,KAAK;AAAA,IACrC,MAAM,YAAY,OAAO;AAAA,EAC3B,EAAO;AAAA,IACL,SAAS,IAAI,EAAG,IAAI,MAAM,QAAQ,KAAK;AAAA,MACrC,MAAM,OAAO,MAAM;AAAA,MACnB,IAAI;AAAA,QACF,IAAI,MAAM,SAAS,GAAG;AAAA,UACpB,IAAI,IAAI;AAAA,YAAG,MAAM,IAAI,OAAO,UAAU;AAAA,CAAI;AAAA,UAC1C,MAAM,IAAI,OAAO,UAAU,OAAO;AAAA,CAAY;AAAA,QAChD;AAAA,QACA,MAAM,OAAO,IAAI,GAAG,QAAQ,IAAI,KAAK,IAAI;AAAA,QACzC,MAAM,WAAW,MAAM,IAAI,GAAG,SAAS,IAAI,GAAG,SAAS;AAAA,QACvD,MAAM,YAAY,OAAO;AAAA,QACzB,OAAO,KAAK;AAAA,QACZ,MAAM,IAAI,OAAO,UAAU,SAAS;AAAA,CAAmC;AAAA,QACvE,OAAO;AAAA;AAAA,IAEX;AAAA;AAAA,EAGF,OAAO;AAAA;",
|
|
8
|
+
"debugId": "828D3CDC24D5272A64756E2164756E21",
|
|
9
|
+
"names": []
|
|
10
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
// src/commands/tee/tee.ts
|
|
2
|
+
var tee = async (ctx) => {
|
|
3
|
+
let append = false;
|
|
4
|
+
const files = [];
|
|
5
|
+
for (const arg of ctx.args) {
|
|
6
|
+
if (arg === "-a" || arg === "--append") {
|
|
7
|
+
append = true;
|
|
8
|
+
} else if (!arg.startsWith("-")) {
|
|
9
|
+
files.push(arg);
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
const content = await ctx.stdin.buffer();
|
|
13
|
+
await ctx.stdout.write(new Uint8Array(content));
|
|
14
|
+
for (const file of files) {
|
|
15
|
+
const path = ctx.fs.resolve(ctx.cwd, file);
|
|
16
|
+
try {
|
|
17
|
+
if (append) {
|
|
18
|
+
await ctx.fs.appendFile(path, content);
|
|
19
|
+
} else {
|
|
20
|
+
await ctx.fs.writeFile(path, content);
|
|
21
|
+
}
|
|
22
|
+
} catch (err) {
|
|
23
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
24
|
+
await ctx.stderr.writeText(`tee: ${file}: ${message}
|
|
25
|
+
`);
|
|
26
|
+
return 1;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
return 0;
|
|
30
|
+
};
|
|
31
|
+
export {
|
|
32
|
+
tee
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
//# debugId=FFA8E289A5C4079A64756E2164756E21
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../../src/commands/tee/tee.ts"],
|
|
4
|
+
"sourcesContent": [
|
|
5
|
+
"import type { Command } from \"../../types.mjs\";\n\nexport const tee: Command = async (ctx) => {\n let append = false;\n const files: string[] = [];\n\n for (const arg of ctx.args) {\n if (arg === \"-a\" || arg === \"--append\") {\n append = true;\n } else if (!arg.startsWith(\"-\")) {\n files.push(arg);\n }\n }\n\n // Read all stdin content\n const content = await ctx.stdin.buffer();\n\n // Write to stdout\n await ctx.stdout.write(new Uint8Array(content));\n\n // Write to each file\n for (const file of files) {\n const path = ctx.fs.resolve(ctx.cwd, file);\n try {\n if (append) {\n await ctx.fs.appendFile(path, content);\n } else {\n await ctx.fs.writeFile(path, content);\n }\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n await ctx.stderr.writeText(`tee: ${file}: ${message}\\n`);\n return 1;\n }\n }\n\n return 0;\n};\n"
|
|
6
|
+
],
|
|
7
|
+
"mappings": ";AAEO,IAAM,MAAe,OAAO,QAAQ;AAAA,EACzC,IAAI,SAAS;AAAA,EACb,MAAM,QAAkB,CAAC;AAAA,EAEzB,WAAW,OAAO,IAAI,MAAM;AAAA,IAC1B,IAAI,QAAQ,QAAQ,QAAQ,YAAY;AAAA,MACtC,SAAS;AAAA,IACX,EAAO,SAAI,CAAC,IAAI,WAAW,GAAG,GAAG;AAAA,MAC/B,MAAM,KAAK,GAAG;AAAA,IAChB;AAAA,EACF;AAAA,EAGA,MAAM,UAAU,MAAM,IAAI,MAAM,OAAO;AAAA,EAGvC,MAAM,IAAI,OAAO,MAAM,IAAI,WAAW,OAAO,CAAC;AAAA,EAG9C,WAAW,QAAQ,OAAO;AAAA,IACxB,MAAM,OAAO,IAAI,GAAG,QAAQ,IAAI,KAAK,IAAI;AAAA,IACzC,IAAI;AAAA,MACF,IAAI,QAAQ;AAAA,QACV,MAAM,IAAI,GAAG,WAAW,MAAM,OAAO;AAAA,MACvC,EAAO;AAAA,QACL,MAAM,IAAI,GAAG,UAAU,MAAM,OAAO;AAAA;AAAA,MAEtC,OAAO,KAAK;AAAA,MACZ,MAAM,UAAU,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAAA,MAC/D,MAAM,IAAI,OAAO,UAAU,QAAQ,SAAS;AAAA,CAAW;AAAA,MACvD,OAAO;AAAA;AAAA,EAEX;AAAA,EAEA,OAAO;AAAA;",
|
|
8
|
+
"debugId": "FFA8E289A5C4079A64756E2164756E21",
|
|
9
|
+
"names": []
|
|
10
|
+
}
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
// src/commands/test/test.ts
|
|
2
|
+
var test = async (ctx) => {
|
|
3
|
+
const args = [...ctx.args];
|
|
4
|
+
if (args[args.length - 1] === "]") {
|
|
5
|
+
args.pop();
|
|
6
|
+
}
|
|
7
|
+
if (args.length === 0) {
|
|
8
|
+
return 1;
|
|
9
|
+
}
|
|
10
|
+
if (args.length === 1) {
|
|
11
|
+
return args[0].length > 0 ? 0 : 1;
|
|
12
|
+
}
|
|
13
|
+
if (args.length === 2) {
|
|
14
|
+
const [op, operand] = args;
|
|
15
|
+
switch (op) {
|
|
16
|
+
case "-n":
|
|
17
|
+
return operand.length > 0 ? 0 : 1;
|
|
18
|
+
case "-z":
|
|
19
|
+
return operand.length === 0 ? 0 : 1;
|
|
20
|
+
case "-f":
|
|
21
|
+
try {
|
|
22
|
+
const path = ctx.fs.resolve(ctx.cwd, operand);
|
|
23
|
+
const stat = await ctx.fs.stat(path);
|
|
24
|
+
return stat.isFile() ? 0 : 1;
|
|
25
|
+
} catch {
|
|
26
|
+
return 1;
|
|
27
|
+
}
|
|
28
|
+
case "-d":
|
|
29
|
+
try {
|
|
30
|
+
const path = ctx.fs.resolve(ctx.cwd, operand);
|
|
31
|
+
const stat = await ctx.fs.stat(path);
|
|
32
|
+
return stat.isDirectory() ? 0 : 1;
|
|
33
|
+
} catch {
|
|
34
|
+
return 1;
|
|
35
|
+
}
|
|
36
|
+
case "-e":
|
|
37
|
+
try {
|
|
38
|
+
const path = ctx.fs.resolve(ctx.cwd, operand);
|
|
39
|
+
return await ctx.fs.exists(path) ? 0 : 1;
|
|
40
|
+
} catch {
|
|
41
|
+
return 1;
|
|
42
|
+
}
|
|
43
|
+
case "-s":
|
|
44
|
+
try {
|
|
45
|
+
const path = ctx.fs.resolve(ctx.cwd, operand);
|
|
46
|
+
const stat = await ctx.fs.stat(path);
|
|
47
|
+
return stat.size > 0 ? 0 : 1;
|
|
48
|
+
} catch {
|
|
49
|
+
return 1;
|
|
50
|
+
}
|
|
51
|
+
case "-r":
|
|
52
|
+
case "-w":
|
|
53
|
+
case "-x":
|
|
54
|
+
try {
|
|
55
|
+
const path = ctx.fs.resolve(ctx.cwd, operand);
|
|
56
|
+
return await ctx.fs.exists(path) ? 0 : 1;
|
|
57
|
+
} catch {
|
|
58
|
+
return 1;
|
|
59
|
+
}
|
|
60
|
+
case "!":
|
|
61
|
+
return operand.length > 0 ? 1 : 0;
|
|
62
|
+
default:
|
|
63
|
+
await ctx.stderr.writeText(`test: unknown operator: ${op}
|
|
64
|
+
`);
|
|
65
|
+
return 2;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
if (args.length === 3) {
|
|
69
|
+
const [left, op, right] = args;
|
|
70
|
+
if (left === "!") {
|
|
71
|
+
const innerResult = await test({
|
|
72
|
+
...ctx,
|
|
73
|
+
args: [op, right]
|
|
74
|
+
});
|
|
75
|
+
return innerResult === 0 ? 1 : 0;
|
|
76
|
+
}
|
|
77
|
+
switch (op) {
|
|
78
|
+
case "=":
|
|
79
|
+
case "==":
|
|
80
|
+
return left === right ? 0 : 1;
|
|
81
|
+
case "!=":
|
|
82
|
+
return left !== right ? 0 : 1;
|
|
83
|
+
case "-eq":
|
|
84
|
+
return parseInt(left, 10) === parseInt(right, 10) ? 0 : 1;
|
|
85
|
+
case "-ne":
|
|
86
|
+
return parseInt(left, 10) !== parseInt(right, 10) ? 0 : 1;
|
|
87
|
+
case "-lt":
|
|
88
|
+
return parseInt(left, 10) < parseInt(right, 10) ? 0 : 1;
|
|
89
|
+
case "-le":
|
|
90
|
+
return parseInt(left, 10) <= parseInt(right, 10) ? 0 : 1;
|
|
91
|
+
case "-gt":
|
|
92
|
+
return parseInt(left, 10) > parseInt(right, 10) ? 0 : 1;
|
|
93
|
+
case "-ge":
|
|
94
|
+
return parseInt(left, 10) >= parseInt(right, 10) ? 0 : 1;
|
|
95
|
+
default:
|
|
96
|
+
await ctx.stderr.writeText(`test: unknown operator: ${op}
|
|
97
|
+
`);
|
|
98
|
+
return 2;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
if (args.length === 4 && args[0] === "!") {
|
|
102
|
+
const innerResult = await test({
|
|
103
|
+
...ctx,
|
|
104
|
+
args: args.slice(1)
|
|
105
|
+
});
|
|
106
|
+
return innerResult === 0 ? 1 : 0;
|
|
107
|
+
}
|
|
108
|
+
await ctx.stderr.writeText(`test: too many arguments
|
|
109
|
+
`);
|
|
110
|
+
return 2;
|
|
111
|
+
};
|
|
112
|
+
var bracket = test;
|
|
113
|
+
export {
|
|
114
|
+
test,
|
|
115
|
+
bracket
|
|
116
|
+
};
|
|
117
|
+
|
|
118
|
+
//# debugId=D02FD78FF5614A9164756E2164756E21
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../../src/commands/test/test.ts"],
|
|
4
|
+
"sourcesContent": [
|
|
5
|
+
"import type { Command } from \"../../types.mjs\";\n\nexport const test: Command = async (ctx) => {\n const args = [...ctx.args];\n\n // Handle [ ... ] syntax - remove trailing ]\n if (args[args.length - 1] === \"]\") {\n args.pop();\n }\n\n if (args.length === 0) {\n return 1; // Empty test is false\n }\n\n // Single argument: true if non-empty string\n if (args.length === 1) {\n return args[0]!.length > 0 ? 0 : 1;\n }\n\n // Two arguments: unary operators\n if (args.length === 2) {\n const [op, operand] = args;\n\n switch (op) {\n case \"-n\": // Non-zero length\n return operand!.length > 0 ? 0 : 1;\n case \"-z\": // Zero length\n return operand!.length === 0 ? 0 : 1;\n case \"-f\": // Is regular file\n try {\n const path = ctx.fs.resolve(ctx.cwd, operand!);\n const stat = await ctx.fs.stat(path);\n return stat.isFile() ? 0 : 1;\n } catch {\n return 1;\n }\n case \"-d\": // Is directory\n try {\n const path = ctx.fs.resolve(ctx.cwd, operand!);\n const stat = await ctx.fs.stat(path);\n return stat.isDirectory() ? 0 : 1;\n } catch {\n return 1;\n }\n case \"-e\": // Exists\n try {\n const path = ctx.fs.resolve(ctx.cwd, operand!);\n return (await ctx.fs.exists(path)) ? 0 : 1;\n } catch {\n return 1;\n }\n case \"-s\": // Has size > 0\n try {\n const path = ctx.fs.resolve(ctx.cwd, operand!);\n const stat = await ctx.fs.stat(path);\n return stat.size > 0 ? 0 : 1;\n } catch {\n return 1;\n }\n case \"-r\": // Readable (always true in virtual fs)\n case \"-w\": // Writable (always true in virtual fs)\n case \"-x\": // Executable (always true in virtual fs)\n try {\n const path = ctx.fs.resolve(ctx.cwd, operand!);\n return (await ctx.fs.exists(path)) ? 0 : 1;\n } catch {\n return 1;\n }\n case \"!\": // Negation\n return operand!.length > 0 ? 1 : 0;\n default:\n await ctx.stderr.writeText(`test: unknown operator: ${op}\\n`);\n return 2;\n }\n }\n\n // Three arguments: binary operators\n if (args.length === 3) {\n const [left, op, right] = args;\n\n // Handle negation with two-arg expression\n if (left === \"!\") {\n const innerResult = await test({\n ...ctx,\n args: [op!, right!],\n });\n return innerResult === 0 ? 1 : 0;\n }\n\n switch (op) {\n case \"=\":\n case \"==\":\n return left === right ? 0 : 1;\n case \"!=\":\n return left !== right ? 0 : 1;\n case \"-eq\":\n return parseInt(left!, 10) === parseInt(right!, 10) ? 0 : 1;\n case \"-ne\":\n return parseInt(left!, 10) !== parseInt(right!, 10) ? 0 : 1;\n case \"-lt\":\n return parseInt(left!, 10) < parseInt(right!, 10) ? 0 : 1;\n case \"-le\":\n return parseInt(left!, 10) <= parseInt(right!, 10) ? 0 : 1;\n case \"-gt\":\n return parseInt(left!, 10) > parseInt(right!, 10) ? 0 : 1;\n case \"-ge\":\n return parseInt(left!, 10) >= parseInt(right!, 10) ? 0 : 1;\n default:\n await ctx.stderr.writeText(`test: unknown operator: ${op}\\n`);\n return 2;\n }\n }\n\n // Four arguments: handle negation with three-arg expression\n if (args.length === 4 && args[0] === \"!\") {\n const innerResult = await test({\n ...ctx,\n args: args.slice(1),\n });\n return innerResult === 0 ? 1 : 0;\n }\n\n await ctx.stderr.writeText(\"test: too many arguments\\n\");\n return 2;\n};\n\n// Alias for [ command\nexport const bracket: Command = test;\n"
|
|
6
|
+
],
|
|
7
|
+
"mappings": "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",
|
|
8
|
+
"debugId": "D02FD78FF5614A9164756E2164756E21",
|
|
9
|
+
"names": []
|
|
10
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
// src/commands/touch/touch.ts
|
|
2
|
+
var touch = async (ctx) => {
|
|
3
|
+
let noCreate = false;
|
|
4
|
+
const files = [];
|
|
5
|
+
for (const arg of ctx.args) {
|
|
6
|
+
if (arg === "-c" || arg === "--no-create") {
|
|
7
|
+
noCreate = true;
|
|
8
|
+
} else if (!arg.startsWith("-")) {
|
|
9
|
+
files.push(arg);
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
if (files.length === 0) {
|
|
13
|
+
await ctx.stderr.writeText(`touch: missing file operand
|
|
14
|
+
`);
|
|
15
|
+
return 1;
|
|
16
|
+
}
|
|
17
|
+
for (const file of files) {
|
|
18
|
+
const path = ctx.fs.resolve(ctx.cwd, file);
|
|
19
|
+
try {
|
|
20
|
+
const exists = await ctx.fs.exists(path);
|
|
21
|
+
if (exists) {
|
|
22
|
+
const content = await ctx.fs.readFile(path);
|
|
23
|
+
await ctx.fs.writeFile(path, content);
|
|
24
|
+
} else if (!noCreate) {
|
|
25
|
+
await ctx.fs.writeFile(path, "");
|
|
26
|
+
}
|
|
27
|
+
} catch (err) {
|
|
28
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
29
|
+
await ctx.stderr.writeText(`touch: cannot touch '${file}': ${message}
|
|
30
|
+
`);
|
|
31
|
+
return 1;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
return 0;
|
|
35
|
+
};
|
|
36
|
+
export {
|
|
37
|
+
touch
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
//# debugId=022883A9907704D464756E2164756E21
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../../src/commands/touch/touch.ts"],
|
|
4
|
+
"sourcesContent": [
|
|
5
|
+
"import type { Command } from \"../../types.mjs\";\n\nexport const touch: Command = async (ctx) => {\n let noCreate = false;\n const files: string[] = [];\n\n for (const arg of ctx.args) {\n if (arg === \"-c\" || arg === \"--no-create\") {\n noCreate = true;\n } else if (!arg.startsWith(\"-\")) {\n files.push(arg);\n }\n }\n\n if (files.length === 0) {\n await ctx.stderr.writeText(\"touch: missing file operand\\n\");\n return 1;\n }\n\n for (const file of files) {\n const path = ctx.fs.resolve(ctx.cwd, file);\n try {\n const exists = await ctx.fs.exists(path);\n if (exists) {\n // Update mtime by reading and writing back\n const content = await ctx.fs.readFile(path);\n await ctx.fs.writeFile(path, content);\n } else if (!noCreate) {\n // Create empty file\n await ctx.fs.writeFile(path, \"\");\n }\n // If noCreate and doesn't exist, skip silently\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n await ctx.stderr.writeText(`touch: cannot touch '${file}': ${message}\\n`);\n return 1;\n }\n }\n\n return 0;\n};\n"
|
|
6
|
+
],
|
|
7
|
+
"mappings": ";AAEO,IAAM,QAAiB,OAAO,QAAQ;AAAA,EAC3C,IAAI,WAAW;AAAA,EACf,MAAM,QAAkB,CAAC;AAAA,EAEzB,WAAW,OAAO,IAAI,MAAM;AAAA,IAC1B,IAAI,QAAQ,QAAQ,QAAQ,eAAe;AAAA,MACzC,WAAW;AAAA,IACb,EAAO,SAAI,CAAC,IAAI,WAAW,GAAG,GAAG;AAAA,MAC/B,MAAM,KAAK,GAAG;AAAA,IAChB;AAAA,EACF;AAAA,EAEA,IAAI,MAAM,WAAW,GAAG;AAAA,IACtB,MAAM,IAAI,OAAO,UAAU;AAAA,CAA+B;AAAA,IAC1D,OAAO;AAAA,EACT;AAAA,EAEA,WAAW,QAAQ,OAAO;AAAA,IACxB,MAAM,OAAO,IAAI,GAAG,QAAQ,IAAI,KAAK,IAAI;AAAA,IACzC,IAAI;AAAA,MACF,MAAM,SAAS,MAAM,IAAI,GAAG,OAAO,IAAI;AAAA,MACvC,IAAI,QAAQ;AAAA,QAEV,MAAM,UAAU,MAAM,IAAI,GAAG,SAAS,IAAI;AAAA,QAC1C,MAAM,IAAI,GAAG,UAAU,MAAM,OAAO;AAAA,MACtC,EAAO,SAAI,CAAC,UAAU;AAAA,QAEpB,MAAM,IAAI,GAAG,UAAU,MAAM,EAAE;AAAA,MACjC;AAAA,MAEA,OAAO,KAAK;AAAA,MACZ,MAAM,UAAU,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAAA,MAC/D,MAAM,IAAI,OAAO,UAAU,wBAAwB,UAAU;AAAA,CAAW;AAAA,MACxE,OAAO;AAAA;AAAA,EAEX;AAAA,EAEA,OAAO;AAAA;",
|
|
8
|
+
"debugId": "022883A9907704D464756E2164756E21",
|
|
9
|
+
"names": []
|
|
10
|
+
}
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
// src/commands/tree/tree.ts
|
|
2
|
+
var tree = async (ctx) => {
|
|
3
|
+
let showAll = false;
|
|
4
|
+
let directoriesOnly = false;
|
|
5
|
+
let maxDepth = Infinity;
|
|
6
|
+
let targetPath = ".";
|
|
7
|
+
const args = [...ctx.args];
|
|
8
|
+
for (let i = 0;i < args.length; i++) {
|
|
9
|
+
const arg = args[i];
|
|
10
|
+
if (arg === "-a" || arg === "--all") {
|
|
11
|
+
showAll = true;
|
|
12
|
+
} else if (arg === "-d") {
|
|
13
|
+
directoriesOnly = true;
|
|
14
|
+
} else if (arg === "-L") {
|
|
15
|
+
const depthArg = args[++i];
|
|
16
|
+
if (depthArg === undefined || isNaN(parseInt(depthArg, 10))) {
|
|
17
|
+
await ctx.stderr.writeText(`tree: missing argument to -L
|
|
18
|
+
`);
|
|
19
|
+
return 1;
|
|
20
|
+
}
|
|
21
|
+
maxDepth = parseInt(depthArg, 10);
|
|
22
|
+
if (maxDepth < 1) {
|
|
23
|
+
await ctx.stderr.writeText(`tree: Invalid level, must be greater than 0
|
|
24
|
+
`);
|
|
25
|
+
return 1;
|
|
26
|
+
}
|
|
27
|
+
} else if (arg.startsWith("-L")) {
|
|
28
|
+
const depthStr = arg.slice(2);
|
|
29
|
+
const depth = parseInt(depthStr, 10);
|
|
30
|
+
if (isNaN(depth) || depth < 1) {
|
|
31
|
+
await ctx.stderr.writeText(`tree: Invalid level, must be greater than 0
|
|
32
|
+
`);
|
|
33
|
+
return 1;
|
|
34
|
+
}
|
|
35
|
+
maxDepth = depth;
|
|
36
|
+
} else if (arg.startsWith("-") && arg !== "-") {
|
|
37
|
+
for (const flag of arg.slice(1)) {
|
|
38
|
+
if (flag === "a")
|
|
39
|
+
showAll = true;
|
|
40
|
+
else if (flag === "d")
|
|
41
|
+
directoriesOnly = true;
|
|
42
|
+
else {
|
|
43
|
+
await ctx.stderr.writeText(`tree: Invalid argument -${flag}
|
|
44
|
+
`);
|
|
45
|
+
return 1;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
} else {
|
|
49
|
+
targetPath = arg;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
const resolvedPath = ctx.fs.resolve(ctx.cwd, targetPath);
|
|
53
|
+
let stat;
|
|
54
|
+
try {
|
|
55
|
+
stat = await ctx.fs.stat(resolvedPath);
|
|
56
|
+
} catch {
|
|
57
|
+
await ctx.stderr.writeText(`tree: ${targetPath}: No such file or directory
|
|
58
|
+
`);
|
|
59
|
+
return 1;
|
|
60
|
+
}
|
|
61
|
+
if (stat.isFile()) {
|
|
62
|
+
await ctx.stdout.writeText(targetPath + `
|
|
63
|
+
|
|
64
|
+
0 directories, 1 file
|
|
65
|
+
`);
|
|
66
|
+
return 0;
|
|
67
|
+
}
|
|
68
|
+
let dirCount = 0;
|
|
69
|
+
let fileCount = 0;
|
|
70
|
+
await ctx.stdout.writeText(targetPath + `
|
|
71
|
+
`);
|
|
72
|
+
async function printTree(path, prefix, depth) {
|
|
73
|
+
if (depth > maxDepth)
|
|
74
|
+
return;
|
|
75
|
+
let entries = await ctx.fs.readdir(path);
|
|
76
|
+
if (!showAll) {
|
|
77
|
+
entries = entries.filter((e) => !e.startsWith("."));
|
|
78
|
+
}
|
|
79
|
+
entries.sort();
|
|
80
|
+
const dirEntries = [];
|
|
81
|
+
const fileEntries = [];
|
|
82
|
+
for (const entry of entries) {
|
|
83
|
+
const entryPath = ctx.fs.resolve(path, entry);
|
|
84
|
+
try {
|
|
85
|
+
const entryStat = await ctx.fs.stat(entryPath);
|
|
86
|
+
if (entryStat.isDirectory()) {
|
|
87
|
+
dirEntries.push(entry);
|
|
88
|
+
} else {
|
|
89
|
+
fileEntries.push(entry);
|
|
90
|
+
}
|
|
91
|
+
} catch {}
|
|
92
|
+
}
|
|
93
|
+
const sortedEntries = directoriesOnly ? dirEntries : [...dirEntries, ...fileEntries];
|
|
94
|
+
for (let i = 0;i < sortedEntries.length; i++) {
|
|
95
|
+
const entry = sortedEntries[i];
|
|
96
|
+
const isLast = i === sortedEntries.length - 1;
|
|
97
|
+
const connector = isLast ? "└── " : "├── ";
|
|
98
|
+
const entryPath = ctx.fs.resolve(path, entry);
|
|
99
|
+
let isDir = false;
|
|
100
|
+
try {
|
|
101
|
+
const entryStat = await ctx.fs.stat(entryPath);
|
|
102
|
+
isDir = entryStat.isDirectory();
|
|
103
|
+
} catch {
|
|
104
|
+
continue;
|
|
105
|
+
}
|
|
106
|
+
await ctx.stdout.writeText(prefix + connector + entry + `
|
|
107
|
+
`);
|
|
108
|
+
if (isDir) {
|
|
109
|
+
dirCount++;
|
|
110
|
+
if (depth < maxDepth) {
|
|
111
|
+
const newPrefix = prefix + (isLast ? " " : "│ ");
|
|
112
|
+
await printTree(entryPath, newPrefix, depth + 1);
|
|
113
|
+
}
|
|
114
|
+
} else {
|
|
115
|
+
fileCount++;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
await printTree(resolvedPath, "", 1);
|
|
120
|
+
const dirWord = dirCount === 1 ? "directory" : "directories";
|
|
121
|
+
const fileWord = fileCount === 1 ? "file" : "files";
|
|
122
|
+
await ctx.stdout.writeText(`
|
|
123
|
+
${dirCount} ${dirWord}, ${fileCount} ${fileWord}
|
|
124
|
+
`);
|
|
125
|
+
return 0;
|
|
126
|
+
};
|
|
127
|
+
export {
|
|
128
|
+
tree
|
|
129
|
+
};
|
|
130
|
+
|
|
131
|
+
//# debugId=226DC5A2B9E71D1764756E2164756E21
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../../src/commands/tree/tree.ts"],
|
|
4
|
+
"sourcesContent": [
|
|
5
|
+
"import type { Command } from \"../../types.mjs\";\n\nexport const tree: Command = async (ctx) => {\n let showAll = false;\n let directoriesOnly = false;\n let maxDepth = Infinity;\n let targetPath = \".\";\n\n // Parse arguments\n const args = [...ctx.args];\n for (let i = 0; i < args.length; i++) {\n const arg = args[i]!;\n if (arg === \"-a\" || arg === \"--all\") {\n showAll = true;\n } else if (arg === \"-d\") {\n directoriesOnly = true;\n } else if (arg === \"-L\") {\n const depthArg = args[++i];\n if (depthArg === undefined || isNaN(parseInt(depthArg, 10))) {\n await ctx.stderr.writeText(\"tree: missing argument to -L\\n\");\n return 1;\n }\n maxDepth = parseInt(depthArg, 10);\n if (maxDepth < 1) {\n await ctx.stderr.writeText(\"tree: Invalid level, must be greater than 0\\n\");\n return 1;\n }\n } else if (arg.startsWith(\"-L\")) {\n // Handle -L2 format (no space)\n const depthStr = arg.slice(2);\n const depth = parseInt(depthStr, 10);\n if (isNaN(depth) || depth < 1) {\n await ctx.stderr.writeText(\"tree: Invalid level, must be greater than 0\\n\");\n return 1;\n }\n maxDepth = depth;\n } else if (arg.startsWith(\"-\") && arg !== \"-\") {\n // Handle combined short flags\n for (const flag of arg.slice(1)) {\n if (flag === \"a\") showAll = true;\n else if (flag === \"d\") directoriesOnly = true;\n else {\n await ctx.stderr.writeText(`tree: Invalid argument -${flag}\\n`);\n return 1;\n }\n }\n } else {\n targetPath = arg;\n }\n }\n\n const resolvedPath = ctx.fs.resolve(ctx.cwd, targetPath);\n\n // Check if path exists\n let stat;\n try {\n stat = await ctx.fs.stat(resolvedPath);\n } catch {\n await ctx.stderr.writeText(`tree: ${targetPath}: No such file or directory\\n`);\n return 1;\n }\n\n // If it's a file, just print the filename\n if (stat.isFile()) {\n await ctx.stdout.writeText(targetPath + \"\\n\\n0 directories, 1 file\\n\");\n return 0;\n }\n\n let dirCount = 0;\n let fileCount = 0;\n\n // Print root\n await ctx.stdout.writeText(targetPath + \"\\n\");\n\n // Recursive function to build tree\n async function printTree(path: string, prefix: string, depth: number): Promise<void> {\n if (depth > maxDepth) return;\n\n let entries = await ctx.fs.readdir(path);\n\n // Filter hidden files unless -a\n if (!showAll) {\n entries = entries.filter((e) => !e.startsWith(\".\"));\n }\n\n // Sort entries\n entries.sort();\n\n // Separate dirs and files, dirs first\n const dirEntries: string[] = [];\n const fileEntries: string[] = [];\n\n for (const entry of entries) {\n const entryPath = ctx.fs.resolve(path, entry);\n try {\n const entryStat = await ctx.fs.stat(entryPath);\n if (entryStat.isDirectory()) {\n dirEntries.push(entry);\n } else {\n fileEntries.push(entry);\n }\n } catch {\n // Skip entries we can't stat\n }\n }\n\n // Combine: directories first, then files (unless directoriesOnly)\n const sortedEntries = directoriesOnly\n ? dirEntries\n : [...dirEntries, ...fileEntries];\n\n for (let i = 0; i < sortedEntries.length; i++) {\n const entry = sortedEntries[i]!;\n const isLast = i === sortedEntries.length - 1;\n const connector = isLast ? \"└── \" : \"├── \";\n const entryPath = ctx.fs.resolve(path, entry);\n\n let isDir = false;\n try {\n const entryStat = await ctx.fs.stat(entryPath);\n isDir = entryStat.isDirectory();\n } catch {\n continue;\n }\n\n await ctx.stdout.writeText(prefix + connector + entry + \"\\n\");\n\n if (isDir) {\n dirCount++;\n if (depth < maxDepth) {\n const newPrefix = prefix + (isLast ? \" \" : \"│ \");\n await printTree(entryPath, newPrefix, depth + 1);\n }\n } else {\n fileCount++;\n }\n }\n }\n\n await printTree(resolvedPath, \"\", 1);\n\n // Print summary\n const dirWord = dirCount === 1 ? \"directory\" : \"directories\";\n const fileWord = fileCount === 1 ? \"file\" : \"files\";\n await ctx.stdout.writeText(`\\n${dirCount} ${dirWord}, ${fileCount} ${fileWord}\\n`);\n\n return 0;\n};\n"
|
|
6
|
+
],
|
|
7
|
+
"mappings": "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",
|
|
8
|
+
"debugId": "226DC5A2B9E71D1764756E2164756E21",
|
|
9
|
+
"names": []
|
|
10
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../../src/commands/true-false/true-false.ts"],
|
|
4
|
+
"sourcesContent": [
|
|
5
|
+
"import type { Command } from \"../../types.mjs\";\n\nexport const trueCmd: Command = async () => {\n return 0;\n};\n\nexport const falseCmd: Command = async () => {\n return 1;\n};\n"
|
|
6
|
+
],
|
|
7
|
+
"mappings": ";AAEO,IAAM,UAAmB,YAAY;AAAA,EAC1C,OAAO;AAAA;AAGF,IAAM,WAAoB,YAAY;AAAA,EAC3C,OAAO;AAAA;",
|
|
8
|
+
"debugId": "7B305164589F4D3464756E2164756E21",
|
|
9
|
+
"names": []
|
|
10
|
+
}
|