zx with some extras
- Node.js >= 16.0.0
- Bun >= 1.0.12
# npm
npm i zx-extra
# yarn
yarn add zx-extra
Inherits zx, so all original methods are available. Follow the upstream docs for details.
striked text marks APIs that was merged into zx core.
Resolves the current IP address via node-ip.
import {ip} from 'zx-extra'
ip.address() // 1.2.3.4
Semantic versioning API provided by node-semver.
import {semver} from 'zx-extra'
semver.gte('1.0.1', '1.0.0')
Asserts the version of the specified package or binary against the semver range.
import {ver} from 'zx-extra'
ver('ip') // '1.1.8'
ver('git') // '2.37.0'
ver('git', '>=2') // '2.37.0'
ver('git', '>=5') // Error: [email protected] does not satisfy >=5
Checks the network availability of the specified gateway via is-reachable.
import {tcping} from 'zx-extra'
await tcping('example.com:443') // true
await tcping('unknown:1234') // false
deprecated, use tmpfile
and tmpdir
instead: zx#803
Creates temp dirs and files.
import {tempy} from 'zx-extra'
temporaryFile() // '/private/var/folders/p0/p7xckky93s30rshd51gs4pdc0000gn/T/1b7e9277860eb90b94aad816d4f66f8e'
temporaryDirectory() // '/private/var/folders/p0/p7xckky93s30rshd51gs4pdc0000gn/T/1b7e9277860eb90b94aad816d4f66f8e'
Provides globby
-boosted copying API.
import {copy} from 'zx-extra'
await copy({
from: 'src/**/*.js',
to: 'dist/',
baseFrom, // process.cwd()
baseTo, // process.cwd(),
debug, // () => {}
ignoreFiles // undefined
})
Provides INI API.
import {INI} from 'zx-extra'
const ini = `[database]
user = dbuser
password = dbpassword
`
const parsed = INI.parse(ini)
parsed.database.user // 'dbuser'
INI.stringify(parsed, {whitespace: true}) // ini
Exposes SSRI API
import {SSRI} from 'zx-extra'
const integrity = 'sha512-9KhgCRIx/AmzC8xqYJTZRrnO8OW2Pxyl2DIMZSBOr0oDvtEFyht3xpp71j/r/pAe1DM+JI/A+line3jUBgzQ7A==?foo'
// Parsing and serializing
const parsed = SSRI.parse(integrity)
SSRI.stringify(parsed) // === integrity (works on non-Integrity objects)
parsed.toString() // === integrity
async_hooks-driven scope isolator. Creates a separate zx-context for the specified function.
import {ctx} from 'zx/experimental'
const _$ = $
ctx(async ($) => {
await sleep(10)
cd('/foo')
// $.cwd refers to /foo
// _$.cwd === $.cwd
})
ctx(async ($) => {
await sleep(20)
// _$.cwd refers to /foo
// but _$.cwd !== $.cwd
})
const ref = $.bind(null)
ctx(($) => {
ref === $ // true
}, ref)
Landed as zx#798
In npm run scripts you can execute locally installed binaries by name. This enables the same for zx.
$`terser input.js --compress ecma=2015,computed_props=false`
Note, that yarn and npm modify env.$PATH
value, so some */node_modules/.bin
binaries are available for invocation.
To disable this side-effect, append smth like PATH=$(env -i bash -c 'echo $PATH')
to the command.
Evaluates target cmd as is without shq
.
const cmd = 'echo foo'
const msg = 'bar'
const output = (await $.raw`${cmd} ${msg}`).toString().trim()
// $ echo foo bar
Since [email protected]
Set to false
by default.
Applies .trim()
to ProcessOutput
string representation. Set true
by default.
Landed as zx#733
Returns $
with the specified preset. Aliased for $.o
.
const $$ = $.opt({verbose: false, spawn: customSpawn})
await $$`foo 'bar'`
Helper to create chainable extras.
const quiet = createHook({ verbose: false }, 'quiet')
const timeout = createHook(
null,
'timeout',
(p, t, signal) => {
if (!t) return p
let timer = setTimeout(() => p.kill(signal), t)
return Object.assign(
p.finally(() => clearTimeout(timer)),
p
)
},
true
)
const p = $`sleep 9999`
await quiet(timeout(100, 'SIGKILL')(p))
await $`sleep 9999`.quiet().timeout(100, 'SIGKILL')
await quiet(timeout(100, 'SIGKILL')`sleep 9999`)
merged as bf88f50
Sets verbose = false
for a single invocation.
await $.silent`echo foo`
// <no output in console>
merged as d8b6b87
Refers to fs-extra instead of standard Node.js fs
module.
await fs.copy('/tmp/myfile', '/tmp/mynewfile')
merged as d8b6b87
Represents parsed with minimist script arguments
// zx-extra test.mjs --foo=bar
argv
{ _: [ 'test.mjs' ], foo: 'bar' }