이세린

Trying to embed random puppy, img not working

Showing 80 changed files with 3914 additions and 0 deletions
1 +'use strict';
2 +
3 +module.exports = Error.captureStackTrace || function (error) {
4 + var container = new Error();
5 +
6 + Object.defineProperty(error, 'stack', {
7 + configurable: true,
8 + get: function getStack() {
9 + var stack = container.stack;
10 +
11 + Object.defineProperty(this, 'stack', {
12 + value: stack
13 + });
14 +
15 + return stack;
16 + }
17 + });
18 +};
1 +The MIT License (MIT)
2 +
3 +Copyright (c) Vsevolod Strukchinsky <floatdrop@gmail.com> (github.com/floatdrop)
4 +
5 +Permission is hereby granted, free of charge, to any person obtaining a copy
6 +of this software and associated documentation files (the "Software"), to deal
7 +in the Software without restriction, including without limitation the rights
8 +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 +copies of the Software, and to permit persons to whom the Software is
10 +furnished to do so, subject to the following conditions:
11 +
12 +The above copyright notice and this permission notice shall be included in
13 +all copies or substantial portions of the Software.
14 +
15 +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 +THE SOFTWARE.
1 +{
2 + "name": "capture-stack-trace",
3 + "version": "1.0.1",
4 + "description": "Error.captureStackTrace ponyfill",
5 + "license": "MIT",
6 + "repository": "floatdrop/capture-stack-trace",
7 + "author": {
8 + "name": "Vsevolod Strukchinsky",
9 + "email": "floatdrop@gmail.com",
10 + "url": "github.com/floatdrop"
11 + },
12 + "engines": {
13 + "node": ">=0.10.0"
14 + },
15 + "scripts": {
16 + "test": "mocha"
17 + },
18 + "files": [
19 + "index.js"
20 + ],
21 + "keywords": [
22 + "Error",
23 + "captureStackTrace"
24 + ],
25 + "dependencies": {},
26 + "devDependencies": {
27 + "mocha": "*"
28 + }
29 +}
1 +# capture-stack-trace [![Build Status](https://travis-ci.org/floatdrop/capture-stack-trace.svg?branch=master)](https://travis-ci.org/floatdrop/capture-stack-trace)
2 +
3 +> Ponyfill for Error.captureStackTrace
4 +
5 +
6 +## Install
7 +
8 +```
9 +$ npm install --save capture-stack-trace
10 +```
11 +
12 +
13 +## Usage
14 +
15 +```js
16 +var captureStackTrace = require('capture-stack-trace');
17 +
18 +captureStackTrace({});
19 +// => {stack: ...}
20 +```
21 +
22 +
23 +## API
24 +
25 +### captureStackTrace(error)
26 +
27 +#### error
28 +
29 +*Required*
30 +Type: `Object`
31 +
32 +Target Object, that will recieve stack property.
33 +
34 +## License
35 +
36 +MIT © [Vsevolod Strukchinsky](http://github.com/floatdrop)
1 +'use strict';
2 +var captureStackTrace = require('capture-stack-trace');
3 +
4 +function inherits(ctor, superCtor) {
5 + ctor.super_ = superCtor;
6 + ctor.prototype = Object.create(superCtor.prototype, {
7 + constructor: {
8 + value: ctor,
9 + enumerable: false,
10 + writable: true,
11 + configurable: true
12 + }
13 + });
14 +}
15 +
16 +module.exports = function createErrorClass(className, setup) {
17 + if (typeof className !== 'string') {
18 + throw new TypeError('Expected className to be a string');
19 + }
20 +
21 + if (/[^0-9a-zA-Z_$]/.test(className)) {
22 + throw new Error('className contains invalid characters');
23 + }
24 +
25 + setup = setup || function (message) {
26 + this.message = message;
27 + };
28 +
29 + var ErrorClass = function () {
30 + Object.defineProperty(this, 'name', {
31 + configurable: true,
32 + value: className,
33 + writable: true
34 + });
35 +
36 + captureStackTrace(this, this.constructor);
37 +
38 + setup.apply(this, arguments);
39 + };
40 +
41 + inherits(ErrorClass, Error);
42 +
43 + return ErrorClass;
44 +};
1 +The MIT License (MIT)
2 +
3 +Copyright (c) Vsevolod Strukchinsky <floatdrop@gmail.com> (github.com/floatdrop)
4 +
5 +Permission is hereby granted, free of charge, to any person obtaining a copy
6 +of this software and associated documentation files (the "Software"), to deal
7 +in the Software without restriction, including without limitation the rights
8 +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 +copies of the Software, and to permit persons to whom the Software is
10 +furnished to do so, subject to the following conditions:
11 +
12 +The above copyright notice and this permission notice shall be included in
13 +all copies or substantial portions of the Software.
14 +
15 +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 +THE SOFTWARE.
1 +{
2 + "name": "create-error-class",
3 + "version": "3.0.2",
4 + "description": "Create Error classes",
5 + "license": "MIT",
6 + "repository": "floatdrop/create-error-class",
7 + "author": {
8 + "name": "Vsevolod Strukchinsky",
9 + "email": "floatdrop@gmail.com",
10 + "url": "github.com/floatdrop"
11 + },
12 + "engines": {
13 + "node": ">=0.10.0"
14 + },
15 + "scripts": {
16 + "test": "mocha"
17 + },
18 + "files": [
19 + "index.js"
20 + ],
21 + "keywords": [
22 + ""
23 + ],
24 + "dependencies": {
25 + "capture-stack-trace": "^1.0.0"
26 + },
27 + "devDependencies": {
28 + "mocha": "*"
29 + }
30 +}
1 +# create-error-class [![Build Status](https://travis-ci.org/floatdrop/create-error-class.svg?branch=master)](https://travis-ci.org/floatdrop/create-error-class)
2 +
3 +> Create error class
4 +
5 +
6 +## Install
7 +
8 +```
9 +$ npm install --save create-error-class
10 +```
11 +
12 +
13 +## Usage
14 +
15 +```js
16 +var createErrorClass = require('create-error-class');
17 +
18 +var HTTPError = createErrorClass('HTTPError', function (props) {
19 + this.message = 'Status code is ' + props.statusCode;
20 +});
21 +
22 +throw new HTTPError({statusCode: 404});
23 +```
24 +
25 +
26 +## API
27 +
28 +### createErrorClass(className, [setup])
29 +
30 +Return constructor of Errors with `className`.
31 +
32 +#### className
33 +
34 +*Required*
35 +Type: `string`
36 +
37 +Class name of Error Object. Should contain characters from `[0-9a-zA-Z_$]` range.
38 +
39 +#### setup
40 +Type: `function`
41 +
42 +Setup function, that will be called after each Error object is created from constructor with context of Error object.
43 +
44 +By default `setup` function sets `this.message` as first argument:
45 +
46 +```js
47 +var MyError = createErrorClass('MyError');
48 +
49 +new MyError('Something gone wrong!').message; // => 'Something gone wrong!'
50 +```
51 +
52 +## License
53 +
54 +MIT © [Vsevolod Strukchinsky](http://github.com/floatdrop)
1 +The MIT License (MIT)
2 +
3 +Copyright (c) 2016 David Frank
4 +
5 +Permission is hereby granted, free of charge, to any person obtaining a copy
6 +of this software and associated documentation files (the "Software"), to deal
7 +in the Software without restriction, including without limitation the rights
8 +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 +copies of the Software, and to permit persons to whom the Software is
10 +furnished to do so, subject to the following conditions:
11 +
12 +The above copyright notice and this permission notice shall be included in all
13 +copies or substantial portions of the Software.
14 +
15 +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 +SOFTWARE.
22 +
This diff is collapsed. Click to expand it.
1 +"use strict";
2 +
3 +// ref: https://github.com/tc39/proposal-global
4 +var getGlobal = function () {
5 + // the only reliable means to get the global object is
6 + // `Function('return this')()`
7 + // However, this causes CSP violations in Chrome apps.
8 + if (typeof self !== 'undefined') { return self; }
9 + if (typeof window !== 'undefined') { return window; }
10 + if (typeof global !== 'undefined') { return global; }
11 + throw new Error('unable to locate global object');
12 +}
13 +
14 +var global = getGlobal();
15 +
16 +module.exports = exports = global.fetch;
17 +
18 +// Needed for TypeScript and Webpack.
19 +if (global.fetch) {
20 + exports.default = global.fetch.bind(global);
21 +}
22 +
23 +exports.Headers = global.Headers;
24 +exports.Request = global.Request;
25 +exports.Response = global.Response;
...\ No newline at end of file ...\ No newline at end of file
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
1 +{
2 + "name": "node-fetch",
3 + "version": "2.6.7",
4 + "description": "A light-weight module that brings window.fetch to node.js",
5 + "main": "lib/index.js",
6 + "browser": "./browser.js",
7 + "module": "lib/index.mjs",
8 + "files": [
9 + "lib/index.js",
10 + "lib/index.mjs",
11 + "lib/index.es.js",
12 + "browser.js"
13 + ],
14 + "engines": {
15 + "node": "4.x || >=6.0.0"
16 + },
17 + "scripts": {
18 + "build": "cross-env BABEL_ENV=rollup rollup -c",
19 + "prepare": "npm run build",
20 + "test": "cross-env BABEL_ENV=test mocha --require babel-register --throw-deprecation test/test.js",
21 + "report": "cross-env BABEL_ENV=coverage nyc --reporter lcov --reporter text mocha -R spec test/test.js",
22 + "coverage": "cross-env BABEL_ENV=coverage nyc --reporter json --reporter text mocha -R spec test/test.js && codecov -f coverage/coverage-final.json"
23 + },
24 + "repository": {
25 + "type": "git",
26 + "url": "https://github.com/bitinn/node-fetch.git"
27 + },
28 + "keywords": [
29 + "fetch",
30 + "http",
31 + "promise"
32 + ],
33 + "author": "David Frank",
34 + "license": "MIT",
35 + "bugs": {
36 + "url": "https://github.com/bitinn/node-fetch/issues"
37 + },
38 + "homepage": "https://github.com/bitinn/node-fetch",
39 + "dependencies": {
40 + "whatwg-url": "^5.0.0"
41 + },
42 + "peerDependencies": {
43 + "encoding": "^0.1.0"
44 + },
45 + "peerDependenciesMeta": {
46 + "encoding": {
47 + "optional": true
48 + }
49 + },
50 + "devDependencies": {
51 + "@ungap/url-search-params": "^0.1.2",
52 + "abort-controller": "^1.1.0",
53 + "abortcontroller-polyfill": "^1.3.0",
54 + "babel-core": "^6.26.3",
55 + "babel-plugin-istanbul": "^4.1.6",
56 + "babel-preset-env": "^1.6.1",
57 + "babel-register": "^6.16.3",
58 + "chai": "^3.5.0",
59 + "chai-as-promised": "^7.1.1",
60 + "chai-iterator": "^1.1.1",
61 + "chai-string": "~1.3.0",
62 + "codecov": "3.3.0",
63 + "cross-env": "^5.2.0",
64 + "form-data": "^2.3.3",
65 + "is-builtin-module": "^1.0.0",
66 + "mocha": "^5.0.0",
67 + "nyc": "11.9.0",
68 + "parted": "^0.1.1",
69 + "promise": "^8.0.3",
70 + "resumer": "0.0.0",
71 + "rollup": "^0.63.4",
72 + "rollup-plugin-babel": "^3.0.7",
73 + "string-to-arraybuffer": "^1.0.2",
74 + "teeny-request": "3.7.0"
75 + }
76 +}
1 +Copyright (c) 2013, Deoxxa Development
2 +======================================
3 +All rights reserved.
4 +--------------------
5 +
6 +Redistribution and use in source and binary forms, with or without
7 +modification, are permitted provided that the following conditions are met:
8 +1. Redistributions of source code must retain the above copyright
9 + notice, this list of conditions and the following disclaimer.
10 +2. Redistributions in binary form must reproduce the above copyright
11 + notice, this list of conditions and the following disclaimer in the
12 + documentation and/or other materials provided with the distribution.
13 +3. Neither the name of Deoxxa Development nor the names of its contributors
14 + may be used to endorse or promote products derived from this software
15 + without specific prior written permission.
16 +
17 +THIS SOFTWARE IS PROVIDED BY DEOXXA DEVELOPMENT ''AS IS'' AND ANY
18 +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19 +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20 +DISCLAIMED. IN NO EVENT SHALL DEOXXA DEVELOPMENT BE LIABLE FOR ANY
21 +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22 +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23 +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24 +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
26 +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
1 +# duplexer3 [![Build Status](https://travis-ci.org/floatdrop/duplexer3.svg?branch=master)](https://travis-ci.org/floatdrop/duplexer3) [![Coverage Status](https://coveralls.io/repos/floatdrop/duplexer3/badge.svg?branch=master&service=github)](https://coveralls.io/github/floatdrop/duplexer3?branch=master)
2 +
3 +Like [duplexer2](https://github.com/deoxxa/duplexer2) but using Streams3 without readable-stream dependency
4 +
5 +```javascript
6 +var stream = require("stream");
7 +
8 +var duplexer3 = require("duplexer3");
9 +
10 +var writable = new stream.Writable({objectMode: true}),
11 + readable = new stream.Readable({objectMode: true});
12 +
13 +writable._write = function _write(input, encoding, done) {
14 + if (readable.push(input)) {
15 + return done();
16 + } else {
17 + readable.once("drain", done);
18 + }
19 +};
20 +
21 +readable._read = function _read(n) {
22 + // no-op
23 +};
24 +
25 +// simulate the readable thing closing after a bit
26 +writable.once("finish", function() {
27 + setTimeout(function() {
28 + readable.push(null);
29 + }, 500);
30 +});
31 +
32 +var duplex = duplexer3(writable, readable);
33 +
34 +duplex.on("data", function(e) {
35 + console.log("got data", JSON.stringify(e));
36 +});
37 +
38 +duplex.on("finish", function() {
39 + console.log("got finish event");
40 +});
41 +
42 +duplex.on("end", function() {
43 + console.log("got end event");
44 +});
45 +
46 +duplex.write("oh, hi there", function() {
47 + console.log("finished writing");
48 +});
49 +
50 +duplex.end(function() {
51 + console.log("finished ending");
52 +});
53 +```
54 +
55 +```
56 +got data "oh, hi there"
57 +finished writing
58 +got finish event
59 +finished ending
60 +got end event
61 +```
62 +
63 +## Overview
64 +
65 +This is a reimplementation of [duplexer](https://www.npmjs.com/package/duplexer) using the
66 +Streams3 API which is standard in Node as of v4. Everything largely
67 +works the same.
68 +
69 +
70 +
71 +## Installation
72 +
73 +[Available via `npm`](https://docs.npmjs.com/cli/install):
74 +
75 +```
76 +$ npm i duplexer3
77 +```
78 +
79 +## API
80 +
81 +### duplexer3
82 +
83 +Creates a new `DuplexWrapper` object, which is the actual class that implements
84 +most of the fun stuff. All that fun stuff is hidden. DON'T LOOK.
85 +
86 +```javascript
87 +duplexer3([options], writable, readable)
88 +```
89 +
90 +```javascript
91 +const duplex = duplexer3(new stream.Writable(), new stream.Readable());
92 +```
93 +
94 +Arguments
95 +
96 +* __options__ - an object specifying the regular `stream.Duplex` options, as
97 + well as the properties described below.
98 +* __writable__ - a writable stream
99 +* __readable__ - a readable stream
100 +
101 +Options
102 +
103 +* __bubbleErrors__ - a boolean value that specifies whether to bubble errors
104 + from the underlying readable/writable streams. Default is `true`.
105 +
106 +
107 +## License
108 +
109 +3-clause BSD. [A copy](./LICENSE) is included with the source.
110 +
111 +## Contact
112 +
113 +* GitHub ([deoxxa](http://github.com/deoxxa))
114 +* Twitter ([@deoxxa](http://twitter.com/deoxxa))
115 +* Email ([deoxxa@fknsrs.biz](mailto:deoxxa@fknsrs.biz))
1 +"use strict";
2 +
3 +var stream = require("stream");
4 +
5 +function DuplexWrapper(options, writable, readable) {
6 + if (typeof readable === "undefined") {
7 + readable = writable;
8 + writable = options;
9 + options = null;
10 + }
11 +
12 + stream.Duplex.call(this, options);
13 +
14 + if (typeof readable.read !== "function") {
15 + readable = (new stream.Readable(options)).wrap(readable);
16 + }
17 +
18 + this._writable = writable;
19 + this._readable = readable;
20 + this._waiting = false;
21 +
22 + var self = this;
23 +
24 + writable.once("finish", function() {
25 + self.end();
26 + });
27 +
28 + this.once("finish", function() {
29 + writable.end();
30 + });
31 +
32 + readable.on("readable", function() {
33 + if (self._waiting) {
34 + self._waiting = false;
35 + self._read();
36 + }
37 + });
38 +
39 + readable.once("end", function() {
40 + self.push(null);
41 + });
42 +
43 + if (!options || typeof options.bubbleErrors === "undefined" || options.bubbleErrors) {
44 + writable.on("error", function(err) {
45 + self.emit("error", err);
46 + });
47 +
48 + readable.on("error", function(err) {
49 + self.emit("error", err);
50 + });
51 + }
52 +}
53 +
54 +DuplexWrapper.prototype = Object.create(stream.Duplex.prototype, {constructor: {value: DuplexWrapper}});
55 +
56 +DuplexWrapper.prototype._write = function _write(input, encoding, done) {
57 + this._writable.write(input, encoding, done);
58 +};
59 +
60 +DuplexWrapper.prototype._read = function _read() {
61 + var buf;
62 + var reads = 0;
63 + while ((buf = this._readable.read()) !== null) {
64 + this.push(buf);
65 + reads++;
66 + }
67 + if (reads === 0) {
68 + this._waiting = true;
69 + }
70 +};
71 +
72 +module.exports = function duplex2(options, writable, readable) {
73 + return new DuplexWrapper(options, writable, readable);
74 +};
75 +
76 +module.exports.DuplexWrapper = DuplexWrapper;
1 +{
2 + "name": "duplexer3",
3 + "version": "0.1.4",
4 + "description": "Like duplexer but using streams3",
5 + "engine": {
6 + "node": ">=4"
7 + },
8 + "files": [
9 + "index.js"
10 + ],
11 + "scripts": {
12 + "test": "mocha -R tap"
13 + },
14 + "repository": "floatdrop/duplexer3",
15 + "keywords": [
16 + "duplex",
17 + "duplexer",
18 + "stream",
19 + "stream3",
20 + "join",
21 + "combine"
22 + ],
23 + "author": "Conrad Pankoff <deoxxa@fknsrs.biz> (http://www.fknsrs.biz/)",
24 + "license": "BSD-3-Clause",
25 + "devDependencies": {
26 + "mocha": "^2.2.5"
27 + }
28 +}
1 +The MIT License (MIT)
2 +
3 +Copyright (c) 2014 Arnout Kazemier
4 +
5 +Permission is hereby granted, free of charge, to any person obtaining a copy
6 +of this software and associated documentation files (the "Software"), to deal
7 +in the Software without restriction, including without limitation the rights
8 +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 +copies of the Software, and to permit persons to whom the Software is
10 +furnished to do so, subject to the following conditions:
11 +
12 +The above copyright notice and this permission notice shall be included in all
13 +copies or substantial portions of the Software.
14 +
15 +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 +SOFTWARE.
1 +# EventEmitter3
2 +
3 +[![Version npm](https://img.shields.io/npm/v/eventemitter3.svg?style=flat-square)](http://browsenpm.org/package/eventemitter3)[![Build Status](https://img.shields.io/travis/primus/eventemitter3/master.svg?style=flat-square)](https://travis-ci.org/primus/eventemitter3)[![Dependencies](https://img.shields.io/david/primus/eventemitter3.svg?style=flat-square)](https://david-dm.org/primus/eventemitter3)[![Coverage Status](https://img.shields.io/coveralls/primus/eventemitter3/master.svg?style=flat-square)](https://coveralls.io/r/primus/eventemitter3?branch=master)[![IRC channel](https://img.shields.io/badge/IRC-irc.freenode.net%23primus-00a8ff.svg?style=flat-square)](https://webchat.freenode.net/?channels=primus)
4 +
5 +[![Sauce Test Status](https://saucelabs.com/browser-matrix/eventemitter3.svg)](https://saucelabs.com/u/eventemitter3)
6 +
7 +EventEmitter3 is a high performance EventEmitter. It has been micro-optimized
8 +for various of code paths making this, one of, if not the fastest EventEmitter
9 +available for Node.js and browsers. The module is API compatible with the
10 +EventEmitter that ships by default with Node.js but there are some slight
11 +differences:
12 +
13 +- Domain support has been removed.
14 +- We do not `throw` an error when you emit an `error` event and nobody is
15 + listening.
16 +- The `newListener` event is removed as the use-cases for this functionality are
17 + really just edge cases.
18 +- No `setMaxListeners` and it's pointless memory leak warnings. If you want to
19 + add `end` listeners you should be able to do that without modules complaining.
20 +- No `listenerCount` function. Use `EE.listeners(event).length` instead.
21 +- Support for custom context for events so there is no need to use `fn.bind`.
22 +- `listeners` method can do existence checking instead of returning only arrays.
23 +
24 +It's a drop in replacement for existing EventEmitters, but just faster. Free
25 +performance, who wouldn't want that? The EventEmitter is written in EcmaScript 3
26 +so it will work in the oldest browsers and node versions that you need to
27 +support.
28 +
29 +## Installation
30 +
31 +```bash
32 +$ npm install --save eventemitter3 # npm
33 +$ component install primus/eventemitter3 # Component
34 +$ bower install eventemitter3 # Bower
35 +```
36 +
37 +## Usage
38 +
39 +After installation the only thing you need to do is require the module:
40 +
41 +```js
42 +var EventEmitter = require('eventemitter3');
43 +```
44 +
45 +And you're ready to create your own EventEmitter instances. For the API
46 +documentation, please follow the official Node.js documentation:
47 +
48 +http://nodejs.org/api/events.html
49 +
50 +### Contextual emits
51 +
52 +We've upgraded the API of the `EventEmitter.on`, `EventEmitter.once` and
53 +`EventEmitter.removeListener` to accept an extra argument which is the `context`
54 +or `this` value that should be set for the emitted events. This means you no
55 +longer have the overhead of an event that required `fn.bind` in order to get a
56 +custom `this` value.
57 +
58 +```js
59 +var EE = new EventEmitter()
60 + , context = { foo: 'bar' };
61 +
62 +function emitted() {
63 + console.log(this === context); // true
64 +}
65 +
66 +EE.once('event-name', emitted, context);
67 +EE.on('another-event', emitted, context);
68 +EE.removeListener('another-event', emitted, context);
69 +```
70 +
71 +### Existence
72 +
73 +To check if there is already a listener for a given event you can supply the
74 +`listeners` method with an extra boolean argument. This will transform the
75 +output from an array, to a boolean value which indicates if there are listeners
76 +in place for the given event:
77 +
78 +```js
79 +var EE = new EventEmitter();
80 +EE.once('event-name', function () {});
81 +EE.on('another-event', function () {});
82 +
83 +EE.listeners('event-name', true); // returns true
84 +EE.listeners('unknown-name', true); // returns false
85 +```
86 +
87 +## License
88 +
89 +[MIT](LICENSE)
1 +'use strict';
2 +
3 +var has = Object.prototype.hasOwnProperty;
4 +
5 +//
6 +// We store our EE objects in a plain object whose properties are event names.
7 +// If `Object.create(null)` is not supported we prefix the event names with a
8 +// `~` to make sure that the built-in object properties are not overridden or
9 +// used as an attack vector.
10 +// We also assume that `Object.create(null)` is available when the event name
11 +// is an ES6 Symbol.
12 +//
13 +var prefix = typeof Object.create !== 'function' ? '~' : false;
14 +
15 +/**
16 + * Representation of a single EventEmitter function.
17 + *
18 + * @param {Function} fn Event handler to be called.
19 + * @param {Mixed} context Context for function execution.
20 + * @param {Boolean} [once=false] Only emit once
21 + * @api private
22 + */
23 +function EE(fn, context, once) {
24 + this.fn = fn;
25 + this.context = context;
26 + this.once = once || false;
27 +}
28 +
29 +/**
30 + * Minimal EventEmitter interface that is molded against the Node.js
31 + * EventEmitter interface.
32 + *
33 + * @constructor
34 + * @api public
35 + */
36 +function EventEmitter() { /* Nothing to set */ }
37 +
38 +/**
39 + * Hold the assigned EventEmitters by name.
40 + *
41 + * @type {Object}
42 + * @private
43 + */
44 +EventEmitter.prototype._events = undefined;
45 +
46 +/**
47 + * Return an array listing the events for which the emitter has registered
48 + * listeners.
49 + *
50 + * @returns {Array}
51 + * @api public
52 + */
53 +EventEmitter.prototype.eventNames = function eventNames() {
54 + var events = this._events
55 + , names = []
56 + , name;
57 +
58 + if (!events) return names;
59 +
60 + for (name in events) {
61 + if (has.call(events, name)) names.push(prefix ? name.slice(1) : name);
62 + }
63 +
64 + if (Object.getOwnPropertySymbols) {
65 + return names.concat(Object.getOwnPropertySymbols(events));
66 + }
67 +
68 + return names;
69 +};
70 +
71 +/**
72 + * Return a list of assigned event listeners.
73 + *
74 + * @param {String} event The events that should be listed.
75 + * @param {Boolean} exists We only need to know if there are listeners.
76 + * @returns {Array|Boolean}
77 + * @api public
78 + */
79 +EventEmitter.prototype.listeners = function listeners(event, exists) {
80 + var evt = prefix ? prefix + event : event
81 + , available = this._events && this._events[evt];
82 +
83 + if (exists) return !!available;
84 + if (!available) return [];
85 + if (available.fn) return [available.fn];
86 +
87 + for (var i = 0, l = available.length, ee = new Array(l); i < l; i++) {
88 + ee[i] = available[i].fn;
89 + }
90 +
91 + return ee;
92 +};
93 +
94 +/**
95 + * Emit an event to all registered event listeners.
96 + *
97 + * @param {String} event The name of the event.
98 + * @returns {Boolean} Indication if we've emitted an event.
99 + * @api public
100 + */
101 +EventEmitter.prototype.emit = function emit(event, a1, a2, a3, a4, a5) {
102 + var evt = prefix ? prefix + event : event;
103 +
104 + if (!this._events || !this._events[evt]) return false;
105 +
106 + var listeners = this._events[evt]
107 + , len = arguments.length
108 + , args
109 + , i;
110 +
111 + if ('function' === typeof listeners.fn) {
112 + if (listeners.once) this.removeListener(event, listeners.fn, undefined, true);
113 +
114 + switch (len) {
115 + case 1: return listeners.fn.call(listeners.context), true;
116 + case 2: return listeners.fn.call(listeners.context, a1), true;
117 + case 3: return listeners.fn.call(listeners.context, a1, a2), true;
118 + case 4: return listeners.fn.call(listeners.context, a1, a2, a3), true;
119 + case 5: return listeners.fn.call(listeners.context, a1, a2, a3, a4), true;
120 + case 6: return listeners.fn.call(listeners.context, a1, a2, a3, a4, a5), true;
121 + }
122 +
123 + for (i = 1, args = new Array(len -1); i < len; i++) {
124 + args[i - 1] = arguments[i];
125 + }
126 +
127 + listeners.fn.apply(listeners.context, args);
128 + } else {
129 + var length = listeners.length
130 + , j;
131 +
132 + for (i = 0; i < length; i++) {
133 + if (listeners[i].once) this.removeListener(event, listeners[i].fn, undefined, true);
134 +
135 + switch (len) {
136 + case 1: listeners[i].fn.call(listeners[i].context); break;
137 + case 2: listeners[i].fn.call(listeners[i].context, a1); break;
138 + case 3: listeners[i].fn.call(listeners[i].context, a1, a2); break;
139 + default:
140 + if (!args) for (j = 1, args = new Array(len -1); j < len; j++) {
141 + args[j - 1] = arguments[j];
142 + }
143 +
144 + listeners[i].fn.apply(listeners[i].context, args);
145 + }
146 + }
147 + }
148 +
149 + return true;
150 +};
151 +
152 +/**
153 + * Register a new EventListener for the given event.
154 + *
155 + * @param {String} event Name of the event.
156 + * @param {Function} fn Callback function.
157 + * @param {Mixed} [context=this] The context of the function.
158 + * @api public
159 + */
160 +EventEmitter.prototype.on = function on(event, fn, context) {
161 + var listener = new EE(fn, context || this)
162 + , evt = prefix ? prefix + event : event;
163 +
164 + if (!this._events) this._events = prefix ? {} : Object.create(null);
165 + if (!this._events[evt]) this._events[evt] = listener;
166 + else {
167 + if (!this._events[evt].fn) this._events[evt].push(listener);
168 + else this._events[evt] = [
169 + this._events[evt], listener
170 + ];
171 + }
172 +
173 + return this;
174 +};
175 +
176 +/**
177 + * Add an EventListener that's only called once.
178 + *
179 + * @param {String} event Name of the event.
180 + * @param {Function} fn Callback function.
181 + * @param {Mixed} [context=this] The context of the function.
182 + * @api public
183 + */
184 +EventEmitter.prototype.once = function once(event, fn, context) {
185 + var listener = new EE(fn, context || this, true)
186 + , evt = prefix ? prefix + event : event;
187 +
188 + if (!this._events) this._events = prefix ? {} : Object.create(null);
189 + if (!this._events[evt]) this._events[evt] = listener;
190 + else {
191 + if (!this._events[evt].fn) this._events[evt].push(listener);
192 + else this._events[evt] = [
193 + this._events[evt], listener
194 + ];
195 + }
196 +
197 + return this;
198 +};
199 +
200 +/**
201 + * Remove event listeners.
202 + *
203 + * @param {String} event The event we want to remove.
204 + * @param {Function} fn The listener that we need to find.
205 + * @param {Mixed} context Only remove listeners matching this context.
206 + * @param {Boolean} once Only remove once listeners.
207 + * @api public
208 + */
209 +EventEmitter.prototype.removeListener = function removeListener(event, fn, context, once) {
210 + var evt = prefix ? prefix + event : event;
211 +
212 + if (!this._events || !this._events[evt]) return this;
213 +
214 + var listeners = this._events[evt]
215 + , events = [];
216 +
217 + if (fn) {
218 + if (listeners.fn) {
219 + if (
220 + listeners.fn !== fn
221 + || (once && !listeners.once)
222 + || (context && listeners.context !== context)
223 + ) {
224 + events.push(listeners);
225 + }
226 + } else {
227 + for (var i = 0, length = listeners.length; i < length; i++) {
228 + if (
229 + listeners[i].fn !== fn
230 + || (once && !listeners[i].once)
231 + || (context && listeners[i].context !== context)
232 + ) {
233 + events.push(listeners[i]);
234 + }
235 + }
236 + }
237 + }
238 +
239 + //
240 + // Reset the array, or remove it completely if we have no more listeners.
241 + //
242 + if (events.length) {
243 + this._events[evt] = events.length === 1 ? events[0] : events;
244 + } else {
245 + delete this._events[evt];
246 + }
247 +
248 + return this;
249 +};
250 +
251 +/**
252 + * Remove all listeners or only the listeners for the specified event.
253 + *
254 + * @param {String} event The event want to remove all listeners for.
255 + * @api public
256 + */
257 +EventEmitter.prototype.removeAllListeners = function removeAllListeners(event) {
258 + if (!this._events) return this;
259 +
260 + if (event) delete this._events[prefix ? prefix + event : event];
261 + else this._events = prefix ? {} : Object.create(null);
262 +
263 + return this;
264 +};
265 +
266 +//
267 +// Alias methods names because people roll like that.
268 +//
269 +EventEmitter.prototype.off = EventEmitter.prototype.removeListener;
270 +EventEmitter.prototype.addListener = EventEmitter.prototype.on;
271 +
272 +//
273 +// This function doesn't apply anymore.
274 +//
275 +EventEmitter.prototype.setMaxListeners = function setMaxListeners() {
276 + return this;
277 +};
278 +
279 +//
280 +// Expose the prefix.
281 +//
282 +EventEmitter.prefixed = prefix;
283 +
284 +//
285 +// Expose the module.
286 +//
287 +if ('undefined' !== typeof module) {
288 + module.exports = EventEmitter;
289 +}
1 +{
2 + "name": "eventemitter3",
3 + "version": "1.2.0",
4 + "description": "EventEmitter3 focuses on performance while maintaining a Node.js AND browser compatible interface.",
5 + "main": "index.js",
6 + "scripts": {
7 + "test-node": "istanbul cover _mocha --report lcovonly -- test.js",
8 + "coverage": "istanbul cover _mocha -- test.js",
9 + "test-browser": "zuul -- test.js",
10 + "sync": "node versions.js",
11 + "test": "mocha test.js"
12 + },
13 + "repository": {
14 + "type": "git",
15 + "url": "git://github.com/primus/eventemitter3.git"
16 + },
17 + "keywords": [
18 + "EventEmitter",
19 + "EventEmitter2",
20 + "EventEmitter3",
21 + "Events",
22 + "addEventListener",
23 + "addListener",
24 + "emit",
25 + "emits",
26 + "emitter",
27 + "event",
28 + "once",
29 + "pub/sub",
30 + "publish",
31 + "reactor",
32 + "subscribe"
33 + ],
34 + "author": "Arnout Kazemier",
35 + "license": "MIT",
36 + "bugs": {
37 + "url": "https://github.com/primus/eventemitter3/issues"
38 + },
39 + "pre-commit": "sync, test",
40 + "devDependencies": {
41 + "assume": "1.3.x",
42 + "istanbul": "0.4.x",
43 + "mocha": "2.4.x",
44 + "pre-commit": "1.1.x",
45 + "zuul": "3.10.x"
46 + }
47 +}
1 +'use strict';
2 +const PassThrough = require('stream').PassThrough;
3 +
4 +module.exports = opts => {
5 + opts = Object.assign({}, opts);
6 +
7 + const array = opts.array;
8 + let encoding = opts.encoding;
9 + const buffer = encoding === 'buffer';
10 + let objectMode = false;
11 +
12 + if (array) {
13 + objectMode = !(encoding || buffer);
14 + } else {
15 + encoding = encoding || 'utf8';
16 + }
17 +
18 + if (buffer) {
19 + encoding = null;
20 + }
21 +
22 + let len = 0;
23 + const ret = [];
24 + const stream = new PassThrough({objectMode});
25 +
26 + if (encoding) {
27 + stream.setEncoding(encoding);
28 + }
29 +
30 + stream.on('data', chunk => {
31 + ret.push(chunk);
32 +
33 + if (objectMode) {
34 + len = ret.length;
35 + } else {
36 + len += chunk.length;
37 + }
38 + });
39 +
40 + stream.getBufferedValue = () => {
41 + if (array) {
42 + return ret;
43 + }
44 +
45 + return buffer ? Buffer.concat(ret, len) : ret.join('');
46 + };
47 +
48 + stream.getBufferedLength = () => len;
49 +
50 + return stream;
51 +};
1 +'use strict';
2 +const bufferStream = require('./buffer-stream');
3 +
4 +function getStream(inputStream, opts) {
5 + if (!inputStream) {
6 + return Promise.reject(new Error('Expected a stream'));
7 + }
8 +
9 + opts = Object.assign({maxBuffer: Infinity}, opts);
10 +
11 + const maxBuffer = opts.maxBuffer;
12 + let stream;
13 + let clean;
14 +
15 + const p = new Promise((resolve, reject) => {
16 + const error = err => {
17 + if (err) { // null check
18 + err.bufferedData = stream.getBufferedValue();
19 + }
20 +
21 + reject(err);
22 + };
23 +
24 + stream = bufferStream(opts);
25 + inputStream.once('error', error);
26 + inputStream.pipe(stream);
27 +
28 + stream.on('data', () => {
29 + if (stream.getBufferedLength() > maxBuffer) {
30 + reject(new Error('maxBuffer exceeded'));
31 + }
32 + });
33 + stream.once('error', error);
34 + stream.on('end', resolve);
35 +
36 + clean = () => {
37 + // some streams doesn't implement the `stream.Readable` interface correctly
38 + if (inputStream.unpipe) {
39 + inputStream.unpipe(stream);
40 + }
41 + };
42 + });
43 +
44 + p.then(clean, clean);
45 +
46 + return p.then(() => stream.getBufferedValue());
47 +}
48 +
49 +module.exports = getStream;
50 +module.exports.buffer = (stream, opts) => getStream(stream, Object.assign({}, opts, {encoding: 'buffer'}));
51 +module.exports.array = (stream, opts) => getStream(stream, Object.assign({}, opts, {array: true}));
1 +The MIT License (MIT)
2 +
3 +Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (sindresorhus.com)
4 +
5 +Permission is hereby granted, free of charge, to any person obtaining a copy
6 +of this software and associated documentation files (the "Software"), to deal
7 +in the Software without restriction, including without limitation the rights
8 +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 +copies of the Software, and to permit persons to whom the Software is
10 +furnished to do so, subject to the following conditions:
11 +
12 +The above copyright notice and this permission notice shall be included in
13 +all copies or substantial portions of the Software.
14 +
15 +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 +THE SOFTWARE.
1 +{
2 + "name": "get-stream",
3 + "version": "3.0.0",
4 + "description": "Get a stream as a string, buffer, or array",
5 + "license": "MIT",
6 + "repository": "sindresorhus/get-stream",
7 + "author": {
8 + "name": "Sindre Sorhus",
9 + "email": "sindresorhus@gmail.com",
10 + "url": "sindresorhus.com"
11 + },
12 + "engines": {
13 + "node": ">=4"
14 + },
15 + "scripts": {
16 + "test": "xo && ava"
17 + },
18 + "files": [
19 + "index.js",
20 + "buffer-stream.js"
21 + ],
22 + "keywords": [
23 + "get",
24 + "stream",
25 + "promise",
26 + "concat",
27 + "string",
28 + "str",
29 + "text",
30 + "buffer",
31 + "read",
32 + "data",
33 + "consume",
34 + "readable",
35 + "readablestream",
36 + "array",
37 + "object",
38 + "obj"
39 + ],
40 + "devDependencies": {
41 + "ava": "*",
42 + "into-stream": "^3.0.0",
43 + "xo": "*"
44 + },
45 + "xo": {
46 + "esnext": true
47 + }
48 +}
1 +# get-stream [![Build Status](https://travis-ci.org/sindresorhus/get-stream.svg?branch=master)](https://travis-ci.org/sindresorhus/get-stream)
2 +
3 +> Get a stream as a string, buffer, or array
4 +
5 +
6 +## Install
7 +
8 +```
9 +$ npm install --save get-stream
10 +```
11 +
12 +
13 +## Usage
14 +
15 +```js
16 +const fs = require('fs');
17 +const getStream = require('get-stream');
18 +const stream = fs.createReadStream('unicorn.txt');
19 +
20 +getStream(stream).then(str => {
21 + console.log(str);
22 + /*
23 + ,,))))))));,
24 + __)))))))))))))),
25 + \|/ -\(((((''''((((((((.
26 + -*-==//////(('' . `)))))),
27 + /|\ ))| o ;-. '((((( ,(,
28 + ( `| / ) ;))))' ,_))^;(~
29 + | | | ,))((((_ _____------~~~-. %,;(;(>';'~
30 + o_); ; )))(((` ~---~ `:: \ %%~~)(v;(`('~
31 + ; ''''```` `: `:::|\,__,%% );`'; ~
32 + | _ ) / `:|`----' `-'
33 + ______/\/~ | / /
34 + /~;;.____/;;' / ___--,-( `;;;/
35 + / // _;______;'------~~~~~ /;;/\ /
36 + // | | / ; \;;,\
37 + (<_ | ; /',/-----' _>
38 + \_| ||_ //~;~~~~~~~~~
39 + `\_| (,~~
40 + \~\
41 + ~~
42 + */
43 +});
44 +```
45 +
46 +
47 +## API
48 +
49 +The methods returns a promise that resolves when the `end` event fires on the stream, indicating that there is no more data to be read. The stream is switched to flowing mode.
50 +
51 +### getStream(stream, [options])
52 +
53 +Get the `stream` as a string.
54 +
55 +#### options
56 +
57 +##### encoding
58 +
59 +Type: `string`<br>
60 +Default: `utf8`
61 +
62 +[Encoding](https://nodejs.org/api/buffer.html#buffer_buffer) of the incoming stream.
63 +
64 +##### maxBuffer
65 +
66 +Type: `number`<br>
67 +Default: `Infinity`
68 +
69 +Maximum length of the returned string. If it exceeds this value before the stream ends, the promise will be rejected.
70 +
71 +### getStream.buffer(stream, [options])
72 +
73 +Get the `stream` as a buffer.
74 +
75 +It honors the `maxBuffer` option as above, but it refers to byte length rather than string length.
76 +
77 +### getStream.array(stream, [options])
78 +
79 +Get the `stream` as an array of values.
80 +
81 +It honors both the `maxBuffer` and `encoding` options. The behavior changes slightly based on the encoding chosen:
82 +
83 +- When `encoding` is unset, it assumes an [object mode stream](https://nodesource.com/blog/understanding-object-streams/) and collects values emitted from `stream` unmodified. In this case `maxBuffer` refers to the number of items in the array (not the sum of their sizes).
84 +
85 +- When `encoding` is set to `buffer`, it collects an array of buffers. `maxBuffer` refers to the summed byte lengths of every buffer in the array.
86 +
87 +- When `encoding` is set to anything else, it collects an array of strings. `maxBuffer` refers to the summed character lengths of every string in the array.
88 +
89 +
90 +## Errors
91 +
92 +If the input stream emits an `error` event, the promise will be rejected with the error. The buffered data will be attached to the `bufferedData` property of the error.
93 +
94 +```js
95 +getStream(streamThatErrorsAtTheEnd('unicorn'))
96 + .catch(err => {
97 + console.log(err.bufferedData);
98 + //=> 'unicorn'
99 + });
100 +```
101 +
102 +
103 +## FAQ
104 +
105 +### How is this different from [`concat-stream`](https://github.com/maxogden/concat-stream)?
106 +
107 +This module accepts a stream instead of being one and returns a promise instead of using a callback. The API is simpler and it only supports returning a string, buffer, or array. It doesn't have a fragile type inference. You explicitly choose what you want. And it doesn't depend on the huge `readable-stream` package.
108 +
109 +
110 +## Related
111 +
112 +- [get-stdin](https://github.com/sindresorhus/get-stdin) - Get stdin as a string or buffer
113 +
114 +
115 +## License
116 +
117 +MIT © [Sindre Sorhus](https://sindresorhus.com)
1 +'use strict';
2 +const EventEmitter = require('events');
3 +const http = require('http');
4 +const https = require('https');
5 +const PassThrough = require('stream').PassThrough;
6 +const urlLib = require('url');
7 +const querystring = require('querystring');
8 +const duplexer3 = require('duplexer3');
9 +const isStream = require('is-stream');
10 +const getStream = require('get-stream');
11 +const timedOut = require('timed-out');
12 +const urlParseLax = require('url-parse-lax');
13 +const lowercaseKeys = require('lowercase-keys');
14 +const isRedirect = require('is-redirect');
15 +const unzipResponse = require('unzip-response');
16 +const createErrorClass = require('create-error-class');
17 +const isRetryAllowed = require('is-retry-allowed');
18 +const Buffer = require('safe-buffer').Buffer;
19 +const pkg = require('./package');
20 +
21 +function requestAsEventEmitter(opts) {
22 + opts = opts || {};
23 +
24 + const ee = new EventEmitter();
25 + const requestUrl = opts.href || urlLib.resolve(urlLib.format(opts), opts.path);
26 + let redirectCount = 0;
27 + let retryCount = 0;
28 + let redirectUrl;
29 +
30 + const get = opts => {
31 + const fn = opts.protocol === 'https:' ? https : http;
32 +
33 + const req = fn.request(opts, res => {
34 + const statusCode = res.statusCode;
35 +
36 + if (isRedirect(statusCode) && opts.followRedirect && 'location' in res.headers && (opts.method === 'GET' || opts.method === 'HEAD')) {
37 + res.resume();
38 +
39 + if (++redirectCount > 10) {
40 + ee.emit('error', new got.MaxRedirectsError(statusCode, opts), null, res);
41 + return;
42 + }
43 +
44 + const bufferString = Buffer.from(res.headers.location, 'binary').toString();
45 +
46 + redirectUrl = urlLib.resolve(urlLib.format(opts), bufferString);
47 + const redirectOpts = Object.assign({}, opts, urlLib.parse(redirectUrl));
48 +
49 + ee.emit('redirect', res, redirectOpts);
50 +
51 + get(redirectOpts);
52 +
53 + return;
54 + }
55 +
56 + setImmediate(() => {
57 + const response = typeof unzipResponse === 'function' && req.method !== 'HEAD' ? unzipResponse(res) : res;
58 + response.url = redirectUrl || requestUrl;
59 + response.requestUrl = requestUrl;
60 +
61 + ee.emit('response', response);
62 + });
63 + });
64 +
65 + req.once('error', err => {
66 + const backoff = opts.retries(++retryCount, err);
67 +
68 + if (backoff) {
69 + setTimeout(get, backoff, opts);
70 + return;
71 + }
72 +
73 + ee.emit('error', new got.RequestError(err, opts));
74 + });
75 +
76 + if (opts.gotTimeout) {
77 + timedOut(req, opts.gotTimeout);
78 + }
79 +
80 + setImmediate(() => {
81 + ee.emit('request', req);
82 + });
83 + };
84 +
85 + get(opts);
86 + return ee;
87 +}
88 +
89 +function asPromise(opts) {
90 + return new Promise((resolve, reject) => {
91 + const ee = requestAsEventEmitter(opts);
92 +
93 + ee.on('request', req => {
94 + if (isStream(opts.body)) {
95 + opts.body.pipe(req);
96 + opts.body = undefined;
97 + return;
98 + }
99 +
100 + req.end(opts.body);
101 + });
102 +
103 + ee.on('response', res => {
104 + const stream = opts.encoding === null ? getStream.buffer(res) : getStream(res, opts);
105 +
106 + stream
107 + .catch(err => reject(new got.ReadError(err, opts)))
108 + .then(data => {
109 + const statusCode = res.statusCode;
110 + const limitStatusCode = opts.followRedirect ? 299 : 399;
111 +
112 + res.body = data;
113 +
114 + if (opts.json && res.body) {
115 + try {
116 + res.body = JSON.parse(res.body);
117 + } catch (e) {
118 + throw new got.ParseError(e, statusCode, opts, data);
119 + }
120 + }
121 +
122 + if (statusCode < 200 || statusCode > limitStatusCode) {
123 + throw new got.HTTPError(statusCode, opts);
124 + }
125 +
126 + resolve(res);
127 + })
128 + .catch(err => {
129 + Object.defineProperty(err, 'response', {value: res});
130 + reject(err);
131 + });
132 + });
133 +
134 + ee.on('error', reject);
135 + });
136 +}
137 +
138 +function asStream(opts) {
139 + const input = new PassThrough();
140 + const output = new PassThrough();
141 + const proxy = duplexer3(input, output);
142 +
143 + if (opts.json) {
144 + throw new Error('got can not be used as stream when options.json is used');
145 + }
146 +
147 + if (opts.body) {
148 + proxy.write = () => {
149 + throw new Error('got\'s stream is not writable when options.body is used');
150 + };
151 + }
152 +
153 + const ee = requestAsEventEmitter(opts);
154 +
155 + ee.on('request', req => {
156 + proxy.emit('request', req);
157 +
158 + if (isStream(opts.body)) {
159 + opts.body.pipe(req);
160 + return;
161 + }
162 +
163 + if (opts.body) {
164 + req.end(opts.body);
165 + return;
166 + }
167 +
168 + if (opts.method === 'POST' || opts.method === 'PUT' || opts.method === 'PATCH') {
169 + input.pipe(req);
170 + return;
171 + }
172 +
173 + req.end();
174 + });
175 +
176 + ee.on('response', res => {
177 + const statusCode = res.statusCode;
178 +
179 + res.pipe(output);
180 +
181 + if (statusCode < 200 || statusCode > 299) {
182 + proxy.emit('error', new got.HTTPError(statusCode, opts), null, res);
183 + return;
184 + }
185 +
186 + proxy.emit('response', res);
187 + });
188 +
189 + ee.on('redirect', proxy.emit.bind(proxy, 'redirect'));
190 + ee.on('error', proxy.emit.bind(proxy, 'error'));
191 +
192 + return proxy;
193 +}
194 +
195 +function normalizeArguments(url, opts) {
196 + if (typeof url !== 'string' && typeof url !== 'object') {
197 + throw new Error(`Parameter \`url\` must be a string or object, not ${typeof url}`);
198 + }
199 +
200 + if (typeof url === 'string') {
201 + url = url.replace(/^unix:/, 'http://$&');
202 + url = urlParseLax(url);
203 +
204 + if (url.auth) {
205 + throw new Error('Basic authentication must be done with auth option');
206 + }
207 + }
208 +
209 + opts = Object.assign(
210 + {
211 + protocol: 'http:',
212 + path: '',
213 + retries: 5
214 + },
215 + url,
216 + opts
217 + );
218 +
219 + opts.headers = Object.assign({
220 + 'user-agent': `${pkg.name}/${pkg.version} (https://github.com/sindresorhus/got)`,
221 + 'accept-encoding': 'gzip,deflate'
222 + }, lowercaseKeys(opts.headers));
223 +
224 + const query = opts.query;
225 +
226 + if (query) {
227 + if (typeof query !== 'string') {
228 + opts.query = querystring.stringify(query);
229 + }
230 +
231 + opts.path = `${opts.path.split('?')[0]}?${opts.query}`;
232 + delete opts.query;
233 + }
234 +
235 + if (opts.json && opts.headers.accept === undefined) {
236 + opts.headers.accept = 'application/json';
237 + }
238 +
239 + let body = opts.body;
240 +
241 + if (body) {
242 + if (typeof body !== 'string' && !(body !== null && typeof body === 'object')) {
243 + throw new Error('options.body must be a ReadableStream, string, Buffer or plain Object');
244 + }
245 +
246 + opts.method = opts.method || 'POST';
247 +
248 + if (isStream(body) && typeof body.getBoundary === 'function') {
249 + // Special case for https://github.com/form-data/form-data
250 + opts.headers['content-type'] = opts.headers['content-type'] || `multipart/form-data; boundary=${body.getBoundary()}`;
251 + } else if (body !== null && typeof body === 'object' && !Buffer.isBuffer(body) && !isStream(body)) {
252 + opts.headers['content-type'] = opts.headers['content-type'] || 'application/x-www-form-urlencoded';
253 + body = opts.body = querystring.stringify(body);
254 + }
255 +
256 + if (opts.headers['content-length'] === undefined && opts.headers['transfer-encoding'] === undefined && !isStream(body)) {
257 + const length = typeof body === 'string' ? Buffer.byteLength(body) : body.length;
258 + opts.headers['content-length'] = length;
259 + }
260 + }
261 +
262 + opts.method = (opts.method || 'GET').toUpperCase();
263 +
264 + if (opts.hostname === 'unix') {
265 + const matches = /(.+):(.+)/.exec(opts.path);
266 +
267 + if (matches) {
268 + opts.socketPath = matches[1];
269 + opts.path = matches[2];
270 + opts.host = null;
271 + }
272 + }
273 +
274 + if (typeof opts.retries !== 'function') {
275 + const retries = opts.retries;
276 +
277 + opts.retries = (iter, err) => {
278 + if (iter > retries || !isRetryAllowed(err)) {
279 + return 0;
280 + }
281 +
282 + const noise = Math.random() * 100;
283 +
284 + return ((1 << iter) * 1000) + noise;
285 + };
286 + }
287 +
288 + if (opts.followRedirect === undefined) {
289 + opts.followRedirect = true;
290 + }
291 +
292 + if (opts.timeout) {
293 + opts.gotTimeout = opts.timeout;
294 + delete opts.timeout;
295 + }
296 +
297 + return opts;
298 +}
299 +
300 +function got(url, opts) {
301 + try {
302 + return asPromise(normalizeArguments(url, opts));
303 + } catch (err) {
304 + return Promise.reject(err);
305 + }
306 +}
307 +
308 +const helpers = [
309 + 'get',
310 + 'post',
311 + 'put',
312 + 'patch',
313 + 'head',
314 + 'delete'
315 +];
316 +
317 +helpers.forEach(el => {
318 + got[el] = (url, opts) => got(url, Object.assign({}, opts, {method: el}));
319 +});
320 +
321 +got.stream = (url, opts) => asStream(normalizeArguments(url, opts));
322 +
323 +for (const el of helpers) {
324 + got.stream[el] = (url, opts) => got.stream(url, Object.assign({}, opts, {method: el}));
325 +}
326 +
327 +function stdError(error, opts) {
328 + if (error.code !== undefined) {
329 + this.code = error.code;
330 + }
331 +
332 + Object.assign(this, {
333 + message: error.message,
334 + host: opts.host,
335 + hostname: opts.hostname,
336 + method: opts.method,
337 + path: opts.path
338 + });
339 +}
340 +
341 +got.RequestError = createErrorClass('RequestError', stdError);
342 +got.ReadError = createErrorClass('ReadError', stdError);
343 +got.ParseError = createErrorClass('ParseError', function (e, statusCode, opts, data) {
344 + stdError.call(this, e, opts);
345 + this.statusCode = statusCode;
346 + this.statusMessage = http.STATUS_CODES[this.statusCode];
347 + this.message = `${e.message} in "${urlLib.format(opts)}": \n${data.slice(0, 77)}...`;
348 +});
349 +
350 +got.HTTPError = createErrorClass('HTTPError', function (statusCode, opts) {
351 + stdError.call(this, {}, opts);
352 + this.statusCode = statusCode;
353 + this.statusMessage = http.STATUS_CODES[this.statusCode];
354 + this.message = `Response code ${this.statusCode} (${this.statusMessage})`;
355 +});
356 +
357 +got.MaxRedirectsError = createErrorClass('MaxRedirectsError', function (statusCode, opts) {
358 + stdError.call(this, {}, opts);
359 + this.statusCode = statusCode;
360 + this.statusMessage = http.STATUS_CODES[this.statusCode];
361 + this.message = 'Redirected 10 times. Aborting.';
362 +});
363 +
364 +module.exports = got;
1 +The MIT License (MIT)
2 +
3 +Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (sindresorhus.com)
4 +
5 +Permission is hereby granted, free of charge, to any person obtaining a copy
6 +of this software and associated documentation files (the "Software"), to deal
7 +in the Software without restriction, including without limitation the rights
8 +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 +copies of the Software, and to permit persons to whom the Software is
10 +furnished to do so, subject to the following conditions:
11 +
12 +The above copyright notice and this permission notice shall be included in
13 +all copies or substantial portions of the Software.
14 +
15 +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 +THE SOFTWARE.
1 +{
2 + "name": "got",
3 + "version": "6.7.1",
4 + "description": "Simplified HTTP requests",
5 + "license": "MIT",
6 + "repository": "sindresorhus/got",
7 + "maintainers": [
8 + {
9 + "name": "Sindre Sorhus",
10 + "email": "sindresorhus@gmail.com",
11 + "url": "sindresorhus.com"
12 + },
13 + {
14 + "name": "Vsevolod Strukchinsky",
15 + "email": "floatdrop@gmail.com",
16 + "url": "github.com/floatdrop"
17 + }
18 + ],
19 + "engines": {
20 + "node": ">=4"
21 + },
22 + "browser": {
23 + "unzip-response": false
24 + },
25 + "scripts": {
26 + "test": "xo && nyc ava",
27 + "coveralls": "nyc report --reporter=text-lcov | coveralls"
28 + },
29 + "files": [
30 + "index.js"
31 + ],
32 + "keywords": [
33 + "http",
34 + "https",
35 + "get",
36 + "got",
37 + "url",
38 + "uri",
39 + "request",
40 + "util",
41 + "utility",
42 + "simple",
43 + "curl",
44 + "wget",
45 + "fetch"
46 + ],
47 + "dependencies": {
48 + "create-error-class": "^3.0.0",
49 + "duplexer3": "^0.1.4",
50 + "get-stream": "^3.0.0",
51 + "is-redirect": "^1.0.0",
52 + "is-retry-allowed": "^1.0.0",
53 + "is-stream": "^1.0.0",
54 + "lowercase-keys": "^1.0.0",
55 + "safe-buffer": "^5.0.1",
56 + "timed-out": "^4.0.0",
57 + "unzip-response": "^2.0.1",
58 + "url-parse-lax": "^1.0.0"
59 + },
60 + "devDependencies": {
61 + "ava": "^0.17.0",
62 + "coveralls": "^2.11.4",
63 + "form-data": "^2.1.1",
64 + "get-port": "^2.0.0",
65 + "into-stream": "^3.0.0",
66 + "nyc": "^10.0.0",
67 + "pem": "^1.4.4",
68 + "pify": "^2.3.0",
69 + "tempfile": "^1.1.1",
70 + "xo": "*"
71 + },
72 + "xo": {
73 + "esnext": true
74 + },
75 + "ava": {
76 + "concurrency": 4
77 + }
78 +}
1 +<h1 align="center">
2 + <br>
3 + <img width="360" src="https://rawgit.com/sindresorhus/got/master/media/logo.svg" alt="got">
4 + <br>
5 + <br>
6 + <br>
7 +</h1>
8 +
9 +> Simplified HTTP requests
10 +
11 +[![Build Status](https://travis-ci.org/sindresorhus/got.svg?branch=master)](https://travis-ci.org/sindresorhus/got) [![Coverage Status](https://coveralls.io/repos/github/sindresorhus/got/badge.svg?branch=master)](https://coveralls.io/github/sindresorhus/got?branch=master) [![Downloads](https://img.shields.io/npm/dm/got.svg)](https://npmjs.com/got)
12 +
13 +A nicer interface to the built-in [`http`](http://nodejs.org/api/http.html) module.
14 +
15 +It supports following redirects, promises, streams, retries, automagically handling gzip/deflate and some convenience options.
16 +
17 +Created because [`request`](https://github.com/request/request) is bloated *(several megabytes!)*.
18 +
19 +
20 +## Install
21 +
22 +**WARNING: Node.js 4 or higher is required for got@6 and above.** For older Node.js versions use [got@5](https://github.com/sindresorhus/got/tree/v5.x).
23 +
24 +```
25 +$ npm install --save got
26 +```
27 +
28 +
29 +## Usage
30 +
31 +```js
32 +const fs = require('fs');
33 +const got = require('got');
34 +
35 +got('todomvc.com')
36 + .then(response => {
37 + console.log(response.body);
38 + //=> '<!doctype html> ...'
39 + })
40 + .catch(error => {
41 + console.log(error.response.body);
42 + //=> 'Internal server error ...'
43 + });
44 +
45 +// Streams
46 +got.stream('todomvc.com').pipe(fs.createWriteStream('index.html'));
47 +
48 +// For POST, PUT and PATCH methods got.stream returns a WritableStream
49 +fs.createReadStream('index.html').pipe(got.stream.post('todomvc.com'));
50 +```
51 +
52 +
53 +### API
54 +
55 +It's a `GET` request by default, but can be changed in `options`.
56 +
57 +#### got(url, [options])
58 +
59 +Returns a Promise for a `response` object with a `body` property, a `url` property with the request URL or the final URL after redirects, and a `requestUrl` property with the original request URL.
60 +
61 +##### url
62 +
63 +Type: `string`, `object`
64 +
65 +The URL to request or a [`http.request` options](https://nodejs.org/api/http.html#http_http_request_options_callback) object.
66 +
67 +Properties from `options` will override properties in the parsed `url`.
68 +
69 +##### options
70 +
71 +Type: `object`
72 +
73 +Any of the [`http.request`](http://nodejs.org/api/http.html#http_http_request_options_callback) options.
74 +
75 +###### body
76 +
77 +Type: `string`, `buffer`, `readableStream`, `object`
78 +
79 +*This is mutually exclusive with stream mode.*
80 +
81 +Body that will be sent with a `POST` request.
82 +
83 +If present in `options` and `options.method` is not set, `options.method` will be set to `POST`.
84 +
85 +If `content-length` or `transfer-encoding` is not set in `options.headers` and `body` is a string or buffer, `content-length` will be set to the body length.
86 +
87 +If `body` is a plain object, it will be stringified with [`querystring.stringify`](https://nodejs.org/api/querystring.html#querystring_querystring_stringify_obj_sep_eq_options) and sent as `application/x-www-form-urlencoded`.
88 +
89 +###### encoding
90 +
91 +Type: `string`, `null`<br>
92 +Default: `'utf8'`
93 +
94 +Encoding to be used on `setEncoding` of the response data. If `null`, the body is returned as a Buffer.
95 +
96 +###### json
97 +
98 +Type: `boolean`<br>
99 +Default: `false`
100 +
101 +*This is mutually exclusive with stream mode.*
102 +
103 +Parse response body with `JSON.parse` and set `accept` header to `application/json`.
104 +
105 +###### query
106 +
107 +Type: `string`, `object`<br>
108 +
109 +Query string object that will be added to the request URL. This will override the query string in `url`.
110 +
111 +###### timeout
112 +
113 +Type: `number`, `object`
114 +
115 +Milliseconds to wait for a server to send response headers before aborting request with `ETIMEDOUT` error.
116 +
117 +Option accepts `object` with separate `connect` and `socket` fields for connection and socket inactivity timeouts.
118 +
119 +###### retries
120 +
121 +Type: `number`, `function`<br>
122 +Default: `5`
123 +
124 +Number of request retries when network errors happens. Delays between retries counts with function `1000 * Math.pow(2, retry) + Math.random() * 100`, where `retry` is attempt number (starts from 0).
125 +
126 +Option accepts `function` with `retry` and `error` arguments. Function must return delay in milliseconds (`0` return value cancels retry).
127 +
128 +**Note:** if `retries` is `number`, `ENOTFOUND` and `ENETUNREACH` error will not be retried (see full list in [`is-retry-allowed`](https://github.com/floatdrop/is-retry-allowed/blob/master/index.js#L12) module).
129 +
130 +###### followRedirect
131 +
132 +Type: `boolean`<br>
133 +Default: `true`
134 +
135 +Defines if redirect responses should be followed automatically.
136 +
137 +
138 +#### Streams
139 +
140 +#### got.stream(url, [options])
141 +
142 +`stream` method will return Duplex stream with additional events:
143 +
144 +##### .on('request', request)
145 +
146 +`request` event to get the request object of the request.
147 +
148 +**Tip**: You can use `request` event to abort request:
149 +
150 +```js
151 +got.stream('github.com')
152 + .on('request', req => setTimeout(() => req.abort(), 50));
153 +```
154 +
155 +##### .on('response', response)
156 +
157 +`response` event to get the response object of the final request.
158 +
159 +##### .on('redirect', response, nextOptions)
160 +
161 +`redirect` event to get the response object of a redirect. The second argument is options for the next request to the redirect location.
162 +
163 +##### .on('error', error, body, response)
164 +
165 +`error` event emitted in case of protocol error (like `ENOTFOUND` etc.) or status error (4xx or 5xx). The second argument is the body of the server response in case of status error. The third argument is response object.
166 +
167 +#### got.get(url, [options])
168 +#### got.post(url, [options])
169 +#### got.put(url, [options])
170 +#### got.patch(url, [options])
171 +#### got.head(url, [options])
172 +#### got.delete(url, [options])
173 +
174 +Sets `options.method` to the method name and makes a request.
175 +
176 +
177 +## Errors
178 +
179 +Each error contains (if available) `statusCode`, `statusMessage`, `host`, `hostname`, `method` and `path` properties to make debugging easier.
180 +
181 +In Promise mode, the `response` is attached to the error.
182 +
183 +#### got.RequestError
184 +
185 +When a request fails. Contains a `code` property with error class code, like `ECONNREFUSED`.
186 +
187 +#### got.ReadError
188 +
189 +When reading from response stream fails.
190 +
191 +#### got.ParseError
192 +
193 +When `json` option is enabled and `JSON.parse` fails.
194 +
195 +#### got.HTTPError
196 +
197 +When server response code is not 2xx. Contains `statusCode` and `statusMessage`.
198 +
199 +#### got.MaxRedirectsError
200 +
201 +When server redirects you more than 10 times.
202 +
203 +
204 +## Proxies
205 +
206 +You can use the [`tunnel`](https://github.com/koichik/node-tunnel) module with the `agent` option to work with proxies:
207 +
208 +```js
209 +const got = require('got');
210 +const tunnel = require('tunnel');
211 +
212 +got('todomvc.com', {
213 + agent: tunnel.httpOverHttp({
214 + proxy: {
215 + host: 'localhost'
216 + }
217 + })
218 +});
219 +```
220 +
221 +
222 +## Cookies
223 +
224 +You can use the [`cookie`](https://github.com/jshttp/cookie) module to include cookies in a request:
225 +
226 +```js
227 +const got = require('got');
228 +const cookie = require('cookie');
229 +
230 +got('google.com', {
231 + headers: {
232 + cookie: cookie.serialize('foo', 'bar')
233 + }
234 +});
235 +```
236 +
237 +
238 +## Form data
239 +
240 +You can use the [`form-data`](https://github.com/form-data/form-data) module to create POST request with form data:
241 +
242 +```js
243 +const fs = require('fs');
244 +const got = require('got');
245 +const FormData = require('form-data');
246 +const form = new FormData();
247 +
248 +form.append('my_file', fs.createReadStream('/foo/bar.jpg'));
249 +
250 +got.post('google.com', {
251 + body: form
252 +});
253 +```
254 +
255 +
256 +## OAuth
257 +
258 +You can use the [`oauth-1.0a`](https://github.com/ddo/oauth-1.0a) module to create a signed OAuth request:
259 +
260 +```js
261 +const got = require('got');
262 +const crypto = require('crypto');
263 +const OAuth = require('oauth-1.0a');
264 +
265 +const oauth = OAuth({
266 + consumer: {
267 + key: process.env.CONSUMER_KEY,
268 + secret: process.env.CONSUMER_SECRET
269 + },
270 + signature_method: 'HMAC-SHA1',
271 + hash_function: (baseString, key) => crypto.createHmac('sha1', key).update(baseString).digest('base64')
272 +});
273 +
274 +const token = {
275 + key: process.env.ACCESS_TOKEN,
276 + secret: process.env.ACCESS_TOKEN_SECRET
277 +};
278 +
279 +const url = 'https://api.twitter.com/1.1/statuses/home_timeline.json';
280 +
281 +got(url, {
282 + headers: oauth.toHeader(oauth.authorize({url, method: 'GET'}, token)),
283 + json: true
284 +});
285 +```
286 +
287 +
288 +## Unix Domain Sockets
289 +
290 +Requests can also be sent via [unix domain sockets](http://serverfault.com/questions/124517/whats-the-difference-between-unix-socket-and-tcp-ip-socket). Use the following URL scheme: `PROTOCOL://unix:SOCKET:PATH`.
291 +
292 +- `PROTOCOL` - `http` or `https` *(optional)*
293 +- `SOCKET` - absolute path to a unix domain socket, e.g. `/var/run/docker.sock`
294 +- `PATH` - request path, e.g. `/v2/keys`
295 +
296 +```js
297 +got('http://unix:/var/run/docker.sock:/containers/json');
298 +
299 +// or without protocol (http by default)
300 +got('unix:/var/run/docker.sock:/containers/json');
301 +```
302 +
303 +
304 +## Tip
305 +
306 +It's a good idea to set the `'user-agent'` header so the provider can more easily see how their resource is used. By default, it's the URL to this repo.
307 +
308 +```js
309 +const got = require('got');
310 +const pkg = require('./package.json');
311 +
312 +got('todomvc.com', {
313 + headers: {
314 + 'user-agent': `my-module/${pkg.version} (https://github.com/username/my-module)`
315 + }
316 +});
317 +```
318 +
319 +
320 +## Related
321 +
322 +- [gh-got](https://github.com/sindresorhus/gh-got) - Convenience wrapper for interacting with the GitHub API
323 +- [travis-got](https://github.com/samverschueren/travis-got) - Convenience wrapper for interacting with the Travis API
324 +
325 +
326 +## Created by
327 +
328 +[![Sindre Sorhus](https://avatars.githubusercontent.com/u/170270?v=3&s=100)](https://sindresorhus.com) | [![Vsevolod Strukchinsky](https://avatars.githubusercontent.com/u/365089?v=3&s=100)](https://github.com/floatdrop)
329 +---|---
330 +[Sindre Sorhus](https://sindresorhus.com) | [Vsevolod Strukchinsky](https://github.com/floatdrop)
331 +
332 +
333 +## License
334 +
335 +MIT © [Sindre Sorhus](https://sindresorhus.com)
1 +'use strict';
2 +module.exports = function (x) {
3 + if (typeof x !== 'number') {
4 + throw new TypeError('Expected a number');
5 + }
6 +
7 + return x === 300 ||
8 + x === 301 ||
9 + x === 302 ||
10 + x === 303 ||
11 + x === 305 ||
12 + x === 307 ||
13 + x === 308;
14 +};
1 +The MIT License (MIT)
2 +
3 +Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (sindresorhus.com)
4 +
5 +Permission is hereby granted, free of charge, to any person obtaining a copy
6 +of this software and associated documentation files (the "Software"), to deal
7 +in the Software without restriction, including without limitation the rights
8 +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 +copies of the Software, and to permit persons to whom the Software is
10 +furnished to do so, subject to the following conditions:
11 +
12 +The above copyright notice and this permission notice shall be included in
13 +all copies or substantial portions of the Software.
14 +
15 +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 +THE SOFTWARE.
1 +{
2 + "name": "is-redirect",
3 + "version": "1.0.0",
4 + "description": "Check if a number is a redirect HTTP status code",
5 + "license": "MIT",
6 + "repository": "sindresorhus/is-redirect",
7 + "author": {
8 + "name": "Sindre Sorhus",
9 + "email": "sindresorhus@gmail.com",
10 + "url": "sindresorhus.com"
11 + },
12 + "engines": {
13 + "node": ">=0.10.0"
14 + },
15 + "scripts": {
16 + "test": "node test.js"
17 + },
18 + "files": [
19 + "index.js"
20 + ],
21 + "keywords": [
22 + "redirect",
23 + "http",
24 + "https",
25 + "status",
26 + "code",
27 + "codes",
28 + "is",
29 + "check",
30 + "detect"
31 + ],
32 + "devDependencies": {
33 + "ava": "0.0.4"
34 + }
35 +}
1 +# is-redirect [![Build Status](https://travis-ci.org/sindresorhus/is-redirect.svg?branch=master)](https://travis-ci.org/sindresorhus/is-redirect)
2 +
3 +> Check if a number is a [redirect HTTP status code](http://en.wikipedia.org/wiki/List_of_HTTP_status_codes#3xx_Redirection)
4 +
5 +
6 +## Install
7 +
8 +```
9 +$ npm install --save is-redirect
10 +```
11 +
12 +
13 +## Usage
14 +
15 +```js
16 +var isRedirect = require('is-redirect');
17 +
18 +isRedirect(302);
19 +//=> true
20 +
21 +isRedirect(200);
22 +//=> false
23 +```
24 +
25 +
26 +## License
27 +
28 +MIT © [Sindre Sorhus](http://sindresorhus.com)
1 +'use strict';
2 +
3 +var WHITELIST = [
4 + 'ETIMEDOUT',
5 + 'ECONNRESET',
6 + 'EADDRINUSE',
7 + 'ESOCKETTIMEDOUT',
8 + 'ECONNREFUSED',
9 + 'EPIPE',
10 + 'EHOSTUNREACH',
11 + 'EAI_AGAIN'
12 +];
13 +
14 +var BLACKLIST = [
15 + 'ENOTFOUND',
16 + 'ENETUNREACH',
17 +
18 + // SSL errors from https://github.com/nodejs/node/blob/ed3d8b13ee9a705d89f9e0397d9e96519e7e47ac/src/node_crypto.cc#L1950
19 + 'UNABLE_TO_GET_ISSUER_CERT',
20 + 'UNABLE_TO_GET_CRL',
21 + 'UNABLE_TO_DECRYPT_CERT_SIGNATURE',
22 + 'UNABLE_TO_DECRYPT_CRL_SIGNATURE',
23 + 'UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY',
24 + 'CERT_SIGNATURE_FAILURE',
25 + 'CRL_SIGNATURE_FAILURE',
26 + 'CERT_NOT_YET_VALID',
27 + 'CERT_HAS_EXPIRED',
28 + 'CRL_NOT_YET_VALID',
29 + 'CRL_HAS_EXPIRED',
30 + 'ERROR_IN_CERT_NOT_BEFORE_FIELD',
31 + 'ERROR_IN_CERT_NOT_AFTER_FIELD',
32 + 'ERROR_IN_CRL_LAST_UPDATE_FIELD',
33 + 'ERROR_IN_CRL_NEXT_UPDATE_FIELD',
34 + 'OUT_OF_MEM',
35 + 'DEPTH_ZERO_SELF_SIGNED_CERT',
36 + 'SELF_SIGNED_CERT_IN_CHAIN',
37 + 'UNABLE_TO_GET_ISSUER_CERT_LOCALLY',
38 + 'UNABLE_TO_VERIFY_LEAF_SIGNATURE',
39 + 'CERT_CHAIN_TOO_LONG',
40 + 'CERT_REVOKED',
41 + 'INVALID_CA',
42 + 'PATH_LENGTH_EXCEEDED',
43 + 'INVALID_PURPOSE',
44 + 'CERT_UNTRUSTED',
45 + 'CERT_REJECTED'
46 +];
47 +
48 +module.exports = function (err) {
49 + if (!err || !err.code) {
50 + return true;
51 + }
52 +
53 + if (WHITELIST.indexOf(err.code) !== -1) {
54 + return true;
55 + }
56 +
57 + if (BLACKLIST.indexOf(err.code) !== -1) {
58 + return false;
59 + }
60 +
61 + return true;
62 +};
1 +The MIT License (MIT)
2 +
3 +Copyright (c) Vsevolod Strukchinsky <floatdrop@gmail.com> (github.com/floatdrop)
4 +
5 +Permission is hereby granted, free of charge, to any person obtaining a copy
6 +of this software and associated documentation files (the "Software"), to deal
7 +in the Software without restriction, including without limitation the rights
8 +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 +copies of the Software, and to permit persons to whom the Software is
10 +furnished to do so, subject to the following conditions:
11 +
12 +The above copyright notice and this permission notice shall be included in
13 +all copies or substantial portions of the Software.
14 +
15 +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 +THE SOFTWARE.
1 +{
2 + "name": "is-retry-allowed",
3 + "version": "1.2.0",
4 + "description": "Is retry allowed for Error?",
5 + "license": "MIT",
6 + "repository": "floatdrop/is-retry-allowed",
7 + "author": {
8 + "name": "Vsevolod Strukchinsky",
9 + "email": "floatdrop@gmail.com",
10 + "url": "github.com/floatdrop"
11 + },
12 + "engines": {
13 + "node": ">=0.10.0"
14 + },
15 + "scripts": {
16 + "test": "xo && ava"
17 + },
18 + "files": [
19 + "index.js"
20 + ],
21 + "keywords": [
22 + ""
23 + ],
24 + "dependencies": {},
25 + "devDependencies": {
26 + "ava": "^0.8.0",
27 + "xo": "^0.12.1"
28 + }
29 +}
1 +# is-retry-allowed [![Build Status](https://travis-ci.org/floatdrop/is-retry-allowed.svg?branch=master)](https://travis-ci.org/floatdrop/is-retry-allowed)
2 +
3 +Is retry allowed for Error?
4 +
5 +
6 +## Install
7 +
8 +```
9 +$ npm install --save is-retry-allowed
10 +```
11 +
12 +
13 +## Usage
14 +
15 +```js
16 +const isRetryAllowed = require('is-retry-allowed');
17 +
18 +isRetryAllowed({code: 'ETIMEDOUT'});
19 +//=> true
20 +
21 +isRetryAllowed({code: 'ENOTFOUND'});
22 +//=> false
23 +
24 +isRetryAllowed({});
25 +//=> true
26 +```
27 +
28 +
29 +## API
30 +
31 +### isRetryAllowed(error)
32 +
33 +#### error
34 +
35 +Type: `object`
36 +
37 +Object with `code` property, which will be used to determine retry.
38 +
39 +
40 +## License
41 +
42 +MIT © [Vsevolod Strukchinsky](http://github.com/floatdrop)
1 +'use strict';
2 +
3 +var isStream = module.exports = function (stream) {
4 + return stream !== null && typeof stream === 'object' && typeof stream.pipe === 'function';
5 +};
6 +
7 +isStream.writable = function (stream) {
8 + return isStream(stream) && stream.writable !== false && typeof stream._write === 'function' && typeof stream._writableState === 'object';
9 +};
10 +
11 +isStream.readable = function (stream) {
12 + return isStream(stream) && stream.readable !== false && typeof stream._read === 'function' && typeof stream._readableState === 'object';
13 +};
14 +
15 +isStream.duplex = function (stream) {
16 + return isStream.writable(stream) && isStream.readable(stream);
17 +};
18 +
19 +isStream.transform = function (stream) {
20 + return isStream.duplex(stream) && typeof stream._transform === 'function' && typeof stream._transformState === 'object';
21 +};
1 +The MIT License (MIT)
2 +
3 +Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (sindresorhus.com)
4 +
5 +Permission is hereby granted, free of charge, to any person obtaining a copy
6 +of this software and associated documentation files (the "Software"), to deal
7 +in the Software without restriction, including without limitation the rights
8 +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 +copies of the Software, and to permit persons to whom the Software is
10 +furnished to do so, subject to the following conditions:
11 +
12 +The above copyright notice and this permission notice shall be included in
13 +all copies or substantial portions of the Software.
14 +
15 +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 +THE SOFTWARE.
1 +{
2 + "name": "is-stream",
3 + "version": "1.1.0",
4 + "description": "Check if something is a Node.js stream",
5 + "license": "MIT",
6 + "repository": "sindresorhus/is-stream",
7 + "author": {
8 + "name": "Sindre Sorhus",
9 + "email": "sindresorhus@gmail.com",
10 + "url": "sindresorhus.com"
11 + },
12 + "engines": {
13 + "node": ">=0.10.0"
14 + },
15 + "scripts": {
16 + "test": "xo && ava"
17 + },
18 + "files": [
19 + "index.js"
20 + ],
21 + "keywords": [
22 + "stream",
23 + "type",
24 + "streams",
25 + "writable",
26 + "readable",
27 + "duplex",
28 + "transform",
29 + "check",
30 + "detect",
31 + "is"
32 + ],
33 + "devDependencies": {
34 + "ava": "*",
35 + "tempfile": "^1.1.0",
36 + "xo": "*"
37 + }
38 +}
1 +# is-stream [![Build Status](https://travis-ci.org/sindresorhus/is-stream.svg?branch=master)](https://travis-ci.org/sindresorhus/is-stream)
2 +
3 +> Check if something is a [Node.js stream](https://nodejs.org/api/stream.html)
4 +
5 +
6 +## Install
7 +
8 +```
9 +$ npm install --save is-stream
10 +```
11 +
12 +
13 +## Usage
14 +
15 +```js
16 +const fs = require('fs');
17 +const isStream = require('is-stream');
18 +
19 +isStream(fs.createReadStream('unicorn.png'));
20 +//=> true
21 +
22 +isStream({});
23 +//=> false
24 +```
25 +
26 +
27 +## API
28 +
29 +### isStream(stream)
30 +
31 +#### isStream.writable(stream)
32 +
33 +#### isStream.readable(stream)
34 +
35 +#### isStream.duplex(stream)
36 +
37 +#### isStream.transform(stream)
38 +
39 +
40 +## License
41 +
42 +MIT © [Sindre Sorhus](https://sindresorhus.com)
1 +'use strict';
2 +module.exports = function (obj) {
3 + var ret = {};
4 + var keys = Object.keys(Object(obj));
5 +
6 + for (var i = 0; i < keys.length; i++) {
7 + ret[keys[i].toLowerCase()] = obj[keys[i]];
8 + }
9 +
10 + return ret;
11 +};
1 +The MIT License (MIT)
2 +
3 +Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (sindresorhus.com)
4 +
5 +Permission is hereby granted, free of charge, to any person obtaining a copy
6 +of this software and associated documentation files (the "Software"), to deal
7 +in the Software without restriction, including without limitation the rights
8 +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 +copies of the Software, and to permit persons to whom the Software is
10 +furnished to do so, subject to the following conditions:
11 +
12 +The above copyright notice and this permission notice shall be included in
13 +all copies or substantial portions of the Software.
14 +
15 +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 +THE SOFTWARE.
1 +{
2 + "name": "lowercase-keys",
3 + "version": "1.0.1",
4 + "description": "Lowercase the keys of an object",
5 + "license": "MIT",
6 + "repository": "sindresorhus/lowercase-keys",
7 + "author": {
8 + "name": "Sindre Sorhus",
9 + "email": "sindresorhus@gmail.com",
10 + "url": "sindresorhus.com"
11 + },
12 + "engines": {
13 + "node": ">=0.10.0"
14 + },
15 + "scripts": {
16 + "test": "ava"
17 + },
18 + "files": [
19 + "index.js"
20 + ],
21 + "keywords": [
22 + "object",
23 + "assign",
24 + "extend",
25 + "properties",
26 + "lowercase",
27 + "lower-case",
28 + "case",
29 + "keys",
30 + "key"
31 + ],
32 + "devDependencies": {
33 + "ava": "*"
34 + }
35 +}
1 +# lowercase-keys [![Build Status](https://travis-ci.org/sindresorhus/lowercase-keys.svg?branch=master)](https://travis-ci.org/sindresorhus/lowercase-keys)
2 +
3 +> Lowercase the keys of an object
4 +
5 +
6 +## Install
7 +
8 +```
9 +$ npm install --save lowercase-keys
10 +```
11 +
12 +
13 +## Usage
14 +
15 +```js
16 +var lowercaseKeys = require('lowercase-keys');
17 +
18 +lowercaseKeys({FOO: true, bAr: false});
19 +//=> {foo: true, bar: false}
20 +```
21 +
22 +
23 +## API
24 +
25 +### lowercaseKeys(object)
26 +
27 +Lowercases the keys and returns a new object.
28 +
29 +
30 +
31 +## License
32 +
33 +MIT © [Sindre Sorhus](http://sindresorhus.com)
1 +'use strict';
2 +module.exports = function (url) {
3 + if (typeof url !== 'string') {
4 + throw new TypeError('Expected a string, got ' + typeof url);
5 + }
6 +
7 + url = url.trim();
8 +
9 + if (/^\.*\/|^(?!localhost)\w+:/.test(url)) {
10 + return url;
11 + }
12 +
13 + return url.replace(/^(?!(?:\w+:)?\/\/)/, 'http://');
14 +};
1 +The MIT License (MIT)
2 +
3 +Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (sindresorhus.com)
4 +
5 +Permission is hereby granted, free of charge, to any person obtaining a copy
6 +of this software and associated documentation files (the "Software"), to deal
7 +in the Software without restriction, including without limitation the rights
8 +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 +copies of the Software, and to permit persons to whom the Software is
10 +furnished to do so, subject to the following conditions:
11 +
12 +The above copyright notice and this permission notice shall be included in
13 +all copies or substantial portions of the Software.
14 +
15 +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 +THE SOFTWARE.
1 +{
2 + "name": "prepend-http",
3 + "version": "1.0.4",
4 + "description": "Prepend `http://` to humanized URLs like todomvc.com and localhost",
5 + "license": "MIT",
6 + "repository": "sindresorhus/prepend-http",
7 + "author": {
8 + "name": "Sindre Sorhus",
9 + "email": "sindresorhus@gmail.com",
10 + "url": "sindresorhus.com"
11 + },
12 + "engines": {
13 + "node": ">=0.10.0"
14 + },
15 + "scripts": {
16 + "test": "xo && ava"
17 + },
18 + "files": [
19 + "index.js"
20 + ],
21 + "keywords": [
22 + "prepend",
23 + "protocol",
24 + "scheme",
25 + "url",
26 + "uri",
27 + "http",
28 + "https",
29 + "humanized"
30 + ],
31 + "devDependencies": {
32 + "ava": "*",
33 + "xo": "*"
34 + }
35 +}
1 +# prepend-http [![Build Status](https://travis-ci.org/sindresorhus/prepend-http.svg?branch=master)](https://travis-ci.org/sindresorhus/prepend-http)
2 +
3 +> Prepend `http://` to humanized URLs like `todomvc.com` and `localhost`
4 +
5 +
6 +## Install
7 +
8 +```
9 +$ npm install --save prepend-http
10 +```
11 +
12 +
13 +## Usage
14 +
15 +```js
16 +const prependHttp = require('prepend-http');
17 +
18 +prependHttp('todomvc.com');
19 +//=> 'http://todomvc.com'
20 +
21 +prependHttp('localhost');
22 +//=> 'http://localhost'
23 +
24 +prependHttp('http://todomvc.com');
25 +//=> 'http://todomvc.com'
26 +```
27 +
28 +
29 +## License
30 +
31 +MIT © [Sindre Sorhus](https://sindresorhus.com)
1 +'use strict';
2 +
3 +const got = require('got');
4 +const uniqueRandomArray = require('unique-random-array');
5 +const EventEmitter = require('eventemitter3');
6 +
7 +const randomCache = {};
8 +
9 +function formatResult(getRandomImage) {
10 + const imageData = getRandomImage();
11 + if (!imageData) {
12 + return;
13 + }
14 + return `http://imgur.com/${imageData.hash}${imageData.ext.replace(/\?.*/, '')}`;
15 +}
16 +
17 +function storeResults(images, subreddit) {
18 + const getRandomImage = uniqueRandomArray(images);
19 +
20 + randomCache[subreddit] = getRandomImage;
21 + return getRandomImage;
22 +}
23 +
24 +function randomPuppy(subreddit) {
25 + subreddit = (typeof subreddit === 'string' && subreddit.length !== 0) ? subreddit : 'puppies';
26 +
27 + if (randomCache[subreddit]) {
28 + return Promise.resolve(formatResult(randomCache[subreddit]));
29 + }
30 +
31 + return got(`https://imgur.com/r/${subreddit}/hot.json`, {json: true})
32 + .then(response => storeResults(response.body.data, subreddit))
33 + .then(getRandomImage => formatResult(getRandomImage));
34 +}
35 +
36 +// silly feature to play with observables
37 +function all(subreddit) {
38 + const eventEmitter = new EventEmitter();
39 +
40 + function emitRandomImage(subreddit) {
41 + randomPuppy(subreddit).then(imageUrl => {
42 + eventEmitter.emit('data', imageUrl + '#' + subreddit);
43 + if (eventEmitter.listeners('data').length) {
44 + setTimeout(() => emitRandomImage(subreddit), 200);
45 + }
46 + });
47 + }
48 +
49 + emitRandomImage(subreddit);
50 + return eventEmitter;
51 +}
52 +
53 +function callback(subreddit, cb) {
54 + randomPuppy(subreddit)
55 + .then(url => cb(null, url))
56 + .catch(err => cb(err));
57 +}
58 +
59 +// subreddit is optional
60 +// callback support is provided for a training exercise
61 +module.exports = (subreddit, cb) => {
62 + if (typeof cb === 'function') {
63 + callback(subreddit, cb);
64 + } else if (typeof subreddit === 'function') {
65 + callback(null, subreddit);
66 + } else {
67 + return randomPuppy(subreddit);
68 + }
69 +};
70 +
71 +module.exports.all = all;
1 +The MIT License (MIT)
2 +
3 +Copyright (c) Dylan Greene <dylang@gmail.com> (github.com/dylang)
4 +
5 +Permission is hereby granted, free of charge, to any person obtaining a copy
6 +of this software and associated documentation files (the "Software"), to deal
7 +in the Software without restriction, including without limitation the rights
8 +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 +copies of the Software, and to permit persons to whom the Software is
10 +furnished to do so, subject to the following conditions:
11 +
12 +The above copyright notice and this permission notice shall be included in
13 +all copies or substantial portions of the Software.
14 +
15 +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 +THE SOFTWARE.
1 +{
2 + "name": "random-puppy",
3 + "version": "1.1.0",
4 + "description": "Get a random imgur image url, by default a puppy.",
5 + "license": "MIT",
6 + "repository": "dylang/random-puppy",
7 + "author": {
8 + "name": "Dylan Greene",
9 + "email": "dylang@gmail.com",
10 + "url": "github.com/dylang"
11 + },
12 + "engines": {
13 + "node": ">=4.0.0"
14 + },
15 + "scripts": {
16 + "test": "xo && ava",
17 + "watch": "ava --watch"
18 + },
19 + "files": [
20 + "index.js"
21 + ],
22 + "keywords": [
23 + "puppy",
24 + "doggie",
25 + "dog",
26 + "imgur",
27 + "random",
28 + "placeholder"
29 + ],
30 + "dependencies": {
31 + "eventemitter3": "^1.2.0",
32 + "got": "^6.3.0",
33 + "unique-random-array": "^1.0.0"
34 + },
35 + "devDependencies": {
36 + "ava": "^0.14.0",
37 + "rx-lite": "^4.0.8",
38 + "xo": "^0.14.0"
39 + },
40 + "xo": {
41 + "space": 4
42 + }
43 +}
1 +# random-puppy [![Build Status](https://travis-ci.org/dylang/random-puppy.svg?branch=master)](https://travis-ci.org/dylang/random-puppy)
2 +
3 +> Get a random puppy image url.
4 +
5 +<img src="http://i.imgur.com/0zZ8m6B.jpg" width="300px">
6 +
7 +## Install
8 +
9 +```
10 +$ npm install --save random-puppy
11 +```
12 +
13 +
14 +## Usage
15 +
16 +```js
17 +const randomPuppy = require('random-puppy');
18 +
19 +randomPuppy()
20 + .then(url => {
21 + console.log(url);
22 + })
23 +
24 +//=> 'http://imgur.com/IoI8uS5'
25 +```
26 +
27 +
28 +## API
29 +
30 +### `randomPuppy()`
31 +
32 +Returns a `promise` for a random puppy image url from http://imgur.com/ from https://www.reddit.com/r/puppy
33 +
34 +### `randomPuppy(subreddit)`
35 +
36 +Returns a `promise` for a random image url from the selected subreddit. *Warning: We cannot promise it will be a image of a puppy!*
37 +
38 +### `randomPuppy.all(subreddit)`
39 +
40 +Returns an `eventemitter` for getting all random images for a subreddit.
41 +
42 +```js
43 +const event = randomPuppy.all(subreddit);
44 +event.on('data', url => console.log(url));
45 +```
46 +
47 +Or:
48 +```js
49 +const event = randomPuppy.all('puppies');
50 +
51 +Observable.fromEvent(event, 'data')
52 + .subscribe(data => {
53 + console.log(data);
54 + });
55 +```
56 +
57 +## Notes
58 +
59 +* Node 4 or newer.
60 +* Caches results from imgur in memory.
61 +* Created for the purpose of using in a training exercise on different ways to do async in JavaScript at [Opower](https://opower.com/).
62 +
63 +## License
64 +
65 +MIT © [Dylan Greene](https://github.com/dylang)
1 +The MIT License (MIT)
2 +
3 +Copyright (c) Feross Aboukhadijeh
4 +
5 +Permission is hereby granted, free of charge, to any person obtaining a copy
6 +of this software and associated documentation files (the "Software"), to deal
7 +in the Software without restriction, including without limitation the rights
8 +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 +copies of the Software, and to permit persons to whom the Software is
10 +furnished to do so, subject to the following conditions:
11 +
12 +The above copyright notice and this permission notice shall be included in
13 +all copies or substantial portions of the Software.
14 +
15 +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 +THE SOFTWARE.
This diff is collapsed. Click to expand it.
1 +declare module "safe-buffer" {
2 + export class Buffer {
3 + length: number
4 + write(string: string, offset?: number, length?: number, encoding?: string): number;
5 + toString(encoding?: string, start?: number, end?: number): string;
6 + toJSON(): { type: 'Buffer', data: any[] };
7 + equals(otherBuffer: Buffer): boolean;
8 + compare(otherBuffer: Buffer, targetStart?: number, targetEnd?: number, sourceStart?: number, sourceEnd?: number): number;
9 + copy(targetBuffer: Buffer, targetStart?: number, sourceStart?: number, sourceEnd?: number): number;
10 + slice(start?: number, end?: number): Buffer;
11 + writeUIntLE(value: number, offset: number, byteLength: number, noAssert?: boolean): number;
12 + writeUIntBE(value: number, offset: number, byteLength: number, noAssert?: boolean): number;
13 + writeIntLE(value: number, offset: number, byteLength: number, noAssert?: boolean): number;
14 + writeIntBE(value: number, offset: number, byteLength: number, noAssert?: boolean): number;
15 + readUIntLE(offset: number, byteLength: number, noAssert?: boolean): number;
16 + readUIntBE(offset: number, byteLength: number, noAssert?: boolean): number;
17 + readIntLE(offset: number, byteLength: number, noAssert?: boolean): number;
18 + readIntBE(offset: number, byteLength: number, noAssert?: boolean): number;
19 + readUInt8(offset: number, noAssert?: boolean): number;
20 + readUInt16LE(offset: number, noAssert?: boolean): number;
21 + readUInt16BE(offset: number, noAssert?: boolean): number;
22 + readUInt32LE(offset: number, noAssert?: boolean): number;
23 + readUInt32BE(offset: number, noAssert?: boolean): number;
24 + readInt8(offset: number, noAssert?: boolean): number;
25 + readInt16LE(offset: number, noAssert?: boolean): number;
26 + readInt16BE(offset: number, noAssert?: boolean): number;
27 + readInt32LE(offset: number, noAssert?: boolean): number;
28 + readInt32BE(offset: number, noAssert?: boolean): number;
29 + readFloatLE(offset: number, noAssert?: boolean): number;
30 + readFloatBE(offset: number, noAssert?: boolean): number;
31 + readDoubleLE(offset: number, noAssert?: boolean): number;
32 + readDoubleBE(offset: number, noAssert?: boolean): number;
33 + swap16(): Buffer;
34 + swap32(): Buffer;
35 + swap64(): Buffer;
36 + writeUInt8(value: number, offset: number, noAssert?: boolean): number;
37 + writeUInt16LE(value: number, offset: number, noAssert?: boolean): number;
38 + writeUInt16BE(value: number, offset: number, noAssert?: boolean): number;
39 + writeUInt32LE(value: number, offset: number, noAssert?: boolean): number;
40 + writeUInt32BE(value: number, offset: number, noAssert?: boolean): number;
41 + writeInt8(value: number, offset: number, noAssert?: boolean): number;
42 + writeInt16LE(value: number, offset: number, noAssert?: boolean): number;
43 + writeInt16BE(value: number, offset: number, noAssert?: boolean): number;
44 + writeInt32LE(value: number, offset: number, noAssert?: boolean): number;
45 + writeInt32BE(value: number, offset: number, noAssert?: boolean): number;
46 + writeFloatLE(value: number, offset: number, noAssert?: boolean): number;
47 + writeFloatBE(value: number, offset: number, noAssert?: boolean): number;
48 + writeDoubleLE(value: number, offset: number, noAssert?: boolean): number;
49 + writeDoubleBE(value: number, offset: number, noAssert?: boolean): number;
50 + fill(value: any, offset?: number, end?: number): this;
51 + indexOf(value: string | number | Buffer, byteOffset?: number, encoding?: string): number;
52 + lastIndexOf(value: string | number | Buffer, byteOffset?: number, encoding?: string): number;
53 + includes(value: string | number | Buffer, byteOffset?: number, encoding?: string): boolean;
54 +
55 + /**
56 + * Allocates a new buffer containing the given {str}.
57 + *
58 + * @param str String to store in buffer.
59 + * @param encoding encoding to use, optional. Default is 'utf8'
60 + */
61 + constructor (str: string, encoding?: string);
62 + /**
63 + * Allocates a new buffer of {size} octets.
64 + *
65 + * @param size count of octets to allocate.
66 + */
67 + constructor (size: number);
68 + /**
69 + * Allocates a new buffer containing the given {array} of octets.
70 + *
71 + * @param array The octets to store.
72 + */
73 + constructor (array: Uint8Array);
74 + /**
75 + * Produces a Buffer backed by the same allocated memory as
76 + * the given {ArrayBuffer}.
77 + *
78 + *
79 + * @param arrayBuffer The ArrayBuffer with which to share memory.
80 + */
81 + constructor (arrayBuffer: ArrayBuffer);
82 + /**
83 + * Allocates a new buffer containing the given {array} of octets.
84 + *
85 + * @param array The octets to store.
86 + */
87 + constructor (array: any[]);
88 + /**
89 + * Copies the passed {buffer} data onto a new {Buffer} instance.
90 + *
91 + * @param buffer The buffer to copy.
92 + */
93 + constructor (buffer: Buffer);
94 + prototype: Buffer;
95 + /**
96 + * Allocates a new Buffer using an {array} of octets.
97 + *
98 + * @param array
99 + */
100 + static from(array: any[]): Buffer;
101 + /**
102 + * When passed a reference to the .buffer property of a TypedArray instance,
103 + * the newly created Buffer will share the same allocated memory as the TypedArray.
104 + * The optional {byteOffset} and {length} arguments specify a memory range
105 + * within the {arrayBuffer} that will be shared by the Buffer.
106 + *
107 + * @param arrayBuffer The .buffer property of a TypedArray or a new ArrayBuffer()
108 + * @param byteOffset
109 + * @param length
110 + */
111 + static from(arrayBuffer: ArrayBuffer, byteOffset?: number, length?: number): Buffer;
112 + /**
113 + * Copies the passed {buffer} data onto a new Buffer instance.
114 + *
115 + * @param buffer
116 + */
117 + static from(buffer: Buffer): Buffer;
118 + /**
119 + * Creates a new Buffer containing the given JavaScript string {str}.
120 + * If provided, the {encoding} parameter identifies the character encoding.
121 + * If not provided, {encoding} defaults to 'utf8'.
122 + *
123 + * @param str
124 + */
125 + static from(str: string, encoding?: string): Buffer;
126 + /**
127 + * Returns true if {obj} is a Buffer
128 + *
129 + * @param obj object to test.
130 + */
131 + static isBuffer(obj: any): obj is Buffer;
132 + /**
133 + * Returns true if {encoding} is a valid encoding argument.
134 + * Valid string encodings in Node 0.12: 'ascii'|'utf8'|'utf16le'|'ucs2'(alias of 'utf16le')|'base64'|'binary'(deprecated)|'hex'
135 + *
136 + * @param encoding string to test.
137 + */
138 + static isEncoding(encoding: string): boolean;
139 + /**
140 + * Gives the actual byte length of a string. encoding defaults to 'utf8'.
141 + * This is not the same as String.prototype.length since that returns the number of characters in a string.
142 + *
143 + * @param string string to test.
144 + * @param encoding encoding used to evaluate (defaults to 'utf8')
145 + */
146 + static byteLength(string: string, encoding?: string): number;
147 + /**
148 + * Returns a buffer which is the result of concatenating all the buffers in the list together.
149 + *
150 + * If the list has no items, or if the totalLength is 0, then it returns a zero-length buffer.
151 + * If the list has exactly one item, then the first item of the list is returned.
152 + * If the list has more than one item, then a new Buffer is created.
153 + *
154 + * @param list An array of Buffer objects to concatenate
155 + * @param totalLength Total length of the buffers when concatenated.
156 + * If totalLength is not provided, it is read from the buffers in the list. However, this adds an additional loop to the function, so it is faster to provide the length explicitly.
157 + */
158 + static concat(list: Buffer[], totalLength?: number): Buffer;
159 + /**
160 + * The same as buf1.compare(buf2).
161 + */
162 + static compare(buf1: Buffer, buf2: Buffer): number;
163 + /**
164 + * Allocates a new buffer of {size} octets.
165 + *
166 + * @param size count of octets to allocate.
167 + * @param fill if specified, buffer will be initialized by calling buf.fill(fill).
168 + * If parameter is omitted, buffer will be filled with zeros.
169 + * @param encoding encoding used for call to buf.fill while initalizing
170 + */
171 + static alloc(size: number, fill?: string | Buffer | number, encoding?: string): Buffer;
172 + /**
173 + * Allocates a new buffer of {size} octets, leaving memory not initialized, so the contents
174 + * of the newly created Buffer are unknown and may contain sensitive data.
175 + *
176 + * @param size count of octets to allocate
177 + */
178 + static allocUnsafe(size: number): Buffer;
179 + /**
180 + * Allocates a new non-pooled buffer of {size} octets, leaving memory not initialized, so the contents
181 + * of the newly created Buffer are unknown and may contain sensitive data.
182 + *
183 + * @param size count of octets to allocate
184 + */
185 + static allocUnsafeSlow(size: number): Buffer;
186 + }
187 +}
...\ No newline at end of file ...\ No newline at end of file
1 +/*! safe-buffer. MIT License. Feross Aboukhadijeh <https://feross.org/opensource> */
2 +/* eslint-disable node/no-deprecated-api */
3 +var buffer = require('buffer')
4 +var Buffer = buffer.Buffer
5 +
6 +// alternative to using Object.keys for old browsers
7 +function copyProps (src, dst) {
8 + for (var key in src) {
9 + dst[key] = src[key]
10 + }
11 +}
12 +if (Buffer.from && Buffer.alloc && Buffer.allocUnsafe && Buffer.allocUnsafeSlow) {
13 + module.exports = buffer
14 +} else {
15 + // Copy properties from require('buffer')
16 + copyProps(buffer, exports)
17 + exports.Buffer = SafeBuffer
18 +}
19 +
20 +function SafeBuffer (arg, encodingOrOffset, length) {
21 + return Buffer(arg, encodingOrOffset, length)
22 +}
23 +
24 +SafeBuffer.prototype = Object.create(Buffer.prototype)
25 +
26 +// Copy static methods from Buffer
27 +copyProps(Buffer, SafeBuffer)
28 +
29 +SafeBuffer.from = function (arg, encodingOrOffset, length) {
30 + if (typeof arg === 'number') {
31 + throw new TypeError('Argument must not be a number')
32 + }
33 + return Buffer(arg, encodingOrOffset, length)
34 +}
35 +
36 +SafeBuffer.alloc = function (size, fill, encoding) {
37 + if (typeof size !== 'number') {
38 + throw new TypeError('Argument must be a number')
39 + }
40 + var buf = Buffer(size)
41 + if (fill !== undefined) {
42 + if (typeof encoding === 'string') {
43 + buf.fill(fill, encoding)
44 + } else {
45 + buf.fill(fill)
46 + }
47 + } else {
48 + buf.fill(0)
49 + }
50 + return buf
51 +}
52 +
53 +SafeBuffer.allocUnsafe = function (size) {
54 + if (typeof size !== 'number') {
55 + throw new TypeError('Argument must be a number')
56 + }
57 + return Buffer(size)
58 +}
59 +
60 +SafeBuffer.allocUnsafeSlow = function (size) {
61 + if (typeof size !== 'number') {
62 + throw new TypeError('Argument must be a number')
63 + }
64 + return buffer.SlowBuffer(size)
65 +}
1 +{
2 + "name": "safe-buffer",
3 + "description": "Safer Node.js Buffer API",
4 + "version": "5.2.1",
5 + "author": {
6 + "name": "Feross Aboukhadijeh",
7 + "email": "feross@feross.org",
8 + "url": "https://feross.org"
9 + },
10 + "bugs": {
11 + "url": "https://github.com/feross/safe-buffer/issues"
12 + },
13 + "devDependencies": {
14 + "standard": "*",
15 + "tape": "^5.0.0"
16 + },
17 + "homepage": "https://github.com/feross/safe-buffer",
18 + "keywords": [
19 + "buffer",
20 + "buffer allocate",
21 + "node security",
22 + "safe",
23 + "safe-buffer",
24 + "security",
25 + "uninitialized"
26 + ],
27 + "license": "MIT",
28 + "main": "index.js",
29 + "types": "index.d.ts",
30 + "repository": {
31 + "type": "git",
32 + "url": "git://github.com/feross/safe-buffer.git"
33 + },
34 + "scripts": {
35 + "test": "standard && tape test/*.js"
36 + },
37 + "funding": [
38 + {
39 + "type": "github",
40 + "url": "https://github.com/sponsors/feross"
41 + },
42 + {
43 + "type": "patreon",
44 + "url": "https://www.patreon.com/feross"
45 + },
46 + {
47 + "type": "consulting",
48 + "url": "https://feross.org/support"
49 + }
50 + ]
51 +}
1 +'use strict';
2 +
3 +module.exports = function (req, time) {
4 + if (req.timeoutTimer) {
5 + return req;
6 + }
7 +
8 + var delays = isNaN(time) ? time : {socket: time, connect: time};
9 + var host = req._headers ? (' to ' + req._headers.host) : '';
10 +
11 + if (delays.connect !== undefined) {
12 + req.timeoutTimer = setTimeout(function timeoutHandler() {
13 + req.abort();
14 + var e = new Error('Connection timed out on request' + host);
15 + e.code = 'ETIMEDOUT';
16 + req.emit('error', e);
17 + }, delays.connect);
18 + }
19 +
20 + // Clear the connection timeout timer once a socket is assigned to the
21 + // request and is connected.
22 + req.on('socket', function assign(socket) {
23 + // Socket may come from Agent pool and may be already connected.
24 + if (!(socket.connecting || socket._connecting)) {
25 + connect();
26 + return;
27 + }
28 +
29 + socket.once('connect', connect);
30 + });
31 +
32 + function clear() {
33 + if (req.timeoutTimer) {
34 + clearTimeout(req.timeoutTimer);
35 + req.timeoutTimer = null;
36 + }
37 + }
38 +
39 + function connect() {
40 + clear();
41 +
42 + if (delays.socket !== undefined) {
43 + // Abort the request if there is no activity on the socket for more
44 + // than `delays.socket` milliseconds.
45 + req.setTimeout(delays.socket, function socketTimeoutHandler() {
46 + req.abort();
47 + var e = new Error('Socket timed out on request' + host);
48 + e.code = 'ESOCKETTIMEDOUT';
49 + req.emit('error', e);
50 + });
51 + }
52 + }
53 +
54 + return req.on('error', clear);
55 +};
1 +The MIT License (MIT)
2 +
3 +Copyright (c) Vsevolod Strukchinsky <floatdrop@gmail.com>
4 +
5 +Permission is hereby granted, free of charge, to any person obtaining a copy
6 +of this software and associated documentation files (the "Software"), to deal
7 +in the Software without restriction, including without limitation the rights
8 +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 +copies of the Software, and to permit persons to whom the Software is
10 +furnished to do so, subject to the following conditions:
11 +
12 +The above copyright notice and this permission notice shall be included in
13 +all copies or substantial portions of the Software.
14 +
15 +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 +THE SOFTWARE.
1 +{
2 + "name": "timed-out",
3 + "version": "4.0.1",
4 + "description": "Emit `ETIMEDOUT` or `ESOCKETTIMEDOUT` when ClientRequest is hanged",
5 + "license": "MIT",
6 + "repository": "floatdrop/timed-out",
7 + "author": {
8 + "name": "Vsevolod Strukchinsky",
9 + "email": "floatdrop@gmail.com"
10 + },
11 + "engines": {
12 + "node": ">=0.10.0"
13 + },
14 + "scripts": {
15 + "test": "xo && mocha"
16 + },
17 + "files": [
18 + "index.js"
19 + ],
20 + "keywords": [
21 + "http",
22 + "https",
23 + "get",
24 + "got",
25 + "url",
26 + "uri",
27 + "request",
28 + "util",
29 + "utility",
30 + "simple"
31 + ],
32 + "devDependencies": {
33 + "mocha": "*",
34 + "xo": "^0.16.0"
35 + }
36 +}
1 +# timed-out [![Build Status](https://travis-ci.org/floatdrop/timed-out.svg?branch=master)](https://travis-ci.org/floatdrop/timed-out)
2 +
3 +> Timeout HTTP/HTTPS requests
4 +
5 +Emit Error object with `code` property equal `ETIMEDOUT` or `ESOCKETTIMEDOUT` when ClientRequest is hanged.
6 +
7 +## Usage
8 +
9 +```js
10 +var get = require('http').get;
11 +var timeout = require('timed-out');
12 +
13 +var req = get('http://www.google.ru');
14 +timeout(req, 2000); // Set 2 seconds limit
15 +```
16 +
17 +### API
18 +
19 +#### timedout(request, time)
20 +
21 +##### request
22 +
23 +*Required*
24 +Type: [`ClientRequest`](http://nodejs.org/api/http.html#http_class_http_clientrequest)
25 +
26 +The request to watch on.
27 +
28 +##### time
29 +
30 +*Required*
31 +Type: `number` or `object`
32 +
33 +Time in milliseconds to wait for `connect` event on socket and also time to wait on inactive socket.
34 +
35 +Or you can pass Object with following fields:
36 +
37 +- `connect` - time to wait for connection
38 +- `socket` - time to wait for activity on socket
39 +
40 +## License
41 +
42 +MIT © [Vsevolod Strukchinsky](floatdrop@gmail.com)
1 +'use strict';
2 +var uniqueRandom = require('unique-random');
3 +
4 +module.exports = function (arr) {
5 + var rand = uniqueRandom(0, arr.length - 1);
6 +
7 + return function () {
8 + return arr[rand()];
9 + };
10 +};
1 +The MIT License (MIT)
2 +
3 +Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (sindresorhus.com)
4 +
5 +Permission is hereby granted, free of charge, to any person obtaining a copy
6 +of this software and associated documentation files (the "Software"), to deal
7 +in the Software without restriction, including without limitation the rights
8 +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 +copies of the Software, and to permit persons to whom the Software is
10 +furnished to do so, subject to the following conditions:
11 +
12 +The above copyright notice and this permission notice shall be included in
13 +all copies or substantial portions of the Software.
14 +
15 +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 +THE SOFTWARE.
1 +{
2 + "name": "unique-random-array",
3 + "version": "1.0.1",
4 + "description": "Get consecutively unique elements from an array",
5 + "keywords": [
6 + "unique",
7 + "uniq",
8 + "random",
9 + "rand",
10 + "number",
11 + "single",
12 + "generate",
13 + "non-repeating",
14 + "array",
15 + "arr",
16 + "item",
17 + "element"
18 + ],
19 + "license": "MIT",
20 + "author": {
21 + "name": "Sindre Sorhus",
22 + "email": "sindresorhus@gmail.com",
23 + "url": "sindresorhus.com"
24 + },
25 + "files": [
26 + "index.js"
27 + ],
28 + "repository": "sindresorhus/unique-random-array",
29 + "scripts": {
30 + "test": "ava"
31 + },
32 + "dependencies": {
33 + "unique-random": "^1.0.0"
34 + },
35 + "devDependencies": {
36 + "ava": "*"
37 + },
38 + "engines": {
39 + "node": ">=0.10.0"
40 + }
41 +}
1 +# unique-random-array [![Build Status](https://travis-ci.org/sindresorhus/unique-random-array.svg?branch=master)](https://travis-ci.org/sindresorhus/unique-random-array)
2 +
3 +> Get consecutively unique elements from an array
4 +
5 +Useful for things like slideshows where you don't want to have the same slide twice in a row.
6 +
7 +
8 +## Install
9 +
10 +```sh
11 +$ npm install --save unique-random-array
12 +```
13 +
14 +
15 +## Usage
16 +
17 +```js
18 +var uniqueRandomArray = require('unique-random-array');
19 +var rand = uniqueRandomArray([1, 2, 3, 4]);
20 +
21 +console.log(rand(), rand(), rand(), rand());
22 +//=> 4 2 1 4
23 +```
24 +
25 +
26 +## API
27 +
28 +### uniqueRandomArray(input)
29 +
30 +Returns a function that when called will return a random element that's never the same as the previous.
31 +
32 +#### input
33 +
34 +*Required*
35 +Type: `array`
36 +
37 +
38 +## Related
39 +
40 +- [unique-random](https://github.com/sindresorhus/unique-random) - Generate random numbers that are consecutively unique
41 +- [random-int](https://github.com/sindresorhus/random-int) - Generate a random integer
42 +- [random-float](https://github.com/sindresorhus/random-float) - Generate a random float
43 +- [random-item](https://github.com/sindresorhus/random-item) - Get a random item from an array
44 +- [random-obj-key](https://github.com/sindresorhus/random-obj-key) - Get a random key from an object
45 +- [random-obj-prop](https://github.com/sindresorhus/random-obj-prop) - Get a random property from an object
46 +- [crypto-random-string](https://github.com/sindresorhus/crypto-random-string) - Generate a cryptographically strong random string
47 +
48 +
49 +## License
50 +
51 +MIT © [Sindre Sorhus](http://sindresorhus.com)
1 +'use strict';
2 +module.exports = function (min, max) {
3 + var prev;
4 + return function rand() {
5 + var num = Math.floor(Math.random() * (max - min + 1) + min);
6 + return prev = num === prev && min !== max ? rand() : num;
7 + };
8 +};
1 +{
2 + "name": "unique-random",
3 + "version": "1.0.0",
4 + "description": "Generate random numbers that are consecutively unique",
5 + "keywords": [
6 + "unique",
7 + "random",
8 + "rand",
9 + "number",
10 + "single",
11 + "generate",
12 + "non-repeating"
13 + ],
14 + "license": "MIT",
15 + "author": {
16 + "name": "Sindre Sorhus",
17 + "email": "sindresorhus@gmail.com",
18 + "url": "http://sindresorhus.com"
19 + },
20 + "files": [
21 + "index.js"
22 + ],
23 + "repository": "sindresorhus/unique-random",
24 + "scripts": {
25 + "test": "mocha"
26 + },
27 + "devDependencies": {
28 + "mocha": "*"
29 + },
30 + "engines": {
31 + "node": ">=0.10.0"
32 + }
33 +}
1 +# unique-random [![Build Status](https://travis-ci.org/sindresorhus/unique-random.svg?branch=master)](https://travis-ci.org/sindresorhus/unique-random)
2 +
3 +> Generate random numbers that are consecutively unique.
4 +
5 +Useful for eg. slideshows where you don't want to have the same slide twice in a row.
6 +
7 +
8 +## Install
9 +
10 +```sh
11 +$ npm install --save unique-random
12 +```
13 +
14 +
15 +## Usage
16 +
17 +```js
18 +var rand = require('unique-random')(1, 10);
19 +console.log(rand(), rand(), rand());
20 +//=> 5 2 6
21 +```
22 +
23 +
24 +## API
25 +
26 +### uniqueRandom(*min*, *max*)
27 +
28 +Returns a function which when called will return a random number that's never the same as the previous number.
29 +
30 +
31 +## License
32 +
33 +MIT © [Sindre Sorhus](http://sindresorhus.com)
1 +'use strict';
2 +const PassThrough = require('stream').PassThrough;
3 +const zlib = require('zlib');
4 +
5 +module.exports = res => {
6 + // TODO: use Array#includes when targeting Node.js 6
7 + if (['gzip', 'deflate'].indexOf(res.headers['content-encoding']) === -1) {
8 + return res;
9 + }
10 +
11 + const unzip = zlib.createUnzip();
12 + const stream = new PassThrough();
13 +
14 + stream.httpVersion = res.httpVersion;
15 + stream.headers = res.headers;
16 + stream.rawHeaders = res.rawHeaders;
17 + stream.trailers = res.trailers;
18 + stream.rawTrailers = res.rawTrailers;
19 + stream.setTimeout = res.setTimeout.bind(res);
20 + stream.statusCode = res.statusCode;
21 + stream.statusMessage = res.statusMessage;
22 + stream.socket = res.socket;
23 +
24 + unzip.on('error', err => {
25 + if (err.code === 'Z_BUF_ERROR') {
26 + stream.end();
27 + return;
28 + }
29 +
30 + stream.emit('error', err);
31 + });
32 +
33 + res.pipe(unzip).pipe(stream);
34 +
35 + return stream;
36 +};
1 +`The MIT License (MIT)
2 +
3 +Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (sindresorhus.com)
4 +
5 +Permission is hereby granted, free of charge, to any person obtaining a copy
6 +of this software and associated documentation files (the "Software"), to deal
7 +in the Software without restriction, including without limitation the rights
8 +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 +copies of the Software, and to permit persons to whom the Software is
10 +furnished to do so, subject to the following conditions:
11 +
12 +The above copyright notice and this permission notice shall be included in
13 +all copies or substantial portions of the Software.
14 +
15 +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 +THE SOFTWARE.
1 +{
2 + "name": "unzip-response",
3 + "version": "2.0.1",
4 + "description": "Unzip a HTTP response if needed",
5 + "license": "MIT",
6 + "repository": "sindresorhus/unzip-response",
7 + "maintainers": [
8 + {
9 + "name": "Sindre Sorhus",
10 + "email": "sindresorhus@gmail.com",
11 + "url": "sindresorhus.com"
12 + },
13 + {
14 + "name": "Vsevolod Strukchinsky",
15 + "email": "floatdrop@gmail.com",
16 + "url": "github.com/floatdrop"
17 + }
18 + ],
19 + "engines": {
20 + "node": ">=4"
21 + },
22 + "scripts": {
23 + "test": "xo && ava"
24 + },
25 + "files": [
26 + "index.js"
27 + ],
28 + "keywords": [
29 + "http",
30 + "unzip",
31 + "zlib",
32 + "gzip",
33 + "deflate",
34 + "incoming",
35 + "message",
36 + "response",
37 + "stream"
38 + ],
39 + "devDependencies": {
40 + "ava": "*",
41 + "get-stream": "^2.3.0",
42 + "pify": "^2.3.0",
43 + "rfpify": "^1.0.0",
44 + "xo": "*"
45 + },
46 + "xo": {
47 + "esnext": true
48 + }
49 +}
1 +# unzip-response [![Build Status](https://travis-ci.org/sindresorhus/unzip-response.svg?branch=master)](https://travis-ci.org/sindresorhus/unzip-response)
2 +
3 +> Unzip a HTTP response if needed
4 +
5 +Unzips the response from [`http.request`](https://nodejs.org/api/http.html#http_http_request_options_callback) if it's gzipped/deflated, otherwise just passes it through.
6 +
7 +
8 +## Install
9 +
10 +```
11 +$ npm install --save unzip-response
12 +```
13 +
14 +
15 +## Usage
16 +
17 +```js
18 +const http = require('http');
19 +const unzipResponse = require('unzip-response');
20 +
21 +http.get('http://sindresorhus.com', res => {
22 + res = unzipResponse(res);
23 +});
24 +```
25 +
26 +
27 +## License
28 +
29 +MIT © [Sindre Sorhus](https://sindresorhus.com)
1 +'use strict';
2 +var url = require('url');
3 +var prependHttp = require('prepend-http');
4 +
5 +module.exports = function (x) {
6 + var withProtocol = prependHttp(x);
7 + var parsed = url.parse(withProtocol);
8 +
9 + if (withProtocol !== x) {
10 + parsed.protocol = null;
11 + }
12 +
13 + return parsed;
14 +};
1 +The MIT License (MIT)
2 +
3 +Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (sindresorhus.com)
4 +
5 +Permission is hereby granted, free of charge, to any person obtaining a copy
6 +of this software and associated documentation files (the "Software"), to deal
7 +in the Software without restriction, including without limitation the rights
8 +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 +copies of the Software, and to permit persons to whom the Software is
10 +furnished to do so, subject to the following conditions:
11 +
12 +The above copyright notice and this permission notice shall be included in
13 +all copies or substantial portions of the Software.
14 +
15 +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 +THE SOFTWARE.
1 +{
2 + "name": "url-parse-lax",
3 + "version": "1.0.0",
4 + "description": "url.parse() with support for protocol-less URLs & IPs",
5 + "license": "MIT",
6 + "repository": "sindresorhus/url-parse-lax",
7 + "author": {
8 + "name": "Sindre Sorhus",
9 + "email": "sindresorhus@gmail.com",
10 + "url": "sindresorhus.com"
11 + },
12 + "engines": {
13 + "node": ">=0.10.0"
14 + },
15 + "scripts": {
16 + "test": "node test.js"
17 + },
18 + "files": [
19 + "index.js"
20 + ],
21 + "keywords": [
22 + "url",
23 + "uri",
24 + "parse",
25 + "parser",
26 + "loose",
27 + "lax",
28 + "protocol",
29 + "less",
30 + "protocol-less",
31 + "ip",
32 + "ipv4",
33 + "ipv6"
34 + ],
35 + "dependencies": {
36 + "prepend-http": "^1.0.1"
37 + },
38 + "devDependencies": {
39 + "ava": "0.0.4"
40 + }
41 +}
1 +# url-parse-lax [![Build Status](https://travis-ci.org/sindresorhus/url-parse-lax.svg?branch=master)](https://travis-ci.org/sindresorhus/url-parse-lax)
2 +
3 +> [`url.parse()`](https://nodejs.org/docs/latest/api/url.html#url_url_parse_urlstr_parsequerystring_slashesdenotehost) with support for protocol-less URLs & IPs
4 +
5 +
6 +## Install
7 +
8 +```
9 +$ npm install --save url-parse-lax
10 +```
11 +
12 +
13 +## Usage
14 +
15 +```js
16 +var urlParseLax = require('url-parse-lax');
17 +
18 +urlParseLax('sindresorhus.com');
19 +/*
20 +{
21 + protocol: null,
22 + slashes: true,
23 + auth: null,
24 + host: 'sindresorhus.com',
25 + port: null,
26 + hostname: 'sindresorhus.com',
27 + hash: null,
28 + search: null,
29 + query: null,
30 + pathname: '/',
31 + path: '/',
32 + href: 'http://sindresorhus.com/'
33 +}
34 +*/
35 +
36 +urlParseLax('[2001:db8::]:8000');
37 +/*
38 +{
39 + protocol: null,
40 + slashes: true,
41 + auth: null,
42 + host: '[2001:db8::]:8000',
43 + port: '8000',
44 + hostname: '2001:db8::',
45 + hash: null,
46 + search: null,
47 + query: null,
48 + pathname: '/',
49 + path: '/',
50 + href: 'http://[2001:db8::]:8000/'
51 +}
52 +*/
53 +```
54 +
55 +And with the built-in `url.parse()`:
56 +
57 +```js
58 +var url = require('url');
59 +
60 +url.parse('sindresorhus.com');
61 +/*
62 +{
63 + protocol: null,
64 + slashes: null,
65 + auth: null,
66 + host: null,
67 + port: null,
68 + hostname: null,
69 + hash: null,
70 + search: null,
71 + query: null,
72 + pathname: 'sindresorhus',
73 + path: 'sindresorhus',
74 + href: 'sindresorhus'
75 +}
76 +*/
77 +
78 +url.parse('[2001:db8::]:8000');
79 +/*
80 +{
81 + protocol: null,
82 + slashes: null,
83 + auth: null,
84 + host: null,
85 + port: null,
86 + hostname: null,
87 + hash: null,
88 + search: null,
89 + query: null,
90 + pathname: '[2001:db8::]:8000',
91 + path: '[2001:db8::]:8000',
92 + href: '[2001:db8::]:8000'
93 +}
94 +*/
95 +```
96 +
97 +
98 +## License
99 +
100 +MIT © [Sindre Sorhus](http://sindresorhus.com)