Skip to content

Commit 48c455f

Browse files
Add shlex.join method (#19)
1 parent 7bf060b commit 48c455f

File tree

5 files changed

+52
-3
lines changed

5 files changed

+52
-3
lines changed

README.md

+9-1
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,14 @@ operators (such as `2>/dev/null`) or comments, and it does not perform variable
2323

2424
## Usage
2525

26+
### `shlex.join()`
27+
28+
```node
29+
var join = require("shlex").join
30+
join(["ls", "-al", '/']) // returns: 'ls -al /'
31+
join([ 'rm', '-f', '/Volumes/Macintosh HD' ]) // returns: "rm -f '/Volumes/Macintosh HD'"
32+
```
33+
2634
### `shlex.quote()`
2735

2836
```node
@@ -37,5 +45,5 @@ quote("can't") // returns: 'can'"'"'t'
3745
```node
3846
var split = require("shlex").split
3947
split('ls -al /') // returns: [ 'ls', '-al', '/' ]
40-
split('rm -f "/Volumes/Macintosh HD"') // returns [ 'rm', '-f', '/Volumes/Macintosh HD' ]
48+
split('rm -f "/Volumes/Macintosh HD"') // returns: [ 'rm', '-f', '/Volumes/Macintosh HD' ]
4149
```

shlex.d.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
1-
export function split(s: string): string[];
1+
export function join(args: string[]): string;
22
export function quote(s: string): string;
3+
export function split(s: string): string[];

shlex.js

+20-1
Original file line numberDiff line numberDiff line change
@@ -260,7 +260,8 @@ class Shlexer {
260260

261261

262262
/**
263-
* Splits a given string using shell-like syntax.
263+
* Splits a given string using shell-like syntax. This function is the inverse
264+
* of shlex.join().
264265
*
265266
* @param {String} s String to split.
266267
* @returns {String[]}
@@ -283,3 +284,21 @@ exports.quote = function (s) {
283284

284285
return ('\'' + s.replace(/('+)/g, '\'"$1"\'') + '\'').replace(/^''|''$/g, '')
285286
}
287+
288+
289+
/**
290+
* Concatenate the tokens of the list args and return a string. This function
291+
* is the inverse of shlex.split().
292+
*
293+
* The returned value is shell-escaped to protect against injection
294+
* vulnerabilities (see shlex.quote()).
295+
*
296+
* @param {String[]} args List of args to join
297+
* @returns {String}
298+
*/
299+
exports.join = function (args) {
300+
if (!Array.isArray(args)) {
301+
throw new TypeError("args should be an array")
302+
}
303+
return args.map(exports.quote).join(" ")
304+
}

test/test.ts

+1
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,6 @@ shlex.quote('test text')
44
shlex.split('test text "multi word thing"')
55

66
// Should error
7+
shlex.join()
78
shlex.quote()
89
shlex.split()

test/test_join.js

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
/* eslint-env mocha */
2+
'use strict'
3+
4+
const { assert } = require('chai')
5+
const shlex = require('../shlex')
6+
7+
describe('shlex.join()', () => {
8+
const posixTestcases = [
9+
[['ls', '-al', '/'], 'ls -al /'],
10+
[['rm', '-f', '/Volumes/Macintosh HD'], "rm -f '/Volumes/Macintosh HD'"]
11+
]
12+
13+
it('should join according to POSIX rules', () => {
14+
posixTestcases.forEach(function (test) {
15+
const [input, expected] = test
16+
17+
assert.deepEqual(shlex.join(input), expected)
18+
})
19+
})
20+
})

0 commit comments

Comments
 (0)