pax_global_header00006660000000000000000000000064142650217710014517gustar00rootroot0000000000000052 comment=b113fa538f5b9c5520e1adfdfa8d73afe437c700 clone-response-1.0.3/000077500000000000000000000000001426502177100144545ustar00rootroot00000000000000clone-response-1.0.3/.gitignore000066400000000000000000000020161426502177100164430ustar00rootroot00000000000000## Node # Logs logs *.log npm-debug.log* # Runtime data pids *.pid *.seed *.pid.lock # Directory for instrumented libs generated by jscoverage/JSCover lib-cov # Coverage directory used by tools like istanbul coverage # nyc test coverage .nyc_output # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) .grunt # node-waf configuration .lock-wscript # Compiled binary addons (http://nodejs.org/api/addons.html) build/Release # Dependency directories node_modules jspm_packages # Optional npm cache directory .npm # Optional eslint cache .eslintcache # Optional REPL history .node_repl_history ## OS X *.DS_Store .AppleDouble .LSOverride # Icon must end with two \r Icon # Thumbnails ._* # Files that might appear in the root of a volume .DocumentRevisions-V100 .fseventsd .Spotlight-V100 .TemporaryItems .Trashes .VolumeIcon.icns .com.apple.timemachine.donotpresent # Directories potentially created on remote AFP share .AppleDB .AppleDesktop Network Trash Folder Temporary Items .apdisk clone-response-1.0.3/.npmignore000066400000000000000000000000071426502177100164500ustar00rootroot00000000000000* !src clone-response-1.0.3/.travis.yml000066400000000000000000000002221426502177100165610ustar00rootroot00000000000000language: node_js node_js: - '8' - '6' - '4' script: npm test after_success: npm run coverage notifications: email: on_success: never clone-response-1.0.3/LICENSE000066400000000000000000000020541426502177100154620ustar00rootroot00000000000000MIT License Copyright (c) 2017 Luke Childs Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. clone-response-1.0.3/README.md000066400000000000000000000040471426502177100157400ustar00rootroot00000000000000# clone-response > Clone a Node.js HTTP response stream [![Build Status](https://travis-ci.org/lukechilds/clone-response.svg?branch=master)](https://travis-ci.org/lukechilds/clone-response) [![Coverage Status](https://coveralls.io/repos/github/lukechilds/clone-response/badge.svg?branch=master)](https://coveralls.io/github/lukechilds/clone-response?branch=master) [![npm](https://img.shields.io/npm/dm/clone-response.svg)](https://www.npmjs.com/package/clone-response) [![npm](https://img.shields.io/npm/v/clone-response.svg)](https://www.npmjs.com/package/clone-response) Returns a new stream and copies over all properties and methods from the original response giving you a complete duplicate. This is useful in situations where you need to consume the response stream but also want to pass an unconsumed stream somewhere else to be consumed later. ## Install ```shell npm install --save clone-response ``` ## Usage ```js const http = require('http'); const cloneResponse = require('clone-response'); http.get('http://example.com', response => { const clonedResponse = cloneResponse(response); response.pipe(process.stdout); setImmediate(() => { // The response stream has already been consumed by the time this executes, // however the cloned response stream is still available. doSomethingWithResponse(clonedResponse); }); }); ``` Please bear in mind that the process of cloning a stream consumes it. However, you can consume a stream multiple times in the same tick, therefore allowing you to create multiple clones. e.g: ```js const clone1 = cloneResponse(response); const clone2 = cloneResponse(response); // response can still be consumed in this tick but cannot be consumed if passed // into any async callbacks. clone1 and clone2 can be passed around and be // consumed in the future. ``` ## API ### cloneResponse(response) Returns a clone of the passed in response. #### response Type: `stream` A [Node.js HTTP response stream](https://nodejs.org/api/http.html#http_class_http_incomingmessage) to clone. ## License MIT © Luke Childs clone-response-1.0.3/package.json000066400000000000000000000017121426502177100167430ustar00rootroot00000000000000{ "name": "clone-response", "version": "1.0.3", "description": "Clone a Node.js HTTP response stream", "main": "src/index.js", "scripts": { "test": "xo && nyc ava", "coverage": "nyc report --reporter=text-lcov | coveralls" }, "funding": "https://github.com/sponsors/sindresorhus", "xo": { "extends": "xo-lukechilds" }, "repository": { "type": "git", "url": "git+https://github.com/sindresorhus/clone-response.git" }, "keywords": [ "clone", "duplicate", "copy", "response", "HTTP", "stream" ], "author": "Luke Childs (http://lukechilds.co.uk)", "license": "MIT", "dependencies": { "mimic-response": "^1.0.0" }, "devDependencies": { "ava": "^0.22.0", "coveralls": "^2.13.1", "create-test-server": "^2.0.1", "eslint-config-xo-lukechilds": "^1.0.0", "get-stream": "^3.0.0", "nyc": "^11.0.2", "pify": "^3.0.0", "xo": "^0.19.0" } } clone-response-1.0.3/src/000077500000000000000000000000001426502177100152435ustar00rootroot00000000000000clone-response-1.0.3/src/index.js000066400000000000000000000006211426502177100167070ustar00rootroot00000000000000'use strict'; const PassThrough = require('stream').PassThrough; const mimicResponse = require('mimic-response'); const cloneResponse = response => { if (!(response && response.pipe)) { throw new TypeError('Parameter `response` must be a response stream.'); } const clone = new PassThrough(); mimicResponse(response, clone); return response.pipe(clone); }; module.exports = cloneResponse; clone-response-1.0.3/test/000077500000000000000000000000001426502177100154335ustar00rootroot00000000000000clone-response-1.0.3/test/clone-response.js000066400000000000000000000037671426502177100207420ustar00rootroot00000000000000import http from 'http'; import { PassThrough } from 'stream'; import test from 'ava'; import pify from 'pify'; import getStream from 'get-stream'; import createTestServer from 'create-test-server'; import cloneResponse from '../'; const get = pify(http.get, { errorFirst: false }); let s; const responseText = 'Hi!'; test.before(async () => { s = await createTestServer(); s.get('/', (req, res) => res.send(responseText)); }); test('cloneResponse is a function', t => { t.is(typeof cloneResponse, 'function'); }); test('returns a new PassThrough stream', async t => { const response = await get(s.url); const clonedResponse = cloneResponse(response); t.true(clonedResponse instanceof PassThrough); }); test('throws TypeError if response isn\'t passed in', t => { const error = t.throws(() => cloneResponse()); t.is(error.message, 'Parameter `response` must be a response stream.'); }); test('streaming a response twice should fail', async t => { const response = await get(s.url); const firstStream = await getStream(response); const secondStream = await getStream(response); t.is(firstStream, responseText); t.is(secondStream, ''); }); test('streaming multiple cloned responses succeeds', async t => { const response = await get(s.url); const clonedResponse = cloneResponse(response); const firstStream = await getStream(response); const clonedStream = await getStream(clonedResponse); t.is(firstStream, responseText); t.is(clonedStream, responseText); }); test('custom properties are copied over', async t => { const response = await get(s.url); response.foo = 'bar'; const clonedResponse = cloneResponse(response); t.is(clonedResponse.foo, 'bar'); }); test('function methods are bound to the original response instance', async t => { const response = await get(s.url); response.getContext = function () { return this; }; const clonedResponse = cloneResponse(response); t.is(response.getContext(), clonedResponse.getContext()); }); test.after('cleanup', async () => { await s.close(); });