just-bash 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +201 -0
- package/README.md +326 -0
- package/dist/Bash.d.ts +90 -0
- package/dist/ai/index.d.ts +56 -0
- package/dist/ast/types.d.ts +518 -0
- package/dist/bin/chunks/alias-74DFXE2E.js +7 -0
- package/dist/bin/chunks/awk-S63F6IYK.js +15 -0
- package/dist/bin/chunks/base64-NC7HTKLZ.js +5 -0
- package/dist/bin/chunks/basename-Y7JDBYHN.js +6 -0
- package/dist/bin/chunks/bash-TQGTNXAE.js +7 -0
- package/dist/bin/chunks/cat-YZXBF5YF.js +6 -0
- package/dist/bin/chunks/chmod-3G4LK462.js +9 -0
- package/dist/bin/chunks/chunk-26Q3PZQ6.js +2 -0
- package/dist/bin/chunks/chunk-4VDEBYW7.js +2 -0
- package/dist/bin/chunks/chunk-5KNEBKYN.js +2 -0
- package/dist/bin/chunks/chunk-GTNBSMZR.js +23 -0
- package/dist/bin/chunks/chunk-J7BCMQDI.js +16 -0
- package/dist/bin/chunks/chunk-J7MJV6WO.js +3 -0
- package/dist/bin/chunks/chunk-LV662IGP.js +6 -0
- package/dist/bin/chunks/chunk-TA7RUHGQ.js +4 -0
- package/dist/bin/chunks/clear-GTCFHSB2.js +2 -0
- package/dist/bin/chunks/cp-77UY7PGN.js +8 -0
- package/dist/bin/chunks/curl-NE7XEWMN.js +26 -0
- package/dist/bin/chunks/cut-UYV3FM7R.js +6 -0
- package/dist/bin/chunks/date-7NBRXV2Z.js +5 -0
- package/dist/bin/chunks/diff-TG2NXCX2.js +19 -0
- package/dist/bin/chunks/dirname-VLHP44TU.js +5 -0
- package/dist/bin/chunks/du-4FZ7WF2P.js +8 -0
- package/dist/bin/chunks/echo-DEUIS5JO.js +4 -0
- package/dist/bin/chunks/env-FVITWNHG.js +9 -0
- package/dist/bin/chunks/expr-HA2ZNL6S.js +5 -0
- package/dist/bin/chunks/find-4B67H4RP.js +11 -0
- package/dist/bin/chunks/grep-OVWU4WCZ.js +15 -0
- package/dist/bin/chunks/head-VGXR3WWL.js +2 -0
- package/dist/bin/chunks/help-5V3MPCYQ.js +16 -0
- package/dist/bin/chunks/history-PRQ4B6N2.js +3 -0
- package/dist/bin/chunks/html-to-markdown-L4UWMK4S.js +84 -0
- package/dist/bin/chunks/jq-EYSXBSCP.js +14 -0
- package/dist/bin/chunks/ln-DB7J2W5X.js +10 -0
- package/dist/bin/chunks/ls-C4MPAF3H.js +26 -0
- package/dist/bin/chunks/mkdir-LWULWDHP.js +7 -0
- package/dist/bin/chunks/mv-TDYCNSIQ.js +7 -0
- package/dist/bin/chunks/paste-R36J3G4K.js +8 -0
- package/dist/bin/chunks/printf-BOFQVMMK.js +15 -0
- package/dist/bin/chunks/pwd-X4MWD4JP.js +3 -0
- package/dist/bin/chunks/readlink-DPNOQY67.js +7 -0
- package/dist/bin/chunks/rm-W6CCBEMG.js +8 -0
- package/dist/bin/chunks/sed-7IS44XON.js +48 -0
- package/dist/bin/chunks/seq-DGJILX2Q.js +7 -0
- package/dist/bin/chunks/sleep-E4DIYGTT.js +10 -0
- package/dist/bin/chunks/sort-UJP353TM.js +15 -0
- package/dist/bin/chunks/stat-3PHITCPO.js +9 -0
- package/dist/bin/chunks/tail-YSVKBQ77.js +2 -0
- package/dist/bin/chunks/tee-UU2VS3OM.js +3 -0
- package/dist/bin/chunks/timeout-OZVAGW2H.js +12 -0
- package/dist/bin/chunks/touch-XCIAYF5I.js +4 -0
- package/dist/bin/chunks/tr-2EEKHHO6.js +20 -0
- package/dist/bin/chunks/tree-4247W67O.js +12 -0
- package/dist/bin/chunks/true-JCX733LK.js +2 -0
- package/dist/bin/chunks/uniq-W4HF6YSB.js +5 -0
- package/dist/bin/chunks/wc-CNJ3QDRA.js +6 -0
- package/dist/bin/chunks/which-HX2NMOP3.js +3 -0
- package/dist/bin/chunks/xargs-YNLVLPOF.js +4 -0
- package/dist/bin/just-bash.js +188 -0
- package/dist/bin/shell/chunks/alias-74DFXE2E.js +7 -0
- package/dist/bin/shell/chunks/awk-S63F6IYK.js +15 -0
- package/dist/bin/shell/chunks/base64-NC7HTKLZ.js +5 -0
- package/dist/bin/shell/chunks/basename-Y7JDBYHN.js +6 -0
- package/dist/bin/shell/chunks/bash-TQGTNXAE.js +7 -0
- package/dist/bin/shell/chunks/cat-YZXBF5YF.js +6 -0
- package/dist/bin/shell/chunks/chmod-3G4LK462.js +9 -0
- package/dist/bin/shell/chunks/chunk-26Q3PZQ6.js +2 -0
- package/dist/bin/shell/chunks/chunk-4VDEBYW7.js +2 -0
- package/dist/bin/shell/chunks/chunk-5KNEBKYN.js +2 -0
- package/dist/bin/shell/chunks/chunk-GTNBSMZR.js +23 -0
- package/dist/bin/shell/chunks/chunk-J7BCMQDI.js +16 -0
- package/dist/bin/shell/chunks/chunk-J7MJV6WO.js +3 -0
- package/dist/bin/shell/chunks/chunk-LV662IGP.js +6 -0
- package/dist/bin/shell/chunks/chunk-TA7RUHGQ.js +4 -0
- package/dist/bin/shell/chunks/clear-GTCFHSB2.js +2 -0
- package/dist/bin/shell/chunks/cp-77UY7PGN.js +8 -0
- package/dist/bin/shell/chunks/curl-NE7XEWMN.js +26 -0
- package/dist/bin/shell/chunks/cut-UYV3FM7R.js +6 -0
- package/dist/bin/shell/chunks/date-7NBRXV2Z.js +5 -0
- package/dist/bin/shell/chunks/diff-TG2NXCX2.js +19 -0
- package/dist/bin/shell/chunks/dirname-VLHP44TU.js +5 -0
- package/dist/bin/shell/chunks/du-4FZ7WF2P.js +8 -0
- package/dist/bin/shell/chunks/echo-DEUIS5JO.js +4 -0
- package/dist/bin/shell/chunks/env-FVITWNHG.js +9 -0
- package/dist/bin/shell/chunks/expr-HA2ZNL6S.js +5 -0
- package/dist/bin/shell/chunks/find-4B67H4RP.js +11 -0
- package/dist/bin/shell/chunks/grep-OVWU4WCZ.js +15 -0
- package/dist/bin/shell/chunks/head-VGXR3WWL.js +2 -0
- package/dist/bin/shell/chunks/help-5V3MPCYQ.js +16 -0
- package/dist/bin/shell/chunks/history-PRQ4B6N2.js +3 -0
- package/dist/bin/shell/chunks/html-to-markdown-L4UWMK4S.js +84 -0
- package/dist/bin/shell/chunks/jq-EYSXBSCP.js +14 -0
- package/dist/bin/shell/chunks/ln-DB7J2W5X.js +10 -0
- package/dist/bin/shell/chunks/ls-C4MPAF3H.js +26 -0
- package/dist/bin/shell/chunks/mkdir-LWULWDHP.js +7 -0
- package/dist/bin/shell/chunks/mv-TDYCNSIQ.js +7 -0
- package/dist/bin/shell/chunks/paste-R36J3G4K.js +8 -0
- package/dist/bin/shell/chunks/printf-BOFQVMMK.js +15 -0
- package/dist/bin/shell/chunks/pwd-X4MWD4JP.js +3 -0
- package/dist/bin/shell/chunks/readlink-DPNOQY67.js +7 -0
- package/dist/bin/shell/chunks/rm-W6CCBEMG.js +8 -0
- package/dist/bin/shell/chunks/sed-7IS44XON.js +48 -0
- package/dist/bin/shell/chunks/seq-DGJILX2Q.js +7 -0
- package/dist/bin/shell/chunks/sleep-E4DIYGTT.js +10 -0
- package/dist/bin/shell/chunks/sort-UJP353TM.js +15 -0
- package/dist/bin/shell/chunks/stat-3PHITCPO.js +9 -0
- package/dist/bin/shell/chunks/tail-YSVKBQ77.js +2 -0
- package/dist/bin/shell/chunks/tee-UU2VS3OM.js +3 -0
- package/dist/bin/shell/chunks/timeout-OZVAGW2H.js +12 -0
- package/dist/bin/shell/chunks/touch-XCIAYF5I.js +4 -0
- package/dist/bin/shell/chunks/tr-2EEKHHO6.js +20 -0
- package/dist/bin/shell/chunks/tree-4247W67O.js +12 -0
- package/dist/bin/shell/chunks/true-JCX733LK.js +2 -0
- package/dist/bin/shell/chunks/uniq-W4HF6YSB.js +5 -0
- package/dist/bin/shell/chunks/wc-CNJ3QDRA.js +6 -0
- package/dist/bin/shell/chunks/which-HX2NMOP3.js +3 -0
- package/dist/bin/shell/chunks/xargs-YNLVLPOF.js +4 -0
- package/dist/bin/shell/shell.js +172 -0
- package/dist/bundle/ai/index.js +541 -0
- package/dist/bundle/chunks/alias-7ZSTROM7.js +6 -0
- package/dist/bundle/chunks/awk-V4C3GTJI.js +14 -0
- package/dist/bundle/chunks/base64-WATI5PWI.js +4 -0
- package/dist/bundle/chunks/basename-SB5JXIY3.js +5 -0
- package/dist/bundle/chunks/bash-T4PXVRYX.js +6 -0
- package/dist/bundle/chunks/cat-5KESXK2M.js +5 -0
- package/dist/bundle/chunks/chmod-VLKWIL3N.js +8 -0
- package/dist/bundle/chunks/chunk-3YNHMZ5M.js +2 -0
- package/dist/bundle/chunks/chunk-44UOCSGV.js +1 -0
- package/dist/bundle/chunks/chunk-74CEPOFO.js +22 -0
- package/dist/bundle/chunks/chunk-JYYFSUWP.js +5 -0
- package/dist/bundle/chunks/chunk-UJMN5NLH.js +1 -0
- package/dist/bundle/chunks/chunk-W2EKKAIL.js +15 -0
- package/dist/bundle/chunks/chunk-ZVV5VXYZ.js +3 -0
- package/dist/bundle/chunks/clear-ZBD2DMXN.js +1 -0
- package/dist/bundle/chunks/cp-BLHAPLQZ.js +7 -0
- package/dist/bundle/chunks/curl-PA2MWGKN.js +25 -0
- package/dist/bundle/chunks/cut-7RHEYJ7Y.js +5 -0
- package/dist/bundle/chunks/date-YOOSNZVA.js +4 -0
- package/dist/bundle/chunks/diff-IVJFQANX.js +6 -0
- package/dist/bundle/chunks/dirname-Q5HDZLH2.js +4 -0
- package/dist/bundle/chunks/du-I5HYAKTQ.js +7 -0
- package/dist/bundle/chunks/echo-W2TA2N7Y.js +3 -0
- package/dist/bundle/chunks/env-OORA5GFS.js +8 -0
- package/dist/bundle/chunks/expr-A4LJAGVP.js +4 -0
- package/dist/bundle/chunks/find-K3NO35MZ.js +10 -0
- package/dist/bundle/chunks/grep-3D2INI4S.js +14 -0
- package/dist/bundle/chunks/head-7H5R4WKO.js +1 -0
- package/dist/bundle/chunks/help-SDCRRU2F.js +15 -0
- package/dist/bundle/chunks/history-7Z2STZ6Y.js +2 -0
- package/dist/bundle/chunks/html-to-markdown-XMBYO6FD.js +4 -0
- package/dist/bundle/chunks/jq-7R2XGLLH.js +13 -0
- package/dist/bundle/chunks/ln-UTUVIAFP.js +9 -0
- package/dist/bundle/chunks/ls-B7C35UDO.js +23 -0
- package/dist/bundle/chunks/mkdir-WYI2LJ6H.js +6 -0
- package/dist/bundle/chunks/mv-GN23UIZU.js +6 -0
- package/dist/bundle/chunks/paste-L4TYPVSP.js +7 -0
- package/dist/bundle/chunks/printf-3ZT5XOIZ.js +14 -0
- package/dist/bundle/chunks/pwd-ZVX5RTL4.js +2 -0
- package/dist/bundle/chunks/readlink-HHC33N5C.js +6 -0
- package/dist/bundle/chunks/rm-5X2XSQQ6.js +7 -0
- package/dist/bundle/chunks/sed-UZJSXYQZ.js +47 -0
- package/dist/bundle/chunks/seq-TFPZQZPJ.js +6 -0
- package/dist/bundle/chunks/sleep-QJBQD6VS.js +9 -0
- package/dist/bundle/chunks/sort-LHMQWYH2.js +14 -0
- package/dist/bundle/chunks/stat-TM5F5YO4.js +8 -0
- package/dist/bundle/chunks/tail-BLGGG2VX.js +1 -0
- package/dist/bundle/chunks/tee-VCNOG5VI.js +2 -0
- package/dist/bundle/chunks/timeout-THAT7IOO.js +11 -0
- package/dist/bundle/chunks/touch-Z5XRYFYY.js +3 -0
- package/dist/bundle/chunks/tr-UV4V27RJ.js +19 -0
- package/dist/bundle/chunks/tree-75UXQ4XJ.js +11 -0
- package/dist/bundle/chunks/true-OD7ZXH3O.js +1 -0
- package/dist/bundle/chunks/uniq-IIOQKNTS.js +4 -0
- package/dist/bundle/chunks/wc-OXLYBRUE.js +5 -0
- package/dist/bundle/chunks/which-ONWH3TNF.js +2 -0
- package/dist/bundle/chunks/xargs-E5JPQL24.js +3 -0
- package/dist/bundle/index.js +141 -0
- package/dist/commands/alias/alias.d.ts +3 -0
- package/dist/commands/awk/awk.d.ts +2 -0
- package/dist/commands/awk/executor.d.ts +3 -0
- package/dist/commands/awk/expressions.d.ts +3 -0
- package/dist/commands/awk/functions.d.ts +12 -0
- package/dist/commands/awk/parser.d.ts +3 -0
- package/dist/commands/awk/types.d.ts +44 -0
- package/dist/commands/base64/base64.d.ts +5 -0
- package/dist/commands/basename/basename.d.ts +2 -0
- package/dist/commands/bash/bash.d.ts +3 -0
- package/dist/commands/cat/cat.d.ts +2 -0
- package/dist/commands/chmod/chmod.d.ts +2 -0
- package/dist/commands/clear/clear.d.ts +2 -0
- package/dist/commands/cp/cp.d.ts +2 -0
- package/dist/commands/curl/curl.d.ts +8 -0
- package/dist/commands/curl/form.d.ts +21 -0
- package/dist/commands/curl/help.d.ts +9 -0
- package/dist/commands/curl/parse.d.ts +9 -0
- package/dist/commands/curl/types.d.ts +31 -0
- package/dist/commands/curl/utils.d.ts +20 -0
- package/dist/commands/cut/cut.d.ts +2 -0
- package/dist/commands/date/date.d.ts +5 -0
- package/dist/commands/diff/diff.d.ts +5 -0
- package/dist/commands/dirname/dirname.d.ts +2 -0
- package/dist/commands/du/du.d.ts +2 -0
- package/dist/commands/echo/echo.d.ts +2 -0
- package/dist/commands/env/env.d.ts +3 -0
- package/dist/commands/expr/expr.d.ts +7 -0
- package/dist/commands/find/find.d.ts +2 -0
- package/dist/commands/find/matcher.d.ts +3 -0
- package/dist/commands/find/parser.d.ts +2 -0
- package/dist/commands/find/types.d.ts +70 -0
- package/dist/commands/grep/grep.d.ts +4 -0
- package/dist/commands/head/head-tail-shared.d.ts +38 -0
- package/dist/commands/head/head.d.ts +2 -0
- package/dist/commands/help/help.d.ts +2 -0
- package/dist/commands/help.d.ts +16 -0
- package/dist/commands/history/history.d.ts +2 -0
- package/dist/commands/html-to-markdown/html-to-markdown.d.ts +7 -0
- package/dist/commands/jq/jq.d.ts +14 -0
- package/dist/commands/ln/ln.d.ts +2 -0
- package/dist/commands/ls/ls.d.ts +2 -0
- package/dist/commands/mkdir/mkdir.d.ts +2 -0
- package/dist/commands/mv/mv.d.ts +2 -0
- package/dist/commands/paste/paste.d.ts +2 -0
- package/dist/commands/printf/printf.d.ts +2 -0
- package/dist/commands/pwd/pwd.d.ts +2 -0
- package/dist/commands/readlink/readlink.d.ts +2 -0
- package/dist/commands/registry.d.ts +33 -0
- package/dist/commands/rm/rm.d.ts +2 -0
- package/dist/commands/sed/executor.d.ts +7 -0
- package/dist/commands/sed/parser.d.ts +5 -0
- package/dist/commands/sed/sed.d.ts +2 -0
- package/dist/commands/sed/types.d.ts +141 -0
- package/dist/commands/seq/seq.d.ts +14 -0
- package/dist/commands/sleep/sleep.d.ts +2 -0
- package/dist/commands/sort/comparator.d.ts +9 -0
- package/dist/commands/sort/parser.d.ts +11 -0
- package/dist/commands/sort/sort.d.ts +2 -0
- package/dist/commands/sort/types.d.ts +18 -0
- package/dist/commands/stat/stat.d.ts +2 -0
- package/dist/commands/tail/tail.d.ts +2 -0
- package/dist/commands/tee/tee.d.ts +2 -0
- package/dist/commands/timeout/timeout.d.ts +2 -0
- package/dist/commands/touch/touch.d.ts +2 -0
- package/dist/commands/tr/tr.d.ts +2 -0
- package/dist/commands/tree/tree.d.ts +2 -0
- package/dist/commands/true/true.d.ts +3 -0
- package/dist/commands/uniq/uniq.d.ts +2 -0
- package/dist/commands/wc/wc.d.ts +2 -0
- package/dist/commands/which/which.d.ts +2 -0
- package/dist/commands/xargs/xargs.d.ts +2 -0
- package/dist/fs-interface.d.ts +186 -0
- package/dist/fs.d.ts +39 -0
- package/dist/index.d.ts +12 -0
- package/dist/interpreter/arithmetic.d.ts +29 -0
- package/dist/interpreter/builtins/break.d.ts +6 -0
- package/dist/interpreter/builtins/cd.d.ts +6 -0
- package/dist/interpreter/builtins/continue.d.ts +6 -0
- package/dist/interpreter/builtins/declare.d.ts +29 -0
- package/dist/interpreter/builtins/eval.d.ts +9 -0
- package/dist/interpreter/builtins/exit.d.ts +5 -0
- package/dist/interpreter/builtins/export.d.ts +13 -0
- package/dist/interpreter/builtins/index.d.ts +36 -0
- package/dist/interpreter/builtins/let.d.ts +18 -0
- package/dist/interpreter/builtins/local.d.ts +6 -0
- package/dist/interpreter/builtins/read.d.ts +6 -0
- package/dist/interpreter/builtins/return.d.ts +6 -0
- package/dist/interpreter/builtins/set.d.ts +6 -0
- package/dist/interpreter/builtins/shift.d.ts +12 -0
- package/dist/interpreter/builtins/source.d.ts +6 -0
- package/dist/interpreter/builtins/unset.d.ts +12 -0
- package/dist/interpreter/builtins/variable-helpers.d.ts +30 -0
- package/dist/interpreter/conditionals.d.ts +17 -0
- package/dist/interpreter/control-flow.d.ts +21 -0
- package/dist/interpreter/errors.d.ts +107 -0
- package/dist/interpreter/expansion/analysis.d.ts +39 -0
- package/dist/interpreter/expansion/brace-range.d.ts +20 -0
- package/dist/interpreter/expansion/pattern.d.ts +22 -0
- package/dist/interpreter/expansion/variable.d.ts +27 -0
- package/dist/interpreter/expansion/word-split.d.ts +24 -0
- package/dist/interpreter/expansion.d.ts +27 -0
- package/dist/interpreter/functions.d.ts +12 -0
- package/dist/interpreter/helpers/array.d.ts +23 -0
- package/dist/interpreter/helpers/condition.d.ts +22 -0
- package/dist/interpreter/helpers/errors.d.ts +8 -0
- package/dist/interpreter/helpers/file-tests.d.ts +33 -0
- package/dist/interpreter/helpers/ifs.d.ts +43 -0
- package/dist/interpreter/helpers/loop.d.ts +24 -0
- package/dist/interpreter/helpers/numeric-compare.d.ts +13 -0
- package/dist/interpreter/helpers/readonly.d.ts +21 -0
- package/dist/interpreter/helpers/regex.d.ts +8 -0
- package/dist/interpreter/helpers/result.d.ts +54 -0
- package/dist/interpreter/helpers/statements.d.ts +20 -0
- package/dist/interpreter/helpers/string-compare.d.ts +22 -0
- package/dist/interpreter/helpers/string-tests.d.ts +13 -0
- package/dist/interpreter/helpers/variable-tests.d.ts +9 -0
- package/dist/interpreter/helpers/word-parts.d.ts +22 -0
- package/dist/interpreter/index.d.ts +3 -0
- package/dist/interpreter/interpreter.d.ts +61 -0
- package/dist/interpreter/redirections.d.ts +14 -0
- package/dist/interpreter/types.d.ts +68 -0
- package/dist/limits.d.ts +26 -0
- package/dist/network/allow-list/shared.d.ts +45 -0
- package/dist/network/allow-list.d.ts +51 -0
- package/dist/network/fetch.d.ts +25 -0
- package/dist/network/index.d.ts +7 -0
- package/dist/network/types.d.ts +85 -0
- package/dist/overlay-fs/OverlayFs.d.ts +87 -0
- package/dist/overlay-fs/index.d.ts +1 -0
- package/dist/parser/arithmetic-parser.d.ts +25 -0
- package/dist/parser/command-parser.d.ts +10 -0
- package/dist/parser/compound-parser.d.ts +14 -0
- package/dist/parser/conditional-parser.d.ts +8 -0
- package/dist/parser/expansion-parser.d.ts +10 -0
- package/dist/parser/lexer.d.ts +135 -0
- package/dist/parser/parser.d.ts +92 -0
- package/dist/parser/types.d.ts +23 -0
- package/dist/parser/word-parser.d.ts +33 -0
- package/dist/sandbox/Command.d.ts +28 -0
- package/dist/sandbox/Sandbox.d.ts +60 -0
- package/dist/sandbox/index.d.ts +2 -0
- package/dist/types.d.ts +80 -0
- package/dist/utils/args.d.ts +55 -0
- package/dist/utils/file-reader.d.ts +64 -0
- package/dist/utils/glob.d.ts +25 -0
- package/package.json +103 -0
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Lexer for Bash Scripts
|
|
3
|
+
*
|
|
4
|
+
* The lexer tokenizes input into a stream of tokens that the parser consumes.
|
|
5
|
+
* It handles:
|
|
6
|
+
* - Operators and delimiters
|
|
7
|
+
* - Words (with quoting rules)
|
|
8
|
+
* - Comments
|
|
9
|
+
* - Here-documents
|
|
10
|
+
* - Escape sequences
|
|
11
|
+
*/
|
|
12
|
+
export declare enum TokenType {
|
|
13
|
+
EOF = "EOF",
|
|
14
|
+
NEWLINE = "NEWLINE",
|
|
15
|
+
SEMICOLON = "SEMICOLON",
|
|
16
|
+
AMP = "AMP",// &
|
|
17
|
+
PIPE = "PIPE",// |
|
|
18
|
+
PIPE_AMP = "PIPE_AMP",// |&
|
|
19
|
+
AND_AND = "AND_AND",// &&
|
|
20
|
+
OR_OR = "OR_OR",// ||
|
|
21
|
+
BANG = "BANG",// !
|
|
22
|
+
LESS = "LESS",// <
|
|
23
|
+
GREAT = "GREAT",// >
|
|
24
|
+
DLESS = "DLESS",// <<
|
|
25
|
+
DGREAT = "DGREAT",// >>
|
|
26
|
+
LESSAND = "LESSAND",// <&
|
|
27
|
+
GREATAND = "GREATAND",// >&
|
|
28
|
+
LESSGREAT = "LESSGREAT",// <>
|
|
29
|
+
DLESSDASH = "DLESSDASH",// <<-
|
|
30
|
+
CLOBBER = "CLOBBER",// >|
|
|
31
|
+
TLESS = "TLESS",// <<<
|
|
32
|
+
AND_GREAT = "AND_GREAT",// &>
|
|
33
|
+
AND_DGREAT = "AND_DGREAT",// &>>
|
|
34
|
+
LPAREN = "LPAREN",// (
|
|
35
|
+
RPAREN = "RPAREN",// )
|
|
36
|
+
LBRACE = "LBRACE",// {
|
|
37
|
+
RBRACE = "RBRACE",// }
|
|
38
|
+
DSEMI = "DSEMI",// ;;
|
|
39
|
+
SEMI_AND = "SEMI_AND",// ;&
|
|
40
|
+
SEMI_SEMI_AND = "SEMI_SEMI_AND",// ;;&
|
|
41
|
+
DBRACK_START = "DBRACK_START",// [[
|
|
42
|
+
DBRACK_END = "DBRACK_END",// ]]
|
|
43
|
+
DPAREN_START = "DPAREN_START",// ((
|
|
44
|
+
DPAREN_END = "DPAREN_END",// ))
|
|
45
|
+
IF = "IF",
|
|
46
|
+
THEN = "THEN",
|
|
47
|
+
ELSE = "ELSE",
|
|
48
|
+
ELIF = "ELIF",
|
|
49
|
+
FI = "FI",
|
|
50
|
+
FOR = "FOR",
|
|
51
|
+
WHILE = "WHILE",
|
|
52
|
+
UNTIL = "UNTIL",
|
|
53
|
+
DO = "DO",
|
|
54
|
+
DONE = "DONE",
|
|
55
|
+
CASE = "CASE",
|
|
56
|
+
ESAC = "ESAC",
|
|
57
|
+
IN = "IN",
|
|
58
|
+
FUNCTION = "FUNCTION",
|
|
59
|
+
SELECT = "SELECT",
|
|
60
|
+
TIME = "TIME",
|
|
61
|
+
COPROC = "COPROC",
|
|
62
|
+
WORD = "WORD",
|
|
63
|
+
NAME = "NAME",// Valid variable name
|
|
64
|
+
NUMBER = "NUMBER",// For redirections like 2>&1
|
|
65
|
+
ASSIGNMENT_WORD = "ASSIGNMENT_WORD",// VAR=value
|
|
66
|
+
COMMENT = "COMMENT",
|
|
67
|
+
HEREDOC_CONTENT = "HEREDOC_CONTENT"
|
|
68
|
+
}
|
|
69
|
+
export interface Token {
|
|
70
|
+
type: TokenType;
|
|
71
|
+
value: string;
|
|
72
|
+
/** Original position in input */
|
|
73
|
+
start: number;
|
|
74
|
+
end: number;
|
|
75
|
+
line: number;
|
|
76
|
+
column: number;
|
|
77
|
+
/** For WORD tokens: quote information */
|
|
78
|
+
quoted?: boolean;
|
|
79
|
+
singleQuoted?: boolean;
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Lexer class
|
|
83
|
+
*/
|
|
84
|
+
export declare class Lexer {
|
|
85
|
+
private input;
|
|
86
|
+
private pos;
|
|
87
|
+
private line;
|
|
88
|
+
private column;
|
|
89
|
+
private tokens;
|
|
90
|
+
private pendingHeredocs;
|
|
91
|
+
constructor(input: string);
|
|
92
|
+
/**
|
|
93
|
+
* Tokenize the entire input
|
|
94
|
+
*/
|
|
95
|
+
tokenize(): Token[];
|
|
96
|
+
private skipWhitespace;
|
|
97
|
+
private nextToken;
|
|
98
|
+
private makeToken;
|
|
99
|
+
private readComment;
|
|
100
|
+
private readWord;
|
|
101
|
+
private readHeredocContent;
|
|
102
|
+
/**
|
|
103
|
+
* Register a here-document to be read after the next newline
|
|
104
|
+
*/
|
|
105
|
+
addPendingHeredoc(delimiter: string, stripTabs: boolean, quoted: boolean): void;
|
|
106
|
+
/**
|
|
107
|
+
* Look ahead from current position to find the here-doc delimiter
|
|
108
|
+
* and register it as a pending here-doc
|
|
109
|
+
*/
|
|
110
|
+
private registerHeredocFromLookahead;
|
|
111
|
+
/**
|
|
112
|
+
* Check if position is followed by word characters (not a word boundary).
|
|
113
|
+
* Used to determine if } should be literal or RBRACE token.
|
|
114
|
+
*/
|
|
115
|
+
private isWordCharFollowing;
|
|
116
|
+
/**
|
|
117
|
+
* Read a word that starts with a brace expansion.
|
|
118
|
+
* Includes the brace expansion plus any suffix characters and additional brace expansions.
|
|
119
|
+
*/
|
|
120
|
+
private readWordWithBraceExpansion;
|
|
121
|
+
/**
|
|
122
|
+
* Scan ahead to detect brace expansion pattern.
|
|
123
|
+
* Returns the full brace expansion string if found, null otherwise.
|
|
124
|
+
* Brace expansion must contain either:
|
|
125
|
+
* - A comma (e.g., {a,b,c})
|
|
126
|
+
* - A range with .. (e.g., {1..10})
|
|
127
|
+
*/
|
|
128
|
+
private scanBraceExpansion;
|
|
129
|
+
/**
|
|
130
|
+
* Scan a literal brace word like {foo} (no comma, no range).
|
|
131
|
+
* Returns the literal string if found, null otherwise.
|
|
132
|
+
* This is used when {} contains something but it's not a valid brace expansion.
|
|
133
|
+
*/
|
|
134
|
+
private scanLiteralBraceWord;
|
|
135
|
+
}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Recursive Descent Parser for Bash Scripts
|
|
3
|
+
*
|
|
4
|
+
* This parser consumes tokens from the lexer and produces an AST.
|
|
5
|
+
* It follows the bash grammar structure for correctness.
|
|
6
|
+
*
|
|
7
|
+
* Grammar (simplified):
|
|
8
|
+
* script ::= statement*
|
|
9
|
+
* statement ::= pipeline ((&&|'||') pipeline)* [&]
|
|
10
|
+
* pipeline ::= [!] command (| command)*
|
|
11
|
+
* command ::= simple_command | compound_command | function_def
|
|
12
|
+
* simple_cmd ::= (assignment)* [word] (word)* (redirection)*
|
|
13
|
+
* compound_cmd ::= if | for | while | until | case | subshell | group | (( | [[
|
|
14
|
+
*/
|
|
15
|
+
import { type ArithmeticExpansionPart, type ArithmeticExpressionNode, type CommandSubstitutionPart, type RedirectionNode, type ScriptNode, type StatementNode, type WordNode } from "../ast/types.js";
|
|
16
|
+
import { type Token, TokenType } from "./lexer.js";
|
|
17
|
+
export type { ParseError } from "./types.js";
|
|
18
|
+
export { ParseException } from "./types.js";
|
|
19
|
+
/**
|
|
20
|
+
* Parser class - transforms tokens into AST
|
|
21
|
+
*/
|
|
22
|
+
export declare class Parser {
|
|
23
|
+
private tokens;
|
|
24
|
+
private pos;
|
|
25
|
+
private pendingHeredocs;
|
|
26
|
+
private parseIterations;
|
|
27
|
+
/**
|
|
28
|
+
* Check parse iteration limit to prevent infinite loops
|
|
29
|
+
*/
|
|
30
|
+
checkIterationLimit(): void;
|
|
31
|
+
/**
|
|
32
|
+
* Parse a bash script string
|
|
33
|
+
*/
|
|
34
|
+
parse(input: string): ScriptNode;
|
|
35
|
+
/**
|
|
36
|
+
* Parse from pre-tokenized input
|
|
37
|
+
*/
|
|
38
|
+
parseTokens(tokens: Token[]): ScriptNode;
|
|
39
|
+
current(): Token;
|
|
40
|
+
peek(offset?: number): Token;
|
|
41
|
+
advance(): Token;
|
|
42
|
+
getPos(): number;
|
|
43
|
+
/**
|
|
44
|
+
* Check if current token matches any of the given types.
|
|
45
|
+
* Optimized to avoid array allocation for common cases (1-4 args).
|
|
46
|
+
*/
|
|
47
|
+
check(t1: TokenType, t2?: TokenType, t3?: TokenType, t4?: TokenType, ...rest: TokenType[]): boolean;
|
|
48
|
+
expect(type: TokenType, message?: string): Token;
|
|
49
|
+
error(message: string): never;
|
|
50
|
+
skipNewlines(): void;
|
|
51
|
+
skipSeparators(includeCaseTerminators?: boolean): void;
|
|
52
|
+
addPendingHeredoc(redirect: RedirectionNode, delimiter: string, stripTabs: boolean, quoted: boolean): void;
|
|
53
|
+
private processHeredocs;
|
|
54
|
+
isStatementEnd(): boolean;
|
|
55
|
+
private isCommandStart;
|
|
56
|
+
private parseScript;
|
|
57
|
+
/**
|
|
58
|
+
* Check for unexpected tokens that can't appear at statement start
|
|
59
|
+
*/
|
|
60
|
+
private checkUnexpectedToken;
|
|
61
|
+
parseStatement(): StatementNode | null;
|
|
62
|
+
private parsePipeline;
|
|
63
|
+
private parseCommand;
|
|
64
|
+
isWord(): boolean;
|
|
65
|
+
parseWord(): WordNode;
|
|
66
|
+
parseWordFromString(value: string, quoted?: boolean, singleQuoted?: boolean, isAssignment?: boolean, hereDoc?: boolean): WordNode;
|
|
67
|
+
parseCommandSubstitution(value: string, start: number): {
|
|
68
|
+
part: CommandSubstitutionPart;
|
|
69
|
+
endIndex: number;
|
|
70
|
+
};
|
|
71
|
+
parseBacktickSubstitution(value: string, start: number,
|
|
72
|
+
/** Whether the backtick is inside double quotes */
|
|
73
|
+
inDoubleQuotes?: boolean): {
|
|
74
|
+
part: CommandSubstitutionPart;
|
|
75
|
+
endIndex: number;
|
|
76
|
+
};
|
|
77
|
+
parseArithmeticExpansion(value: string, start: number): {
|
|
78
|
+
part: ArithmeticExpansionPart;
|
|
79
|
+
endIndex: number;
|
|
80
|
+
};
|
|
81
|
+
private parseArithmeticCommand;
|
|
82
|
+
private parseConditionalCommand;
|
|
83
|
+
private parseFunctionDef;
|
|
84
|
+
private parseCompoundCommandBody;
|
|
85
|
+
parseCompoundList(): StatementNode[];
|
|
86
|
+
parseOptionalRedirections(): RedirectionNode[];
|
|
87
|
+
parseArithmeticExpression(input: string): ArithmeticExpressionNode;
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Convenience function to parse a bash script
|
|
91
|
+
*/
|
|
92
|
+
export declare function parse(input: string): ScriptNode;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Parser Types and Constants
|
|
3
|
+
*
|
|
4
|
+
* Shared types, interfaces, and constants used across parser modules.
|
|
5
|
+
*/
|
|
6
|
+
import { type Token, TokenType } from "./lexer.js";
|
|
7
|
+
export declare const MAX_INPUT_SIZE = 1000000;
|
|
8
|
+
export declare const MAX_TOKENS = 100000;
|
|
9
|
+
export declare const MAX_PARSE_ITERATIONS = 1000000;
|
|
10
|
+
export declare const REDIRECTION_TOKENS: Set<TokenType>;
|
|
11
|
+
export declare const REDIRECTION_AFTER_NUMBER: Set<TokenType>;
|
|
12
|
+
export interface ParseError {
|
|
13
|
+
message: string;
|
|
14
|
+
line: number;
|
|
15
|
+
column: number;
|
|
16
|
+
token?: Token;
|
|
17
|
+
}
|
|
18
|
+
export declare class ParseException extends Error {
|
|
19
|
+
line: number;
|
|
20
|
+
column: number;
|
|
21
|
+
token: Token | undefined;
|
|
22
|
+
constructor(message: string, line: number, column: number, token?: Token | undefined);
|
|
23
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Word Parsing Utilities
|
|
3
|
+
*
|
|
4
|
+
* String manipulation utilities for parsing words, expansions, and patterns.
|
|
5
|
+
* These are pure functions extracted from the Parser class.
|
|
6
|
+
*/
|
|
7
|
+
import { type ArithmeticExpressionNode, type RedirectionOperator, type WordNode, type WordPart } from "../ast/types.js";
|
|
8
|
+
import { TokenType } from "./lexer.js";
|
|
9
|
+
import type { Parser } from "./parser.js";
|
|
10
|
+
export declare function findTildeEnd(_p: Parser, value: string, start: number): number;
|
|
11
|
+
export declare function findMatchingBracket(_p: Parser, value: string, start: number, open: string, close: string): number;
|
|
12
|
+
export declare function findParameterOperationEnd(_p: Parser, value: string, start: number): number;
|
|
13
|
+
export declare function findPatternEnd(_p: Parser, value: string, start: number): number;
|
|
14
|
+
export declare function parseGlobPattern(_p: Parser, value: string, start: number): {
|
|
15
|
+
pattern: string;
|
|
16
|
+
endIndex: number;
|
|
17
|
+
};
|
|
18
|
+
export declare function parseAnsiCQuoted(_p: Parser, value: string, start: number): {
|
|
19
|
+
part: WordPart;
|
|
20
|
+
endIndex: number;
|
|
21
|
+
};
|
|
22
|
+
export declare function parseArithExprFromString(p: Parser, str: string): ArithmeticExpressionNode;
|
|
23
|
+
export type WordPartsParser = (p: Parser, value: string, quoted?: boolean, singleQuoted?: boolean, isAssignment?: boolean) => WordPart[];
|
|
24
|
+
export declare function tryParseBraceExpansion(p: Parser, value: string, start: number, parseWordPartsFn?: WordPartsParser): {
|
|
25
|
+
part: WordPart;
|
|
26
|
+
endIndex: number;
|
|
27
|
+
} | null;
|
|
28
|
+
/**
|
|
29
|
+
* Convert a WordNode back to a string representation.
|
|
30
|
+
* Used for reconstructing array assignment strings for declare/local.
|
|
31
|
+
*/
|
|
32
|
+
export declare function wordToString(_p: Parser, word: WordNode): string;
|
|
33
|
+
export declare function tokenToRedirectOp(_p: Parser, type: TokenType): RedirectionOperator;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { Bash } from "../Bash.js";
|
|
2
|
+
export interface OutputMessage {
|
|
3
|
+
type: "stdout" | "stderr";
|
|
4
|
+
data: string;
|
|
5
|
+
timestamp: Date;
|
|
6
|
+
}
|
|
7
|
+
export declare class Command {
|
|
8
|
+
readonly cmdId: string;
|
|
9
|
+
readonly cwd: string;
|
|
10
|
+
readonly startedAt: Date;
|
|
11
|
+
exitCode: number | undefined;
|
|
12
|
+
private bashEnv;
|
|
13
|
+
private cmdLine;
|
|
14
|
+
private env?;
|
|
15
|
+
private explicitCwd;
|
|
16
|
+
private resultPromise;
|
|
17
|
+
constructor(bashEnv: Bash, cmdLine: string, cwd: string, env?: Record<string, string>, explicitCwd?: boolean);
|
|
18
|
+
private execute;
|
|
19
|
+
logs(): AsyncGenerator<OutputMessage, void, unknown>;
|
|
20
|
+
wait(): Promise<CommandFinished>;
|
|
21
|
+
output(): Promise<string>;
|
|
22
|
+
stdout(): Promise<string>;
|
|
23
|
+
stderr(): Promise<string>;
|
|
24
|
+
kill(): Promise<void>;
|
|
25
|
+
}
|
|
26
|
+
export interface CommandFinished extends Command {
|
|
27
|
+
exitCode: number;
|
|
28
|
+
}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { Bash } from "../Bash.js";
|
|
2
|
+
import type { IFileSystem } from "../fs-interface.js";
|
|
3
|
+
import type { NetworkConfig } from "../network/index.js";
|
|
4
|
+
import type { CommandFinished } from "./Command.js";
|
|
5
|
+
import { Command } from "./Command.js";
|
|
6
|
+
export interface SandboxOptions {
|
|
7
|
+
cwd?: string;
|
|
8
|
+
env?: Record<string, string>;
|
|
9
|
+
timeoutMs?: number;
|
|
10
|
+
/**
|
|
11
|
+
* Custom filesystem implementation.
|
|
12
|
+
* Mutually exclusive with `overlayRoot`.
|
|
13
|
+
*/
|
|
14
|
+
fs?: IFileSystem;
|
|
15
|
+
/**
|
|
16
|
+
* Path to a directory to use as the root of an OverlayFs.
|
|
17
|
+
* Reads come from this directory, writes stay in memory.
|
|
18
|
+
* Mutually exclusive with `fs`.
|
|
19
|
+
*/
|
|
20
|
+
overlayRoot?: string;
|
|
21
|
+
maxCallDepth?: number;
|
|
22
|
+
maxCommandCount?: number;
|
|
23
|
+
maxLoopIterations?: number;
|
|
24
|
+
/**
|
|
25
|
+
* Network configuration for commands like curl.
|
|
26
|
+
* Network access is disabled by default - you must explicitly configure allowed URLs.
|
|
27
|
+
*/
|
|
28
|
+
network?: NetworkConfig;
|
|
29
|
+
}
|
|
30
|
+
export interface WriteFilesInput {
|
|
31
|
+
[path: string]: string | {
|
|
32
|
+
content: string;
|
|
33
|
+
encoding?: "utf-8" | "base64";
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
export declare class Sandbox {
|
|
37
|
+
private bashEnv;
|
|
38
|
+
private constructor();
|
|
39
|
+
static create(opts?: SandboxOptions): Promise<Sandbox>;
|
|
40
|
+
runCommand(cmd: string, opts?: {
|
|
41
|
+
cwd?: string;
|
|
42
|
+
env?: Record<string, string>;
|
|
43
|
+
}): Promise<Command>;
|
|
44
|
+
writeFiles(files: WriteFilesInput): Promise<void>;
|
|
45
|
+
readFile(path: string, encoding?: "utf-8" | "base64"): Promise<string>;
|
|
46
|
+
mkDir(path: string, opts?: {
|
|
47
|
+
recursive?: boolean;
|
|
48
|
+
}): Promise<void>;
|
|
49
|
+
stop(): Promise<void>;
|
|
50
|
+
extendTimeout(_ms: number): Promise<void>;
|
|
51
|
+
get domain(): string | undefined;
|
|
52
|
+
/**
|
|
53
|
+
* Bash-specific: Get the underlying Bash instance for advanced operations.
|
|
54
|
+
* Not available in Vercel Sandbox API.
|
|
55
|
+
*/
|
|
56
|
+
get bashEnvInstance(): Bash;
|
|
57
|
+
}
|
|
58
|
+
export { Command };
|
|
59
|
+
export type { CommandFinished };
|
|
60
|
+
export type { OutputMessage } from "./Command.js";
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import type { IFileSystem } from "./fs-interface.js";
|
|
2
|
+
import type { ExecutionLimits } from "./limits.js";
|
|
3
|
+
import type { SecureFetch } from "./network/index.js";
|
|
4
|
+
export interface ExecResult {
|
|
5
|
+
stdout: string;
|
|
6
|
+
stderr: string;
|
|
7
|
+
exitCode: number;
|
|
8
|
+
/** The final environment variables after execution (only set by BashEnv.exec) */
|
|
9
|
+
env?: Record<string, string>;
|
|
10
|
+
}
|
|
11
|
+
/** Result from BashEnv.exec() - always includes env */
|
|
12
|
+
export interface BashExecResult extends ExecResult {
|
|
13
|
+
env: Record<string, string>;
|
|
14
|
+
}
|
|
15
|
+
/** Options for exec calls within commands */
|
|
16
|
+
export interface CommandExecOptions {
|
|
17
|
+
/** Environment variables to merge into the exec state */
|
|
18
|
+
env?: Record<string, string>;
|
|
19
|
+
/** Working directory for the exec */
|
|
20
|
+
cwd?: string;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Context provided to commands during execution.
|
|
24
|
+
*
|
|
25
|
+
* ## Field Availability
|
|
26
|
+
*
|
|
27
|
+
* **Always available (core fields):**
|
|
28
|
+
* - `fs`, `cwd`, `env`, `stdin`
|
|
29
|
+
*
|
|
30
|
+
* **Available when running via BashEnv interpreter:**
|
|
31
|
+
* - `exec` - For commands like `xargs`, `bash -c` that need to run subcommands
|
|
32
|
+
* - `getRegisteredCommands` - For the `help` command to list available commands
|
|
33
|
+
*
|
|
34
|
+
* **Conditionally available based on configuration:**
|
|
35
|
+
* - `fetch` - Only when `network` option is configured in BashEnv
|
|
36
|
+
* - `sleep` - Only when a custom sleep function is provided (e.g., for testing)
|
|
37
|
+
*/
|
|
38
|
+
export interface CommandContext {
|
|
39
|
+
/** Virtual filesystem interface for file operations */
|
|
40
|
+
fs: IFileSystem;
|
|
41
|
+
/** Current working directory */
|
|
42
|
+
cwd: string;
|
|
43
|
+
/** Environment variables */
|
|
44
|
+
env: Record<string, string>;
|
|
45
|
+
/** Standard input content */
|
|
46
|
+
stdin: string;
|
|
47
|
+
/**
|
|
48
|
+
* Execution limits configuration.
|
|
49
|
+
* Available when running commands via BashEnv interpreter.
|
|
50
|
+
*/
|
|
51
|
+
limits?: Required<ExecutionLimits>;
|
|
52
|
+
/**
|
|
53
|
+
* Execute a subcommand (e.g., for `xargs`, `bash -c`).
|
|
54
|
+
* Available when running commands via BashEnv interpreter.
|
|
55
|
+
*/
|
|
56
|
+
exec?: (command: string, options?: CommandExecOptions) => Promise<ExecResult>;
|
|
57
|
+
/**
|
|
58
|
+
* Secure fetch function for network requests (e.g., for `curl`).
|
|
59
|
+
* Only available when `network` option is configured in BashEnv.
|
|
60
|
+
*/
|
|
61
|
+
fetch?: SecureFetch;
|
|
62
|
+
/**
|
|
63
|
+
* Returns names of all registered commands.
|
|
64
|
+
* Available when running commands via BashEnv interpreter.
|
|
65
|
+
* Used by the `help` command.
|
|
66
|
+
*/
|
|
67
|
+
getRegisteredCommands?: () => string[];
|
|
68
|
+
/**
|
|
69
|
+
* Custom sleep implementation.
|
|
70
|
+
* If provided, used instead of real setTimeout.
|
|
71
|
+
* Useful for testing with mock clocks.
|
|
72
|
+
*/
|
|
73
|
+
sleep?: (ms: number) => Promise<void>;
|
|
74
|
+
}
|
|
75
|
+
export interface Command {
|
|
76
|
+
name: string;
|
|
77
|
+
execute(args: string[], ctx: CommandContext): Promise<ExecResult>;
|
|
78
|
+
}
|
|
79
|
+
export type CommandRegistry = Map<string, Command>;
|
|
80
|
+
export type { IFileSystem };
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Lightweight argument parser for command implementations.
|
|
3
|
+
*
|
|
4
|
+
* Handles common patterns:
|
|
5
|
+
* - Boolean flags: -n, --number
|
|
6
|
+
* - Combined short flags: -rn (same as -r -n)
|
|
7
|
+
* - Value options: -k VALUE, -kVALUE, --key=VALUE, --key VALUE
|
|
8
|
+
* - Positional arguments
|
|
9
|
+
* - Unknown option detection
|
|
10
|
+
*/
|
|
11
|
+
import type { ExecResult } from "../types.js";
|
|
12
|
+
export type ArgType = "boolean" | "string" | "number";
|
|
13
|
+
export interface ArgDef {
|
|
14
|
+
/** Short form without dash, e.g., "n" for -n */
|
|
15
|
+
short?: string;
|
|
16
|
+
/** Long form without dashes, e.g., "number" for --number */
|
|
17
|
+
long?: string;
|
|
18
|
+
/** Type of the argument */
|
|
19
|
+
type: ArgType;
|
|
20
|
+
/** Default value */
|
|
21
|
+
default?: boolean | string | number;
|
|
22
|
+
}
|
|
23
|
+
export interface ParsedArgs<T extends Record<string, ArgDef>> {
|
|
24
|
+
/** Parsed flag/option values */
|
|
25
|
+
flags: {
|
|
26
|
+
[K in keyof T]: T[K]["type"] extends "boolean" ? boolean : T[K]["default"] extends number | string ? T[K]["type"] extends "number" ? number : string : T[K]["type"] extends "number" ? number | undefined : string | undefined;
|
|
27
|
+
};
|
|
28
|
+
/** Positional arguments (non-flag arguments) */
|
|
29
|
+
positional: string[];
|
|
30
|
+
}
|
|
31
|
+
export type ParseResult<T extends Record<string, ArgDef>> = {
|
|
32
|
+
ok: true;
|
|
33
|
+
result: ParsedArgs<T>;
|
|
34
|
+
} | {
|
|
35
|
+
ok: false;
|
|
36
|
+
error: ExecResult;
|
|
37
|
+
};
|
|
38
|
+
/**
|
|
39
|
+
* Parse command arguments according to the provided definitions.
|
|
40
|
+
*
|
|
41
|
+
* @param cmdName - Command name for error messages
|
|
42
|
+
* @param args - Arguments to parse
|
|
43
|
+
* @param defs - Argument definitions
|
|
44
|
+
* @returns Parsed arguments or error result
|
|
45
|
+
*
|
|
46
|
+
* @example
|
|
47
|
+
* const defs = {
|
|
48
|
+
* reverse: { short: "r", long: "reverse", type: "boolean" as const },
|
|
49
|
+
* count: { short: "n", long: "lines", type: "number" as const, default: 10 },
|
|
50
|
+
* };
|
|
51
|
+
* const result = parseArgs("head", args, defs);
|
|
52
|
+
* if (!result.ok) return result.error;
|
|
53
|
+
* const { flags, positional } = result.result;
|
|
54
|
+
*/
|
|
55
|
+
export declare function parseArgs<T extends Record<string, ArgDef>>(cmdName: string, args: string[], defs: T): ParseResult<T>;
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* File reading utilities for command implementations.
|
|
3
|
+
*
|
|
4
|
+
* Provides common patterns for reading from files or stdin.
|
|
5
|
+
*/
|
|
6
|
+
import type { CommandContext, ExecResult } from "../types.js";
|
|
7
|
+
export interface ReadFilesOptions {
|
|
8
|
+
/** Command name for error messages */
|
|
9
|
+
cmdName: string;
|
|
10
|
+
/** If true, "-" in file list means stdin */
|
|
11
|
+
allowStdinMarker?: boolean;
|
|
12
|
+
/** If true, stop on first error. If false, collect errors and continue */
|
|
13
|
+
stopOnError?: boolean;
|
|
14
|
+
}
|
|
15
|
+
export interface FileContent {
|
|
16
|
+
/** File name (or "-" for stdin, or "" if stdin with no files) */
|
|
17
|
+
filename: string;
|
|
18
|
+
/** File content */
|
|
19
|
+
content: string;
|
|
20
|
+
}
|
|
21
|
+
export interface ReadFilesResult {
|
|
22
|
+
/** Successfully read files */
|
|
23
|
+
files: FileContent[];
|
|
24
|
+
/** Error messages (e.g., "cmd: file: No such file or directory\n") */
|
|
25
|
+
stderr: string;
|
|
26
|
+
/** 0 if all files read successfully, 1 if any errors */
|
|
27
|
+
exitCode: number;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Read content from files or stdin.
|
|
31
|
+
*
|
|
32
|
+
* If files array is empty, reads from stdin.
|
|
33
|
+
* If files contains "-", reads stdin at that position.
|
|
34
|
+
*
|
|
35
|
+
* @example
|
|
36
|
+
* const result = await readFiles(ctx, files, { cmdName: "cat" });
|
|
37
|
+
* if (result.exitCode !== 0 && options.stopOnError) {
|
|
38
|
+
* return { stdout: "", stderr: result.stderr, exitCode: result.exitCode };
|
|
39
|
+
* }
|
|
40
|
+
* for (const { filename, content } of result.files) {
|
|
41
|
+
* // process content
|
|
42
|
+
* }
|
|
43
|
+
*/
|
|
44
|
+
export declare function readFiles(ctx: CommandContext, files: string[], options: ReadFilesOptions): Promise<ReadFilesResult>;
|
|
45
|
+
/**
|
|
46
|
+
* Read and concatenate all files into a single string.
|
|
47
|
+
*
|
|
48
|
+
* Useful for commands like sort and uniq that process all input together.
|
|
49
|
+
*
|
|
50
|
+
* @example
|
|
51
|
+
* const result = await readAndConcat(ctx, files, { cmdName: "sort" });
|
|
52
|
+
* if (!result.ok) return result.error;
|
|
53
|
+
* const lines = result.content.split("\n");
|
|
54
|
+
*/
|
|
55
|
+
export declare function readAndConcat(ctx: CommandContext, files: string[], options: {
|
|
56
|
+
cmdName: string;
|
|
57
|
+
allowStdinMarker?: boolean;
|
|
58
|
+
}): Promise<{
|
|
59
|
+
ok: true;
|
|
60
|
+
content: string;
|
|
61
|
+
} | {
|
|
62
|
+
ok: false;
|
|
63
|
+
error: ExecResult;
|
|
64
|
+
}>;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared glob pattern matching utilities.
|
|
3
|
+
*
|
|
4
|
+
* Used by grep, find, and other commands that need glob matching.
|
|
5
|
+
*/
|
|
6
|
+
export interface MatchGlobOptions {
|
|
7
|
+
/** Case-insensitive matching */
|
|
8
|
+
ignoreCase?: boolean;
|
|
9
|
+
/** Strip surrounding quotes from pattern before matching */
|
|
10
|
+
stripQuotes?: boolean;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Match a filename against a glob pattern.
|
|
14
|
+
*
|
|
15
|
+
* Supports:
|
|
16
|
+
* - `*` matches any sequence of characters
|
|
17
|
+
* - `?` matches any single character
|
|
18
|
+
* - `[...]` character classes
|
|
19
|
+
*
|
|
20
|
+
* @param name - The filename to test
|
|
21
|
+
* @param pattern - The glob pattern
|
|
22
|
+
* @param options - Matching options
|
|
23
|
+
* @returns true if the name matches the pattern
|
|
24
|
+
*/
|
|
25
|
+
export declare function matchGlob(name: string, pattern: string, options?: MatchGlobOptions | boolean): boolean;
|