shell-dsl 0.0.37 → 0.0.39
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 +4 -3
- package/dist/cjs/index.cjs +2 -1
- package/dist/cjs/index.cjs.map +3 -3
- package/dist/cjs/package.json +1 -1
- package/dist/cjs/src/commands/find/find.cjs +27 -11
- package/dist/cjs/src/commands/find/find.cjs.map +3 -3
- package/dist/cjs/src/commands/index.cjs +5 -1
- package/dist/cjs/src/commands/index.cjs.map +3 -3
- package/dist/cjs/src/commands/printf/printf.cjs +416 -0
- package/dist/cjs/src/commands/printf/printf.cjs.map +10 -0
- package/dist/cjs/src/commands/tree/tree.cjs +15 -8
- package/dist/cjs/src/commands/tree/tree.cjs.map +3 -3
- package/dist/mjs/index.mjs +3 -1
- package/dist/mjs/index.mjs.map +3 -3
- package/dist/mjs/package.json +1 -1
- package/dist/mjs/src/commands/find/find.mjs +27 -11
- package/dist/mjs/src/commands/find/find.mjs.map +3 -3
- package/dist/mjs/src/commands/index.mjs +5 -1
- package/dist/mjs/src/commands/index.mjs.map +3 -3
- package/dist/mjs/src/commands/printf/printf.mjs +376 -0
- package/dist/mjs/src/commands/printf/printf.mjs.map +10 -0
- package/dist/mjs/src/commands/tree/tree.mjs +15 -8
- package/dist/mjs/src/commands/tree/tree.mjs.map +3 -3
- package/dist/types/index.d.ts +1 -1
- package/dist/types/src/commands/index.d.ts +1 -0
- package/dist/types/src/commands/printf/printf.d.ts +2 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -567,12 +567,13 @@ import { builtinCommands } from "shell-dsl/commands";
|
|
|
567
567
|
Or import individually:
|
|
568
568
|
|
|
569
569
|
```ts
|
|
570
|
-
import { echo, cat, grep, wc, cp, mv, touch, tee, tree, find, sed, awk, cut, od } from "shell-dsl/commands";
|
|
570
|
+
import { echo, printf, cat, grep, wc, cp, mv, touch, tee, tree, find, sed, awk, cut, od } from "shell-dsl/commands";
|
|
571
571
|
```
|
|
572
572
|
|
|
573
573
|
| Command | Description |
|
|
574
574
|
|---------|-------------|
|
|
575
575
|
| `echo` | Print arguments to stdout |
|
|
576
|
+
| `printf` | Format output without an implicit trailing newline (`%s`, `%b`, numeric formats, escapes) |
|
|
576
577
|
| `cat` | Concatenate files or stdin to stdout |
|
|
577
578
|
| `grep` | Linux-compatible pattern search |
|
|
578
579
|
| `wc` | Count lines, words, or characters (`-l`, `-w`, `-c`) |
|
|
@@ -588,8 +589,8 @@ import { echo, cat, grep, wc, cp, mv, touch, tee, tree, find, sed, awk, cut, od
|
|
|
588
589
|
| `mv` | Move/rename files/directories (`-n` no-clobber) |
|
|
589
590
|
| `touch` | Create empty files or update timestamps (`-c` no-create) |
|
|
590
591
|
| `tee` | Duplicate stdin to stdout and files (`-a` append) |
|
|
591
|
-
| `tree` | Display directory structure as tree (`-a` all, `-d` dirs only, `-L <n>` depth, `-I <pattern>` ignore, `--prune` remove empty dirs) |
|
|
592
|
-
| `find` | Search for files (`-name`, `-iname`, `-type f\|d`, `-maxdepth`, `-mindepth`) |
|
|
592
|
+
| `tree` | Display directory structure as tree (`-a` all, `-d` dirs only, `-L <n>` depth, `-I <pattern>` ignore, `--prune` remove empty dirs, `--noreport` hide summary) |
|
|
593
|
+
| `find` | Search for files (`-name`, `-iname`, `-type f\|d`, `-maxdepth`, `-mindepth`, `-print`) |
|
|
593
594
|
| `sed` | Stream editor (`s///`, `d`, `p`, `-n`, `-e`) |
|
|
594
595
|
| `awk` | Pattern scanning (`{print $1}`, `-F`, `NF`, `NR`) |
|
|
595
596
|
| `cut` | Select fields/characters (`-f`, `-d`, `-c`, `-b`, `-s`, `--complement`) |
|
package/dist/cjs/index.cjs
CHANGED
|
@@ -69,6 +69,7 @@ __export(exports_shell_dsl, {
|
|
|
69
69
|
sed: () => import_commands2.sed,
|
|
70
70
|
rm: () => import_commands2.rm,
|
|
71
71
|
pwd: () => import_commands2.pwd,
|
|
72
|
+
printf: () => import_commands2.printf,
|
|
72
73
|
od: () => import_commands2.od,
|
|
73
74
|
mv: () => import_commands2.mv,
|
|
74
75
|
mkdir: () => import_commands2.mkdir,
|
|
@@ -91,4 +92,4 @@ __reExport(exports_shell_dsl, require("./src/index.cjs"), module.exports);
|
|
|
91
92
|
var import_commands = require("./src/commands/index.cjs");
|
|
92
93
|
var import_commands2 = require("./src/commands/index.cjs");
|
|
93
94
|
|
|
94
|
-
//# debugId=
|
|
95
|
+
//# debugId=B2100C1B0A657D9464756E2164756E21
|
package/dist/cjs/index.cjs.map
CHANGED
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../index.ts"],
|
|
4
4
|
"sourcesContent": [
|
|
5
|
-
"// Re-export everything from src\nexport * from \"./src/index.cjs\";\n\n// Re-export built-in commands\nexport { builtinCommands } from \"./src/commands/index.cjs\";\nexport {\n echo,\n cat,\n grep,\n wc,\n head,\n tail,\n sort,\n uniq,\n pwd,\n ls,\n mkdir,\n rm,\n test,\n bracket,\n trueCmd,\n falseCmd,\n touch,\n cp,\n mv,\n tee,\n tree,\n find,\n sed,\n awk,\n breakCmd,\n continueCmd,\n od,\n} from \"./src/commands/index.cjs\";\n"
|
|
5
|
+
"// Re-export everything from src\nexport * from \"./src/index.cjs\";\n\n// Re-export built-in commands\nexport { builtinCommands } from \"./src/commands/index.cjs\";\nexport {\n echo,\n printf,\n cat,\n grep,\n wc,\n head,\n tail,\n sort,\n uniq,\n pwd,\n ls,\n mkdir,\n rm,\n test,\n bracket,\n trueCmd,\n falseCmd,\n touch,\n cp,\n mv,\n tee,\n tree,\n find,\n sed,\n awk,\n breakCmd,\n continueCmd,\n od,\n} from \"./src/commands/index.cjs\";\n"
|
|
6
6
|
],
|
|
7
|
-
"mappings": "
|
|
8
|
-
"debugId": "
|
|
7
|
+
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AACA;AAGgC,IAAhC;AA8BO,IA7BP;",
|
|
8
|
+
"debugId": "B2100C1B0A657D9464756E2164756E21",
|
|
9
9
|
"names": []
|
|
10
10
|
}
|
package/dist/cjs/package.json
CHANGED
|
@@ -43,7 +43,7 @@ __export(exports_find, {
|
|
|
43
43
|
});
|
|
44
44
|
module.exports = __toCommonJS(exports_find);
|
|
45
45
|
var import_match_glob = require("../../utils/match-glob.cjs");
|
|
46
|
-
async function evalExpr(expr, basename, isFile, isDir, entryPath, ctx) {
|
|
46
|
+
async function evalExpr(expr, basename, isFile, isDir, entryPath, ctx, runActions) {
|
|
47
47
|
switch (expr.type) {
|
|
48
48
|
case "true":
|
|
49
49
|
return true;
|
|
@@ -52,23 +52,32 @@ async function evalExpr(expr, basename, isFile, isDir, entryPath, ctx) {
|
|
|
52
52
|
case "ftype":
|
|
53
53
|
return expr.value === "f" ? isFile : isDir;
|
|
54
54
|
case "and": {
|
|
55
|
-
const leftResult = await evalExpr(expr.left, basename, isFile, isDir, entryPath, ctx);
|
|
55
|
+
const leftResult = await evalExpr(expr.left, basename, isFile, isDir, entryPath, ctx, runActions);
|
|
56
56
|
if (!leftResult)
|
|
57
57
|
return false;
|
|
58
|
-
return evalExpr(expr.right, basename, isFile, isDir, entryPath, ctx);
|
|
58
|
+
return evalExpr(expr.right, basename, isFile, isDir, entryPath, ctx, runActions);
|
|
59
59
|
}
|
|
60
60
|
case "or": {
|
|
61
|
-
const leftResult = await evalExpr(expr.left, basename, isFile, isDir, entryPath, ctx);
|
|
61
|
+
const leftResult = await evalExpr(expr.left, basename, isFile, isDir, entryPath, ctx, runActions);
|
|
62
62
|
if (leftResult)
|
|
63
63
|
return true;
|
|
64
|
-
return evalExpr(expr.right, basename, isFile, isDir, entryPath, ctx);
|
|
64
|
+
return evalExpr(expr.right, basename, isFile, isDir, entryPath, ctx, runActions);
|
|
65
65
|
}
|
|
66
66
|
case "not":
|
|
67
|
-
return !await evalExpr(expr.expr, basename, isFile, isDir, entryPath, ctx);
|
|
67
|
+
return !await evalExpr(expr.expr, basename, isFile, isDir, entryPath, ctx, runActions);
|
|
68
|
+
case "print":
|
|
69
|
+
if (runActions) {
|
|
70
|
+
await ctx.stdout.writeText(entryPath + `
|
|
71
|
+
`);
|
|
72
|
+
}
|
|
73
|
+
return true;
|
|
68
74
|
case "exec": {
|
|
69
75
|
if (expr.batchMode) {
|
|
70
76
|
return true;
|
|
71
77
|
}
|
|
78
|
+
if (!runActions) {
|
|
79
|
+
return true;
|
|
80
|
+
}
|
|
72
81
|
if (!ctx.exec) {
|
|
73
82
|
await ctx.stderr.writeText(`find: -exec not supported (no exec capability)
|
|
74
83
|
`);
|
|
@@ -88,6 +97,7 @@ async function evalExpr(expr, basename, isFile, isDir, entryPath, ctx) {
|
|
|
88
97
|
}
|
|
89
98
|
function hasActionExpr(expr) {
|
|
90
99
|
switch (expr.type) {
|
|
100
|
+
case "print":
|
|
91
101
|
case "exec":
|
|
92
102
|
return true;
|
|
93
103
|
case "and":
|
|
@@ -226,6 +236,10 @@ function parseExprArgs(args) {
|
|
|
226
236
|
}
|
|
227
237
|
return { type: "exec", cmdName, cmdArgs, batchMode };
|
|
228
238
|
}
|
|
239
|
+
if (tok === "-print") {
|
|
240
|
+
advance();
|
|
241
|
+
return { type: "print" };
|
|
242
|
+
}
|
|
229
243
|
throw new ParseError(`find: unknown predicate '${tok}'`);
|
|
230
244
|
}
|
|
231
245
|
const expr = parseOr();
|
|
@@ -324,8 +338,9 @@ var find = async (ctx) => {
|
|
|
324
338
|
const isDir = entryStat.isDirectory();
|
|
325
339
|
const isFile = entryStat.isFile();
|
|
326
340
|
const basename = ctx.fs.basename(path);
|
|
327
|
-
const
|
|
328
|
-
|
|
341
|
+
const meetsMinDepth = minDepth === undefined || depth >= minDepth;
|
|
342
|
+
const matches = await evalExpr(expr, basename, isFile, isDir, displayPath, ctx, meetsMinDepth);
|
|
343
|
+
if (matches && meetsMinDepth) {
|
|
329
344
|
if (batchExecNodes.length > 0) {
|
|
330
345
|
batchPaths.push(displayPath);
|
|
331
346
|
} else if (!hasAction) {
|
|
@@ -347,8 +362,9 @@ var find = async (ctx) => {
|
|
|
347
362
|
}
|
|
348
363
|
if (stat.isFile()) {
|
|
349
364
|
const basename = ctx.fs.basename(resolvedStart);
|
|
350
|
-
const
|
|
351
|
-
|
|
365
|
+
const meetsMinDepth = minDepth === undefined || minDepth <= 0;
|
|
366
|
+
const matches = await evalExpr(expr, basename, true, false, normalizedPath, ctx, meetsMinDepth);
|
|
367
|
+
if (maxDepth !== undefined && maxDepth < 0) {} else if (matches && meetsMinDepth) {
|
|
352
368
|
if (batchExecNodes.length > 0) {
|
|
353
369
|
batchPaths.push(normalizedPath);
|
|
354
370
|
} else if (!hasAction) {
|
|
@@ -382,4 +398,4 @@ var find = async (ctx) => {
|
|
|
382
398
|
return hasError ? 1 : 0;
|
|
383
399
|
};
|
|
384
400
|
|
|
385
|
-
//# debugId=
|
|
401
|
+
//# debugId=BF345B4B7EBB593364756E2164756E21
|
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../../src/commands/find/find.ts"],
|
|
4
4
|
"sourcesContent": [
|
|
5
|
-
"import type { Command, CommandContext, ExecResult } from \"../../types.cjs\";\nimport { matchGlob } from \"../../utils/match-glob.cjs\";\n\n// Expression tree types\ntype FindExpr =\n | { type: \"name\"; pattern: string; ignoreCase: boolean }\n | { type: \"ftype\"; value: \"f\" | \"d\" }\n | { type: \"and\"; left: FindExpr; right: FindExpr }\n | { type: \"or\"; left: FindExpr; right: FindExpr }\n | { type: \"not\"; expr: FindExpr }\n | { type: \"true\" }\n | { type: \"exec\"; cmdName: string; cmdArgs: string[]; batchMode: boolean };\n\nasync function evalExpr(\n expr: FindExpr,\n basename: string,\n isFile: boolean,\n isDir: boolean,\n entryPath: string,\n ctx: CommandContext,\n): Promise<boolean> {\n switch (expr.type) {\n case \"true\":\n return true;\n case \"name\":\n return matchGlob(expr.pattern, basename, expr.ignoreCase);\n case \"ftype\":\n return expr.value === \"f\" ? isFile : isDir;\n case \"and\": {\n const leftResult = await evalExpr(expr.left, basename, isFile, isDir, entryPath, ctx);\n if (!leftResult) return false;\n return evalExpr(expr.right, basename, isFile, isDir, entryPath, ctx);\n }\n case \"or\": {\n const leftResult = await evalExpr(expr.left, basename, isFile, isDir, entryPath, ctx);\n if (leftResult) return true;\n return evalExpr(expr.right, basename, isFile, isDir, entryPath, ctx);\n }\n case \"not\":\n return !(await evalExpr(expr.expr, basename, isFile, isDir, entryPath, ctx));\n case \"exec\": {\n if (expr.batchMode) {\n // In batch mode, always return true during traversal; paths are collected externally\n return true;\n }\n // Per-file mode: execute command with {} replaced by entryPath\n if (!ctx.exec) {\n await ctx.stderr.writeText(\"find: -exec not supported (no exec capability)\\n\");\n return false;\n }\n const resolvedArgs = expr.cmdArgs.map(a => a === \"{}\" ? entryPath : a);\n const result: ExecResult = await ctx.exec(expr.cmdName, resolvedArgs);\n // Pass stdout/stderr through to find's streams\n if (result.stdout.length > 0) {\n await ctx.stdout.write(result.stdout);\n }\n if (result.stderr.length > 0) {\n await ctx.stderr.write(result.stderr);\n }\n return result.exitCode === 0;\n }\n }\n}\n\n/** Check if expression tree contains any -exec node */\nfunction hasActionExpr(expr: FindExpr): boolean {\n switch (expr.type) {\n case \"exec\":\n return true;\n case \"and\":\n case \"or\":\n return hasActionExpr(expr.left) || hasActionExpr(expr.right);\n case \"not\":\n return hasActionExpr(expr.expr);\n default:\n return false;\n }\n}\n\n/** Collect all batch-mode -exec nodes from the expression tree */\nfunction collectBatchExecNodes(expr: FindExpr): Array<{ type: \"exec\"; cmdName: string; cmdArgs: string[]; batchMode: boolean }> {\n switch (expr.type) {\n case \"exec\":\n return expr.batchMode ? [expr] : [];\n case \"and\":\n case \"or\":\n return [...collectBatchExecNodes(expr.left), ...collectBatchExecNodes(expr.right)];\n case \"not\":\n return collectBatchExecNodes(expr.expr);\n default:\n return [];\n }\n}\n\nclass ParseError extends Error {\n constructor(msg: string) {\n super(msg);\n }\n}\n\nfunction parseExprArgs(args: string[]): FindExpr {\n if (args.length === 0) return { type: \"true\" };\n\n let pos = 0;\n\n function peek(): string | undefined {\n return args[pos];\n }\n\n function advance(): string {\n return args[pos++]!;\n }\n\n function parseOr(): FindExpr {\n let left = parseAnd();\n while (peek() === \"-o\") {\n advance();\n const right = parseAnd();\n left = { type: \"or\", left, right };\n }\n return left;\n }\n\n function parseAnd(): FindExpr {\n let left = parseUnary();\n while (pos < args.length) {\n const next = peek();\n if (next === \"-o\" || next === \")\" || next === undefined) break;\n if (next === \"-a\") {\n advance();\n }\n const right = parseUnary();\n left = { type: \"and\", left, right };\n }\n return left;\n }\n\n function parseUnary(): FindExpr {\n const next = peek();\n if (next === \"!\" || next === \"-not\") {\n advance();\n const expr = parseUnary();\n return { type: \"not\", expr };\n }\n return parsePrimary();\n }\n\n function parsePrimary(): FindExpr {\n const tok = peek();\n if (tok === undefined) {\n throw new ParseError(\"find: expected expression\");\n }\n\n if (tok === \"(\") {\n advance();\n const expr = parseOr();\n if (peek() !== \")\") {\n throw new ParseError(\"find: missing closing ')'\");\n }\n advance();\n return expr;\n }\n\n if (tok === \"-name\" || tok === \"-iname\") {\n advance();\n const pattern = peek();\n if (pattern === undefined) {\n throw new ParseError(`find: missing argument to '${tok}'`);\n }\n advance();\n return { type: \"name\", pattern, ignoreCase: tok === \"-iname\" };\n }\n\n if (tok === \"-type\") {\n advance();\n const val = peek();\n if (val === undefined) {\n throw new ParseError(\"find: missing argument to '-type'\");\n }\n if (val !== \"f\" && val !== \"d\") {\n throw new ParseError(`find: Unknown argument to -type: ${val}`);\n }\n advance();\n return { type: \"ftype\", value: val };\n }\n\n if (tok === \"-exec\") {\n advance();\n const cmdName = peek();\n if (cmdName === undefined || cmdName === \";\" || cmdName === \"+\") {\n throw new ParseError(\"find: -exec: missing command\");\n }\n advance();\n\n const cmdArgs: string[] = [];\n let batchMode = false;\n let foundTerminator = false;\n\n while (pos < args.length) {\n const a = args[pos]!;\n if (a === \";\") {\n advance();\n foundTerminator = true;\n break;\n }\n if (a === \"+\") {\n advance();\n batchMode = true;\n foundTerminator = true;\n break;\n }\n cmdArgs.push(a);\n advance();\n }\n\n if (!foundTerminator) {\n throw new ParseError(\"find: -exec: missing terminator (';' or '+')\");\n }\n\n return { type: \"exec\", cmdName, cmdArgs, batchMode };\n }\n\n throw new ParseError(`find: unknown predicate '${tok}'`);\n }\n\n const expr = parseOr();\n if (pos < args.length) {\n throw new ParseError(`find: unexpected '${args[pos]}'`);\n }\n return expr;\n}\n\nexport const find: Command = async (ctx) => {\n const args = [...ctx.args];\n const paths: string[] = [];\n\n // Parse arguments: paths come before first flag/operator\n let i = 0;\n\n // Collect paths (args before first -, !, or ()\n while (i < args.length && !args[i]!.startsWith(\"-\") && args[i] !== \"!\" && args[i] !== \"(\" && args[i] !== \")\") {\n paths.push(args[i]!);\n i++;\n }\n\n // Default to current directory if no paths\n if (paths.length === 0) {\n paths.push(\".\");\n }\n\n // Extract global options (-maxdepth, -mindepth) from remaining args\n let maxDepth: number | undefined;\n let minDepth: number | undefined;\n const exprArgs: string[] = [];\n\n let j = i;\n while (j < args.length) {\n const arg = args[j]!;\n if (arg === \"-maxdepth\") {\n j++;\n if (j >= args.length) {\n await ctx.stderr.writeText(\"find: missing argument to '-maxdepth'\\n\");\n return 1;\n }\n const depth = parseInt(args[j]!, 10);\n if (isNaN(depth) || depth < 0) {\n await ctx.stderr.writeText(`find: Invalid argument '${args[j]}' to -maxdepth\\n`);\n return 1;\n }\n maxDepth = depth;\n } else if (arg === \"-mindepth\") {\n j++;\n if (j >= args.length) {\n await ctx.stderr.writeText(\"find: missing argument to '-mindepth'\\n\");\n return 1;\n }\n const depth = parseInt(args[j]!, 10);\n if (isNaN(depth) || depth < 0) {\n await ctx.stderr.writeText(`find: Invalid argument '${args[j]}' to -mindepth\\n`);\n return 1;\n }\n minDepth = depth;\n } else {\n exprArgs.push(arg);\n }\n j++;\n }\n\n // Parse expression tree\n let expr: FindExpr;\n try {\n expr = parseExprArgs(exprArgs);\n } catch (e) {\n if (e instanceof ParseError) {\n await ctx.stderr.writeText(e.message + \"\\n\");\n return 1;\n }\n throw e;\n }\n\n const hasAction = hasActionExpr(expr);\n const batchExecNodes = collectBatchExecNodes(expr);\n const batchPaths: string[] = [];\n\n let hasError = false;\n\n // Process each starting path\n for (const startPath of paths) {\n const normalizedPath = startPath === \"/\" ? \"/\" : startPath.replace(/\\/+$/, '');\n const resolvedStart = ctx.fs.resolve(ctx.cwd, startPath);\n\n // Check if path exists\n let stat;\n try {\n stat = await ctx.fs.stat(resolvedStart);\n } catch {\n await ctx.stderr.writeText(`find: '${startPath}': No such file or directory\\n`);\n hasError = true;\n continue;\n }\n\n // Recursive traversal function\n async function traverse(path: string, displayPath: string, depth: number): Promise<void> {\n // Check maxdepth\n if (maxDepth !== undefined && depth > maxDepth) {\n return;\n }\n\n let entryStat;\n try {\n entryStat = await ctx.fs.stat(path);\n } catch {\n return;\n }\n\n const isDir = entryStat.isDirectory();\n const isFile = entryStat.isFile();\n const basename = ctx.fs.basename(path);\n\n // Check if this entry matches the expression\n const matches = await evalExpr(expr, basename, isFile, isDir, displayPath, ctx);\n\n if (matches && (minDepth === undefined || depth >= minDepth)) {\n if (batchExecNodes.length > 0) {\n batchPaths.push(displayPath);\n } else if (!hasAction) {\n // No action expressions: default print behavior\n await ctx.stdout.writeText(displayPath + \"\\n\");\n }\n // If has per-file -exec actions, output was already handled in evalExpr\n }\n\n // Recurse into directories\n if (isDir) {\n try {\n const entries = await ctx.fs.readdir(path);\n entries.sort();\n for (const entry of entries) {\n const childPath = ctx.fs.resolve(path, entry);\n const childDisplayPath = displayPath === \".\" ? entry : `${displayPath}/${entry}`;\n await traverse(childPath, childDisplayPath, depth + 1);\n }\n } catch {\n // Ignore errors reading directory contents\n }\n }\n }\n\n // Start traversal\n if (stat.isFile()) {\n const basename = ctx.fs.basename(resolvedStart);\n const matches = await evalExpr(expr, basename, true, false, normalizedPath, ctx);\n\n if (maxDepth !== undefined && maxDepth < 0) {\n // skip\n } else if (matches && (minDepth === undefined || minDepth <= 0)) {\n if (batchExecNodes.length > 0) {\n batchPaths.push(normalizedPath);\n } else if (!hasAction) {\n await ctx.stdout.writeText(normalizedPath + \"\\n\");\n }\n }\n } else {\n await traverse(resolvedStart, normalizedPath, 0);\n }\n }\n\n // Execute batch -exec nodes with all collected paths\n if (batchExecNodes.length > 0 && batchPaths.length > 0 && ctx.exec) {\n for (const node of batchExecNodes) {\n // Replace {} in cmdArgs with all paths\n const resolvedArgs: string[] = [];\n for (const a of node.cmdArgs) {\n if (a === \"{}\") {\n resolvedArgs.push(...batchPaths);\n } else {\n resolvedArgs.push(a);\n }\n }\n const result = await ctx.exec(node.cmdName, resolvedArgs);\n if (result.stdout.length > 0) {\n await ctx.stdout.write(result.stdout);\n }\n if (result.stderr.length > 0) {\n await ctx.stderr.write(result.stderr);\n }\n }\n }\n\n return hasError ? 1 : 0;\n};\n"
|
|
5
|
+
"import type { Command, CommandContext, ExecResult } from \"../../types.cjs\";\nimport { matchGlob } from \"../../utils/match-glob.cjs\";\n\n// Expression tree types\ntype FindExpr =\n | { type: \"name\"; pattern: string; ignoreCase: boolean }\n | { type: \"ftype\"; value: \"f\" | \"d\" }\n | { type: \"and\"; left: FindExpr; right: FindExpr }\n | { type: \"or\"; left: FindExpr; right: FindExpr }\n | { type: \"not\"; expr: FindExpr }\n | { type: \"true\" }\n | { type: \"print\" }\n | { type: \"exec\"; cmdName: string; cmdArgs: string[]; batchMode: boolean };\n\nasync function evalExpr(\n expr: FindExpr,\n basename: string,\n isFile: boolean,\n isDir: boolean,\n entryPath: string,\n ctx: CommandContext,\n runActions: boolean,\n): Promise<boolean> {\n switch (expr.type) {\n case \"true\":\n return true;\n case \"name\":\n return matchGlob(expr.pattern, basename, expr.ignoreCase);\n case \"ftype\":\n return expr.value === \"f\" ? isFile : isDir;\n case \"and\": {\n const leftResult = await evalExpr(expr.left, basename, isFile, isDir, entryPath, ctx, runActions);\n if (!leftResult) return false;\n return evalExpr(expr.right, basename, isFile, isDir, entryPath, ctx, runActions);\n }\n case \"or\": {\n const leftResult = await evalExpr(expr.left, basename, isFile, isDir, entryPath, ctx, runActions);\n if (leftResult) return true;\n return evalExpr(expr.right, basename, isFile, isDir, entryPath, ctx, runActions);\n }\n case \"not\":\n return !(await evalExpr(expr.expr, basename, isFile, isDir, entryPath, ctx, runActions));\n case \"print\":\n if (runActions) {\n await ctx.stdout.writeText(entryPath + \"\\n\");\n }\n return true;\n case \"exec\": {\n if (expr.batchMode) {\n // In batch mode, always return true during traversal; paths are collected externally\n return true;\n }\n if (!runActions) {\n return true;\n }\n // Per-file mode: execute command with {} replaced by entryPath\n if (!ctx.exec) {\n await ctx.stderr.writeText(\"find: -exec not supported (no exec capability)\\n\");\n return false;\n }\n const resolvedArgs = expr.cmdArgs.map(a => a === \"{}\" ? entryPath : a);\n const result: ExecResult = await ctx.exec(expr.cmdName, resolvedArgs);\n // Pass stdout/stderr through to find's streams\n if (result.stdout.length > 0) {\n await ctx.stdout.write(result.stdout);\n }\n if (result.stderr.length > 0) {\n await ctx.stderr.write(result.stderr);\n }\n return result.exitCode === 0;\n }\n }\n}\n\n/** Check if expression tree contains any -exec node */\nfunction hasActionExpr(expr: FindExpr): boolean {\n switch (expr.type) {\n case \"print\":\n case \"exec\":\n return true;\n case \"and\":\n case \"or\":\n return hasActionExpr(expr.left) || hasActionExpr(expr.right);\n case \"not\":\n return hasActionExpr(expr.expr);\n default:\n return false;\n }\n}\n\n/** Collect all batch-mode -exec nodes from the expression tree */\nfunction collectBatchExecNodes(expr: FindExpr): Array<{ type: \"exec\"; cmdName: string; cmdArgs: string[]; batchMode: boolean }> {\n switch (expr.type) {\n case \"exec\":\n return expr.batchMode ? [expr] : [];\n case \"and\":\n case \"or\":\n return [...collectBatchExecNodes(expr.left), ...collectBatchExecNodes(expr.right)];\n case \"not\":\n return collectBatchExecNodes(expr.expr);\n default:\n return [];\n }\n}\n\nclass ParseError extends Error {\n constructor(msg: string) {\n super(msg);\n }\n}\n\nfunction parseExprArgs(args: string[]): FindExpr {\n if (args.length === 0) return { type: \"true\" };\n\n let pos = 0;\n\n function peek(): string | undefined {\n return args[pos];\n }\n\n function advance(): string {\n return args[pos++]!;\n }\n\n function parseOr(): FindExpr {\n let left = parseAnd();\n while (peek() === \"-o\") {\n advance();\n const right = parseAnd();\n left = { type: \"or\", left, right };\n }\n return left;\n }\n\n function parseAnd(): FindExpr {\n let left = parseUnary();\n while (pos < args.length) {\n const next = peek();\n if (next === \"-o\" || next === \")\" || next === undefined) break;\n if (next === \"-a\") {\n advance();\n }\n const right = parseUnary();\n left = { type: \"and\", left, right };\n }\n return left;\n }\n\n function parseUnary(): FindExpr {\n const next = peek();\n if (next === \"!\" || next === \"-not\") {\n advance();\n const expr = parseUnary();\n return { type: \"not\", expr };\n }\n return parsePrimary();\n }\n\n function parsePrimary(): FindExpr {\n const tok = peek();\n if (tok === undefined) {\n throw new ParseError(\"find: expected expression\");\n }\n\n if (tok === \"(\") {\n advance();\n const expr = parseOr();\n if (peek() !== \")\") {\n throw new ParseError(\"find: missing closing ')'\");\n }\n advance();\n return expr;\n }\n\n if (tok === \"-name\" || tok === \"-iname\") {\n advance();\n const pattern = peek();\n if (pattern === undefined) {\n throw new ParseError(`find: missing argument to '${tok}'`);\n }\n advance();\n return { type: \"name\", pattern, ignoreCase: tok === \"-iname\" };\n }\n\n if (tok === \"-type\") {\n advance();\n const val = peek();\n if (val === undefined) {\n throw new ParseError(\"find: missing argument to '-type'\");\n }\n if (val !== \"f\" && val !== \"d\") {\n throw new ParseError(`find: Unknown argument to -type: ${val}`);\n }\n advance();\n return { type: \"ftype\", value: val };\n }\n\n if (tok === \"-exec\") {\n advance();\n const cmdName = peek();\n if (cmdName === undefined || cmdName === \";\" || cmdName === \"+\") {\n throw new ParseError(\"find: -exec: missing command\");\n }\n advance();\n\n const cmdArgs: string[] = [];\n let batchMode = false;\n let foundTerminator = false;\n\n while (pos < args.length) {\n const a = args[pos]!;\n if (a === \";\") {\n advance();\n foundTerminator = true;\n break;\n }\n if (a === \"+\") {\n advance();\n batchMode = true;\n foundTerminator = true;\n break;\n }\n cmdArgs.push(a);\n advance();\n }\n\n if (!foundTerminator) {\n throw new ParseError(\"find: -exec: missing terminator (';' or '+')\");\n }\n\n return { type: \"exec\", cmdName, cmdArgs, batchMode };\n }\n\n if (tok === \"-print\") {\n advance();\n return { type: \"print\" };\n }\n\n throw new ParseError(`find: unknown predicate '${tok}'`);\n }\n\n const expr = parseOr();\n if (pos < args.length) {\n throw new ParseError(`find: unexpected '${args[pos]}'`);\n }\n return expr;\n}\n\nexport const find: Command = async (ctx) => {\n const args = [...ctx.args];\n const paths: string[] = [];\n\n // Parse arguments: paths come before first flag/operator\n let i = 0;\n\n // Collect paths (args before first -, !, or ()\n while (i < args.length && !args[i]!.startsWith(\"-\") && args[i] !== \"!\" && args[i] !== \"(\" && args[i] !== \")\") {\n paths.push(args[i]!);\n i++;\n }\n\n // Default to current directory if no paths\n if (paths.length === 0) {\n paths.push(\".\");\n }\n\n // Extract global options (-maxdepth, -mindepth) from remaining args\n let maxDepth: number | undefined;\n let minDepth: number | undefined;\n const exprArgs: string[] = [];\n\n let j = i;\n while (j < args.length) {\n const arg = args[j]!;\n if (arg === \"-maxdepth\") {\n j++;\n if (j >= args.length) {\n await ctx.stderr.writeText(\"find: missing argument to '-maxdepth'\\n\");\n return 1;\n }\n const depth = parseInt(args[j]!, 10);\n if (isNaN(depth) || depth < 0) {\n await ctx.stderr.writeText(`find: Invalid argument '${args[j]}' to -maxdepth\\n`);\n return 1;\n }\n maxDepth = depth;\n } else if (arg === \"-mindepth\") {\n j++;\n if (j >= args.length) {\n await ctx.stderr.writeText(\"find: missing argument to '-mindepth'\\n\");\n return 1;\n }\n const depth = parseInt(args[j]!, 10);\n if (isNaN(depth) || depth < 0) {\n await ctx.stderr.writeText(`find: Invalid argument '${args[j]}' to -mindepth\\n`);\n return 1;\n }\n minDepth = depth;\n } else {\n exprArgs.push(arg);\n }\n j++;\n }\n\n // Parse expression tree\n let expr: FindExpr;\n try {\n expr = parseExprArgs(exprArgs);\n } catch (e) {\n if (e instanceof ParseError) {\n await ctx.stderr.writeText(e.message + \"\\n\");\n return 1;\n }\n throw e;\n }\n\n const hasAction = hasActionExpr(expr);\n const batchExecNodes = collectBatchExecNodes(expr);\n const batchPaths: string[] = [];\n\n let hasError = false;\n\n // Process each starting path\n for (const startPath of paths) {\n const normalizedPath = startPath === \"/\" ? \"/\" : startPath.replace(/\\/+$/, '');\n const resolvedStart = ctx.fs.resolve(ctx.cwd, startPath);\n\n // Check if path exists\n let stat;\n try {\n stat = await ctx.fs.stat(resolvedStart);\n } catch {\n await ctx.stderr.writeText(`find: '${startPath}': No such file or directory\\n`);\n hasError = true;\n continue;\n }\n\n // Recursive traversal function\n async function traverse(path: string, displayPath: string, depth: number): Promise<void> {\n // Check maxdepth\n if (maxDepth !== undefined && depth > maxDepth) {\n return;\n }\n\n let entryStat;\n try {\n entryStat = await ctx.fs.stat(path);\n } catch {\n return;\n }\n\n const isDir = entryStat.isDirectory();\n const isFile = entryStat.isFile();\n const basename = ctx.fs.basename(path);\n const meetsMinDepth = minDepth === undefined || depth >= minDepth;\n\n // Check if this entry matches the expression\n const matches = await evalExpr(expr, basename, isFile, isDir, displayPath, ctx, meetsMinDepth);\n\n if (matches && meetsMinDepth) {\n if (batchExecNodes.length > 0) {\n batchPaths.push(displayPath);\n } else if (!hasAction) {\n // No action expressions: default print behavior\n await ctx.stdout.writeText(displayPath + \"\\n\");\n }\n // If has per-file -exec actions, output was already handled in evalExpr\n }\n\n // Recurse into directories\n if (isDir) {\n try {\n const entries = await ctx.fs.readdir(path);\n entries.sort();\n for (const entry of entries) {\n const childPath = ctx.fs.resolve(path, entry);\n const childDisplayPath = displayPath === \".\" ? entry : `${displayPath}/${entry}`;\n await traverse(childPath, childDisplayPath, depth + 1);\n }\n } catch {\n // Ignore errors reading directory contents\n }\n }\n }\n\n // Start traversal\n if (stat.isFile()) {\n const basename = ctx.fs.basename(resolvedStart);\n const meetsMinDepth = minDepth === undefined || minDepth <= 0;\n const matches = await evalExpr(expr, basename, true, false, normalizedPath, ctx, meetsMinDepth);\n\n if (maxDepth !== undefined && maxDepth < 0) {\n // skip\n } else if (matches && meetsMinDepth) {\n if (batchExecNodes.length > 0) {\n batchPaths.push(normalizedPath);\n } else if (!hasAction) {\n await ctx.stdout.writeText(normalizedPath + \"\\n\");\n }\n }\n } else {\n await traverse(resolvedStart, normalizedPath, 0);\n }\n }\n\n // Execute batch -exec nodes with all collected paths\n if (batchExecNodes.length > 0 && batchPaths.length > 0 && ctx.exec) {\n for (const node of batchExecNodes) {\n // Replace {} in cmdArgs with all paths\n const resolvedArgs: string[] = [];\n for (const a of node.cmdArgs) {\n if (a === \"{}\") {\n resolvedArgs.push(...batchPaths);\n } else {\n resolvedArgs.push(a);\n }\n }\n const result = await ctx.exec(node.cmdName, resolvedArgs);\n if (result.stdout.length > 0) {\n await ctx.stdout.write(result.stdout);\n }\n if (result.stderr.length > 0) {\n await ctx.stderr.write(result.stderr);\n }\n }\n }\n\n return hasError ? 1 : 0;\n};\n"
|
|
6
6
|
],
|
|
7
|
-
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAC0B,IAA1B;
|
|
8
|
-
"debugId": "
|
|
7
|
+
"mappings": "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",
|
|
8
|
+
"debugId": "BF345B4B7EBB593364756E2164756E21",
|
|
9
9
|
"names": []
|
|
10
10
|
}
|
|
@@ -52,6 +52,7 @@ __export(exports_commands, {
|
|
|
52
52
|
sed: () => import_sed.sed,
|
|
53
53
|
rm: () => import_rm.rm,
|
|
54
54
|
pwd: () => import_pwd.pwd,
|
|
55
|
+
printf: () => import_printf.printf,
|
|
55
56
|
od: () => import_od.od,
|
|
56
57
|
mv: () => import_mv.mv,
|
|
57
58
|
mkdir: () => import_mkdir.mkdir,
|
|
@@ -74,6 +75,7 @@ __export(exports_commands, {
|
|
|
74
75
|
});
|
|
75
76
|
module.exports = __toCommonJS(exports_commands);
|
|
76
77
|
var import_echo = require("./echo/echo.cjs");
|
|
78
|
+
var import_printf = require("./printf/printf.cjs");
|
|
77
79
|
var import_cat = require("./cat/cat.cjs");
|
|
78
80
|
var import_grep = require("./grep/grep.cjs");
|
|
79
81
|
var import_wc = require("./wc/wc.cjs");
|
|
@@ -102,6 +104,7 @@ var import_tr = require("./tr/tr.cjs");
|
|
|
102
104
|
var import_cut = require("./cut/cut.cjs");
|
|
103
105
|
var import_od = require("./od/od.cjs");
|
|
104
106
|
var import_echo2 = require("./echo/echo.cjs");
|
|
107
|
+
var import_printf2 = require("./printf/printf.cjs");
|
|
105
108
|
var import_cat2 = require("./cat/cat.cjs");
|
|
106
109
|
var import_grep2 = require("./grep/grep.cjs");
|
|
107
110
|
var import_wc2 = require("./wc/wc.cjs");
|
|
@@ -131,6 +134,7 @@ var import_cut2 = require("./cut/cut.cjs");
|
|
|
131
134
|
var import_od2 = require("./od/od.cjs");
|
|
132
135
|
var builtinCommands = {
|
|
133
136
|
echo: import_echo2.echo,
|
|
137
|
+
printf: import_printf2.printf,
|
|
134
138
|
cat: import_cat2.cat,
|
|
135
139
|
grep: import_grep2.grep,
|
|
136
140
|
wc: import_wc2.wc,
|
|
@@ -163,4 +167,4 @@ var builtinCommands = {
|
|
|
163
167
|
od: import_od2.od
|
|
164
168
|
};
|
|
165
169
|
|
|
166
|
-
//# debugId=
|
|
170
|
+
//# debugId=2377F0DD6264750A64756E2164756E21
|
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/commands/index.ts"],
|
|
4
4
|
"sourcesContent": [
|
|
5
|
-
"import type { Command } from \"../types.cjs\";\n\nexport { echo } from \"./echo/echo.cjs\";\nexport { cat } from \"./cat/cat.cjs\";\nexport { grep } from \"./grep/grep.cjs\";\nexport { wc } from \"./wc/wc.cjs\";\nexport { head } from \"./head/head.cjs\";\nexport { tail } from \"./tail/tail.cjs\";\nexport { sort } from \"./sort/sort.cjs\";\nexport { uniq } from \"./uniq/uniq.cjs\";\nexport { pwd } from \"./pwd/pwd.cjs\";\nexport { ls } from \"./ls/ls.cjs\";\nexport { mkdir } from \"./mkdir/mkdir.cjs\";\nexport { rm } from \"./rm/rm.cjs\";\nexport { test, bracket } from \"./test/test.cjs\";\nexport { trueCmd, falseCmd } from \"./true-false/true-false.cjs\";\nexport { touch } from \"./touch/touch.cjs\";\nexport { cp } from \"./cp/cp.cjs\";\nexport { mv } from \"./mv/mv.cjs\";\nexport { tee } from \"./tee/tee.cjs\";\nexport { tree } from \"./tree/tree.cjs\";\nexport { find } from \"./find/find.cjs\";\nexport { sed } from \"./sed/sed.cjs\";\nexport { awk } from \"./awk/awk.cjs\";\nexport { breakCmd, continueCmd } from \"./break-continue/break-continue.cjs\";\nexport { colon } from \"./colon/colon.cjs\";\nexport { cd } from \"./cd/cd.cjs\";\nexport { tr } from \"./tr/tr.cjs\";\nexport { cut } from \"./cut/cut.cjs\";\nexport { od } from \"./od/od.cjs\";\n\n// Re-export all commands as a bundle\nimport { echo } from \"./echo/echo.cjs\";\nimport { cat } from \"./cat/cat.cjs\";\nimport { grep } from \"./grep/grep.cjs\";\nimport { wc } from \"./wc/wc.cjs\";\nimport { head } from \"./head/head.cjs\";\nimport { tail } from \"./tail/tail.cjs\";\nimport { sort } from \"./sort/sort.cjs\";\nimport { uniq } from \"./uniq/uniq.cjs\";\nimport { pwd } from \"./pwd/pwd.cjs\";\nimport { ls } from \"./ls/ls.cjs\";\nimport { mkdir } from \"./mkdir/mkdir.cjs\";\nimport { rm } from \"./rm/rm.cjs\";\nimport { test, bracket } from \"./test/test.cjs\";\nimport { trueCmd, falseCmd } from \"./true-false/true-false.cjs\";\nimport { touch } from \"./touch/touch.cjs\";\nimport { cp } from \"./cp/cp.cjs\";\nimport { mv } from \"./mv/mv.cjs\";\nimport { tee } from \"./tee/tee.cjs\";\nimport { tree } from \"./tree/tree.cjs\";\nimport { find } from \"./find/find.cjs\";\nimport { sed } from \"./sed/sed.cjs\";\nimport { awk } from \"./awk/awk.cjs\";\nimport { breakCmd, continueCmd } from \"./break-continue/break-continue.cjs\";\nimport { colon } from \"./colon/colon.cjs\";\nimport { cd } from \"./cd/cd.cjs\";\nimport { tr } from \"./tr/tr.cjs\";\nimport { cut } from \"./cut/cut.cjs\";\nimport { od } from \"./od/od.cjs\";\n\nexport const builtinCommands: Record<string, Command> = {\n echo,\n cat,\n grep,\n wc,\n head,\n tail,\n sort,\n uniq,\n pwd,\n ls,\n mkdir,\n rm,\n test,\n \"[\": bracket,\n true: trueCmd,\n false: falseCmd,\n touch,\n cp,\n mv,\n tee,\n tree,\n find,\n sed,\n awk,\n break: breakCmd,\n continue: continueCmd,\n \":\": colon,\n cd,\n tr,\n cut,\n od,\n};\n"
|
|
5
|
+
"import type { Command } from \"../types.cjs\";\n\nexport { echo } from \"./echo/echo.cjs\";\nexport { printf } from \"./printf/printf.cjs\";\nexport { cat } from \"./cat/cat.cjs\";\nexport { grep } from \"./grep/grep.cjs\";\nexport { wc } from \"./wc/wc.cjs\";\nexport { head } from \"./head/head.cjs\";\nexport { tail } from \"./tail/tail.cjs\";\nexport { sort } from \"./sort/sort.cjs\";\nexport { uniq } from \"./uniq/uniq.cjs\";\nexport { pwd } from \"./pwd/pwd.cjs\";\nexport { ls } from \"./ls/ls.cjs\";\nexport { mkdir } from \"./mkdir/mkdir.cjs\";\nexport { rm } from \"./rm/rm.cjs\";\nexport { test, bracket } from \"./test/test.cjs\";\nexport { trueCmd, falseCmd } from \"./true-false/true-false.cjs\";\nexport { touch } from \"./touch/touch.cjs\";\nexport { cp } from \"./cp/cp.cjs\";\nexport { mv } from \"./mv/mv.cjs\";\nexport { tee } from \"./tee/tee.cjs\";\nexport { tree } from \"./tree/tree.cjs\";\nexport { find } from \"./find/find.cjs\";\nexport { sed } from \"./sed/sed.cjs\";\nexport { awk } from \"./awk/awk.cjs\";\nexport { breakCmd, continueCmd } from \"./break-continue/break-continue.cjs\";\nexport { colon } from \"./colon/colon.cjs\";\nexport { cd } from \"./cd/cd.cjs\";\nexport { tr } from \"./tr/tr.cjs\";\nexport { cut } from \"./cut/cut.cjs\";\nexport { od } from \"./od/od.cjs\";\n\n// Re-export all commands as a bundle\nimport { echo } from \"./echo/echo.cjs\";\nimport { printf } from \"./printf/printf.cjs\";\nimport { cat } from \"./cat/cat.cjs\";\nimport { grep } from \"./grep/grep.cjs\";\nimport { wc } from \"./wc/wc.cjs\";\nimport { head } from \"./head/head.cjs\";\nimport { tail } from \"./tail/tail.cjs\";\nimport { sort } from \"./sort/sort.cjs\";\nimport { uniq } from \"./uniq/uniq.cjs\";\nimport { pwd } from \"./pwd/pwd.cjs\";\nimport { ls } from \"./ls/ls.cjs\";\nimport { mkdir } from \"./mkdir/mkdir.cjs\";\nimport { rm } from \"./rm/rm.cjs\";\nimport { test, bracket } from \"./test/test.cjs\";\nimport { trueCmd, falseCmd } from \"./true-false/true-false.cjs\";\nimport { touch } from \"./touch/touch.cjs\";\nimport { cp } from \"./cp/cp.cjs\";\nimport { mv } from \"./mv/mv.cjs\";\nimport { tee } from \"./tee/tee.cjs\";\nimport { tree } from \"./tree/tree.cjs\";\nimport { find } from \"./find/find.cjs\";\nimport { sed } from \"./sed/sed.cjs\";\nimport { awk } from \"./awk/awk.cjs\";\nimport { breakCmd, continueCmd } from \"./break-continue/break-continue.cjs\";\nimport { colon } from \"./colon/colon.cjs\";\nimport { cd } from \"./cd/cd.cjs\";\nimport { tr } from \"./tr/tr.cjs\";\nimport { cut } from \"./cut/cut.cjs\";\nimport { od } from \"./od/od.cjs\";\n\nexport const builtinCommands: Record<string, Command> = {\n echo,\n printf,\n cat,\n grep,\n wc,\n head,\n tail,\n sort,\n uniq,\n pwd,\n ls,\n mkdir,\n rm,\n test,\n \"[\": bracket,\n true: trueCmd,\n false: falseCmd,\n touch,\n cp,\n mv,\n tee,\n tree,\n find,\n sed,\n awk,\n break: breakCmd,\n continue: continueCmd,\n \":\": colon,\n cd,\n tr,\n cut,\n od,\n};\n"
|
|
6
6
|
],
|
|
7
|
-
"mappings": "
|
|
8
|
-
"debugId": "
|
|
7
|
+
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAEqB,IAArB;AACuB,IAAvB;AACoB,IAApB;AACqB,IAArB;AACmB,IAAnB;AACqB,IAArB;AACqB,IAArB;AACqB,IAArB;AACqB,IAArB;AACoB,IAApB;AACmB,IAAnB;AACsB,IAAtB;AACmB,IAAnB;AAC8B,IAA9B;AACkC,IAAlC;AACsB,IAAtB;AACmB,IAAnB;AACmB,IAAnB;AACoB,IAApB;AACqB,IAArB;AACqB,IAArB;AACoB,IAApB;AACoB,IAApB;AACsC,IAAtC;AACsB,IAAtB;AACmB,IAAnB;AACmB,IAAnB;AACoB,IAApB;AACmB,IAAnB;AAGqB,IAArB;AACuB,IAAvB;AACoB,IAApB;AACqB,IAArB;AACmB,IAAnB;AACqB,IAArB;AACqB,IAArB;AACqB,IAArB;AACqB,IAArB;AACoB,IAApB;AACmB,IAAnB;AACsB,IAAtB;AACmB,IAAnB;AAC8B,IAA9B;AACkC,IAAlC;AACsB,IAAtB;AACmB,IAAnB;AACmB,IAAnB;AACoB,IAApB;AACqB,IAArB;AACqB,IAArB;AACoB,IAApB;AACoB,IAApB;AACsC,IAAtC;AACsB,IAAtB;AACmB,IAAnB;AACmB,IAAnB;AACoB,IAApB;AACmB,IAAnB;AAEO,IAAM,kBAA2C;AAAA,EACtD;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,KAAK;AAAA,EACL,MAAM;AAAA,EACN,OAAO;AAAA,EACP;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,OAAO;AAAA,EACP,UAAU;AAAA,EACV,KAAK;AAAA,EACL;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;",
|
|
8
|
+
"debugId": "2377F0DD6264750A64756E2164756E21",
|
|
9
9
|
"names": []
|
|
10
10
|
}
|