Socket
Socket
Sign inDemoInstall

zx

Package Overview
Dependencies
Maintainers
2
Versions
146
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

zx - npm Package Compare versions

Comparing version 7.0.8 to 7.1.0-dev.862401

build/deps.d.ts

174

build/cli.js

@@ -16,70 +16,82 @@ #!/usr/bin/env node

import fs from 'fs-extra';
import minimist from 'minimist';
import { createRequire } from 'node:module';
import { tmpdir } from 'node:os';
import { basename, dirname, extname, join, resolve } from 'node:path';
import url from 'node:url';
import { updateArgv } from './goods.js';
import { $, argv, chalk, fetch, ProcessOutput } from './index.js';
import { $, chalk, fetch, ProcessOutput } from './index.js';
import { startRepl } from './repl.js';
import { randomId } from './util.js';
import { installDeps, parseDeps } from './deps.js';
function printUsage() {
// language=txt
console.log(`
${chalk.bold('zx ' + getVersion())}
A tool for writing better scripts
${chalk.bold('Usage')}
zx [options] <script>
${chalk.bold('Options')}
--quiet don't echo commands
--shell=<path> custom shell binary
--prefix=<command> prefix all commands
--eval=<js>, -e evaluate script
--install, -i install dependencies
--experimental enable experimental features
--version, -v print current zx version
--help, -h print help
--repl start repl
`);
}
const argv = minimist(process.argv.slice(2), {
string: ['shell', 'prefix', 'eval'],
boolean: ['version', 'help', 'quiet', 'install', 'repl', 'experimental'],
alias: { e: 'eval', i: 'install', v: 'version', h: 'help' },
stopEarly: true,
});
await (async function main() {
const globals = './globals.js';
await import(globals);
if (argv.quiet) {
if (argv.quiet)
$.verbose = false;
}
if (typeof argv.shell === 'string') {
if (argv.shell)
$.shell = argv.shell;
}
if (typeof argv.prefix === 'string') {
if (argv.prefix)
$.prefix = argv.prefix;
}
if (argv.experimental) {
Object.assign(global, await import('./experimental.js'));
}
if (process.argv.length == 3) {
if (['--version', '-v', '-V'].includes(process.argv[2])) {
console.log(getVersion());
return;
}
if (['--help', '-h'].includes(process.argv[2])) {
printUsage();
return;
}
if (['--interactive', '-i'].includes(process.argv[2])) {
startRepl();
return;
}
if (argv.version) {
console.log(getVersion());
return;
}
if (argv.eval || argv.e) {
const script = (argv.eval || argv.e).toString();
await runScript(script);
if (argv.help) {
printUsage();
return;
}
let firstArg = process.argv.slice(2).find((a) => !a.startsWith('--'));
if (typeof firstArg === 'undefined' || firstArg === '-') {
let ok = await scriptFromStdin();
if (!ok) {
startRepl();
}
if (argv.repl) {
startRepl();
return;
}
else if (firstArg.startsWith('http://') ||
firstArg.startsWith('https://')) {
if (argv.eval) {
await runScript(argv.eval);
return;
}
const firstArg = argv._[0];
updateArgv(argv._.slice(firstArg === undefined ? 0 : 1));
if (!firstArg || firstArg === '-') {
const success = await scriptFromStdin();
if (!success)
printUsage();
return;
}
if (/^https?:/.test(firstArg)) {
await scriptFromHttp(firstArg);
return;
}
else {
let filepath;
if (firstArg.startsWith('/')) {
filepath = firstArg;
}
else if (firstArg.startsWith('file:///')) {
filepath = url.fileURLToPath(firstArg);
}
else {
filepath = resolve(firstArg);
}
updateArgv({ sliceAt: 3 });
await importPath(filepath);
}
return;
const filepath = firstArg.startsWith('file:///')
? url.fileURLToPath(firstArg)
: resolve(firstArg);
await importPath(filepath);
})().catch((err) => {

@@ -95,5 +107,4 @@ if (err instanceof ProcessOutput) {

async function runScript(script) {
let filepath = join(tmpdir(), randomId() + '.mjs');
await fs.mkdtemp(filepath);
await writeAndImport(script, filepath, join(process.cwd(), 'stdin.mjs'));
const filepath = join(process.cwd(), `zx-${randomId()}.mjs`);
await writeAndImport(script, filepath);
}

@@ -115,3 +126,3 @@ async function scriptFromStdin() {

async function scriptFromHttp(remote) {
let res = await fetch(remote);
const res = await fetch(remote);
if (!res.ok) {

@@ -121,28 +132,36 @@ console.error(`Error: Can't get ${remote}`);

}
let script = await res.text();
let filename = new URL(remote).pathname;
let filepath = join(tmpdir(), basename(filename));
await fs.mkdtemp(filepath);
await writeAndImport(script, filepath, join(process.cwd(), basename(filename)));
const script = await res.text();
const pathname = new URL(remote).pathname;
const name = basename(pathname);
const ext = extname(pathname) || '.mjs';
const filepath = join(process.cwd(), `${name}-${randomId()}${ext}`);
await writeAndImport(script, filepath);
}
async function writeAndImport(script, filepath, origin = filepath) {
await fs.writeFile(filepath, script.toString());
let wait = importPath(filepath, origin);
await fs.rm(filepath);
await wait;
try {
await importPath(filepath, origin);
}
finally {
await fs.rm(filepath);
}
}
async function importPath(filepath, origin = filepath) {
let ext = extname(filepath);
const ext = extname(filepath);
if (ext === '') {
let tmpFilename = fs.existsSync(`${filepath}.mjs`)
const tmpFilename = fs.existsSync(`${filepath}.mjs`)
? `${basename(filepath)}-${randomId()}.mjs`
: `${basename(filepath)}.mjs`;
return await writeAndImport(await fs.readFile(filepath), join(dirname(filepath), tmpFilename), origin);
return writeAndImport(await fs.readFile(filepath), join(dirname(filepath), tmpFilename), origin);
}
if (ext === '.md') {
return await writeAndImport(transformMarkdown(await fs.readFile(filepath)), join(dirname(filepath), basename(filepath) + '.mjs'), origin);
return writeAndImport(transformMarkdown(await fs.readFile(filepath)), join(dirname(filepath), basename(filepath) + '.mjs'), origin);
}
let __filename = resolve(origin);
let __dirname = dirname(__filename);
let require = createRequire(origin);
if (argv.install) {
const deps = parseDeps(await fs.readFile(filepath));
await installDeps(deps, dirname(filepath));
}
const __filename = resolve(origin);
const __dirname = dirname(__filename);
const require = createRequire(origin);
Object.assign(global, { __filename, __dirname, require });

@@ -152,4 +171,4 @@ await import(url.pathToFileURL(filepath).toString());

function transformMarkdown(buf) {
let source = buf.toString();
let output = [];
const source = buf.toString();
const output = [];
let state = 'root';

@@ -227,20 +246,1 @@ let prevLineIsEmpty = true;

}
function printUsage() {
console.log(`
${chalk.bold('zx ' + getVersion())}
A tool for writing better scripts
${chalk.bold('Usage')}
zx [options] <script>
${chalk.bold('Options')}
--quiet don't echo commands
--shell=<path> custom shell binary
--prefix=<command> prefix all commands
--interactive, -i start repl
--eval=<js>, -e evaluate script
--experimental enable new api proposals
--version, -v print current zx version
--help, -h print help
`);
}

@@ -41,2 +41,3 @@ /// <reference types="node" resolution-mode="require"/>

private _resolved;
private _halted;
private _piped;

@@ -46,13 +47,17 @@ _prerun: typeof noop;

_bind(cmd: string, from: string, resolve: Resolve, reject: Resolve, options: Options): void;
_run(): void;
run(): ProcessPromise;
get stdin(): Writable;
get stdout(): Readable;
get stderr(): Readable;
get exitCode(): Promise<any>;
get exitCode(): Promise<number | null>;
then<R = ProcessOutput, E = ProcessOutput>(onfulfilled?: ((value: ProcessOutput) => PromiseLike<R> | R) | undefined | null, onrejected?: ((reason: ProcessOutput) => PromiseLike<E> | E) | undefined | null): Promise<R | E>;
catch<T = ProcessOutput>(onrejected?: ((reason: ProcessOutput) => PromiseLike<T> | T) | undefined | null): Promise<ProcessOutput | T>;
pipe(dest: Writable | ProcessPromise): ProcessPromise;
kill(signal?: string): Promise<void>;
stdio(stdin: IO, stdout?: IO, stderr?: IO): this;
nothrow(): this;
quiet(): this;
timeout(d: Duration, signal?: string): this;
stdio(stdin: IO, stdout?: IO, stderr?: IO): ProcessPromise;
nothrow(): ProcessPromise;
quiet(): ProcessPromise;
timeout(d: Duration, signal?: string): ProcessPromise;
halt(): ProcessPromise;
get isHalted(): boolean;
}

@@ -59,0 +64,0 @@ export declare class ProcessOutput extends Error {

@@ -59,3 +59,3 @@ // Copyright 2021 Google LLC

let resolve, reject;
let promise = new ProcessPromise((...args) => ([resolve, reject] = args));
const promise = new ProcessPromise((...args) => ([resolve, reject] = args));
let cmd = pieces[0], i = 0;

@@ -73,3 +73,4 @@ while (i < args.length) {

promise._bind(cmd, from, resolve, reject, getStore());
setImmediate(() => promise._run()); // Postpone run to allow promise configuration.
// Postpone run to allow promise configuration.
setImmediate(() => promise.isHalted || promise.run());
return promise;

@@ -105,2 +106,3 @@ }, {

this._resolved = false;
this._halted = false;
this._piped = false;

@@ -117,6 +119,6 @@ this._prerun = noop;

}
_run() {
run() {
const $ = this._snapshot;
if (this.child)
return; // The _run() can be called from a few places.
return this; // The _run() can be called from a few places.
this._prerun(); // In case $1.pipe($2), the $2 returned, and on $2._run() invoke $1._run().

@@ -180,6 +182,7 @@ $.log({

}
return this;
}
get stdin() {
this.stdio('pipe');
this._run();
this.run();
assert(this.child);

@@ -191,3 +194,3 @@ if (this.child.stdin == null)

get stdout() {
this._run();
this.run();
assert(this.child);

@@ -199,3 +202,3 @@ if (this.child.stdout == null)

get stderr() {
this._run();
this.run();
assert(this.child);

@@ -209,2 +212,11 @@ if (this.child.stderr == null)

}
then(onfulfilled, onrejected) {
if (this.isHalted && !this.child) {
throw new Error('The process is halted!');
}
return super.then(onfulfilled, onrejected);
}
catch(onrejected) {
return super.catch(onrejected);
}
pipe(dest) {

@@ -221,3 +233,3 @@ if (typeof dest == 'string')

dest.stdio('pipe');
dest._prerun = this._run.bind(this);
dest._prerun = this.run.bind(this);
dest._postrun = () => {

@@ -269,2 +281,9 @@ if (!dest.child)

}
halt() {
this._halted = true;
return this;
}
get isHalted() {
return this._halted;
}
}

@@ -271,0 +290,0 @@ export class ProcessOutput extends Error {

@@ -12,5 +12,3 @@ import * as globbyModule from 'globby';

export declare let argv: minimist.ParsedArgs;
export declare function updateArgv(params: {
sliceAt: number;
}): void;
export declare function updateArgv(args: string[]): void;
export declare const globby: ((patterns: string | readonly string[], options?: globbyModule.Options) => Promise<string[]>) & typeof globbyModule;

@@ -17,0 +15,0 @@ export declare const glob: ((patterns: string | readonly string[], options?: globbyModule.Options) => Promise<string[]>) & typeof globbyModule;

@@ -27,4 +27,4 @@ // Copyright 2022 Google LLC

export let argv = minimist(process.argv.slice(2));
export function updateArgv(params) {
argv = minimist(process.argv.slice(params.sliceAt));
export function updateArgv(args) {
argv = minimist(args);
global.argv = argv;

@@ -47,3 +47,3 @@ }

let msg;
let lastIdx = pieces.length - 1;
const lastIdx = pieces.length - 1;
if (Array.isArray(pieces) &&

@@ -50,0 +50,0 @@ pieces.every(isString) &&

@@ -26,3 +26,3 @@ // Copyright 2022 Google LLC

export function quote(arg) {
if (/^[a-z0-9/_.-]+$/i.test(arg) || arg === '') {
if (/^[a-z0-9/_.\-@:=]+$/i.test(arg) || arg === '') {
return arg;

@@ -29,0 +29,0 @@ }

{
"name": "zx",
"version": "7.0.8",
"version": "7.1.0-dev.862401",
"description": "A tool for writing better scripts.",

@@ -55,3 +55,3 @@ "type": "module",

"@types/minimist": "^1.2.2",
"@types/node": "^18.6.3",
"@types/node": "^18.7.20",
"@types/ps-tree": "^1.1.2",

@@ -63,3 +63,3 @@ "@types/which": "^2.0.1",

"minimist": "^1.2.6",
"node-fetch": "3.2.8",
"node-fetch": "3.2.10",
"ps-tree": "^1.2.0",

@@ -70,8 +70,8 @@ "which": "^2.0.2",

"devDependencies": {
"@stryker-mutator/core": "^6.1.2",
"@stryker-mutator/core": "^6.2.2",
"c8": "^7.12.0",
"madge": "^5.0.1",
"prettier": "^2.7.1",
"tsd": "^0.22.0",
"typescript": "^4.8.0-dev.20220729",
"tsd": "^0.24.1",
"typescript": "^4.8.3",
"uvu": "^0.5.6"

@@ -78,0 +78,0 @@ },

@@ -353,4 +353,19 @@ # 🐚 zx

Specifies a [logging function](src/log.ts).
Specifies a [logging function](src/core.ts).
```ts
import { LogEntry, log } from 'zx/core'
$.log = (entry: LogEntry) => {
switch (entry.kind) {
case 'cmd':
// for example, apply custom data masker for cmd printing
process.stderr.write(masker(entry.cmd))
break
default:
log(entry)
}
}
```
## Polyfills

@@ -498,6 +513,29 @@

### Installing dependencies via --install
```js
// script.mjs:
import sh from 'tinysh'
sh.say('Hello, world!')
```
Add `--install` flag to the `zx` command to install missing dependencies
automatically.
```bash
zx --install script.mjs
```
You can also specify needed version by adding comment with `@` after
the import.
```js
import sh from 'tinysh' // @^1
```
### Attaching a profile
By default `child_process` does not include aliases and bash functions.
But you are still able to do it by hand. Just attach necessary directives to `$.prefix`.
But you are still able to do it by hand. Just attach necessary directives
to the `$.prefix`.

@@ -529,2 +567,9 @@ ```js

### Canary / Beta / RC builds
Impatient early adopters can try the experimental zx versions. But keep in mind: these builds are ⚠️️ __unstable__ in every sense.
```bash
npm i zx@dev
npx zx@dev --install --quiet <<< 'import _ from "lodash" /* 4.17.15 */; console.log(_.VERSION)'
```
## License

@@ -531,0 +576,0 @@

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc