File tree Expand file tree Collapse file tree 3 files changed +45
-3
lines changed
Expand file tree Collapse file tree 3 files changed +45
-3
lines changed Original file line number Diff line number Diff line change @@ -62,14 +62,30 @@ console.log(result.stdout);
6262
6363## API
6464
65- ### ` tokenizeArgs(command: string): string[] `
65+ ### ` tokenizeArgs(command: string, options: Options ): string[] `
6666
6767Parses a shell command string into an array of arguments. Properly handles:
6868
6969- Quoted strings (e.g., ` '"./path/to/file"' ` ).
7070- Escaped characters (e.g., ` \" ` ).
7171- Multiline commands (e.g., lines ending with ` \\ ` ).
7272
73+ ### Options
74+
75+ - ` loose ` : If ` true ` , the tokenizer will not throw an error when closing quotes are missing. Default is ` false ` .
76+
77+ #### Examples
78+
79+ ``` js
80+ // Without loose option (default behavior)
81+ // This will throw an error due to the missing closing quote
82+ tokenizeArgs (' command "arg1 arg2' );
83+
84+ // With loose option enabled
85+ const args = tokenizeArgs (' command "arg1 arg2' , { loose: true });
86+ // ['command', 'arg1 arg2']
87+ ```
88+
7389## License
7490
7591This project is licensed under the [ MIT License] ( ./LICENSE ) .
Original file line number Diff line number Diff line change @@ -21,6 +21,19 @@ test("inconsistently quoted arguments", () => {
2121 expect ( tokenizeArgs ( `command "arg"um"en"t` ) ) . toEqual ( [ "command" , "argument" ] ) ;
2222} ) ;
2323
24+ test ( "detects incomplete quotes " , ( ) => {
25+ expect ( ( ) => {
26+ tokenizeArgs ( `command "arg1 "arg2" "arg3"` ) ;
27+ } ) . toThrow ( "Unexpected end of string. Closing quote is missing." ) ;
28+ } ) ;
29+
30+ test ( "forgive incomplete quotes in loose mode" , ( ) => {
31+ expect ( tokenizeArgs ( `command "arg1 "arg2" "arg3"` , { loose : true } ) ) . toEqual ( [
32+ "command" ,
33+ "arg1 arg2 arg3" ,
34+ ] ) ;
35+ } ) ;
36+
2437test ( "escape quotes and spaces with other quotes" , ( ) => {
2538 expect ( tokenizeArgs ( `command 'quote "' "quote '"` ) ) . toEqual ( [
2639 "command" ,
@@ -37,7 +50,7 @@ test("escape quotes with backslashes", () => {
3750} ) ;
3851
3952test ( "escape spaces with backslashes" , ( ) => {
40- expect ( tokenizeArgs ( `command space\\ " ` ) ) . toEqual ( [ "command" , "space " ] ) ;
53+ expect ( tokenizeArgs ( `command space\\ ` ) ) . toEqual ( [ "command" , "space " ] ) ;
4154} ) ;
4255
4356test ( "ignore escaped newlines outside of quotes" , ( ) => {
Original file line number Diff line number Diff line change 11const spaceRegex = / \s / ;
22
3+ type Options = {
4+ loose ?: boolean ;
5+ } ;
6+
37/**
48 * Tokenize a shell string into argv array
59 */
6- export const tokenizeArgs = ( argsString : string ) : string [ ] => {
10+ export const tokenizeArgs = (
11+ argsString : string ,
12+ options ?: Options ,
13+ ) : string [ ] => {
714 const tokens = [ ] ;
815 let currentToken = "" ;
916 let openningQuote : undefined | string ;
@@ -50,5 +57,11 @@ export const tokenizeArgs = (argsString: string): string[] => {
5057 if ( currentToken . length > 0 ) {
5158 tokens . push ( currentToken ) ;
5259 }
60+ if ( options ?. loose ) {
61+ return tokens ;
62+ }
63+ if ( openningQuote ) {
64+ throw Error ( "Unexpected end of string. Closing quote is missing." ) ;
65+ }
5366 return tokens ;
5467} ;
You can’t perform that action at this time.
0 commit comments