{"id":21331423,"url":"https://github.com/eibens/jog","last_synced_at":"2026-05-17T13:32:39.709Z","repository":{"id":62422125,"uuid":"374800374","full_name":"eibens/jog","owner":"eibens","description":"A simplified API for running sub-processes in TypeScript for Deno.","archived":false,"fork":false,"pushed_at":"2022-06-12T18:15:07.000Z","size":27,"stargazers_count":1,"open_issues_count":1,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-02-23T00:04:03.854Z","etag":null,"topics":["deno","io","process","run","stderr","stdin","stdout","typescript"],"latest_commit_sha":null,"homepage":"","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/eibens.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}},"created_at":"2021-06-07T21:06:26.000Z","updated_at":"2023-04-10T14:09:43.000Z","dependencies_parsed_at":"2022-11-01T17:31:19.245Z","dependency_job_id":null,"html_url":"https://github.com/eibens/jog","commit_stats":null,"previous_names":[],"tags_count":10,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eibens%2Fjog","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eibens%2Fjog/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eibens%2Fjog/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eibens%2Fjog/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/eibens","download_url":"https://codeload.github.com/eibens/jog/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243809848,"owners_count":20351407,"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","io","process","run","stderr","stdin","stdout","typescript"],"created_at":"2024-11-21T22:33:01.160Z","updated_at":"2026-05-17T13:32:34.682Z","avatar_url":"https://github.com/eibens.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# jog - Simplified Process Runner for Deno\n\n\u003e [jog] — _also known as a leisurely paced run_ — is a simplified API for\n\u003e running sub-processes in TypeScript for [Deno], implemented as a thin wrapper\n\u003e around `Deno.run`.\n\n[![License][license-shield]](LICENSE) [![Deno doc][deno-doc-shield]][deno-doc]\n[![Deno module][deno-land-shield]][deno-land]\n[![Github tag][github-shield]][github] [![Build][build-shield]][build]\n[![Code coverage][coverage-shield]][coverage]\n\n# Motivation\n\nUsing the native [Deno] function `Deno.run` can be tedious, as we must correctly\nconfigure the IO streams and remember to cleanup resources. In [jog] access to\n`stdout`, `stdin`, and `stderr`, as well as resource management is abstracted\naway. Instead, the data for `stdin` can be specified once as a buffer, the data\nfrom `stdout` is returned asynchronously as a buffer or mapped to a custom type,\nand `stderr` is thrown as an error message if the process terminates\nunsuccessfully. The following table summarizes the differences between the\nnative [Deno] API and [jog]:\n\n| `Deno.run`                     | `jog.run`               |\n| ------------------------------ | ----------------------- |\n| `cmd` / `cwd` / `env`          | _same_                  |\n| `stdin`                        | `Uint8Array` / `string` |\n| `stdout` / `output` / `status` | `Promise\u003cUint8Array\u003e`   |\n| `stderr` / `stderrOutput`      | `try`-`catch`           |\n\n# [mod.ts]\n\nThe [mod.ts] module exports all other modules.\n\n# [run.ts]\n\nThe `run` function starts a sub-process and returns its result asynchronously.\nThe required `cmd` and optional `cwd` and `env` options work exactly like their\n`Deno.run` counterparts. The examples assume that the [mockcli.ts] module is\ninstalled as `mockcli` on the command line. This example demonstrates how `run`\ncan be used to get data from `stdout`:\n\n```ts\nimport { Run, run } from \"https://deno.land/x/jog/run.ts\";\n\n// Define a process.\nconst command: Run = {\n  cmd: [\"mockcli\", \"answer\"],\n};\n\n// Run the process.\nconst buffer: Uint8Array = await run(command);\n\n// print: \"42\\n\"\nDeno.stdout.write(buffer);\n```\n\nData for `stdin` can be specified with the `input` option, either as a `string`\nor as a `Uint8Array`:\n\n```ts\nimport { run } from \"https://deno.land/x/jog/run.ts\";\n\nconst buffer = await run({\n  cmd: [\"mockcli\", \"echo\"],\n  input: \"let's jog!\",\n});\n\n// print: \"let's jog!\"\nDeno.stdout.write(buffer);\n```\n\nIf the process exits with an error, an `Error` is thrown and the contents of\n`stderr` are used as the error message:\n\n```ts\nimport { run } from \"https://deno.land/x/jog/run.ts\";\n\ntry {\n  await run({\n    cmd: [\"mockcli\", \"fail\"],\n    input: \"oh no!\",\n  });\n} catch (error) {\n  // print: \"oh no!\"\n  console.log(error.message);\n}\n```\n\n# [out.ts]\n\nThe `out` function extends the `run` API with an asynchronous mapping function\nthat is applied to the `stdout` buffer. For example, instead of the buffer\nitself, one could return its length:\n\n```ts\nimport { Out, out } from \"https://deno.land/x/jog/out.ts\";\n\n// Define a process with output mapping.\nconst command: Out\u003cnumber\u003e = {\n  cmd: [\"mockcli\", \"answer\"],\n  map: async (x: Promise\u003cUint8Array\u003e) =\u003e (await x).length,\n};\n\n// Run the process.\nconst length: number = await out(command);\n\n// print: 3 (buffer contains \"42\\n\")\nconsole.log(length);\n```\n\n# [map.ts]\n\nThe functions `getLines`, `getLinesNonEmpty`, `getFirst`, and `getSuccess` are\ncommon mappings that can be used with the `out` function. For example,\n`getSuccess` can be used to check whether a process succeeds:\n\n```ts\nimport { out } from \"https://deno.land/x/jog/out.ts\";\nimport { getSuccess } from \"https://deno.land/x/jog/map.ts\";\n\nconst worked = await out({\n  cmd: [\"mockcli\", \"fail\"],\n  input: \"oh no!\",\n  map: getSuccess,\n});\n\n// print: false\nconsole.log(worked);\n```\n\nCustom mapping functions can be defined with the `map` and `mapAsync`\nconvenience functions. The `pipe` function can be used for chaining two mapping\nfunctions. In this example, `out` returns the first line of `stdout` in\nuppercase letters:\n\n```ts\nimport { out } from \"https://deno.land/x/jog/out.ts\";\nimport { getFirst, getLines, map, pipe } from \"https://deno.land/x/jog/map.ts\";\n\nconst result = await out({\n  cmd: [\"mockcli\", \"echo\"],\n  input: \"first\\nsecond\",\n  map: pipe(\n    pipe(getLines, getFirst),\n    map((x) =\u003e x.toUpperCase()),\n  ),\n});\n\n// print: \"FIRST\"\nconsole.log(result);\n```\n\n# That's it!\n\nNow, [jog home][github].\n\n[jog]: #\n[Deno]: https://deno.land\n[mod.ts]: mod.ts\n[run.ts]: run.ts\n[out.ts]: out.ts\n[map.ts]: map.ts\n[mockcli.ts]: mockcli.ts\n\n\u003c!-- badges --\u003e\n\n[github]: https://github.com/eibens/jog\n[github-shield]: https://img.shields.io/github/v/tag/eibens/jog?label\u0026logo=github\n[coverage-shield]: https://img.shields.io/codecov/c/github/eibens/jog?logo=codecov\u0026label\n[license-shield]: https://img.shields.io/github/license/eibens/jog?color=informational\n[coverage]: https://codecov.io/gh/eibens/jog\n[build]: https://github.com/eibens/jog/actions/workflows/ci.yml\n[build-shield]: https://img.shields.io/github/workflow/status/eibens/jog/ci?logo=github\u0026label\n[deno-doc]: https://doc.deno.land/https/deno.land/x/jog/mod.ts\n[deno-doc-shield]: https://img.shields.io/badge/doc-informational?logo=deno\n[deno-land]: https://deno.land/x/jog\n[deno-land-shield]: https://img.shields.io/badge/x/jog-informational?logo=deno\u0026label\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Feibens%2Fjog","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Feibens%2Fjog","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Feibens%2Fjog/lists"}