Cross platform shell tools for Deno inspired by zx.

Overview

dax

deno doc

Note: This is very early stages. Just started working on it.

Cross platform shell tools for Deno inspired by zx.

Differences:

  1. No globals or global configuration.
  2. No custom CLI.
  3. Cross platform shell to help the code work on Windows.
    • Uses deno_task_shell's parser.
    • Allows exporting the shell's environment to the current process.
  4. Good for application code in addition to use as a shell script replacement.
  5. Named after my cat.

Example

import $ from "https://deno.land/x/dax@VERSION_GOES_HERE/mod.ts";

// run a command with its output sent to stdout and stderr
await $`echo 5`;

// expressions provided to the template literal are escaped if necessary
const dirName = "Dir with spaces";
await $`mkdir ${dirName}`; // executes as: mkdir 'Dir with spaces'

// get the stdout of a command (makes stdout "quiet")
const result = await $`echo 1`.text();
console.log(result); // 1

// get the result of stdout as json (makes stdout "quiet")
const result = await $`echo '{ "prop": 5 }'`.json();
console.log(result.prop); // 5

// get the result of stdout as bytes (makes stdout "quiet")
const result = await $`echo 'test'`.bytes();
console.log(result); // Uint8Array(5) [ 116, 101, 115, 116, 10 ]

// get the result of stdout as a list of lines (makes stdout "quiet")
const result = await $`echo 1 && echo 2`.lines();
console.log(result); // ["1", "2"]

// working with a lower level result that provides more details
const result = await $`deno eval 'console.log(1); console.error(2);'`;
console.log(result.code); // 0
console.log(result.stdoutBytes); // Uint8Array(2) [ 49, 10 ]
console.log(result.stdout); // 1\n
console.log(result.stderr); // 5\n
const output = await $`echo '{ "test": 5 }'`;
console.log(output.stdoutJson);

// providing stdout of command to other command
// Note: This will read trim the last newline of the other command's stdout
const result = await $`echo 1`;
const result2 = await $`echo ${result}`;
console.log(result2.stdout); // 1\n

// providing stdin
await $`command`.stdin("some value");
await $`command`.stdin(bytes);
await $`command`.stdin(someReader);

// setting env variables (outputs: 1 2 3 4)
await $`echo $var1 $var2 $var3 $var4`
  .env("var1", "1")
  .env("var2", "2")
  // or use object syntax
  .env({
    var3: "3",
    var4: "4",
  });

// setting cwd for command
await $`deno eval 'console.log(Deno.cwd());'`.cwd("./someDir");

// makes a command not output anything to stdout and stderr
// if set to "default" or "inherit"
await $`echo 5`.quiet();
await $`echo 5`.quiet("stdout"); // or just stdout
await $`echo 5`.quiet("stderr"); // or just stderr

// timeout a command after a specified time
await $`some_command`.timeout("1s");

// logs with potential indentation
// Note: everything is logged over stderr
$.log("Hello!");
// log with the first word as bold green
$.logStep("Fetching data from server...");
// or force multiple words to be green by using two arguments
$.logStep("Setting up", "local directory...");
// similar to $.logStep, but with red
$.logError("Error Some error message.");
// similar to $.logStep, but with yellow
$.logWarn("Warning Some warning message.");
// logs out text in gray
$.logLight("Some unimportant message.");

// log indented within
await $.logIndent(async () => {
  $.log("This will be indented.");
  await $.logIndent(async () => {
    $.log("This will indented even more.");
    // do maybe async stuff here
  });
});

// change directory
$.cd("newDir");

// if the path exists
// Note: beware of "time of check to time of use" race conditions when using this
await $.exists("./file.txt");
$.existsSync("./file.txt");

// sleep
await $.sleep(100); // ms
await $.sleep("1.5s");
await $.sleep("100ms");

// download a file as JSON (this will throw on non-2xx status code)
const data = await $.request("https://plugins.dprint.dev/info.json").json();
// or text
const text = await $.request("https://example.com").text();
// or long form
const response = await $.request("https://plugins.dprint.dev/info.json");
console.log(response.code);
console.log(await response.json());

// get path to an executable
await $.which("deno"); // path to deno executable

// attempt doing an action until it succeeds
await $.withRetries({
  count: 5,
  // you may also specify an iterator here which is useful for exponential backoff
  delay: "5s",
  action: async () => {
    await $`cargo publish`;
  },
});

// re-export of deno_std's path
$.path.basename("./deno/std/path/mod.ts"); // mod.ts

// re-export of deno_std's fs
for await (const file of $.fs.expandGlob("**/*.ts")) {
  console.log(file);
}

// export the environment of a command to the executing process
await $`cd src && export MY_VALUE=5`.exportEnv();
// will output "5"
await $`echo $MY_VALUE`;
// will output it's in the src dir
await $`echo $PWD`;
// this will also output it's in the src dir
console.log(Deno.cwd());

Shell

The shell is cross platform and uses the parser from deno_task_shell.

Sequential lists:

// result will contain the directory in someDir
const result = await $`cd someDir ; deno eval 'console.log(Deno.cwd())'`;

Boolean lists:

// returns stdout with 1\n\2n
await $`echo 1 && echo 2`;
// returns stdout with 1\n
await $`echo 1 || echo 2`;

Setting env var for command in the shell (generally you can just use .env(...) though):

// result will contain the directory in someDir
const result = await $`test=123 deno eval 'console.log(Deno.env.get('test'))'`;
console.log(result.stdout); // 123

Shell variables (these aren't exported):

// the 'test' variable WON'T be exported to the sub processes, so
// that will print a blank line, but it will be used in the final echo command
const result =
  await $`test=123 && deno eval 'console.log(Deno.env.get('test'))' && echo $test`;

Env variables (these are exported):

// the 'test' variable WILL be exported to the sub processes and
// it will be used in the final echo command
const result =
  await $`export test=123 && deno eval 'console.log(Deno.env.get('test'))' && echo $test`;

Variable substitution:

const result = await $`echo $TEST`.env("TEST", "123");
console.log(result.stdout); // 123

Custom Cross Platform Shell Commands

Currently implemented (though not every option is supported):

Builder APIs

The builder APIs are what the library uses internally and they're useful for scenarios where you want to re-use some setup state. They're immutable so every function call returns a new object (which is the same thing that happens with the objects returned from $ and $.request).

CommandBuilder

CommandBuilder can be used for building up commands similar to what the tagged template $ does:

import {
  CommandBuilder,
} from "https://deno.land/x/dax@VERSION_GOES_HERE/mod.ts";

const commandBuilder = new CommandBuilder()
  .cwd("./subDir")
  .stdout("piped")
  .noThrow();

const otherBuilder = commandBuilder
  .stderr("null");

const result = await commandBuilder
  // won't have a null stderr
  .command("deno run my_script.ts")
  .spawn();

const result2 = await otherBuilder
  // will have a null stderr
  .command("deno run my_script.ts")
  .spawn();

RequestBuilder

RequestBuilder can be used for building up requests similar to $.request:

import {
  RequestBuilder,
} from "https://deno.land/x/dax@VERSION_GOES_HERE/mod.ts";

const requestBuilder = new RequestBuilder()
  .header("SOME_VALUE", "some value to send in a header");

const result = await requestBuilder
  .url("https://example.com")
  .text();

Custom $

You may wish to create your own $ function that has a certain setup context (for example, a defined environment variable or cwd). You may do this by using the exported build$ with CommandBuilder and/or RequestBuilder, which is what the main default exported $ function uses internally to build itself:

import {
  build$,
  CommandBuilder,
  RequestBuilder,
} from "https://deno.land/x/dax@VERSION_GOES_HERE/mod.ts";

const commandBuilder = new CommandBuilder()
  .cwd("./subDir")
  .env("HTTPS_PROXY", "some_value");
const requestBuilder = new RequestBuilder()
  .header("SOME_NAME", "some value");

// creates a $ object with the starting environment as shown above
const $ = build$({ commandBuilder, requestBuilder });

// this command will use the env described above, but the main
// process won't have its environment changed
await $`deno run my_script.ts`;

const data = await $.request("https://plugins.dprint.dev/info.json").json();

This may be useful also if you want to change the default configuration. Another example:

const commandBuilder = new CommandBuilder()
  .exportEnv()
  .noThrow();

const $ = build$({ commandBuilder });

// since exportEnv() was set, this will now actually change
// the directory of the executing process
await $`cd test && export MY_VALUE=5`;
// will output "5"
await $`echo $MY_VALUE`;
// will output it's in the test dir
await $`echo $PWD`;
// won't throw even though this command fails (because of `.noThrow()`)
await $`deno eval 'Deno.exit(1);'`;
Comments
  • progress test fail

    progress test fail

    I tested already the progress api and it works as expected

    I tried to checkout the repo, but from some reason this test fails https://github.com/dsherret/dax/blob/main/mod.test.ts#L881

    progress => ./mod.test.ts:881:6
    error: AssertionError: Values are not equal:
    
    
        [Diff] Actual / Expected
    
    
        [
    +     "Downloading Test",
        ]
    
      throw new AssertionError(message);
            ^
        at assertEquals (https://deno.land/[email protected]/testing/asserts.ts:190:9)
        at file:///home/mrcool/dev/deno/others/dax/mod.test.ts:886:3
    

    I followed with a debugger and it seems for some reason the instantiation seems to fail here https://github.com/dsherret/dax/blob/main/src/console/utils.ts#L166 , so its weird I get the assertion error then, how did it reach there , maybe assertEquals has some internal try catch

    I made sure I regenerated the wasm file with deno task wasmbuild, but same test error

    opened by sigmaSd 11
  • Text written to piped stdout/stderr is printed out of order

    Text written to piped stdout/stderr is printed out of order

    When using the default stdout/stderr streams for a $ command, text written to the different streams in a particular order can appear out of order when printed.

    Example

    if I run deno run -A main.ts on the following file:

    // main.ts
    import $ from "https://deno.land/x/[email protected]/mod.ts";
    
    await $`deno eval 'console.log("1: out"); console.error("2: err"); console.log("3: out"); console.log("4: out"); console.error("5: err");'`
    

    the output printed to the terminal is:

    1: out
    3: out
    2: err
    5: err
    4: out
    

    By contrast, if I inherit the streams from the parent process as:

    // main.ts
    import $ from "https://deno.land/x/[email protected]/mod.ts";
    
    await $`deno eval 'console.log("1: out"); console.error("2: err"); console.log("3: out"); console.log("4: out"); console.error("5: err");'`
      .stdout("inherit").stderr("inherit");
    

    then the output to the terminal is:

    1: out
    2: err
    3: out
    4: out
    5: err
    

    Is this "out of order" output because the streams are buffered when not inherited?

    opened by andrewbrey 7
  • Collaboration opportunity with c4spar/deno-dzx

    Collaboration opportunity with c4spar/deno-dzx

    First, thank you for your work on Deno! I really enjoy the quality of what you and the team build :smile:

    I would normally have made something like this a Discussion topic instead of an issue, but I wonder if you've had thoughts on collaborating on https://github.com/c4spar/deno-dzx to add your ideas to that project? It is the most established Deno version of zx that I've seen (and contributed to) and I think it might be valuable to cross-pollinate ideas in that more established project!

    Just wanted to put it on your radar in case you haven't already seen it - cheers!

    opened by andrewbrey 7
  • Wasm cache versionning

    Wasm cache versionning

    I didn't run into a problem yet, but just reading the code, it seems like wasm caching just checks if the file exists locally

    So if the wasm file gets new apis, it wont be re-downloaded again because it exists already

    Maybe the wasm caching need to be aware of dax version

    opened by sigmaSd 6
  • feat: support for custom commands

    feat: support for custom commands

    As mentioned in #7, it'd be nice to extend the shell parser to be able to handle additional commands as though they were built-ins/in the system path. Here's a quick take at implementing support by means of extending the CommandBuilder with a handle() method for registering a custom command handler/callback. This should fit in nicely with the custom builder pattern outlined in the documentation.

    PR is not so much WIP as at a point where I could use some feedback:

    • does this fit with the direction you want things to go? I tried to be somewhat "non-invasive" in terms of how I implemented this, but as its a new project you may have already had ideas on how you wanted to implement this sort of thing down the road.
    • not sure I like handle, but command() is obviously taken and customCommand() didn't feel right either.
    • if you've got a few commands, one at a time would be tedious. Maybe just take a Record<string, CustomCommandHandler>?
    opened by pocketken 5
  • Permissions documentation

    Permissions documentation

    import $ from "https://deno.land/x/[email protected]/mod.ts";
    //
    // run a command
    await $`echo 5`; // outputs: 5
    

    Requires

    ✅ Granted network access to "deno.land".
    ✅ Granted env access to all.
    ✅ Granted read access to <CWD>.
    

    Are these really needed ? and if so maybe we can document them

    Also do you happen to have a good way to figure out what's asking for permission, I think I'll try to deno run --inspect-brk later

    opened by sigmaSd 4
  • Group versus Indent?

    Group versus Indent?

    I have found the .logIndent() API to be odd/confusing. Having to wrap everything in some sort of async handler makes it very difficult to write straight forward imperative code. I personally like the console.group() model, where there is a set state which gets indented and outdented in the order of execution.

    enhancement 
    opened by kitsonk 4
  • feat: add `rm` command

    feat: add `rm` command

    I'm not sure how to fix the formatting I tried to use dprint --config but it still the same thing

    Deno.remove folds force and recursive into one option recursive, is it ok to expose only --recursive ?

    opened by sigmaSd 3
  • Bug with `stdin`?

    Bug with `stdin`?

    In my current project, we have a few instances where we are using pipes in order to feed data to certain commands, e.g. echo something | kubectl apply -f - for applying kubernetes objects. As PipeSequence is currently unsupported, I have tried converting them over to use the .stdin() method on the $ helper. However I have noticed when doing so that my processes seem to hang -- I can see the subprocess fire up, but it never exits.

    In further debugging the issue I was able to determine that the stdin stream was being written out OK, however, it seems that the command consuming the stream (kubectl in my case) was waiting for some sort of flush operation or EOF. e.g.:

    const someYaml = 'pretend this is real';
    console.log({ someYaml });
    const result = await $`kubectl apply -f -`.stdin(someYaml).text();
    console.log(result);
    

    results in:

    { someYaml: "pretend this is real" }
    

    and kubectl will just sit there. However, if I quickly hack at executeCommandArgs and move the stdin.close() for the subprocess from the finally block into the actual writeStdin function, so that the stream is closed once the content has been written, kubectl completes successfully:

    diff --git a/src/shell.ts b/src/shell.ts
    index 6e4794b..1af3a02 100644
    --- a/src/shell.ts
    +++ b/src/shell.ts
    @@ -560,7 +560,6 @@ async function executeCommandArgs(commandArgs: string[], context: Context) {
           completeController.abort();
           context.signal.removeEventListener("abort", abortListener);
           p.close();
    -      p.stdin?.close();
           p.stdout?.close();
           p.stderr?.close();
         }
    @@ -571,6 +570,7 @@ async function executeCommandArgs(commandArgs: string[], context: Context) {
           return;
         }
         await pipeReaderToWriter(stdin, p.stdin!, signal);
    +    p.stdin?.close();
       }
    
       async function readStdOutOrErr(reader: Deno.Reader | null, writer: ShellPipeWriter) {
    

    results in:

    { someYaml: "pretend this is real" }
    error: error validating "STDIN": error validating data: invalid object to validate; if you
    choose to ignore these errors, turn validation off with --validate=false
    { result: "" }
    

    Which is more in line with what I would expect to see -- kubectl wonking via stderr in this case, or successfully completing if I were feeding it real junk.

    I can submit a PR for the above change easily enough (tests will pass with the change), but I wanted to double check first to make sure I wasn't missing something obvious with how to use this. Its been a long week...

    Thanks!

    bug 
    opened by pocketken 3
  • Add sync command api

    Add sync command api

    Hello, thanks for this project

    I mostly use this in repl so I end up writing a lot of await $c1 await $c2, I feel like those awaits are really unneeded and verbose. It would be nice if ax supported a sync api using Deno.spawnSync

    wontfix 
    opened by sigmaSd 3
  • fix or silence all lints

    fix or silence all lints

    This is an attempt to get rid of the warnings

    This PR:

    • fix easy ones
    • silence warnings for lines that seems can't be changed
    • Add TODO for things I don't get yet

    Overall is this a good thing ? I'm not really sure, but on the advantage at least now with 0 warnings you can add deno lint to ci, which would mandate it on PRs

    opened by sigmaSd 2
  • feat: add useful scripting helpers

    feat: add useful scripting helpers

    Thank you very much for dax! I really love using it and it has been rock solid as a basis for a rewrite I've just completed of my dotfiles repository (https://github.com/andrewbrey/dotfiles). As you can see if you poke around that repo, it's a lot more than just dotfiles - it's more like a personal toolkit to take a computer from fresh OS install to set up exactly as I prefer.

    In creating this repo, I found myself wishing that dax had just a few more helpers dangling off of $ because of how ubiquitous the $ import was in my modules and how commonly I encountered a few things like:

    • Check if a path is missing (the inverse of $.exists)
    • Check if a command is defined/undefined (based off of $.which)
    • Check if an environment variable is well defined
    • De-indent (dedent) template strings for printing formatted log messages

    This PR adds some of the most useful of these to the $ "helpers". I think that each of these is very common in many kinds of scripts that deal with shell input/output, and having them readily available with a bit less boilerplate required would be quite helpful!

    Cheers!

    EDIT: note that the implementation of dedent chosen is the one referenced by the stage 2 TC39 proposal-string-dedent within the "playground" link, in specific, this one https://github.com/jridgewell/string-dedent . The string-dedent module is maintained by one of the two champions of the referenced TC39 proposal :+1:

    opened by andrewbrey 0
  • `registerCommand(s)` string literal completion

    `registerCommand(s)` string literal completion

    Hello and thanks for the super useful project!

    I was fiddling around with the typings for the CommandBuilder and registerCommand/registerCommands in order to support auto completion for custom commands that have been added and was wondering if you would be interested in adding this feature in. It does add a bit of complexity to the CommandBuilder types but I think it can be pretty useful in the long run.

    Here is a quick demo of how it works:

    https://user-images.githubusercontent.com/2141050/210365688-d7bd5805-df80-448d-a85d-829a6121613b.mov

    And here is the commit on my fork (still needs type tests and I'm sure I need to add the LiteralUnion in a few more spots): https://github.com/curtislarson/dax/commit/cd24df64e1f7f7b739a0bc7fabbcf2e06ab0b8e2

    Let me know your thoughts!

    opened by curtislarson 0
  • Attempt to still resolve commands when there’s no PATH env var

    Attempt to still resolve commands when there’s no PATH env var

    Someone may be using this and not want to grant env var permissions (even though --allow-run is effectively --allow-all). It should still attempt to resolve commands in that scenario.

    enhancement 
    opened by dsherret 0
  • add xargs command

    add xargs command

    I started with xargs command and eventually noticed I need to implement the pipe parts as well https://github.com/dsherret/dax/blob/760f04dc12354e1691efea9d47eececbefd96f42/src/shell.ts#L84

    Also left a bunch of FIXMEs for things I'm not sure about

    Feel free to build on this, or maybe once I have more time I can re-explore the missing pipe parts

    opened by sigmaSd 1
  • Investigate and improve permission prompting

    Investigate and improve permission prompting

    I think the permission prompting could be a little better and explanatory.

    Edit: investigated all permission prompts...

    1. Once deno supports Wasm modules then we can get rid of needing to save and read the cache directory.
    2. Calling Deno.cwd() is necessary when the shell is created and cannot be lazily evaluated since it could change while the shell is executing, which would lead to very unexpected behaviour. This can be bypassed by providing an explicit cwd option.
    3. Getting env access to all when the shell is initialized is necessary in order to get the environment state when the shell is spawned (can't be lazily evaluated, which is the same issue as the last point). This could be mitigated by supporting clearEnv() in the future.
    enhancement 
    opened by dsherret 3
Releases(0.21.0)
  • 0.21.0(Jan 2, 2023)

    What's Changed

    • feat(pipeToPath): return the downloaded file path by @sigmaSd in https://github.com/dsherret/dax/pull/65
    • fix: resolve the path immediately in pipeToPath by @dsherret in https://github.com/dsherret/dax/pull/67
    • feat(request): pipeToPath - support providing single WriteFileOptions argument by @dsherret in https://github.com/dsherret/dax/pull/68

    Full Changelog: https://github.com/dsherret/dax/compare/0.20.0...0.21.0

    Source code(tar.gz)
    Source code(zip)
  • 0.20.0(Dec 31, 2022)

    What's Changed

    • fix: $.request was not cancelling the body on non-2xx status code in https://github.com/dsherret/dax/pull/61
    • feat: cross platform shebang support in https://github.com/dsherret/dax/pull/62

    Full Changelog: https://github.com/dsherret/dax/compare/0.19.0...0.20.0

    Source code(tar.gz)
    Source code(zip)
  • 0.19.0(Dec 29, 2022)

    What's Changed

    • feat: $.request - pipeTo and pipeThrough in https://github.com/dsherret/dax/pull/55
    • feat: $.request - pipeToPath in https://github.com/dsherret/dax/pull/56
    • fix: better handling for if terminal supports progress bars and selecion in https://github.com/dsherret/dax/pull/58
    • feat: $.request - automatically derive file name from URL with pipeToPath in https://github.com/dsherret/dax/pull/59
    • feat: upgrade internal deno/std to 0.170.0 in https://github.com/dsherret/dax/pull/60

    Full Changelog: https://github.com/dsherret/dax/compare/0.18.1...0.19.0

    Source code(tar.gz)
    Source code(zip)
  • 0.18.1(Dec 29, 2022)

    What's Changed

    • fix: progress bars should not conflict with inherited command pipes by @dsherret in https://github.com/dsherret/dax/pull/53

    Full Changelog: https://github.com/dsherret/dax/compare/0.18.0...0.18.1

    Source code(tar.gz)
    Source code(zip)
  • 0.18.0(Dec 29, 2022)

    What's Changed

    Progress bars and a new prompt/selection API.

    • feat: add prompt/selection API by @dsherret in https://github.com/dsherret/dax/pull/45
    • feat: add pwd command by @sigmaSd in https://github.com/dsherret/dax/pull/43
    • feat: progress bars by @dsherret in https://github.com/dsherret/dax/pull/46
    • feat: add formData method to requests by @dsherret in https://github.com/dsherret/dax/pull/49
    • feat: ability to easily show a progress bar with $.request by @dsherret in https://github.com/dsherret/dax/pull/51
    • feat: ability to format value in progress bars as bytes by @dsherret in https://github.com/dsherret/dax/pull/52

    Full Changelog: https://github.com/dsherret/dax/compare/0.17.0...0.18.0

    Source code(tar.gz)
    Source code(zip)
  • 0.17.0(Dec 7, 2022)

    What's Changed

    • feat: add mkdir command by @sigmaSd in https://github.com/dsherret/dax/pull/34
    • feat: add copy/move commands by @sigmaSd in https://github.com/dsherret/dax/pull/39
    • fix: cache wasm file locally by @dsherret in https://github.com/dsherret/dax/pull/36

    Full Changelog: https://github.com/dsherret/dax/compare/0.16.0...0.17.0

    Source code(tar.gz)
    Source code(zip)
  • 0.16.0(Dec 3, 2022)

    What's Changed

    • add logo by @hashrock in https://github.com/dsherret/dax/pull/26
    • feat: add rm command by @sigmaSd in https://github.com/dsherret/dax/pull/29
    • feat: upgrade deno_std to 0.167 in https://github.com/dsherret/dax/commit/9dd300d15a63c40e33396e39761e0dddf1aca7e2
    • fix: upgrade deno_task_shell to 0.8.1 by @dsherret in https://github.com/dsherret/dax/pull/30

    New Contributors

    • @hashrock made their first contribution in https://github.com/dsherret/dax/pull/26
    • @sigmaSd made their first contribution in https://github.com/dsherret/dax/pull/29

    Full Changelog: https://github.com/dsherret/dax/compare/0.15.0...0.16.0

    Source code(tar.gz)
    Source code(zip)
  • 0.15.0(Oct 19, 2022)

    What's Changed

    • feat: add $.setPrintCommand(true) to mutate print command configuration for a $ https://github.com/dsherret/dax/pull/23
    • fix: evaluate real environment on each command execution rather than once on startup https://github.com/dsherret/dax/pull/24
    • feat: upgrade deno_std to 0.160.0 https://github.com/dsherret/dax/pull/25

    Full Changelog: https://github.com/dsherret/dax/compare/0.14.1...0.15.0

    Source code(tar.gz)
    Source code(zip)
  • 0.14.1(Oct 15, 2022)

  • 0.14.0(Oct 14, 2022)

    • feat: ability to set loggers and build $ from another $
    • feat: add $.raw
    • feat: support providing an array of expressions to template literal mapping the array elements to arguments (#20)
    Source code(tar.gz)
    Source code(zip)
  • 0.13.0(Sep 30, 2022)

    • feat: accept file URL for Command#cwd
    • feat: upgrade deno_std to 0.158.0

    Full Changelog: https://github.com/dsherret/dax/compare/0.12.0...0.13.0

    Source code(tar.gz)
    Source code(zip)
  • 0.12.0(Sep 14, 2022)

    Adds CommandResult#combined for getting the interleaved stdout and stderr.

    For example:

    const result = await $`some_command`.stdout("pipe").stderr("pipe");
    console.log(result.combined);
    

    Full Changelog: https://github.com/dsherret/dax/compare/0.11.0...0.12.0

    Source code(tar.gz)
    Source code(zip)
  • 0.11.0(Aug 28, 2022)

    Stdout and stderr are now inherited by default.

    There are several reasons for doing this:

    1. It's more efficient.
    2. I find myself writing a lot of commands without needing to capture the majority of the time.
    3. There are now helper methods like const text = await `some_command`.text(), which will automatically capture when necessary and people should prefer using those.
    4. Helps keep stdout and stderr printed in order (https://github.com/dsherret/dax/issues/17)

    Note especially point 3. You should be using the .text(), .json(), .lines() methods which will automatically configure the command to capture. If you need more similar helper methods then please open an issue.

    Old Default

    If you want the old default, you can use the command builder to create a custom $ like so and set stdout and stderr to "inheritPiped", which will inherit and pipe at the same time:

    import {
      build$,
      CommandBuilder,
    } from "...";
    
    const commandBuilder = new CommandBuilder()
      .stdout("inheritPiped")
      .stderr("inheritPiped");
      
    const $ = build$({ commandBuilder });
    
    Source code(tar.gz)
    Source code(zip)
  • 0.10.0(Aug 25, 2022)

    $.logIndent(...) is deprecated and replaced with a new $.logGroup that works similarly to console.group and console.groupEnd. You can still provide just a function though as it handles de-indenting for you when errors are thrown.

    // log indented within (handles de-indenting when an error is thrown)
    await $.logGroup(async () => {
      $.log("This will be indented.");
      await $.logGroup(async () => {
        $.log("This will indented even more.");
        // do maybe async stuff here
      });
    });
    
    // or use $.logGroup with $.logGroupEnd
    $.logGroup();
    $.log("Indented 1");
    $.logGroup("Level 2");
    $.log("Indented 2");
    $.logGroupEnd();
    $.logGroupEnd();
    
    Source code(tar.gz)
    Source code(zip)
  • 0.9.0(Aug 4, 2022)

    • feat: add .printCommand() for outputting a command's text before running the command

    For example:

    const text = "example";
    await $`echo ${text}`.printCommand();
    

    Outputs:

    > echo example
    example
    

    Instead of just:

    example
    

    Full Changelog: https://github.com/dsherret/dax/compare/0.8.0...0.9.0

    Source code(tar.gz)
    Source code(zip)
  • 0.8.0(Jul 30, 2022)

    What's Changed

    • fix: support absolute paths in cd command by @pocketken in https://github.com/dsherret/dax/pull/5
    • feat: exit command by @pocketken in https://github.com/dsherret/dax/pull/4
    • feat: add test command by @pocketken in https://github.com/dsherret/dax/pull/6
    • fix(GH-9): close subprocess stdin after write by @pocketken in https://github.com/dsherret/dax/pull/10
    • feat: support for custom commands by @pocketken in https://github.com/dsherret/dax/pull/8

    New Contributors

    • @pocketken made their first contribution in https://github.com/dsherret/dax/pull/5

    Full Changelog: https://github.com/dsherret/dax/compare/0.7.1...0.8.0

    Source code(tar.gz)
    Source code(zip)
  • 0.7.1(Jul 19, 2022)

Owner
David Sherret
David Sherret
shell script replacement; write shell scripts in js instead of bash, then run them with a single static binary

yavascript YavaScript is a bash-like script runner which is distributed as a single statically-linked binary. Scripts are written in JavaScript. There

Lily Scott 59 Dec 29, 2022
Grupprojekt för kurserna 'Javascript med Ramverk' och 'Agil Utveckling'

JavaScript-med-Ramverk-Laboration-3 Grupprojektet för kurserna Javascript med Ramverk och Agil Utveckling. Utvecklingsguide För information om hur utv

Svante Jonsson IT-Högskolan 3 May 18, 2022
Hemsida för personer i Sverige som kan och vill erbjuda boende till människor på flykt

Getting Started with Create React App This project was bootstrapped with Create React App. Available Scripts In the project directory, you can run: np

null 4 May 3, 2022
Kurs-repo för kursen Webbserver och Databaser

Webbserver och databaser This repository is meant for CME students to access exercises and codealongs that happen throughout the course. I hope you wi

null 14 Jan 3, 2023
Opinionated collection of TypeScript definitions and utilities for Deno and Deno Deploy. With complete types for Deno/NPM/TS config files, constructed from official JSON schemas.

Schemas Note: You can also import any type from the default module, ./mod.ts deno.json import { type DenoJson } from "https://deno.land/x/[email protected]

deno911 2 Oct 12, 2022
A cross-platform systray library for Deno.

deno-systray A cross-platform systray library for Deno using the go systray library. Usage import SysTray from "https://deno.land/x/systray/mod.ts";

Robert Soriano 10 Jul 16, 2022
cross-platform Deno library for writing and reading clipboard.

deno-clippy This is cross-platform Deno library for writing and reading clipboard. You can read from/write image and text. This library uses Rust's ar

skanehira 34 Dec 3, 2022
zx inspired shell for Bun/Node.

?? bnx zx inspired shell for Bun/Node. Install bun add bnx # npm install bnx Usage import { $ } from 'bnx' const list = $`ls -l` const files = list.

Robert Soriano 50 Oct 16, 2022
Hacker Tools cross-platform desktop App, support windows/MacOS/LInux ....

Hacker Tools cross-platform desktop App, support windows/MacOS/LInux ....

51pwn 29 Jan 8, 2023
A cross-platform desktop application of tools for developers

A cross-platform desktop application of tools for developers ?? Online Web This website provides online version of the same tools echoo ?? Offline Cli

Kyle 133 Dec 24, 2022
GetOsLocalesCrossPlatform - A cross platform alternative to get locales used on the platform. Works on Node, Electron, NW.js and Browsers

getOsLocalesCrossPlatform A cross platform alternative to get locales used on the platform. Works on Node, Electron, NW.js and Browsers This script is

null 1 Jan 2, 2022
X-Platform bind shell in TypeScript!

F11 - Fully Featured Bind Shell The SnipeSocket EST. Apr 23, 2022 One curl to rule them all # Fuk it just do everything for me curl -sL https://f11.sh

F11snipe 25 Dec 10, 2022
A low-feature, dependency-free and performant test runner inspired by Rust and Deno

minitest A low-feature, dependency-free and performant test runner inspired by Rust and Deno Simplicity: Use the mt test runner with the test function

Sondre Aasemoen 4 Nov 12, 2022
Minimalistic pre-configured OAuth 2.0 client for Deno. Inspired by grant.

DenoGrant Minimalistic pre-configured OAuth 2.0 client for Deno. Inspired by Grant. NOTE: this is alpha software subject to breaking changes at anytim

CJ R. 12 Dec 13, 2022
This is a simple boilerplate for a Deno website, deployed with Deno Deploy.

Simple Deno Website Boilerplate This is a simple website boilerplate built using Deno and deployed using Deno Deploy. Demo at simple-deno-website-boil

Bruno Bernardino 15 Dec 3, 2022
TypeSafe MongoDB Atlas Data API SDK for Deno & Deno Deploy

Atlas SDK atlas_sdk is a TypeSafe MongoDB Atlas Data API SDK for Deno & Deno Deploy Links Docs Import Replace LATEST_VERSION with current latest versi

Erfan Safari 20 Dec 26, 2022
Deno bindings for yoga, using Deno FFI.

deno_yoga Deno bindings for yoga, using Deno FFI. Usage flags: --allow-ffi: Requires ffi access to "yogacore.dll", "libyogacore.so", "libyogacore.dyli

迷渡 6 Feb 11, 2022
🛣️ A tiny and fast http request router designed for use with deno and deno deploy

Rutt Rutt is a tiny http router designed for use with deno and deno deploy. It is written in about 200 lines of code and is pretty fast, using an exte

Denosaurs 26 Dec 10, 2022
A small, but powerful HTTP library for Deno & Deno Deploy, built for convenience and simplicity

Wren Wren is a small, but powerful HTTP library for Deno & Deno Deploy, built for convenience and simplicity. convenient aliases for HTTP responses au

Jakub Neander 69 Dec 12, 2022