{"id":17442446,"url":"https://github.com/japiirainen/vl","last_synced_at":"2025-04-19T06:39:43.652Z","repository":{"id":54048812,"uuid":"469382994","full_name":"japiirainen/vl","owner":"japiirainen","description":"Shell scripting in typescript. Powered by deno.","archived":false,"fork":false,"pushed_at":"2023-06-17T10:19:51.000Z","size":29730,"stargazers_count":28,"open_issues_count":0,"forks_count":1,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-03-29T06:51:17.394Z","etag":null,"topics":["deno","javascipt","shell","shell-script","typescript"],"latest_commit_sha":null,"homepage":"https://deno.land/x/violet","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/japiirainen.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-03-13T13:41:28.000Z","updated_at":"2023-12-18T23:31:41.000Z","dependencies_parsed_at":"2024-10-20T14:37:18.564Z","dependency_job_id":null,"html_url":"https://github.com/japiirainen/vl","commit_stats":{"total_commits":33,"total_committers":2,"mean_commits":16.5,"dds":0.06060606060606055,"last_synced_commit":"1e4a8adf5585fcf14f1b0ab3f1928f6ffc8c67b7"},"previous_names":[],"tags_count":6,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/japiirainen%2Fvl","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/japiirainen%2Fvl/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/japiirainen%2Fvl/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/japiirainen%2Fvl/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/japiirainen","download_url":"https://codeload.github.com/japiirainen/vl/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":249191311,"owners_count":21227543,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["deno","javascipt","shell","shell-script","typescript"],"created_at":"2024-10-17T16:06:14.056Z","updated_at":"2025-04-16T03:33:26.952Z","avatar_url":"https://github.com/japiirainen.png","language":"TypeScript","readme":"# vl (violet)\n\n![deno CI](https://github.com/japiirainen/vl/actions/workflows/deno.yml/badge.svg)\n\nShell scripting with TypeScript. Runs on top of [Deno](https://deno.land).\n\n`vl` started as a port of [`zx`](https://github.com/google/zx) to deno. The main\nmotivation for this tool was the lack of native typescript support in `zx`.\nThat's where I got the idea to use `deno` as the runtime, since it supports\nTypeScript natively.\n\n## Table of contents\n\n- [vl (violet)](#vl-violet)\n  - [Table of contents](#table-of-contents)\n  - [Motivation](#motivation)\n    - [Example Program](#example-program)\n  - [Usage](#usage)\n    - [`$command`](#command)\n    - [Pipelines](#pipelines)\n    - [Environment variables](#environment-variables)\n    - [Functions](#functions)\n    - [Configuration](#configuration)\n  - [Install](#install)\n    - [Prerequisites](#prerequisites)\n  - [Execution](#execution)\n    - [Shebang Mode](#shebang-mode)\n    - [Deno basic Mode](#deno-basic-mode)\n  - [Credits](#credits)\n\n## Motivation\n\nBash is great, but when it comes to writing scripts, it has it's limitations and\npeople tend to go for more expressive programming languages.\nJavaScript/TypeScript is a great choice, since they are approachable by a huge\nnumber of developers. The `vl` package provides provides wrappers around\n`child_process`, and a number of other things for all your shell scripting\nneeds. Since `vl` uses `deno`, it has access to both the rich standard library\nof [deno](https://github.com/denoland/deno_std), and the battle tested standard\nlibraries of [node](https://nodejs.dev) through it's\n[node compatibility](https://github.com/denoland/deno_std/tree/main/node).\n\n### Example Program\n\n```ts\n#!/usr/bin/env vl\n\nimport \"https://deno.land/x/violet/globals.d.ts\";\n\nconst { create, mkdir } = Deno;\n\nawait Promise.all([\n  $`sleep 1; echo 1`,\n  $`sleep 2; echo ${2}`,\n  $`sleep 3; echo 3`,\n]);\n\nawait fetch(\"https://google.com\");\n\nawait mkdir(\"tests\");\nawait create(\"tests/test.txt\");\n\ncd(\"tests\");\nawait $`ls`;\ncd(\"..\");\n\n// clean up\nawait $`rm -rf tests`;\n```\n\n## Usage\n\n### `$command`\n\nExecutes the given command by spawning a subprocess. Everything passed through\n`${}` will be automatically quoted.\n\n```ts\nconst fileName = \"awesome\";\nawait $`touch ${awesome}.txt`;\n```\n\nYou can also pass an array of arguments.\n\n```ts\nconst flags = [\"--oneline\", \"--decorate\", \"--color\"];\nconst { exitCode } = await $`git log ${flags}`;\n```\n\n### Pipelines\n\n```ts\n#!/usr/bin/env vl\n\nimport \"https://deno.land/x/violet/globals.d.ts\";\n\nawait $`echo \"Hello, stdout!\"`.pipe(\n  fs.createWriteStream(\"/tmp/output.txt\", {}),\n);\n\nawait $`cat /tmp/output.txt`;\n```\n\n### Environment variables\n\n```ts\n#!/usr/bin/env vl\n\nimport \"https://deno.land/x/violet/globals.d.ts\";\n\nDeno.env.set(\"FOO\", \"bar\");\n\nawait $`echo $FOO \u003e tmp.txt`;\nawait $`cat tmp.txt`;\n```\n\n### Functions\n\n`fetch` works, since it's natively supported in deno.\n\n```ts\nconst resp = await fetch(\"https://wttr.in\");\nconsole.log(await resp.text());\n```\n\n`ask` reads a line from stdin.\n\n```ts\nconst resp = await ask(\"What is your name?\");\nconsole.log(resp);\n```\n\n`choose` prompts the user to choose from the provided options.\n\n```ts\nconst resp = await choose(\"Would you like a foo or a bar?\", [\"foo\", \"bar\"]);\nconsole.log(resp);\n```\n\n`sleep` sleeps for specified ms.\n\n```ts\nawait sleep(2000);\n```\n\n`noThrow()` Changes the behaviour of `$` to not throw an exception on non-zero\nexit codes. You can still access the `exitCode` from the response.\n\n```ts\nconst { exitCode } = await noThrow($`exit 1`);\nconsole.log(exitCode);\n```\n\n`quiet()` Changes the behaviour of `$` to disable verbose output.\n\nusage:\n\n```ts\nawait quiet($`echo foobar`); // command and output will not be displayed.\n```\n\n`sanitize()` Changes the behaviour of `$` to redact output.\n\nusage:\n\n```ts\nawait sanitize($`echo a SECRET_KEY`, ['SECRET_KEY']);\n\u003e a ********\n```\n\n`os` package.\n\nusage:\n\n```ts\nawait $`echo ${os.homedir()}`;\n```\n\n`retry()`\n\nRetries a command as many times as specified. Returns the first successful\nattempt, or will throw after specified attempts count.\n\nusage:\n\n```ts\nawait retry(5)`curl localhost`;\n\n// or with a specified delay (500ms)\nawait retry(5, 500)`curl localhost`;\n```\n\n`startSpinner()`\n\nDisplays a spinner as an loading indicator. Useful with long running processes.\n\nusage:\n\n```ts\nconst { stopSpinner } = startSpinner();\nawait sleep(5000);\nstopSpinner();\n```\n\n### Configuration\n\n`$.shell`\n\nWhich shell is used. Default is bash.\n\n```ts\n$.shell = \"/usr/bin/zsh\";\n```\n\nCLI argument `--shell=/usr/bin/zsh` can be used to achieve the same result.\n\n`$.verbose` can be used to specify verbosity.\n\nDefault is `true`.\n\nCLI argument `--quiet` sets verbosity to `false`.\n\n## Install\n\n### Prerequisites\n\nYou need to have `deno` installed. You can find installation instructions at\n[deno.land](https://deno.land/).\n\n```sh\ndeno install --allow-all -f https://deno.land/x/violet@\u003cversion_number\u003e/vl.ts\n```\n\n### Execution\n\nThere are two modes of execution, either using the shebang of\n`#!/usr/bin/env vl` or using a verbose deno command.\n\n#### Shebang Mode\n\n```ts\n#!/usr/bin/env vl\n\nimport \"https://deno.land/x/violet/globals.d.ts\";\n\nawait $`echo 1`;\n```\n\n#### Deno basic mode\n\n```ts\n#!/usr/bin/env -S deno run --allow-all\n\nimport \"https://deno.land/x/violet/globals.d.ts\";\n// Import the global functions into namespace, required in this method\nimport \"https://deno.land/x/violet@0.1.0/globals.ts\";\n\nawait $`echo 1`;\n```\n\n## Credits\n\nThe project wouldn't have been possible without these resources, so I'm forever\ngrateful for the existence of these!\n\n- [zx](https://github.com/google/zx)\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjapiirainen%2Fvl","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjapiirainen%2Fvl","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjapiirainen%2Fvl/lists"}