Commit ed09d11

Anton Medvedev <anton@medv.io>
2024-03-18 22:30:20
Add v7 folder
1 parent 52a123b
.vitepress/config.mts
@@ -24,35 +24,60 @@ export default defineConfig({
       {text: 'Home', link: '/'},
       {text: 'Docs', link: '/getting-started'},
       {
-        text: '7.x',
+        text: 'v8',
         items: [
-          {text: 'Releases', link: 'https://github.com/google/zx/releases'},
+          {text: 'v7', link: '/v7/api'},
         ],
       },
     ],
 
-    sidebar: [
-      {
-        text: 'Docs',
-        items: [
-          {text: 'Getting Started', link: '/getting-started'},
-          {text: 'Process Promise', link: '/process-promise'},
-          {text: 'API Reference', link: '/api'},
-          {text: 'Configuration', link: '/configuration'},
-          {text: 'CLI Usage', link: '/cli'},
-        ],
-      },
-      {
-        text: 'FAQ',
-        link: '/faq',
-        items: [
-          {text: 'Quotes', link: '/quotes'},
-          {text: 'TypeScript', link: '/typescript'},
-          {text: 'Markdown Scripts', link: '/markdown-scripts'},
-          {text: 'Known Issues', link: '/known-issues'},
-        ],
-      },
-    ],
+    sidebar: {
+      '/': [
+        {
+          text: 'Docs',
+          items: [
+            {text: 'Getting Started', link: '/getting-started'},
+            {text: 'Process Promise', link: '/process-promise'},
+            {text: 'API Reference', link: '/api'},
+            {text: 'Configuration', link: '/configuration'},
+            {text: 'CLI Usage', link: '/cli'},
+          ],
+        },
+        {
+          text: 'FAQ',
+          link: '/faq',
+          items: [
+            {text: 'Quotes', link: '/quotes'},
+            {text: 'TypeScript', link: '/typescript'},
+            {text: 'Markdown Scripts', link: '/markdown-scripts'},
+            {text: 'Known Issues', link: '/known-issues'},
+          ],
+        },
+      ],
+
+      '/v7/': [
+        {
+          text: 'Docs (v7)',
+          items: [
+            {text: 'Getting Started', link: '/v7/getting-started'},
+            {text: 'Process Promise', link: '/v7/process-promise'},
+            {text: 'API Reference', link: '/v7/api'},
+            {text: 'Configuration', link: '/v7/configuration'},
+            {text: 'CLI Usage', link: '/v7/cli'},
+          ],
+        },
+        {
+          text: 'FAQ',
+          link: '/v7/faq',
+          items: [
+            {text: 'Quotes', link: '/v7/quotes'},
+            {text: 'TypeScript', link: '/v7/typescript'},
+            {text: 'Markdown Scripts', link: '/v7/markdown-scripts'},
+            {text: 'Known Issues', link: '/v7/known-issues'},
+          ],
+        },
+      ],
+    },
 
     socialLinks: [
       {icon: 'github', link: 'https://github.com/google/zx'},
v7/api.md
@@ -0,0 +1,206 @@
+::: warning
+This is documentation for zx v7, which is no longer actively maintained.
+
+For up-to-date documentation, see the [latest version](/api) (v8).
+:::
+
+# API Reference
+
+## cd()
+
+Changes the current working directory.
+
+```js
+cd('/tmp')
+await $`pwd` // => /tmp
+```
+
+Like `echo`, in addition to `string` arguments, `cd` accepts and trims
+trailing newlines from `ProcessOutput` enabling common idioms like:
+
+```js
+cd(await $`mktemp -d`)
+```
+
+## fetch()
+
+A wrapper around the [node-fetch](https://www.npmjs.com/package/node-fetch)
+package.
+
+```js
+const resp = await fetch('https://medv.io')
+```
+
+## question()
+
+A wrapper around the [readline](https://nodejs.org/api/readline.html) package.
+
+```js
+const bear = await question('What kind of bear is best? ')
+```
+
+## sleep()
+
+A wrapper around the `setTimeout` function.
+
+```js
+await sleep(1000)
+```
+
+## echo()
+
+A `console.log()` alternative which can take [ProcessOutput](#processoutput).
+
+```js
+const branch = await $`git branch --show-current`
+
+echo`Current branch is ${branch}.`
+// or
+echo('Current branch is', branch)
+```
+
+## stdin()
+
+Returns the stdin as a string.
+
+```js
+const content = JSON.parse(await stdin())
+```
+
+## within()
+
+Creates a new async context.
+
+```js
+await $`pwd` // => /home/path
+
+within(async () => {
+  cd('/tmp')
+
+  setTimeout(async () => {
+    await $`pwd` // => /tmp
+  }, 1000)
+})
+
+await $`pwd` // => /home/path
+```
+
+```js
+await $`node --version` // => v20.2.0
+
+const version = await within(async () => {
+  $.prefix += 'export NVM_DIR=$HOME/.nvm; source $NVM_DIR/nvm.sh; nvm use 16;'
+
+  return $`node --version`
+})
+
+echo(version) // => v16.20.0
+```
+
+## retry()
+
+Retries a callback for a few times. Will return after the first
+successful attempt, or will throw after specifies attempts count.
+
+```js
+const p = await retry(10, () => $`curl https://medv.io`)
+
+// With a specified delay between attempts.
+const p = await retry(20, '1s', () => $`curl https://medv.io`)
+
+// With an exponential backoff.
+const p = await retry(30, expBackoff(), () => $`curl https://medv.io`)
+```
+
+## spinner()
+
+Starts a simple CLI spinner.
+
+```js
+await spinner(() => $`long-running command`)
+
+// With a message.
+await spinner('working...', () => $`sleep 99`)
+```
+
+## glob()
+
+The [globby](https://github.com/sindresorhus/globby) package.
+
+```js
+const packages = await glob(['package.json', 'packages/*/package.json'])
+```
+
+## which()
+
+The [which](https://github.com/npm/node-which) package.
+
+```js
+const node = await which('node')
+```
+
+## argv
+
+The [minimist](https://www.npmjs.com/package/minimist) package.
+
+A minimist-parsed version of the `process.argv` as `argv`.
+
+```js
+if (argv.someFlag) {
+  echo('yes')
+}
+```
+
+Use minimist options to customize the parsing:
+
+```js
+const myCustomArgv = minimist(process.argv.slice(2), {
+  boolean: [
+    'force',
+    'help',
+  ],
+  alias: {
+    h: 'help',
+  },
+})
+```
+
+## chalk
+
+The [chalk](https://www.npmjs.com/package/chalk) package.
+
+```js
+console.log(chalk.blue('Hello world!'))
+```
+
+## fs
+
+The [fs-extra](https://www.npmjs.com/package/fs-extra) package.
+
+```js
+const {version} = await fs.readJson('./package.json')
+```
+
+## os
+
+The [os](https://nodejs.org/api/os.html) package.
+
+```js
+await $`cd ${os.homedir()} && mkdir example`
+```
+
+## path
+
+The [path](https://nodejs.org/api/path.html) package.
+
+```js
+await $`mkdir ${path.join(basedir, 'output')}`
+```
+
+## yaml
+
+The [yaml](https://www.npmjs.com/package/yaml) package.
+
+```js
+console.log(YAML.parse('foo: bar').foo)
+```
v7/cli.md
@@ -0,0 +1,91 @@
+::: warning
+This is documentation for zx v7, which is no longer actively maintained.
+
+For up-to-date documentation, see the [latest version](/api) (v8).
+:::
+
+# CLI Usage
+
+Zx provides a CLI for running scripts. It is installed with the package and can be used as `zx` executable.
+
+```sh
+zx script.mjs
+```
+
+## No extensions
+
+If script does not have a file extension (like `.git/hooks/pre-commit`), zx
+assumes that it is
+an [ESM](https://nodejs.org/api/modules.html#modules_module_createrequire_filename)
+module.
+
+```bash
+zx docs/markdown.md
+```
+
+## Remote scripts
+
+If the argument to the `zx` executable starts with `https://`, the file will be
+downloaded and executed.
+
+```bash
+zx https://medv.io/game-of-life.js
+```
+
+## Scripts from stdin
+
+The `zx` supports executing scripts from stdin.
+
+```js
+zx << 'EOF'
+await $`pwd`
+EOF
+```
+
+## --eval
+
+Evaluate the following argument as a script.
+
+```bash
+cat package.json | zx --eval 'const v = JSON.parse(await stdin()).version; echo(v)'
+```
+
+## --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
+```
+
+## __filename & __dirname
+
+In [ESM](https://nodejs.org/api/esm.html) modules, Node.js does not provide
+`__filename` and `__dirname` globals. As such globals are really handy in scripts,
+zx provides these for use in `.mjs` files (when using the `zx` executable).
+
+## require()
+
+In [ESM](https://nodejs.org/api/modules.html#modules_module_createrequire_filename)
+modules, the `require()` function is not defined.
+The `zx` provides `require()` function, so it can be used with imports in `.mjs`
+files (when using `zx` executable).
+
+```js
+const {version} = require('./package.json')
+```
v7/configuration.md
@@ -0,0 +1,75 @@
+::: warning
+This is documentation for zx v7, which is no longer actively maintained.
+
+For up-to-date documentation, see the [latest version](/api) (v8).
+:::
+
+# Configuration
+
+## $.shell
+
+Specifies what shell is used. Default is `which bash`.
+
+```js
+$.shell = '/usr/bin/bash'
+```
+
+Or use a CLI argument: `--shell=/bin/bash`
+
+## $.spawn
+
+Specifies a `spawn` api. Defaults to `require('child_process').spawn`.
+
+## $.prefix
+
+Specifies the command that will be prefixed to all commands run.
+
+Default is `set -euo pipefail;`.
+
+Or use a CLI argument: `--prefix='set -e;'`
+
+## $.quote
+
+Specifies a function for escaping special characters during
+command substitution.
+
+## $.verbose
+
+Specifies verbosity. Default is `true`.
+
+In verbose mode, `zx` prints all executed commands alongside with their
+outputs.
+
+Or use the CLI argument `--quiet` to set `$.verbose = false`.
+
+## $.env
+
+Specifies an environment variables map.
+
+Defaults to `process.env`.
+
+## $.cwd
+
+Specifies a current working directory of all processes created with the `$`.
+
+The [cd()](#cd) func changes only `process.cwd()` and if no `$.cwd` specified,
+all `$` processes use `process.cwd()` by default (same as `spawn` behavior).
+
+## $.log
+
+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)
+  }
+}
+```
v7/faq.md
@@ -0,0 +1,79 @@
+::: warning
+This is documentation for zx v7, which is no longer actively maintained.
+
+For up-to-date documentation, see the [latest version](/api) (v8).
+:::
+
+# FAQ
+
+## Passing env variables
+
+```js
+process.env.FOO = 'bar'
+await $`echo $FOO`
+```
+
+## Passing array of values
+
+When passing an array of values as an argument to `$`, items of the array will
+be escaped
+individually and concatenated via space.
+
+Example:
+
+```js
+const files = [...]
+await $`tar cz ${files}`
+```
+
+## Importing into other scripts
+
+It is possible to make use of `$` and other functions via explicit imports:
+
+```js
+#!/usr/bin/env node
+import {$} from 'zx'
+
+await $`date`
+```
+
+## 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 the `$.prefix`.
+
+```js
+$.prefix += 'export NVM_DIR=$HOME/.nvm; source $NVM_DIR/nvm.sh; '
+await $`nvm -v`
+```
+
+## Using GitHub Actions
+
+The default GitHub Action runner comes with `npx` installed.
+
+```yaml
+jobs:
+  build:
+    runs-on: ubuntu-latest
+    steps:
+      - uses: actions/checkout@v3
+
+      - name: Build
+        env:
+          FORCE_COLOR: 3
+        run: |
+          npx zx <<'EOF'
+          await $`...`
+          EOF
+```
+
+## Canary / Beta / RC builds
+
+Impatient early adopters can try the experimental zx versions.
+But keep in mind: these builds are โš ๏ธ๏ธ__beta__ in every sense.
+
+```bash
+npm i zx@dev
+npx zx@dev --install --quiet <<< 'import _ from "lodash" /* 4.17.15 */; console.log(_.VERSION)'
+```
v7/getting-started.md
@@ -0,0 +1,153 @@
+::: warning
+This is documentation for zx v7, which is no longer actively maintained.
+
+For up-to-date documentation, see the [latest version](/api) (v8).
+:::
+
+# Getting Started
+
+## Overview
+
+```js
+#!/usr/bin/env zx
+
+await $`cat package.json | grep name`
+
+const branch = await $`git branch --show-current`
+await $`dep deploy --branch=${branch}`
+
+await Promise.all([
+  $`sleep 1; echo 1`,
+  $`sleep 2; echo 2`,
+  $`sleep 3; echo 3`,
+])
+
+const name = 'foo bar'
+await $`mkdir /tmp/${name}`
+```
+
+Bash is great, but when it comes to writing more complex scripts,
+many people prefer a more convenient programming language.
+JavaScript is a perfect choice, but the Node.js standard library
+requires additional hassle before using. The `zx` package provides
+useful wrappers around `child_process`, escapes arguments and
+gives sensible defaults.
+
+## Install
+
+::: code-group
+
+```bash [node]
+npm install zx
+```
+
+```bash [deno]
+deno install -A npm:zx
+```
+
+```bash [brew]
+brew install zx
+```
+
+:::
+
+## Usage
+
+Write your scripts in a file with an `.mjs` extension in order to
+use `await` at the top level. If you prefer the `.js` extension,
+wrap your scripts in something like `void async function () {...}()`.
+
+Add the following shebang to the beginning of your `zx` scripts:
+
+```bash
+#!/usr/bin/env zx
+```
+
+Now you will be able to run your script like so:
+
+```bash
+chmod +x ./script.mjs
+./script.mjs
+```
+
+Or via the [CLI](cli.md):
+
+```bash
+zx ./script.mjs
+```
+
+All functions (`$`, `cd`, `fetch`, etc) are available straight away
+without any imports.
+
+Or import globals explicitly (for better autocomplete in VS Code).
+
+```js
+import 'zx/globals'
+```
+
+### ``$`command` ``
+
+Executes a given command using the `spawn` func
+and returns [`ProcessPromise`](process-promise.md).
+
+Everything passed through `${...}` will be automatically escaped and quoted.
+
+```js
+const name = 'foo & bar'
+await $`mkdir ${name}`
+```
+
+**There is no need to add extra quotes.** Read more about it in
+[quotes](quotes.md).
+
+You can pass an array of arguments if needed:
+
+```js
+const flags = [
+  '--oneline',
+  '--decorate',
+  '--color',
+]
+await $`git log ${flags}`
+```
+
+If the executed program returns a non-zero exit code,
+[`ProcessOutput`](#processoutput) will be thrown.
+
+```js
+try {
+  await $`exit 1`
+} catch (p) {
+  console.log(`Exit code: ${p.exitCode}`)
+  console.log(`Error: ${p.stderr}`)
+}
+```
+
+### `ProcessOutput`
+
+```ts
+class ProcessOutput {
+  readonly stdout: string
+  readonly stderr: string
+  readonly signal: string
+  readonly exitCode: number
+
+  toString(): string // Combined stdout & stderr.
+}
+```
+
+The output of the process is captured as-is. Usually, programs print a new
+line `\n` at the end.
+If `ProcessOutput` is used as an argument to some other `$` process,
+**zx** will use stdout and trim the new line.
+
+```js
+const date = await $`date`
+await $`echo Current date is ${date}.`
+```
+
+## License
+
+[Apache-2.0](https://github.com/google/zx/blob/main/LICENSE)
+
+Disclaimer: _This is not an officially supported Google product._
v7/known-issues.md
@@ -0,0 +1,33 @@
+::: warning
+This is documentation for zx v7, which is no longer actively maintained.
+
+For up-to-date documentation, see the [latest version](/api) (v8).
+:::
+
+# Known Issues
+
+## Output gets truncated
+
+This is a known issue with `console.log()` (see [nodejs/node#6379](https://github.com/nodejs/node/issues/6379)).
+It's caused by different behaviour of `console.log()` writing to the terminal vs
+to a file. If a process calls `process.exit()`, buffered output will be truncated.
+To prevent this, the process should use `process.exitCode = 1` and wait for the
+process to exit itself. Or use something like [exit](https://www.npmjs.com/package/exit) package.
+
+Workaround is to write to a temp file:
+```js
+const tmp = await $`mktemp` // Creates a temp file.
+const {stdout} = await $`cmd > ${tmp}; cat ${tmp}`
+```
+
+## Colors in subprocess
+
+You may see what tools invoked with `await $` don't show colors, compared to
+what you see in a terminal. This is because, the subprocess does not think it's
+a TTY and the subprocess turns off colors. Usually there is a way force
+the subprocess to add colors.
+
+```js
+process.env.FORCE_COLOR='1'
+await $`cmd`
+```
v7/markdown-scripts.md
@@ -0,0 +1,48 @@
+::: warning
+This is documentation for zx v7, which is no longer actively maintained.
+
+For up-to-date documentation, see the [latest version](/api) (v8).
+:::
+
+# Markdown Scripts
+
+It's possible to write scripts using markdown. Only code blocks will be executed
+by zx.
+
+> You can run this markdown file:
+>
+> ```
+> zx docs/markdown.md
+> ```
+
+```js
+await $`whoami`
+await $`echo ${__dirname}`
+```
+
+The `__filename` will be pointed to **markdown.md**:
+
+```js
+console.log(chalk.yellowBright(__filename))
+```
+
+We can use imports here as well:
+
+```js
+await import('chalk')
+```
+
+A bash code (with `bash` or `sh` language tags) also will be executed:
+
+```bash
+VAR=$(date)
+echo "$VAR" | wc -c
+```
+
+Other code blocks are ignored:
+
+```css
+body .hero {
+  margin: 42px;
+}
+```
v7/process-promise.md
@@ -0,0 +1,157 @@
+::: warning
+This is documentation for zx v7, which is no longer actively maintained.
+
+For up-to-date documentation, see the [latest version](/api) (v8).
+:::
+
+# Process Promise
+
+The `$` returns a `ProcessPromise` instance.
+
+```js
+const p = $`command`
+
+await p
+```
+
+## `stdin`
+
+Returns a writable stream of the stdin process. Accessing
+this getter will trigger execution of a subprocess with [`stdio('pipe')`](#stdio).
+
+Do not forget to end the stream.
+
+```js
+const p = $`while read; do echo $REPLY; done`
+p.stdin.write('Hello, World!\n')
+p.stdin.end()
+```
+
+By default, each process is created with stdin in _inherit_ mode.
+
+## `stdout`/`stderr`
+
+Returns a readable streams of stdout/stderr process.
+
+```js
+const p = $`npm init`
+for await (const chunk of p.stdout) {
+  echo(chunk)
+}
+```
+
+## `exitCode`
+
+Returns a promise which resolves to the exit code of the process.
+
+```js
+if (await $`[[ -d path ]]`.exitCode == 0) {
+...
+}
+```
+
+## `pipe()`
+
+Redirects the stdout of the process.
+
+```js
+await $`echo "Hello, stdout!"`
+  .pipe(fs.createWriteStream('/tmp/output.txt'))
+
+await $`cat /tmp/output.txt`
+```
+
+Pipes can be used to show a real-time output of the process:
+
+```js
+await $`echo 1; sleep 1; echo 2; sleep 1; echo 3;`
+  .pipe(process.stdout)
+```
+
+The `pipe()` method can combine `$` processes. Same as `|` in bash:
+
+```js
+const greeting = await $`printf "hello"`
+  .pipe($`awk '{printf $1", world!"}'`)
+  .pipe($`tr '[a-z]' '[A-Z]'`)
+
+echo(greeting)
+```
+
+Use combinations of `pipe()` and [`nothrow()`](#nothrow):
+
+```js
+await $`find ./examples -type f -print0`
+  .pipe($`xargs -0 grep ${'missing' + 'part'}`.nothrow())
+  .pipe($`wc -l`)
+```
+
+## `kill()`
+
+Kills the process and all children.
+
+By default, signal `SIGTERM` is sent. You can specify a signal via an argument.
+
+```js
+const p = $`sleep 999`
+setTimeout(() => p.kill('SIGINT'), 100)
+await p
+```
+
+## `stdio()`
+
+Specifies a stdio for the process.
+
+Default is `.stdio('inherit', 'pipe', 'pipe')`.
+
+```js
+const p = $`read`.stdio('pipe')
+```
+
+## `nothrow()`
+
+Changes behavior of `$` to not throw an exception on non-zero exit codes.
+
+```js
+await $`grep something from-file`.nothrow()
+
+// Inside a pipe():
+
+await $`find ./examples -type f -print0`
+  .pipe($`xargs -0 grep something`.nothrow())
+  .pipe($`wc -l`)
+```
+
+If only the `exitCode` is needed, you can use [`exitCode`](#exitcode) directly:
+
+```js
+if (await $`[[ -d path ]]`.exitCode == 0) {
+...
+}
+
+// Equivalent of:
+
+if ((await $`[[ -d path ]]`.nothrow()).exitCode == 0) {
+...
+}
+```
+
+## `quiet()`
+
+Changes behavior of `$` to disable verbose output.
+
+```js
+// Command and output will not be displayed.
+await $`grep something from-file`.quiet()
+```
+
+## `timeout()`
+
+Kills the process after a specified timeout.
+
+```js
+await $`sleep 999`.timeout('5s')
+
+// Or with a specific signal.
+await $`sleep 999`.timeout('5s', 'SIGKILL')
+```
v7/quotes.md
@@ -0,0 +1,103 @@
+::: warning
+This is documentation for zx v7, which is no longer actively maintained.
+
+For up-to-date documentation, see the [latest version](/api) (v8).
+:::
+
+# Quotes
+
+Bash supports various ways to quote arguments: single quotes, double quotes, and a bash-specific method using C-style
+quotes `$'...'`. Zx prefers the latter approach.
+
+```js
+const name = 'foo & bar'
+await $`mkdir ${name}`
+```
+
+Zx automatically escapes and quotes anything within `${...}`, so there's no need for additional quotes.
+
+The following examples produce the same, correct result:
+
+```js
+await $`mkdir ${'path/to-dir/' + name}`
+```
+
+```js
+await $`mkdir path/to-dir/${name}`
+```
+
+## Array of arguments
+
+Zx can also accept an array of arguments within `${...}`. Each array item will be quoted separately and then joined by a
+space.
+
+```js
+const flags = [
+  '--oneline',
+  '--decorate',
+  '--color',
+]
+await $`git log ${flags}`
+```
+
+## Glob patterns
+
+Because Zx escapes everything inside `${...}`, you can't use glob syntax directly. Instead, Zx provides 
+a [`glob`](api.md#glob) function.
+
+The following example won't work:
+
+```js
+const files = './**/*.md' // [!code error] // Incorrect
+await $`ls ${files}`
+```
+
+The correct approach:
+
+```js
+const files = await glob('./**/*.md')
+await $`ls ${files}`
+```
+
+## Home dir `~`
+
+Zx won't expand the home directory symbol `~` if it's within `${...}`. Use `os.homedir()` for that purpose.
+
+```js
+const dir = `~/Downloads` // [!code error] // Incorrect
+await $`ls ${dir}`
+```
+
+```js
+await $`ls ${os.homedir()}/Downloads` // Correct
+```
+
+```js
+await $`ls ~/Downloads` // Correct, ~ is outside of ${...}
+```
+
+## Assembling commands
+
+If you're trying to dynamically assemble commands in Zx, you might run into limitations. For instance, the following
+approach won't work:
+
+```js
+const cmd = 'rm'
+if (force) cmd += ' -f'
+if (recursive) cmd += ' -r'
+cmd += ' ' + file
+
+await $`${cmd}` // [!code error] // Incorrect
+```
+
+Zx will escape the entire string, making the command invalid. Instead, assemble an array of arguments and pass it to Zx
+like this:
+
+```js
+const args = []
+if (force) args.push('-f')
+if (recursive) args.push('-r')
+args.push(file)
+
+await $`rm ${args}` // [!code hl]
+```
v7/typescript.md
@@ -0,0 +1,34 @@
+::: warning
+This is documentation for zx v7, which is no longer actively maintained.
+
+For up-to-date documentation, see the [latest version](/api) (v8).
+:::
+
+# TypeScript
+
+Configure your project to use [ES modules](https://nodejs.org/api/packages.html#packages_type):
+
+- Set [`"type": "module"`](https://nodejs.org/api/packages.html#packages_type)
+in **package.json**
+- Set [`"module": "ESNext"`](https://www.typescriptlang.org/tsconfig/#module)
+in **tsconfig.json**.
+
+It is possible to make use of `$` and other functions via explicit imports:
+
+```ts
+import { $ } from 'zx'
+```
+
+Or import globals explicitly:
+
+```ts
+import 'zx/globals'
+```
+
+Wrap your code in an async function and call it immediately:
+
+```ts
+void async function () {
+  await $`ls -la`
+}()
+```