Skip to content

Commit 5038ec5

Browse files
authored
feat: enable stringLiterals for pipe() API (#900)
1 parent d814096 commit 5038ec5

File tree

5 files changed

+50
-32
lines changed

5 files changed

+50
-32
lines changed

.size-limit.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
{
1010
"name": "zx/index",
1111
"path": "build/*.{js,cjs}",
12-
"limit": "795 kB",
12+
"limit": "796 kB",
1313
"brotli": false,
1414
"gzip": false
1515
},

src/core.ts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ import {
3030
chalk,
3131
which,
3232
ps,
33+
isStringLiteral,
3334
type ChalkInstance,
3435
type RequestInfo,
3536
type RequestInit,
@@ -461,7 +462,12 @@ export class ProcessPromise extends Promise<ProcessOutput> {
461462
return super.catch(onrejected)
462463
}
463464

464-
pipe(dest: Writable | ProcessPromise): ProcessPromise {
465+
pipe(
466+
dest: Writable | ProcessPromise | TemplateStringsArray,
467+
...args: any[]
468+
): ProcessPromise {
469+
if (isStringLiteral(dest))
470+
return this.pipe($(dest as TemplateStringsArray, ...args))
465471
if (isString(dest))
466472
throw new Error('The pipe() method does not take strings. Forgot $?')
467473
if (this._resolved) {
@@ -488,7 +494,7 @@ export class ProcessPromise extends Promise<ProcessOutput> {
488494
}
489495
return dest
490496
} else {
491-
this._postrun = () => this.stdout.pipe(dest)
497+
this._postrun = () => this.stdout.pipe(dest as Writable)
492498
return this
493499
}
494500
}

src/util.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ import path from 'node:path'
1717
import fs from 'node:fs'
1818
import { chalk } from './vendor-core.js'
1919

20+
export { isStringLiteral } from './vendor-core.js'
21+
2022
export function tempdir(prefix = `zx-${randomId()}`) {
2123
const dirpath = path.join(os.tmpdir(), prefix)
2224
fs.mkdirSync(dirpath, { recursive: true })

src/vendor-core.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
// See the License for the specific language governing permissions and
1313
// limitations under the License.
1414

15-
export { exec, buildCmd, type TSpawnStore } from 'zurk/spawn'
15+
export { exec, buildCmd, isStringLiteral, type TSpawnStore } from 'zurk/spawn'
1616

1717
export type RequestInfo = Parameters<typeof globalThis.fetch>[0]
1818
export type RequestInit = Parameters<typeof globalThis.fetch>[1]

test/core.test.js

Lines changed: 38 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -317,34 +317,6 @@ describe('core', () => {
317317
})
318318

319319
describe('pipe() API', () => {
320-
test('is chainable', async () => {
321-
let { stdout } = await $`echo "hello"`
322-
.pipe($`awk '{print $1" world"}'`)
323-
.pipe($`tr '[a-z]' '[A-Z]'`)
324-
assert.equal(stdout, 'HELLO WORLD\n')
325-
})
326-
327-
test('propagates rejection', async () => {
328-
const p1 = $`exit 1`
329-
const p2 = p1.pipe($`echo hello`)
330-
331-
try {
332-
await p1
333-
} catch (e) {
334-
assert.equal(e.exitCode, 1)
335-
}
336-
337-
try {
338-
await p2
339-
} catch (e) {
340-
assert.equal(e.exitCode, 1)
341-
}
342-
343-
const p3 = await $({ nothrow: true })`echo hello && exit 1`.pipe($`cat`)
344-
assert.equal(p3.exitCode, 0)
345-
assert.equal(p3.stdout.trim(), 'hello')
346-
})
347-
348320
test('accepts Writable', async () => {
349321
let contents = ''
350322
let stream = new Writable({
@@ -376,6 +348,16 @@ describe('core', () => {
376348
}
377349
})
378350

351+
test('accepts ProcessPromise', async () => {
352+
const p = await $`echo foo`.pipe($`cat`)
353+
assert.equal(p.stdout.trim(), 'foo')
354+
})
355+
356+
test('accepts $ template literal', async () => {
357+
const p = await $`echo foo`.pipe`cat`
358+
assert.equal(p.stdout.trim(), 'foo')
359+
})
360+
379361
test('checks argument type', async () => {
380362
let err
381363
try {
@@ -389,6 +371,13 @@ describe('core', () => {
389371
)
390372
})
391373

374+
test('is chainable', async () => {
375+
let { stdout } = await $`echo "hello"`
376+
.pipe($`awk '{print $1" world"}'`)
377+
.pipe($`tr '[a-z]' '[A-Z]'`)
378+
assert.equal(stdout, 'HELLO WORLD\n')
379+
})
380+
392381
test('throws if already resolved', async (t) => {
393382
let ok = true
394383
let p = $`echo "Hello"`
@@ -404,6 +393,27 @@ describe('core', () => {
404393
}
405394
assert.ok(ok, 'Expected failure!')
406395
})
396+
397+
test('propagates rejection', async () => {
398+
const p1 = $`exit 1`
399+
const p2 = p1.pipe($`echo hello`)
400+
401+
try {
402+
await p1
403+
} catch (e) {
404+
assert.equal(e.exitCode, 1)
405+
}
406+
407+
try {
408+
await p2
409+
} catch (e) {
410+
assert.equal(e.exitCode, 1)
411+
}
412+
413+
const p3 = await $({ nothrow: true })`echo hello && exit 1`.pipe($`cat`)
414+
assert.equal(p3.exitCode, 0)
415+
assert.equal(p3.stdout.trim(), 'hello')
416+
})
407417
})
408418

409419
describe('abort()', () => {

0 commit comments

Comments
 (0)