{"id":19475476,"url":"https://github.com/artdecocode/which-stream","last_synced_at":"2026-06-07T20:32:26.038Z","repository":{"id":135405801,"uuid":"144314633","full_name":"artdecocode/which-stream","owner":"artdecocode","description":"A small Node.js library to determine which stream to use.","archived":false,"fork":false,"pushed_at":"2019-08-03T00:30:46.000Z","size":65,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-02-09T04:04:26.417Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","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/artdecocode.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","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":"2018-08-10T17:27:20.000Z","updated_at":"2019-08-03T00:30:48.000Z","dependencies_parsed_at":null,"dependency_job_id":"9b6b5786-96f4-497b-8908-92dde8edcaef","html_url":"https://github.com/artdecocode/which-stream","commit_stats":null,"previous_names":[],"tags_count":5,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/artdecocode%2Fwhich-stream","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/artdecocode%2Fwhich-stream/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/artdecocode%2Fwhich-stream/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/artdecocode%2Fwhich-stream/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/artdecocode","download_url":"https://codeload.github.com/artdecocode/which-stream/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":240699244,"owners_count":19843509,"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":[],"created_at":"2024-11-10T19:33:06.110Z","updated_at":"2026-06-07T20:32:25.978Z","avatar_url":"https://github.com/artdecocode.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# which-stream\n\n[![npm version](https://badge.fury.io/js/which-stream.svg)](https://npmjs.org/package/which-stream)\n\n`which-stream` is a small Node.JS library to pipe an input stream to an output one. It can create filesystem's read and write streams, or use provided ones, as well as piping output to the `stdout`.\n\n```sh\nyarn add which-stream\n```\n\n\u003cp align=\"center\"\u003e\u003ca href=\"#table-of-contents\"\u003e\n  \u003cimg src=\"/.documentary/section-breaks/0.svg?sanitize=true\"\u003e\n\u003c/a\u003e\u003c/p\u003e\n\n## Table Of Contents\n\n- [Table Of Contents](#table-of-contents)\n- [API](#api)\n- [`async whichStream(config: Config)`](#async-whichstreamconfig-config-void)\n  * [`_whichStream.Config`](#type-_whichstreamconfig)\n- [Use Cases](#use-cases)\n  * [Source to Destination](#source-to-destination)\n  * [Source to Writable](#source-to-writable)\n  * [Source to Stdout](#source-to-stdout)\n  * [Readable to Destination](#readable-to-destination)\n  * [Readable to Destination (Overwriting)](#readable-to-destination-overwriting)\n  * [Readable to Writable](#readable-to-writable)\n  * [Readable to Stdout](#readable-to-stdout)\n- [Copyright](#copyright)\n\n\u003cp align=\"center\"\u003e\u003ca href=\"#table-of-contents\"\u003e\n  \u003cimg src=\"/.documentary/section-breaks/1.svg?sanitize=true\"\u003e\n\u003c/a\u003e\u003c/p\u003e\n\n## API\n\nThe package is available by importing its default function:\n\n```js\nimport whichStream from 'which-stream'\n```\n\nThe types and [externs](externs.js) for _Google Closure Compiler_ via [**_Depack_**](https://github.com/dpck/depack) are defined in the `_whichStream` namespace.\n\n\u003cp align=\"center\"\u003e\u003ca href=\"#table-of-contents\"\u003e\n  \u003cimg src=\"/.documentary/section-breaks/2.svg?sanitize=true\"\u003e\n\u003c/a\u003e\u003c/p\u003e\n\n## `async whichStream(`\u003cbr/\u003e\u0026nbsp;\u0026nbsp;`config: Config,`\u003cbr/\u003e`): void`\n\nThe `whichStream` function will determine which streams to use by creating readable and writable streams when source and/or destination are passed as strings, pipe the input to the output, and wait for the output to finish.\n\n\u003cstrong\u003e\u003ca name=\"type-_whichstreamconfig\"\u003e`_whichStream.Config`\u003c/a\u003e\u003c/strong\u003e: The configuration object.\n\n\n|    Name     |                                             Type                                             |                                                                                                                                                                                        Description                                                                                                                                                                                        |\n| ----------- | -------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| source      | \u003cem\u003estring\u003c/em\u003e                                                                              | The path to a source file from which to read data.                                                                                                                                                                                                                                                                                                                                        |\n| readable    | \u003cem\u003e[!stream.Readable](https://nodejs.org/api/stream.html#stream_class_stream_readable)\u003c/em\u003e | An optional input stream, if the `source` is not given.                                                                                                                                                                                                                                                                                                                                   |\n| destination | \u003cem\u003estring\u003c/em\u003e                                                                              | The path to an output file. If `-` is given, `process.stdout` will be used. If the path of the input stream is the same as of the output one, the result will be first written to the memory, and only then to the destination file. Moreover, when used with the `readable` specified to overwrite the file from which data is originally read from, the `source` should also be passed. |\n| writable    | \u003cem\u003e[!stream.Writable](https://nodejs.org/api/stream.html#stream_class_stream_writable)\u003c/em\u003e | A stream into which to pipe the input stream, if `destination` is not given.                                                                                                                                                                                                                                                                                                              |\n\n\u003cp align=\"center\"\u003e\u003ca href=\"#table-of-contents\"\u003e\n  \u003cimg src=\"/.documentary/section-breaks/3.svg?sanitize=true\"\u003e\n\u003c/a\u003e\u003c/p\u003e\n\n## Use Cases\n\nBelow is the list of possible use cases when `which-stream` package could be used.\n\n### Source to Destination\n\nWhen the `source` and `destination` are passed, a file is be copied as it is.\n\n```js\n/* yarn example/source-destination.js */\nimport whichStream from 'which-stream'\nimport { createReadStream } from 'fs'\n\n(async () =\u003e {\n  const source = 'example/millet.txt'\n  const destination = 'example/millet-out.txt'\n  await whichStream({\n    source,\n    destination,\n  })\n  // verify\n  const rs = createReadStream(destination)\n  rs.pipe(process.stdout)\n})()\n```\n\n```\nMillet (gluten-free):\nAn excellet source of manganese, magnesioum, and phosphorus.\n```\n\n### Source to Writable\n\nWhen the `source` and `writable` are supplied, a stream pushing input text from the source file will be piped into the given output writable stream.\n\n```js\n/* yarn example/source-writable.js */\nimport whichStream from 'which-stream'\nimport { Transform } from 'stream';\n\n(async () =\u003e {\n  const source = 'example/brown-rice.txt'\n  const writable = new Transform({\n    transform(data, encoding, next) {\n      const d = `${data}`.toUpperCase()\n      this.push(d)\n      next()\n    },\n  })\n  writable.pipe(process.stdout) // to verify\n  await whichStream({\n    source,\n    writable,\n  })\n})()\n```\n\n```\nBROWN RICE (GLUTEN-FREE):\nUNLIKE WHITE RICE, BROWN RICE IS REACH WITH VITAMINS,\nMINERALS, FIBRE AND FATTY ACIDS.\n```\n\n### Source to Stdout\n\nTo print a file to `stdout`, the destination should be set to `-` .\n\n```js\n/* yarn example/source-stdout.js */\nimport whichStream from 'which-stream'\n\n(async () =\u003e {\n  await whichStream({\n    source: 'example/zinc.txt',\n    destination: '-',\n  })\n})()\n```\n\n```\nZINC: an often-overlooked essential mineral, zinc is the\nmost common mineral found in the body after iron.\n```\n\n### Readable to Destination\n\nPassing both the `readable` and `destination` properties will ensure that the input stream is written to the destination on the disk.\n\n```js\n/* yarn example/readable-destination.js */\nimport whichStream from 'which-stream'\nimport { createReadStream } from 'fs'\nimport { Readable } from 'stream';\n\n(async () =\u003e {\n  const destination = 'example/thiamine-out.txt'\n  const readable = new Readable({\n    read() {\n      this.push(`\nVitamin B1 (Thiamine): essential for proper functioning of\nthe heart, muscles and nervous system.\n`.trim()\n      )\n      this.push(null)\n    },\n  })\n  await whichStream({\n    readable,\n    destination,\n  })\n  // verify\n  const rs = createReadStream(destination)\n  rs.pipe(process.stdout)\n})()\n```\n\n```\nVitamin B1 (Thiamine): essential for proper functioning of\nthe heart, muscles and nervous system.\n```\n\n### Readable to Destination (Overwriting)\n\nIf `readable`'s data initially comes from the same source as the destination to which it will be written, the `source` property must also be set to make sure that the file is overwritten properly. The stream's data will first be buffered in memory, and upon the readable stream's end it will be released to the destination. This is useful when using transform streams which don't necessary read from the source themselves, but are being piped into by another readable.\n\n```js\n/* yarn example/readable-destination-overwrite.js */\nimport whichStream from 'which-stream'\nimport { createReadStream } from 'fs'\nimport { Transform } from 'stream'\n\n(async () =\u003e {\n  const source = 'example/onions.txt'\n  const readable = new Transform({\n    transform(data, encoding, next) {\n      const d = `${data}`.replace(\n        /Modified: (.+)/m,\n        `Modified: ${new Date().toDateString()}`,\n      )\n      this.push(d)\n      next()\n    },\n  })\n  const rs = createReadStream(source)\n  rs.pipe(readable)\n  await whichStream({\n    source,\n    readable,\n    destination: source,\n  })\n  // verify\n  const vrs = createReadStream(source)\n  vrs.pipe(process.stdout)\n})()\n```\n\n```\nBuy a bag of onions, chop in food processor, toss into\nplastic zip bag, and stow in freezer.\nModified: Sat Aug 03 2019\n```\n\nIn case the `source` is not passed, the file will become empty.\n\n### Readable to Writable\n\nIn the scenario when the `readable` and `writable` are specified, the former will be piped into the latter, and the function's promise will be resolved when the writable finishes.\n\n```js\n/* yarn example/readable-writable.js */\nimport whichStream from 'which-stream'\nimport { Readable, Transform } from 'stream';\n\n(async () =\u003e {\n  const readable = new Readable({\n    read() {\n      this.push(`\nOmega-3 fatty acids boost heart health, lower\ntriglycerides, and may help in the treatment\nand prevention of depression.\n`.trim()\n      )\n      this.push(null)\n    },\n  })\n  const writable = new Transform({\n    transform(data, encoding, next) {\n      const d = `*${data}*`\n      this.push(d)\n      next()\n    },\n  })\n  writable.pipe(process.stdout) // to verify\n  await whichStream({\n    readable,\n    writable,\n  })\n})()\n```\n\n```markdown\n*Omega-3 fatty acids boost heart health, lower\ntriglycerides, and may help in the treatment\nand prevention of depression.*\n```\n\n### Readable to Stdout\n\nWhen a _Readable_ stream needs to be output to the `stdout`, the destination should be set to `-`.\n\n```js\n/* yarn example/readable-stdout.js */\nimport whichStream from 'which-stream'\nimport { Readable } from 'stream';\n\n(async () =\u003e {\n  const readable = new Readable({\n    read() {\n      this.push(`\n\u003e Use microwave to quickly steam your veggies:\nplace in a bowl, add a few tablespoons of water,\ncover and cook in 3 to 5 minutes increments.\n`.trim()\n      )\n      this.push(null)\n    },\n  })\n  await whichStream({\n    readable,\n    destination: '-',\n  })\n})()\n```\n```markdown\n\u003e Use microwave to quickly steam your veggies:\nplace in a bowl, add a few tablespoons of water,\ncover and cook in 3 to 5 minutes increments.\n```\n\n\u003cp align=\"center\"\u003e\u003ca href=\"#table-of-contents\"\u003e\n  \u003cimg src=\"/.documentary/section-breaks/-1.svg?sanitize=true\"\u003e\n\u003c/a\u003e\u003c/p\u003e\n\n## Copyright\n\n\u003ctable\u003e\n  \u003ctr\u003e\n    \u003cth\u003e\n      \u003ca href=\"https://artd.eco\"\u003e\n        \u003cimg width=\"100\" src=\"https://raw.githubusercontent.com/wrote/wrote/master/images/artdeco.png\"\n          alt=\"Art Deco\"\u003e\n      \u003c/a\u003e\n    \u003c/th\u003e\n    \u003cth\u003e© \u003ca href=\"https://artd.eco\"\u003eArt Deco\u003c/a\u003e   2019\u003c/th\u003e\n    \u003cth\u003e\n      \u003ca href=\"https://www.technation.sucks\" title=\"Tech Nation Visa\"\u003e\n        \u003cimg width=\"100\" src=\"https://raw.githubusercontent.com/idiocc/cookies/master/wiki/arch4.jpg\"\n          alt=\"Tech Nation Visa\"\u003e\n      \u003c/a\u003e\n    \u003c/th\u003e\n    \u003cth\u003e\u003ca href=\"https://www.technation.sucks\"\u003eTech Nation Visa Sucks\u003c/a\u003e\u003c/th\u003e\n  \u003c/tr\u003e\n\u003c/table\u003e","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fartdecocode%2Fwhich-stream","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fartdecocode%2Fwhich-stream","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fartdecocode%2Fwhich-stream/lists"}