Update dependency zx to v8 [SECURITY]
This PR contains the following updates:
| Package | Change | Age | Confidence |
|---|---|---|---|
| zx (source) | ^7.2.2 -> ^8.0.0 |
GitHub Vulnerability Alerts
CVE-2025-13437
When zx is invoked with --prefer-local=
Release Notes
google/zx (zx)
v8.8.5: — Temporary Reservoir
This release fixes the issue, when zx flushes external node_modules on linking #1348 #1349 #1355
Also [email protected] arrives here.
v8.8.4: — Flange Coupling
It's time. This release updates zx internals to make the ps API and related methods ProcessPromise.kill(), kill() work on Windows systems without wmic.
#1344 webpod/ps#15
- WMIC will be missing in Windows 11 25H2 (kernel >= 26000)
- The windows-latest label in GitHub Actions will migrate from Windows Server 2022 to Windows Server 2025 beginning September 2, 2025 and finishing by September 30, 2025.
v8.8.3: — Sealing Gasket
Continues #1339 to prevent injections via Proxy input or custom toString() manipulations.
v8.8.2: — Leaking Valve
Fixes potential cmd injection via kill() method for Windows platform. #1337 #1339. Affects the versions range 8.7.1...8.8.1.
v8.8.1: — Turbo Flush
We keep improving the projects internal infra to bring more stability, safety and performance for artifacts.
Featfixes
- Applied flags filtration for CLI-driven deps install #1308
- Added
kill()event logging #1312 - Set
SIGTERMaskill()fallback signal #1313 - Allowed
stdio()arg be an array #1311
const p = $({halt: true})`cmd`
p.stdio([stream, 'ignore', 'pipe'])
Enhancements
- Added check for zx@lite pkg contents #1317 #1316
- Simplified
ProcessPromise[asyncIterator]inners #1307 - Updated deps: chalk 5.6.0, fs-extra 11.3.1, yaml 2.8.1 #1309 #1323 #1326
- Added TS@next to the test matrix #1310
- Optimized internal
shellsetters #1314 - Refactored build-publish pipelines and scripts #1319 #1320 #1321 #1322 #1324 #1325 #1327
v8.8.0: — Pressure Tested
This release enhances the coherence between the ProcessPromise and the Streams API, eliminating the need for certain script-level workarounds.
✨ New Features
unpipe() — Selectively stop piping
You can now call .unpipe() to stop data transfer from a source to a destination without closing any of the pair. #1302
const p1 = $`echo foo && sleep 0.1 && echo bar && sleep 0.1 && echo baz && sleep 0.1 && echo qux`
const p2 = $`echo 1 && sleep 0.15 && echo 2 && sleep 0.1 && echo 3`
const p3 = $`cat`
p1.pipe(p3)
p2.pipe(p3)
setTimeout(() => p1.unpipe(p3), 150)
const { stdout } = await p3
// 'foo\n1\nbar\n2\n3\n'
Many-to-one piping
Multiple sources can now stream into a single destination. All sources complete before the destination closes. #1300
const $h = $({ halt: true })
const p1 = $`echo foo`
const p2 = $h`echo a && sleep 0.1 && echo c && sleep 0.2 && echo e`
const p3 = $h`sleep 0.05 && echo b && sleep 0.1 && echo d`
const p4 = $`sleep 0.4 && echo bar`
const p5 = $h`cat`
await p1
p1.pipe(p5)
p2.pipe(p5)
p3.pipe(p5)
p4.pipe(p5)
const { stdout } = await p5.run()
// 'foo\na\nb\nc\nd\ne\nbar\n'
Piping from rejected processes
Processes that exit with errors can now still pipe their output. The internal recorder retains their stream, status, and exit code. #1296
const p1 = $({ nothrow: true })`echo foo && exit 1`
await p1
const p2 = p1.pipe($({ nothrow: true })`cat`)
await p2
p1.output.toString() // 'foo\n'
p1.output.ok // false
p1.output.exitCode // 1
p2.output.toString() // 'foo\n'
p2.output.ok // false
p2.output.exitCode // 1
Components versions
Since zx bundles third-party libraries without their package.jsons, their versions weren’t previously visible. You can now access them via the versions static map — including zx itself. #1298 #1295
import { versions } from 'zx'
versions.zx // 8.7.2
versions.chalk // 5.4.1
v8.7.2: — Copper Crafter
Stability and customizability improvements
- Handle
nothrowoption onProcessPromiseinit stage #1288
const o = await $({ nothrow: true })`\033`
o.ok // false
o.cause // Error
- Handle
_snapshot.killSignalvalue onkill()#1287
const p = $({killSignal: 'SIGKILL'})`sleep 10`
await p.kill()
p.signal // 'SIGKILL'
- Introduced
Failclass #1285
import { Fail } from 'zx'
Fail.EXIT_CODES['2'] = 'Custom error message'
Fail.formatErrorMessage = (err: Error, from: string): string =>
`${err.message} (${from})`
- Expose
$as type #1283
import type { $, Options } from 'zx'
const custom$: $ = (pieces: TemplateStringsArray | Partial<Options>, ...args: any[]) => {
// ... custom implementation
}
-
Internal tweak ups #1276 #1277 #1278 #1279 #1280 #1281 #1282 #1286 #1289
-
Described the zx architecture basics. This section helps to better understand the zx concepts and internal logic, and will be useful for those who want to become a project contributor, make tools based on it, or create something similar from scratch. #1290 #1291 #1292
v8.7.1: — Pipe Whisperer
Continues v8.7.0: handles new ps() corner case and improves $.kill mechanics on Windows #1266 #1267 #1269 webpod/ps#14
v8.7.0: — Solder Savior
Important fixes for annoying flaky bugs
kill() 🐞
We've found an interesting case #1262
const p = $`sleep 1000`
const {pid} = p // 12345
await p.kill()
If we kill the process again, the result might be unexpected:
await ps({pid}) // {pid: 12345, ppid: 67890, command: 'another command', ...}
p.kill()
This happens because the pid may be reused by the system for another process, so we've added extra assertions to prevent indeterminacy:
p.kill() // Error: Too late to kill the process.
p.abort() // Error: Too late to abort the process.
ps() 🐛
-
ps()uses wmic internally on Windows, it relies on fragile heuristics to parse the output. We have improved this logic to handle more format variants, but over time (in v9 maybe) we're planning to change the approach.
#1256 #1263 webpod/ps#12 webpod/ingrid#6
const [root] = await ps.lookup({ pid: process.pid })
assert.equal(root.pid, process.pid)
v8.6.2: — Flow Unstoppable
Fixes $.prefix & $.postfix values settings via env variables #1261 #1260
v8.6.1: — Drain Hero
- Use
process.env.SHELLas default shell if defined #1252
SHELL=/bin/zsh zx script.js
- Accept numeric strings as
parseDuration()arg #1249
await sleep(1000) // 1 second
await sleep('1000') // 1 second
- Update docker base image to
node:24-alpine#1239 - Docs improvements #1242 #1243 #1246 #1248 #1251
v8.6.0: — Valve Vanguard
- Enabled
thenableparams processing for$literals #1237
const a1 = $`echo foo`
const a2 = new Promise((resolve) => setTimeout(resolve, 20, ['bar', 'baz']))
await $`echo ${a1} ${a2}` // foo bar baz
- A dozen of internal refactorings #1225 #1226 #1228 #1229 #1230 #1231 #1232 #1233 #1234 #1235 #1236 #1238 #1239
- Deps bumping
- Bytes shrinking
- Docs improvements
v8.5.5: — PVC Wizard
Minor feature polish.
const cwd = tempdir()
const delimiter = '\0'
const p1 = $({
cwd
})`touch foo bar baz; find ./ -type f -print0 -maxdepth 1`
(await p1.lines(delimiter)).sort() // ['./bar', './baz', './foo']
// or via options
const lines = []
const p2 = $({
delimiter,
cwd,
})`find ./ -type f -print0 -maxdepth 1`
for await (const line of p2) {
lines.push(line)
}
lines.sort() // ['./bar', './baz', './foo']
- Handle
.nothrow()option inProcessProcess[AsyncIterator]#1216 #1217 - Updates yaml to v2.8.0 #1221
v8.5.4: — Pipe Dreamer
v8.5.3: — Trap Master
- Another portion of JSR related improvements #1193 #1192
- Goods refactoring #1195
- Fixes
expBackoffimplementation - Sets
$.log.outputas defaultspinner()output - Makes configurable
question()I/O
- Fixes
- Added Graaljs compatability test #1194
- Docs improvements, usage examples updates #1198
v8.5.2: — Threaded Perfection
v8.5.0: — Flow Splitter
In this release we're significantly expanding the zx setup capabilities.
zx@lite
Just core functions without extras, ~7x smaller than the full version. #1131
npm i zx@lite
npm i [email protected]
Detailed comparison: zx/versions
import { $ } from 'zx'
await $`echo foo`
Channels
We have completely reforged the distribution flow. Now zx is available in multiple formats:
##### npm pkg from registry.npmjs.org
npm i zx
##### install directly from the GH
npm i google/zx
##### from GH the npm registry
npm i --registry=https://npm.pkg.github.com @​google/zx
##### fetch from the JSR
##### https://jsr.io/docs/using-packages
##### @​webpod is temporary JSR scope until @​google/zx becomes ready, we'll migrate later
npx jsr add @​webpod/zx
deno add jsr:@​webpod/zx
##### homebrew formula
##### https://github.com/Homebrew/homebrew-core/blob/master/Formula/z/zx.rb
brew install zx
Docker
If you'd prefer to run zx in a container, you can pull the image from the GH docker registry. node:22-alpine is used as a base. #1142 #1145
docker pull ghcr.io/google/zx:8.5.0
docker run -t ghcr.io/google/zx:8.5.0 -e="await \$({verbose: true})\`echo foo\`"
docker run -t -i -v ./:/script ghcr.io/google/zx:8.5.0 script/t.js
Chores
const p1 = fetch('https://example.com').pipe($`cat`)
const p2 = fetch('https://example.com').pipe`cat`
- Added
glob.syncshortcut #1135
import { glob } from 'zx'
const packages = glob.sync(['package.json', 'packages/*/package.json'])
ZX_REGISTRY='https://custom-registry.example.com' zx script.js
- Enhanced errors stacktrace formatting #1166
- Improved 3rd party licenses digest #1140
- Enabled zizmor checks #1126
- Docs improvements #1128 #1134 #1136 #1164
v8.4.2
v8.4.1: – Rusty Elbow
Logger enhancements are arriving in this release. #1119 #1122 #1123 #1125
- You can customize the output by defining your own formatters for each log entry kind.
$.log.formatters = {
cmd: (entry: LogEntry) => `CMD: ${entry.cmd}`,
fetch: (entry: LogEntry) => `FETCH: ${entry.url}`
//...
}
- Cmd highlighter now should properly detect bins and arguments. If still not, please report it in #1122
- Switched to TS 5.8 #1120
- Applied zizmor to check GHA workflows #1126
- Prettier is now enabled as a pre-commit hook #1118
v8.4.0: – Drip Detective
Try the new batch of enhancements: npm i [email protected] https://www.npmjs.com/package/zx/v/8.4.0
Changes
const cwd = tmpdir()
const external = tmpdir()
await fs.outputJson(path.join(external, 'node_modules/a/package.json'), {
name: 'a',
version: '1.0.0',
type: 'module',
exports: './index.js',
})
await fs.outputFile(
path.join(external, 'node_modules/a/index.js'),
`
export const a = 'AAA'
`
)
const script = `
import {a} from 'a'
console.log(a);
`
const out = await $`zx --cwd=${cwd} --prefer-local=${external} --test <<< ${script}`
assert.equal(out.stdout, 'AAA\n')
const p = $({prefix: '', postfix: ''})`echo ${[1, '', '*', '2']}`
// before
p.cmd // `echo 1 $'*' 2`)
// after
p.cmd // `echo 1 $'' $'*' 2`)
zx script.zx # Unknown file extension "\.zx"
zx --ext=mjs script.zx # OK
const err = new Error('BrokenSpawn')
const o = await $({
nothrow: true,
spawn() {
throw err
},
})`echo foo`
o.ok // false
o.exitCode // null
o.message // BrokenSpawn...
o.cause // err
-
@types/nodeand@types/fs-extradeps replaced with triple-slash typing refs #1102 - Made
ProcessOutputiterable #1101 - Handle inappropriate
ProcessPromiseinstantiation #1097 #1098 - Pass origin error as
ProcessOuputcause #1110 - Separated build and release steps #1106
- Internal improvements
v8.3.2: – Clogged Drain
Restrics unsafe vals usage on dotenv.stringify #1093 #1094
v8.3.1: – Perfect Seal
The release essence: introduced full-featured .env support #461 → #1060 #1052 #1043 #1037 #1032 #1030 #1022
API
envapi is a tiny 100 LOC dotenv-inspired parser and serializer that we've integrated into zx.
import { dotenv, fs } from 'zx'
// parse
const env = dotenv.parse('A=A\nFOO=BAR') // { A: 'A', FOO: 'BAR' }
// serialize
const raw = dotenv.stringify(env) // A=A\nFOO=BAR
await fs.writeFile('.env', raw)
// load
dotenv.load('.env') // { A: 'A', FOO: 'BAR' }
// update the process.env
dotenv.config('.env')
process.env.A // A
CLI
zx --env .env script.mjs
zx --env-file .env script.mjs
QnA
— Why not use dotenv directly?
— 1) Size does matter 2) We'd like to avoid internal vaults.
— Why not load .env by default?
— 1) Explicit is better than implicit 2) Runtime itself (like bun) may provide the feature.
Chore
- Provided
stdallpiping #1033 - Exposed ProcessPromise
fullCmdand uniqueid#1035 - Simplified internal regexps #1040 #1038
- Removed zx globals from unit tests scope #1039
- Added check if tempfile exists #1041
- Added ts support in markdown #1042
- Enabled CodeQL and OSV scanners #1011
- Configured pre-push git hooks #1044
- Explicitly declared permissions for test.yml #1045
- Mentioned
haltandrunAPI in docs #1046 - Fixed
timeoutoption handling for corner cases #1049 - Allowed
killSignalsetting via env vars #1054 - Added
diagnostic_channelto built-ins list #1056 - Enhanced logger: added
idfield and introducedendevent #1057 #1058 - Made
nothrown()toggleable #1066 #1029 - Handle
ZX_REPL_HISTORYenvvar #1065 - Fixed
file://protocol check #1064 - Accept
modeoption fortmpdirandtmpfile#1063 - Enhanced deno support #1062 #1061
- Optimized markdown parser #1068
- Applied zizmor suggestions #1067
- Minor code improvements #1070 #1069
- Optimized output buffers joining #1072
- Fixed predefined
_timeoutSignaloverride #1075 - Exposed
ProcessPromisestage #1077 #967 - Aligned script processing flows (CLI) #1078
- Enhanced $ options tests #1079
v8.3.0: – Pipes of Steel
A few weeks ago zx took a part in OSS Library Night 🎉
Many thanks to the organizers and contributors who have boosted the project with their pull requests!
Today we are releasing the zx with a huge bunch of new features and improvements.
Features
API
- Implemented
[Symbol.asyncIterator]API forProcessPromise#984 #998 #1000 Now you can iterate over the process output usingfor awaitloop from any point of the process execution.
const process = $`sleep 0.1; echo Chunk1; sleep 0.1; echo Chunk2; sleep 0.2; echo Chunk3; sleep 0.1; echo Chunk4;`
const chunks = []
await new Promise((resolve) => setTimeout(resolve, 250))
for await (const chunk of process) {
chunks.push(chunk)
}
chunks.length // 4
chunks[0] // 'Chunk1'
chunks[3] // 'Chunk4'
- zx version is available via JS API #986
import { version } from 'zx'
const [major] = (version || '').split('.').map(Number)
if (major < 6)
throw new Error('zx >= 6 is required')
Pipes
- Enabled stream picking for
pipe()#1023
const p = $`echo foo >&2; echo bar`
const o1 = (await p.pipe.stderr`cat`).toString()
const o2 = (await p.pipe.stdout`cat`).toString()
assert.equal(o1, 'foo\n') // <- piped from stderr
assert.equal(o2, 'bar\n') // <- stdout
- Added
signalhandling on piping #992
const ac = new AbortController()
const { signal } = ac
const p = $({ signal, nothrow: true })`echo test`.pipe`sleep 999`
setTimeout(() => ac.abort(), 50)
try {
await p
} catch ({ message }) {
message // The operation was aborted
}
- Added direct piping to file shortcut #1001
// before
await $`echo "Hello, stdout!"`.pipe(fs.createWriteStream('/tmp/output.txt'))
// after
await $`echo "Hello, stdout!"`.pipe('/tmp/output.txt')
CLI
ZX_VERBOSE=true ZX_SHELL='/bin/bash' zx script.mjs
zx --env=/path/to/some.env script
- Landed installation registry customization #994
zx --install --registry=https://registry.yarnpkg.com script.mjs
- Added
--prefer-localoption #1015
Fixes
- Fixed temp assets clutter on
process.exit()#993 #997 - Handle tslib-generated string templates #966
- Disabled spinner on CI and in quiet mode #1008 #1009 #1017
- Added missing
ZX_SHELLenv handling #1024
Docs
- Contribution guide updated #983
- Documentation is now built from the
mainbranch #985 - Finally synced with the current API #1025 #1026
Chores
- Added autotest generation for 3rd party libs export #987 #990 #1007 #1021
- Added some jsr.io pre-publish tests #989 #991
- Optimized package.json on publishing #1005 #1006
- Attached
.node_versionto improve contributors devx #1012 - Built-in
chalkupdated to v5.4.1 #1019
Merry Christmas! 🎄🎅🎁
v8.2.4: – Leaky Faucet
- Fixed bun async_hooks compatibility #959
v8.2.3: – Golden Wrench
This release continues the work on pipe API enhancements:
const { stdout } = await $({ halt: true })`echo "hello"`
.pipe`awk '{print $1" world"}'`
.pipe`tr '[a-z]' '[A-Z]'`
.run()
stdout // 'HELLO WORLD'
- Let $ be piped directly from streams #953
const getUpperCaseTransform = () =>
new Transform({
transform(chunk, encoding, callback) {
callback(null, String(chunk).toUpperCase())
},
})
// $ > stream (promisified) > $
const o1 = await $`echo "hello"`
.pipe(getUpperCaseTransform())
.pipe($`cat`)
o1.stdout // 'HELLO\n'
// stream > $
const file = tempfile()
await fs.writeFile(file, 'test')
const o2 = await fs
.createReadStream(file)
.pipe(getUpperCaseTransform())
.pipe($`cat`)
o2.stdout // 'TEST'
const file = tempfile()
const fileStream = fs.createWriteStream(file)
const p = $`echo "hello"`
.pipe(getUpperCaseTransform())
.pipe(fileStream)
const o = await p
p instanceof WriteStream // true
o instanceof WriteStream // true
o.stdout // 'hello\n'
o.exitCode; // 0
(await fs.readFile(file)).toString() // 'HELLO\n'
We've also slightly tweaked up dist contents for better compatibility with bundlers #957
v8.2.2
What's Changed
- test: stdio inherit by @antongolub in #941
- fix: handle nullable stdout/stderr by @antongolub in #943
Full Changelog: https://github.com/google/zx/compare/8.2.1...8.2.2
v8.2.1
v8.2.0
Pipes supercharge today! 🚀
Features
- Delayed piping. You can fill dependent streams at any time during the origin process lifecycle (even when finished) without losing data. #914
const result = $`echo 1; sleep 1; echo 2; sleep 1; echo 3`
const piped1 = result.pipe`cat`
let piped2
setTimeout(() => {
piped2 = result.pipe`cat`
}, 1500)
await piped1
assert.equal((await piped1).toString(), '1\n2\n3\n')
assert.equal((await piped2).toString(), '1\n2\n3\n')
const file = tempfile()
const fileStream = fs.createWriteStream(file)
const p = $`echo "hello"`
.pipe(
new Transform({
transform(chunk, encoding, callback) {
callback(null, String(chunk).toUpperCase())
},
})
)
.pipe(fileStream)
p instanceof WriteStream // true
await p === fileStream // true
(await fs.readFile(file)).toString() // 'HELLO\n'
Chore
v8.1.9
Today's release is a minor update that includes:
Enhancements
- We have replaced
ProcessOutputfields with lazy getters to reduce mem consumption #903, #908 - Reduced ReDos risks for codeblock patterns #906
- Kept
argvreference on update #916 - Strengthened
Shellinterface to properly handlesyncmode #915:
expectType<ProcessPromise>($`cmd`)
expectType<ProcessPromise>($({ sync: false })`cmd`)
expectType<ProcessOutput>($({ sync: true })`cmd`)
expectType<ProcessOutput>($.sync`cmd`)
Fixes
v8.1.8
- Apply the proper
TeplateStringArraydetection #904, #905 -
PromiseProcessgot lazy getters to optimize mem usage #903
v8.1.7
Step by step on the road to improvements
Fixes
Finally, we've fixed the issue with piped process rejection #640 #899:
const p1 = $`exit 1`.pipe($`echo hello`)
try {
await p1
} catch (e) {
assert.equal(e.exitCode, 1)
}
const p2 = await $({ nothrow: true })`echo hello && exit 1`.pipe($`cat`)
assert.equal(p2.exitCode, 0)
assert.equal(p2.stdout.trim(), 'hello')
Enhancements
Added cmd display to ProcessPromise #891:
const foo = 'bar'
const p = $`echo ${foo}`
p.cmd // 'echo bar'
and duration field to ProcessOutput #892:
const p = $`sleep 1`.nothrow()
const o = await p
o.duration // ~1000 (in ms)
Enabled zurk-like pipe string literals #900:
const p = await $`echo foo`.pipe`cat`
p.stdout.trim() // 'foo'
v8.1.6
Improvements & Fixes
$.preferLocal = true // injects node_modules/.bin to the $PATH
$.preferLocal = '/foo/bar' // attaches /foo/bar to the $PATH
$.preferLocal = ['/bar', '/baz'] // now the $PATH includes both /bar and /baz
Why not just $.env['PATH'] = 'extra:' + '$.env['PATH']?
Well, the API internally does the same, but also handles the win paths peculiarities.
- Provided
$.killSignaloption for the symmetry with the$.timeoutSignal. You can override the default termination flow #885:
$.killSignal = 'SIGKILL'
const p = $({nothrow: true})`sleep 10000`
setTimeout(p.kill, 100)
(await p).signal // SIGKILL
-
$opt presets became chainable #883:
const $$ = $({ nothrow: true })
assert.equal((await $$`exit 1`).exitCode, 1)
const $$$ = $$({ sync: true }) // Both {nothrow: true, sync: true} are applied
assert.equal($$$`exit 2`.exitCode, 2)
- Enhanced the internal
Durationparser #884:
const p = $({timeout: '1mss'})`sleep 999` // raises an error now
- Abortion signal listeners are now removed after the process completes #881, #889, zurk#12, zurk#13.
- Extended integration tests matrix, added nodejs-nightly builds and TS dev snapshots #888
v8.1.5
We've rolled out a new release!
Fixes
- Added the minimist typings to the dts bundle. #872 brings the fix.
- Re-enabled the YAML extra API. #870 #879
Chores
- Clarified
cd(),within()andsyncProcessCwd()interactions. #878 - Included mention of the
cwdoption in the documentation. #868 - Test enhancements. #877 #880
v8.1.4
We continue optimizing bundles and CI/CD pipelines.
- Update @webpod/ps to v0.0.0-beta.7 to sync internal zurk version. #855
- Split vendor chunk to reduce the
zx/coreentry size. #856 - Add bundle size check. #857
- Refactor the testing flow, remove duplicated tasks. #861
- Add missing types for the global
defaults. #864 - Omit redundant YAML API extras. #866
Which gives us: 897 kB → 829 kB (-7.58%)
v8.1.3
Nothing special today. We just keep improving the implementation.
Features
import {$} from 'zx'
-
zx/cliexports its inners to allow more advanced usage. Imagine, your own CLI tool that useszxas a base:
#828
#!/usr/bin/env node
import './index.mjs'
import {main} from 'zx/cli'
main()
const getFixedSizeArray = (size) => {
const arr = []
return new Proxy(arr, {
get: (target, prop) =>
prop === 'push' && arr.length >= size
? () => {}
: target[prop],
})
}
const store = {
stdout: getFixedSizeArray(1),
stderr: getFixedSizeArray(1),
stdall: getFixedSizeArray(0),
}
const p = await $({ store })`echo foo`
p.stdout.trim() // 'foo'
p.toString() // ''
- Introduced sync methods for
ps:
#840
import { ps } from 'zx'
const list1 = await ps()
const list2 = await tree()
// new methods
const list3 = ps.sync()
const list4 = tree.sync()
Chore
-
$.logacceptskind: 'custom'#834 - Describe
$.verboseand$.quietmodes internals #835 - Mention
quotePowerShellin docs #851 - Finally fixed the annoying flaky problem of the process end detection in Bun #839, coderef
- Suppress
async_hooks.createHookwarning on bun #848 - Remove node-abort-controller in favor of built-in node-fetch polyfill #842
- Add missing global types #853
v8.1.2
Every new zx version is better than previous one. What have we here?
Features
const p = $`echo foo`
p.quiet() // enable silent mode
p.quiet(false) // then disable
p.verbose() // enable verbose/debug mode
p.verbose(false) // and turn it off
await p
- Aligned
ProcessPromise.isSmth()API:
#823
const p = $`echo foo`
p.isHalted()
p.isVerbose()
p.isQuiet()
p.isNothrow()
Bug Fixes
- fix: apply EOL ensurer to the last chunk only #825
- fix(cli): return exit code 1 on incorrect inputs #826
- fix: set cjs bundle as legacy
mainentrypoint #827
Chore
- Published with npm provenance #818
- Minor polyfills optimizations #821
v8.1.1
This release brings a pinch of sugar and minor fixes.
Features
- Introduced
$.preferLocaloption to prefernode_modules/.binlocated binaries over globally system installed ones.
#798
$.preferLocal = true
await $`c8 npm test`
await $({ preferLocal: true })`eslint .`
const p = $`echo 'foo\nbar'`
await p.text() // foo\n\bar\n
await p.text('hex') // 666f6f0a0861720a
await p.buffer() // Buffer.from('foo\n\bar\n')
await p.lines() // ['foo', 'bar']
await $`echo '{"foo": "bar"}'`.json() // {foo: 'bar'}
-
ProcessPromisenow exposes itssignalreference.
#816
const p = $`sleep 999`
const {signal} = p
const res = fetch('https://example.com', {signal})
setTimeout(() => p.abort('reason'), 1000)
Fixes
- CLI flag
--quietis mapped to$.quietoption. #813 - Module conditional exports are properly sorted now. #812
- A newline character is appended to the output of
ProcessPromiseif it's missing. #810
v8.1.0
This new release is a big deal. It brings significant improvements in reliability and compatibility.
- Switched to hybrid-scheme package: both ESM and CJS entry points are provided.
- Extended Node.js supported versions range: from 12.17.0 to the latest 22.x.x.
- Added compatibility with Deno 1.x.
- zx libdefs are now compatible with TS 4.0+.
New features
Added usePwsh() helper to switch to PowerShell v7+ #790
import {usePwsh, useBash} from 'zx'
usePwsh()
$.shell // 'pwsh'
useBash()
$.shell // 'bash'
timeout is now configurable $ opts #796
import {$} from 'zx'
await $({ timeout: 100 })`sleep 999`
$.timeout = 1000 // Sets default timeout for all commands
$.timeoutSignal = 'SIGKILL' // Sets signal to send on timeout
await $`sleep 999`
Added --cwd option for CLI #804
zx --cwd=/some/path script.js
Introduced tmpdir and tmpfile helpers #803
import {tmpdir, tmpfile} from 'zx'
t1 = tmpdir() // /os/based/tmp/zx-1ra1iofojgg/
t2 = tmpdir('foo') // /os/based/tmp/zx-1ra1iofojgg/foo/
f1 = tmpfile() // /os/based/tmp/zx-1ra1iofojgg
f2 = tmpfile('f.txt') // /os/based/tmp/zx-1ra1iofojgg/foo.txt
f3 = tmpfile('f.txt', 'string or buffer')
- Support CRLF for markdown script #788
- Added help digest for man #806
- Added compatibility with Deno 1.x. → zx seems to be working with Deno 1.x.
v8.0.2
In this release:
v8.0.1
In this release:
Configuration
📅 Schedule: Branch creation - "" (UTC), Automerge - At any time (no schedule defined).
🚦 Automerge: Disabled by config. Please merge this manually once you are satisfied.
♻ Rebasing: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.
🔕 Ignore: Close this PR and you won't be reminded about this update again.
- [ ] If you want to rebase/retry this PR, check this box
This PR was generated by Mend Renovate. View the repository job log.