Minty U

delete useless files

Showing 336 changed files with 0 additions and 5043 deletions
This file is too large to display.
This file is too large to display.
This file is too large to display.
1 -#!/bin/sh
2 -basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
3 -
4 -case `uname` in
5 - *CYGWIN*|*MINGW*|*MSYS*) basedir=`cygpath -w "$basedir"`;;
6 -esac
7 -
8 -if [ -x "$basedir/node" ]; then
9 - exec "$basedir/node" "$basedir/../jpeg-autorotate/src/cli.js" "$@"
10 -else
11 - exec node "$basedir/../jpeg-autorotate/src/cli.js" "$@"
12 -fi
1 -@ECHO off
2 -GOTO start
3 -:find_dp0
4 -SET dp0=%~dp0
5 -EXIT /b
6 -:start
7 -SETLOCAL
8 -CALL :find_dp0
9 -
10 -IF EXIST "%dp0%\node.exe" (
11 - SET "_prog=%dp0%\node.exe"
12 -) ELSE (
13 - SET "_prog=node"
14 - SET PATHEXT=%PATHEXT:;.JS;=;%
15 -)
16 -
17 -endLocal & goto #_undefined_# 2>NUL || title %COMSPEC% & "%_prog%" "%dp0%\..\jpeg-autorotate\src\cli.js" %*
1 -#!/usr/bin/env pwsh
2 -$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent
3 -
4 -$exe=""
5 -if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) {
6 - # Fix case when both the Windows and Linux builds of Node
7 - # are installed in the same directory
8 - $exe=".exe"
9 -}
10 -$ret=0
11 -if (Test-Path "$basedir/node$exe") {
12 - # Support pipeline input
13 - if ($MyInvocation.ExpectingInput) {
14 - $input | & "$basedir/node$exe" "$basedir/../jpeg-autorotate/src/cli.js" $args
15 - } else {
16 - & "$basedir/node$exe" "$basedir/../jpeg-autorotate/src/cli.js" $args
17 - }
18 - $ret=$LASTEXITCODE
19 -} else {
20 - # Support pipeline input
21 - if ($MyInvocation.ExpectingInput) {
22 - $input | & "node$exe" "$basedir/../jpeg-autorotate/src/cli.js" $args
23 - } else {
24 - & "node$exe" "$basedir/../jpeg-autorotate/src/cli.js" $args
25 - }
26 - $ret=$LASTEXITCODE
27 -}
28 -exit $ret
1 -#!/bin/sh
2 -basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
3 -
4 -case `uname` in
5 - *CYGWIN*|*MINGW*|*MSYS*) basedir=`cygpath -w "$basedir"`;;
6 -esac
7 -
8 -if [ -x "$basedir/node" ]; then
9 - exec "$basedir/node" "$basedir/../opencollective-postinstall/index.js" "$@"
10 -else
11 - exec node "$basedir/../opencollective-postinstall/index.js" "$@"
12 -fi
1 -@ECHO off
2 -GOTO start
3 -:find_dp0
4 -SET dp0=%~dp0
5 -EXIT /b
6 -:start
7 -SETLOCAL
8 -CALL :find_dp0
9 -
10 -IF EXIST "%dp0%\node.exe" (
11 - SET "_prog=%dp0%\node.exe"
12 -) ELSE (
13 - SET "_prog=node"
14 - SET PATHEXT=%PATHEXT:;.JS;=;%
15 -)
16 -
17 -endLocal & goto #_undefined_# 2>NUL || title %COMSPEC% & "%_prog%" "%dp0%\..\opencollective-postinstall\index.js" %*
1 -#!/usr/bin/env pwsh
2 -$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent
3 -
4 -$exe=""
5 -if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) {
6 - # Fix case when both the Windows and Linux builds of Node
7 - # are installed in the same directory
8 - $exe=".exe"
9 -}
10 -$ret=0
11 -if (Test-Path "$basedir/node$exe") {
12 - # Support pipeline input
13 - if ($MyInvocation.ExpectingInput) {
14 - $input | & "$basedir/node$exe" "$basedir/../opencollective-postinstall/index.js" $args
15 - } else {
16 - & "$basedir/node$exe" "$basedir/../opencollective-postinstall/index.js" $args
17 - }
18 - $ret=$LASTEXITCODE
19 -} else {
20 - # Support pipeline input
21 - if ($MyInvocation.ExpectingInput) {
22 - $input | & "node$exe" "$basedir/../opencollective-postinstall/index.js" $args
23 - } else {
24 - & "node$exe" "$basedir/../opencollective-postinstall/index.js" $args
25 - }
26 - $ret=$LASTEXITCODE
27 -}
28 -exit $ret
This diff is collapsed. Click to expand it.
1 -MIT License
2 -
3 -Copyright (c) 2018 Szymon Marczak
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 -# http-timer
2 -> Timings for HTTP requests
3 -
4 -[![Build Status](https://travis-ci.org/szmarczak/http-timer.svg?branch=master)](https://travis-ci.org/szmarczak/http-timer)
5 -[![Coverage Status](https://coveralls.io/repos/github/szmarczak/http-timer/badge.svg?branch=master)](https://coveralls.io/github/szmarczak/http-timer?branch=master)
6 -[![install size](https://packagephobia.now.sh/badge?p=@szmarczak/http-timer)](https://packagephobia.now.sh/result?p=@szmarczak/http-timer)
7 -
8 -Inspired by the [`request` package](https://github.com/request/request).
9 -
10 -## Usage
11 -```js
12 -'use strict';
13 -const https = require('https');
14 -const timer = require('@szmarczak/http-timer');
15 -
16 -const request = https.get('https://httpbin.org/anything');
17 -const timings = timer(request);
18 -
19 -request.on('response', response => {
20 - response.on('data', () => {}); // Consume the data somehow
21 - response.on('end', () => {
22 - console.log(timings);
23 - });
24 -});
25 -
26 -// { start: 1535708511443,
27 -// socket: 1535708511444,
28 -// lookup: 1535708511444,
29 -// connect: 1535708511582,
30 -// upload: 1535708511887,
31 -// response: 1535708512037,
32 -// end: 1535708512040,
33 -// phases:
34 -// { wait: 1,
35 -// dns: 0,
36 -// tcp: 138,
37 -// request: 305,
38 -// firstByte: 150,
39 -// download: 3,
40 -// total: 597 } }
41 -```
42 -
43 -## API
44 -
45 -### timer(request)
46 -
47 -Returns: `Object`
48 -
49 -- `start` - Time when the request started.
50 -- `socket` - Time when a socket was assigned to the request.
51 -- `lookup` - Time when the DNS lookup finished.
52 -- `connect` - Time when the socket successfully connected.
53 -- `upload` - Time when the request finished uploading.
54 -- `response` - Time when the request fired the `response` event.
55 -- `end` - Time when the response fired the `end` event.
56 -- `error` - Time when the request fired the `error` event.
57 -- `phases`
58 - - `wait` - `timings.socket - timings.start`
59 - - `dns` - `timings.lookup - timings.socket`
60 - - `tcp` - `timings.connect - timings.lookup`
61 - - `request` - `timings.upload - timings.connect`
62 - - `firstByte` - `timings.response - timings.upload`
63 - - `download` - `timings.end - timings.response`
64 - - `total` - `timings.end - timings.start` or `timings.error - timings.start`
65 -
66 -**Note**: The time is a `number` representing the milliseconds elapsed since the UNIX epoch.
67 -
68 -## License
69 -
70 -MIT
1 -{
2 - "name": "@szmarczak/http-timer",
3 - "version": "1.1.2",
4 - "description": "Timings for HTTP requests",
5 - "main": "source",
6 - "engines": {
7 - "node": ">=6"
8 - },
9 - "scripts": {
10 - "test": "xo && nyc ava",
11 - "coveralls": "nyc report --reporter=text-lcov | coveralls"
12 - },
13 - "files": [
14 - "source"
15 - ],
16 - "keywords": [
17 - "http",
18 - "https",
19 - "timer",
20 - "timings"
21 - ],
22 - "repository": {
23 - "type": "git",
24 - "url": "git+https://github.com/szmarczak/http-timer.git"
25 - },
26 - "author": "Szymon Marczak",
27 - "license": "MIT",
28 - "bugs": {
29 - "url": "https://github.com/szmarczak/http-timer/issues"
30 - },
31 - "homepage": "https://github.com/szmarczak/http-timer#readme",
32 - "xo": {
33 - "rules": {
34 - "unicorn/filename-case": "camelCase"
35 - }
36 - },
37 - "devDependencies": {
38 - "ava": "^0.25.0",
39 - "coveralls": "^3.0.2",
40 - "p-event": "^2.1.0",
41 - "nyc": "^12.0.2",
42 - "xo": "^0.22.0"
43 - },
44 - "dependencies": {
45 - "defer-to-connect": "^1.0.1"
46 - }
47 -}
1 -'use strict';
2 -const deferToConnect = require('defer-to-connect');
3 -
4 -module.exports = request => {
5 - const timings = {
6 - start: Date.now(),
7 - socket: null,
8 - lookup: null,
9 - connect: null,
10 - upload: null,
11 - response: null,
12 - end: null,
13 - error: null,
14 - phases: {
15 - wait: null,
16 - dns: null,
17 - tcp: null,
18 - request: null,
19 - firstByte: null,
20 - download: null,
21 - total: null
22 - }
23 - };
24 -
25 - const handleError = origin => {
26 - const emit = origin.emit.bind(origin);
27 - origin.emit = (event, ...args) => {
28 - // Catches the `error` event
29 - if (event === 'error') {
30 - timings.error = Date.now();
31 - timings.phases.total = timings.error - timings.start;
32 -
33 - origin.emit = emit;
34 - }
35 -
36 - // Saves the original behavior
37 - return emit(event, ...args);
38 - };
39 - };
40 -
41 - let uploadFinished = false;
42 - const onUpload = () => {
43 - timings.upload = Date.now();
44 - timings.phases.request = timings.upload - timings.connect;
45 - };
46 -
47 - handleError(request);
48 -
49 - request.once('socket', socket => {
50 - timings.socket = Date.now();
51 - timings.phases.wait = timings.socket - timings.start;
52 -
53 - const lookupListener = () => {
54 - timings.lookup = Date.now();
55 - timings.phases.dns = timings.lookup - timings.socket;
56 - };
57 -
58 - socket.once('lookup', lookupListener);
59 -
60 - deferToConnect(socket, () => {
61 - timings.connect = Date.now();
62 -
63 - if (timings.lookup === null) {
64 - socket.removeListener('lookup', lookupListener);
65 - timings.lookup = timings.connect;
66 - timings.phases.dns = timings.lookup - timings.socket;
67 - }
68 -
69 - timings.phases.tcp = timings.connect - timings.lookup;
70 -
71 - if (uploadFinished && !timings.upload) {
72 - onUpload();
73 - }
74 - });
75 - });
76 -
77 - request.once('finish', () => {
78 - uploadFinished = true;
79 -
80 - if (timings.connect) {
81 - onUpload();
82 - }
83 - });
84 -
85 - request.once('response', response => {
86 - timings.response = Date.now();
87 - timings.phases.firstByte = timings.response - timings.upload;
88 -
89 - handleError(response);
90 -
91 - response.once('end', () => {
92 - timings.end = Date.now();
93 - timings.phases.download = timings.end - timings.response;
94 - timings.phases.total = timings.end - timings.start;
95 - });
96 - });
97 -
98 - return timings;
99 -};
1 -language: node_js
2 -node_js:
3 - - "0.10"
4 - - "0.12"
5 - - "iojs"
1 -Copyright (c) 2010-2014 Caolan McMahon
2 -
3 -Permission is hereby granted, free of charge, to any person obtaining a copy
4 -of this software and associated documentation files (the "Software"), to deal
5 -in the Software without restriction, including without limitation the rights
6 -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7 -copies of the Software, and to permit persons to whom the Software is
8 -furnished to do so, subject to the following conditions:
9 -
10 -The above copyright notice and this permission notice shall be included in
11 -all copies or substantial portions of the Software.
12 -
13 -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19 -THE SOFTWARE.
This diff is collapsed. Click to expand it.
1 -{
2 - "name": "async",
3 - "description": "Higher-order functions and common patterns for asynchronous code",
4 - "version": "0.9.2",
5 - "main": "lib/async.js",
6 - "keywords": [
7 - "async",
8 - "callback",
9 - "utility",
10 - "module"
11 - ],
12 - "license": "MIT",
13 - "repository": {
14 - "type": "git",
15 - "url": "https://github.com/caolan/async.git"
16 - },
17 - "devDependencies": {
18 - "nodeunit": ">0.0.0",
19 - "uglify-js": "1.2.x",
20 - "nodelint": ">0.0.0",
21 - "lodash": ">=2.4.1"
22 - },
23 - "moduleType": [
24 - "amd",
25 - "globals",
26 - "node"
27 - ],
28 - "ignore": [
29 - "**/.*",
30 - "node_modules",
31 - "bower_components",
32 - "test",
33 - "tests"
34 - ],
35 - "authors": [
36 - "Caolan McMahon"
37 - ]
38 -}
...\ No newline at end of file ...\ No newline at end of file
1 -{
2 - "name": "async",
3 - "description": "Higher-order functions and common patterns for asynchronous code",
4 - "version": "0.9.2",
5 - "keywords": [
6 - "async",
7 - "callback",
8 - "utility",
9 - "module"
10 - ],
11 - "license": "MIT",
12 - "repository": "caolan/async",
13 - "scripts": [
14 - "lib/async.js"
15 - ]
16 -}
...\ No newline at end of file ...\ No newline at end of file
This diff is collapsed. Click to expand it.
1 -{
2 - "name": "async",
3 - "description": "Higher-order functions and common patterns for asynchronous code",
4 - "main": "lib/async.js",
5 - "author": "Caolan McMahon",
6 - "version": "0.9.2",
7 - "keywords": [
8 - "async",
9 - "callback",
10 - "utility",
11 - "module"
12 - ],
13 - "repository": {
14 - "type": "git",
15 - "url": "https://github.com/caolan/async.git"
16 - },
17 - "bugs": {
18 - "url": "https://github.com/caolan/async/issues"
19 - },
20 - "license": "MIT",
21 - "devDependencies": {
22 - "nodeunit": ">0.0.0",
23 - "uglify-js": "1.2.x",
24 - "nodelint": ">0.0.0",
25 - "lodash": ">=2.4.1"
26 - },
27 - "jam": {
28 - "main": "lib/async.js",
29 - "include": [
30 - "lib/async.js",
31 - "README.md",
32 - "LICENSE"
33 - ],
34 - "categories": [
35 - "Utilities"
36 - ]
37 - },
38 - "scripts": {
39 - "test": "nodeunit test/test-async.js"
40 - },
41 - "spm": {
42 - "main": "lib/async.js"
43 - },
44 - "volo": {
45 - "main": "lib/async.js",
46 - "ignore": [
47 - "**/.*",
48 - "node_modules",
49 - "bower_components",
50 - "test",
51 - "tests"
52 - ]
53 - }
54 -}
...\ No newline at end of file ...\ No newline at end of file
1 -#!/usr/bin/env node
2 -
3 -// This should probably be its own module but complaints about bower/etc.
4 -// support keep coming up and I'd rather just enable the workflow here for now
5 -// and figure out where this should live later. -- @beaugunderson
6 -
7 -var fs = require('fs');
8 -var _ = require('lodash');
9 -
10 -var packageJson = require('../package.json');
11 -
12 -var IGNORES = ['**/.*', 'node_modules', 'bower_components', 'test', 'tests'];
13 -var INCLUDES = ['lib/async.js', 'README.md', 'LICENSE'];
14 -var REPOSITORY_NAME = 'caolan/async';
15 -
16 -packageJson.jam = {
17 - main: packageJson.main,
18 - include: INCLUDES,
19 - categories: ['Utilities']
20 -};
21 -
22 -packageJson.spm = {
23 - main: packageJson.main
24 -};
25 -
26 -packageJson.volo = {
27 - main: packageJson.main,
28 - ignore: IGNORES
29 -};
30 -
31 -var bowerSpecific = {
32 - moduleType: ['amd', 'globals', 'node'],
33 - ignore: IGNORES,
34 - authors: [packageJson.author]
35 -};
36 -
37 -var bowerInclude = ['name', 'description', 'version', 'main', 'keywords',
38 - 'license', 'homepage', 'repository', 'devDependencies'];
39 -
40 -var componentSpecific = {
41 - repository: REPOSITORY_NAME,
42 - scripts: [packageJson.main]
43 -};
44 -
45 -var componentInclude = ['name', 'description', 'version', 'keywords',
46 - 'license'];
47 -
48 -var bowerJson = _.merge({}, _.pick(packageJson, bowerInclude), bowerSpecific);
49 -var componentJson = _.merge({}, _.pick(packageJson, componentInclude), componentSpecific);
50 -
51 -fs.writeFileSync('./bower.json', JSON.stringify(bowerJson, null, 2));
52 -fs.writeFileSync('./component.json', JSON.stringify(componentJson, null, 2));
53 -fs.writeFileSync('./package.json', JSON.stringify(packageJson, null, 2));
1 -MIT License
2 -
3 -Copyright (c) 2017 Luke Childs
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 -# cacheable-request
2 -
3 -> Wrap native HTTP requests with RFC compliant cache support
4 -
5 -[![Build Status](https://travis-ci.org/lukechilds/cacheable-request.svg?branch=master)](https://travis-ci.org/lukechilds/cacheable-request)
6 -[![Coverage Status](https://coveralls.io/repos/github/lukechilds/cacheable-request/badge.svg?branch=master)](https://coveralls.io/github/lukechilds/cacheable-request?branch=master)
7 -[![npm](https://img.shields.io/npm/dm/cacheable-request.svg)](https://www.npmjs.com/package/cacheable-request)
8 -[![npm](https://img.shields.io/npm/v/cacheable-request.svg)](https://www.npmjs.com/package/cacheable-request)
9 -
10 -[RFC 7234](http://httpwg.org/specs/rfc7234.html) compliant HTTP caching for native Node.js HTTP/HTTPS requests. Caching works out of the box in memory or is easily pluggable with a wide range of storage adapters.
11 -
12 -**Note:** This is a low level wrapper around the core HTTP modules, it's not a high level request library.
13 -
14 -## Features
15 -
16 -- Only stores cacheable responses as defined by RFC 7234
17 -- Fresh cache entries are served directly from cache
18 -- Stale cache entries are revalidated with `If-None-Match`/`If-Modified-Since` headers
19 -- 304 responses from revalidation requests use cached body
20 -- Updates `Age` header on cached responses
21 -- Can completely bypass cache on a per request basis
22 -- In memory cache by default
23 -- Official support for Redis, MongoDB, SQLite, PostgreSQL and MySQL storage adapters
24 -- Easily plug in your own or third-party storage adapters
25 -- If DB connection fails, cache is automatically bypassed ([disabled by default](#optsautomaticfailover))
26 -- Adds cache support to any existing HTTP code with minimal changes
27 -- Uses [http-cache-semantics](https://github.com/pornel/http-cache-semantics) internally for HTTP RFC 7234 compliance
28 -
29 -## Install
30 -
31 -```shell
32 -npm install cacheable-request
33 -```
34 -
35 -## Usage
36 -
37 -```js
38 -const http = require('http');
39 -const CacheableRequest = require('cacheable-request');
40 -
41 -// Then instead of
42 -const req = http.request('http://example.com', cb);
43 -req.end();
44 -
45 -// You can do
46 -const cacheableRequest = new CacheableRequest(http.request);
47 -const cacheReq = cacheableRequest('http://example.com', cb);
48 -cacheReq.on('request', req => req.end());
49 -// Future requests to 'example.com' will be returned from cache if still valid
50 -
51 -// You pass in any other http.request API compatible method to be wrapped with cache support:
52 -const cacheableRequest = new CacheableRequest(https.request);
53 -const cacheableRequest = new CacheableRequest(electron.net);
54 -```
55 -
56 -## Storage Adapters
57 -
58 -`cacheable-request` uses [Keyv](https://github.com/lukechilds/keyv) to support a wide range of storage adapters.
59 -
60 -For example, to use Redis as a cache backend, you just need to install the official Redis Keyv storage adapter:
61 -
62 -```
63 -npm install @keyv/redis
64 -```
65 -
66 -And then you can pass `CacheableRequest` your connection string:
67 -
68 -```js
69 -const cacheableRequest = new CacheableRequest(http.request, 'redis://user:pass@localhost:6379');
70 -```
71 -
72 -[View all official Keyv storage adapters.](https://github.com/lukechilds/keyv#official-storage-adapters)
73 -
74 -Keyv also supports anything that follows the Map API so it's easy to write your own storage adapter or use a third-party solution.
75 -
76 -e.g The following are all valid storage adapters
77 -
78 -```js
79 -const storageAdapter = new Map();
80 -// or
81 -const storageAdapter = require('./my-storage-adapter');
82 -// or
83 -const QuickLRU = require('quick-lru');
84 -const storageAdapter = new QuickLRU({ maxSize: 1000 });
85 -
86 -const cacheableRequest = new CacheableRequest(http.request, storageAdapter);
87 -```
88 -
89 -View the [Keyv docs](https://github.com/lukechilds/keyv) for more information on how to use storage adapters.
90 -
91 -## API
92 -
93 -### new cacheableRequest(request, [storageAdapter])
94 -
95 -Returns the provided request function wrapped with cache support.
96 -
97 -#### request
98 -
99 -Type: `function`
100 -
101 -Request function to wrap with cache support. Should be [`http.request`](https://nodejs.org/api/http.html#http_http_request_options_callback) or a similar API compatible request function.
102 -
103 -#### storageAdapter
104 -
105 -Type: `Keyv storage adapter`<br>
106 -Default: `new Map()`
107 -
108 -A [Keyv](https://github.com/lukechilds/keyv) storage adapter instance, or connection string if using with an official Keyv storage adapter.
109 -
110 -### Instance
111 -
112 -#### cacheableRequest(opts, [cb])
113 -
114 -Returns an event emitter.
115 -
116 -##### opts
117 -
118 -Type: `object`, `string`
119 -
120 -- Any of the default request functions options.
121 -- Any [`http-cache-semantics`](https://github.com/kornelski/http-cache-semantics#constructor-options) options.
122 -- Any of the following:
123 -
124 -###### opts.cache
125 -
126 -Type: `boolean`<br>
127 -Default: `true`
128 -
129 -If the cache should be used. Setting this to false will completely bypass the cache for the current request.
130 -
131 -###### opts.strictTtl
132 -
133 -Type: `boolean`<br>
134 -Default: `false`
135 -
136 -If set to `true` once a cached resource has expired it is deleted and will have to be re-requested.
137 -
138 -If set to `false` (default), after a cached resource's TTL expires it is kept in the cache and will be revalidated on the next request with `If-None-Match`/`If-Modified-Since` headers.
139 -
140 -###### opts.maxTtl
141 -
142 -Type: `number`<br>
143 -Default: `undefined`
144 -
145 -Limits TTL. The `number` represents milliseconds.
146 -
147 -###### opts.automaticFailover
148 -
149 -Type: `boolean`<br>
150 -Default: `false`
151 -
152 -When set to `true`, if the DB connection fails we will automatically fallback to a network request. DB errors will still be emitted to notify you of the problem even though the request callback may succeed.
153 -
154 -###### opts.forceRefresh
155 -
156 -Type: `boolean`<br>
157 -Default: `false`
158 -
159 -Forces refreshing the cache. If the response could be retrieved from the cache, it will perform a new request and override the cache instead.
160 -
161 -##### cb
162 -
163 -Type: `function`
164 -
165 -The callback function which will receive the response as an argument.
166 -
167 -The response can be either a [Node.js HTTP response stream](https://nodejs.org/api/http.html#http_class_http_incomingmessage) or a [responselike object](https://github.com/lukechilds/responselike). The response will also have a `fromCache` property set with a boolean value.
168 -
169 -##### .on('request', request)
170 -
171 -`request` event to get the request object of the request.
172 -
173 -**Note:** This event will only fire if an HTTP request is actually made, not when a response is retrieved from cache. However, you should always handle the `request` event to end the request and handle any potential request errors.
174 -
175 -##### .on('response', response)
176 -
177 -`response` event to get the response object from the HTTP request or cache.
178 -
179 -##### .on('error', error)
180 -
181 -`error` event emitted in case of an error with the cache.
182 -
183 -Errors emitted here will be an instance of `CacheableRequest.RequestError` or `CacheableRequest.CacheError`. You will only ever receive a `RequestError` if the request function throws (normally caused by invalid user input). Normal request errors should be handled inside the `request` event.
184 -
185 -To properly handle all error scenarios you should use the following pattern:
186 -
187 -```js
188 -cacheableRequest('example.com', cb)
189 - .on('error', err => {
190 - if (err instanceof CacheableRequest.CacheError) {
191 - handleCacheError(err); // Cache error
192 - } else if (err instanceof CacheableRequest.RequestError) {
193 - handleRequestError(err); // Request function thrown
194 - }
195 - })
196 - .on('request', req => {
197 - req.on('error', handleRequestError); // Request error emitted
198 - req.end();
199 - });
200 -```
201 -
202 -**Note:** Database connection errors are emitted here, however `cacheable-request` will attempt to re-request the resource and bypass the cache on a connection error. Therefore a database connection error doesn't necessarily mean the request won't be fulfilled.
203 -
204 -## License
205 -
206 -MIT © Luke Childs
1 -'use strict';
2 -const {PassThrough: PassThroughStream} = require('stream');
3 -
4 -module.exports = options => {
5 - options = {...options};
6 -
7 - const {array} = options;
8 - let {encoding} = options;
9 - const isBuffer = encoding === 'buffer';
10 - let objectMode = false;
11 -
12 - if (array) {
13 - objectMode = !(encoding || isBuffer);
14 - } else {
15 - encoding = encoding || 'utf8';
16 - }
17 -
18 - if (isBuffer) {
19 - encoding = null;
20 - }
21 -
22 - const stream = new PassThroughStream({objectMode});
23 -
24 - if (encoding) {
25 - stream.setEncoding(encoding);
26 - }
27 -
28 - let length = 0;
29 - const chunks = [];
30 -
31 - stream.on('data', chunk => {
32 - chunks.push(chunk);
33 -
34 - if (objectMode) {
35 - length = chunks.length;
36 - } else {
37 - length += chunk.length;
38 - }
39 - });
40 -
41 - stream.getBufferedValue = () => {
42 - if (array) {
43 - return chunks;
44 - }
45 -
46 - return isBuffer ? Buffer.concat(chunks, length) : chunks.join('');
47 - };
48 -
49 - stream.getBufferedLength = () => length;
50 -
51 - return stream;
52 -};
1 -/// <reference types="node"/>
2 -import {Stream} from 'stream';
3 -
4 -declare class MaxBufferErrorClass extends Error {
5 - readonly name: 'MaxBufferError';
6 - constructor();
7 -}
8 -
9 -declare namespace getStream {
10 - interface Options {
11 - /**
12 - Maximum length of the returned string. If it exceeds this value before the stream ends, the promise will be rejected with a `MaxBufferError` error.
13 -
14 - @default Infinity
15 - */
16 - readonly maxBuffer?: number;
17 - }
18 -
19 - interface OptionsWithEncoding<EncodingType = BufferEncoding> extends Options {
20 - /**
21 - [Encoding](https://nodejs.org/api/buffer.html#buffer_buffer) of the incoming stream.
22 -
23 - @default 'utf8'
24 - */
25 - readonly encoding?: EncodingType;
26 - }
27 -
28 - type MaxBufferError = MaxBufferErrorClass;
29 -}
30 -
31 -declare const getStream: {
32 - /**
33 - Get the `stream` as a string.
34 -
35 - @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.
36 -
37 - @example
38 - ```
39 - import * as fs from 'fs';
40 - import getStream = require('get-stream');
41 -
42 - (async () => {
43 - const stream = fs.createReadStream('unicorn.txt');
44 -
45 - console.log(await getStream(stream));
46 - // ,,))))))));,
47 - // __)))))))))))))),
48 - // \|/ -\(((((''''((((((((.
49 - // -*-==//////(('' . `)))))),
50 - // /|\ ))| o ;-. '((((( ,(,
51 - // ( `| / ) ;))))' ,_))^;(~
52 - // | | | ,))((((_ _____------~~~-. %,;(;(>';'~
53 - // o_); ; )))(((` ~---~ `:: \ %%~~)(v;(`('~
54 - // ; ''''```` `: `:::|\,__,%% );`'; ~
55 - // | _ ) / `:|`----' `-'
56 - // ______/\/~ | / /
57 - // /~;;.____/;;' / ___--,-( `;;;/
58 - // / // _;______;'------~~~~~ /;;/\ /
59 - // // | | / ; \;;,\
60 - // (<_ | ; /',/-----' _>
61 - // \_| ||_ //~;~~~~~~~~~
62 - // `\_| (,~~
63 - // \~\
64 - // ~~
65 - })();
66 - ```
67 - */
68 - (stream: Stream, options?: getStream.OptionsWithEncoding): Promise<string>;
69 -
70 - /**
71 - Get the `stream` as a buffer.
72 -
73 - It honors the `maxBuffer` option as above, but it refers to byte length rather than string length.
74 - */
75 - buffer(
76 - stream: Stream,
77 - options?: getStream.OptionsWithEncoding
78 - ): Promise<Buffer>;
79 -
80 - /**
81 - Get the `stream` as an array of values.
82 -
83 - It honors both the `maxBuffer` and `encoding` options. The behavior changes slightly based on the encoding chosen:
84 -
85 - - 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).
86 - - 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.
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 - array<StreamObjectModeType>(
90 - stream: Stream,
91 - options?: getStream.Options
92 - ): Promise<StreamObjectModeType[]>;
93 - array(
94 - stream: Stream,
95 - options: getStream.OptionsWithEncoding<'buffer'>
96 - ): Promise<Buffer[]>;
97 - array(
98 - stream: Stream,
99 - options: getStream.OptionsWithEncoding<BufferEncoding>
100 - ): Promise<string[]>;
101 -
102 - MaxBufferError: typeof MaxBufferErrorClass;
103 -
104 - // TODO: Remove this for the next major release
105 - default: typeof getStream;
106 -};
107 -
108 -export = getStream;
1 -'use strict';
2 -const {constants: BufferConstants} = require('buffer');
3 -const pump = require('pump');
4 -const bufferStream = require('./buffer-stream');
5 -
6 -class MaxBufferError extends Error {
7 - constructor() {
8 - super('maxBuffer exceeded');
9 - this.name = 'MaxBufferError';
10 - }
11 -}
12 -
13 -async function getStream(inputStream, options) {
14 - if (!inputStream) {
15 - return Promise.reject(new Error('Expected a stream'));
16 - }
17 -
18 - options = {
19 - maxBuffer: Infinity,
20 - ...options
21 - };
22 -
23 - const {maxBuffer} = options;
24 -
25 - let stream;
26 - await new Promise((resolve, reject) => {
27 - const rejectPromise = error => {
28 - // Don't retrieve an oversized buffer.
29 - if (error && stream.getBufferedLength() <= BufferConstants.MAX_LENGTH) {
30 - error.bufferedData = stream.getBufferedValue();
31 - }
32 -
33 - reject(error);
34 - };
35 -
36 - stream = pump(inputStream, bufferStream(options), error => {
37 - if (error) {
38 - rejectPromise(error);
39 - return;
40 - }
41 -
42 - resolve();
43 - });
44 -
45 - stream.on('data', () => {
46 - if (stream.getBufferedLength() > maxBuffer) {
47 - rejectPromise(new MaxBufferError());
48 - }
49 - });
50 - });
51 -
52 - return stream.getBufferedValue();
53 -}
54 -
55 -module.exports = getStream;
56 -// TODO: Remove this for the next major release
57 -module.exports.default = getStream;
58 -module.exports.buffer = (stream, options) => getStream(stream, {...options, encoding: 'buffer'});
59 -module.exports.array = (stream, options) => getStream(stream, {...options, array: true});
60 -module.exports.MaxBufferError = MaxBufferError;
1 -MIT License
2 -
3 -Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (https://sindresorhus.com)
4 -
5 -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
6 -
7 -The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
8 -
9 -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
1 -{
2 - "name": "get-stream",
3 - "version": "5.2.0",
4 - "description": "Get a stream as a string, buffer, or array",
5 - "license": "MIT",
6 - "repository": "sindresorhus/get-stream",
7 - "funding": "https://github.com/sponsors/sindresorhus",
8 - "author": {
9 - "name": "Sindre Sorhus",
10 - "email": "sindresorhus@gmail.com",
11 - "url": "https://sindresorhus.com"
12 - },
13 - "engines": {
14 - "node": ">=8"
15 - },
16 - "scripts": {
17 - "test": "xo && ava && tsd"
18 - },
19 - "files": [
20 - "index.js",
21 - "index.d.ts",
22 - "buffer-stream.js"
23 - ],
24 - "keywords": [
25 - "get",
26 - "stream",
27 - "promise",
28 - "concat",
29 - "string",
30 - "text",
31 - "buffer",
32 - "read",
33 - "data",
34 - "consume",
35 - "readable",
36 - "readablestream",
37 - "array",
38 - "object"
39 - ],
40 - "dependencies": {
41 - "pump": "^3.0.0"
42 - },
43 - "devDependencies": {
44 - "@types/node": "^12.0.7",
45 - "ava": "^2.0.0",
46 - "into-stream": "^5.0.0",
47 - "tsd": "^0.7.2",
48 - "xo": "^0.24.0"
49 - }
50 -}
1 -# get-stream [![Build Status](https://travis-ci.com/sindresorhus/get-stream.svg?branch=master)](https://travis-ci.com/github/sindresorhus/get-stream)
2 -
3 -> Get a stream as a string, buffer, or array
4 -
5 -## Install
6 -
7 -```
8 -$ npm install get-stream
9 -```
10 -
11 -## Usage
12 -
13 -```js
14 -const fs = require('fs');
15 -const getStream = require('get-stream');
16 -
17 -(async () => {
18 - const stream = fs.createReadStream('unicorn.txt');
19 -
20 - console.log(await getStream(stream));
21 - /*
22 - ,,))))))));,
23 - __)))))))))))))),
24 - \|/ -\(((((''''((((((((.
25 - -*-==//////(('' . `)))))),
26 - /|\ ))| o ;-. '((((( ,(,
27 - ( `| / ) ;))))' ,_))^;(~
28 - | | | ,))((((_ _____------~~~-. %,;(;(>';'~
29 - o_); ; )))(((` ~---~ `:: \ %%~~)(v;(`('~
30 - ; ''''```` `: `:::|\,__,%% );`'; ~
31 - | _ ) / `:|`----' `-'
32 - ______/\/~ | / /
33 - /~;;.____/;;' / ___--,-( `;;;/
34 - / // _;______;'------~~~~~ /;;/\ /
35 - // | | / ; \;;,\
36 - (<_ | ; /',/-----' _>
37 - \_| ||_ //~;~~~~~~~~~
38 - `\_| (,~~
39 - \~\
40 - ~~
41 - */
42 -})();
43 -```
44 -
45 -## API
46 -
47 -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.
48 -
49 -### getStream(stream, options?)
50 -
51 -Get the `stream` as a string.
52 -
53 -#### options
54 -
55 -Type: `object`
56 -
57 -##### encoding
58 -
59 -Type: `string`\
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`\
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 with a `getStream.MaxBufferError` error.
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 -## Errors
90 -
91 -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.
92 -
93 -```js
94 -(async () => {
95 - try {
96 - await getStream(streamThatErrorsAtTheEnd('unicorn'));
97 - } catch (error) {
98 - console.log(error.bufferedData);
99 - //=> 'unicorn'
100 - }
101 -})()
102 -```
103 -
104 -## FAQ
105 -
106 -### How is this different from [`concat-stream`](https://github.com/maxogden/concat-stream)?
107 -
108 -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.
109 -
110 -## Related
111 -
112 -- [get-stdin](https://github.com/sindresorhus/get-stdin) - Get stdin as a string or buffer
113 -
114 ----
115 -
116 -<div align="center">
117 - <b>
118 - <a href="https://tidelift.com/subscription/pkg/npm-get-stream?utm_source=npm-get-stream&utm_medium=referral&utm_campaign=readme">Get professional support for this package with a Tidelift subscription</a>
119 - </b>
120 - <br>
121 - <sub>
122 - Tidelift helps make open source sustainable for maintainers while giving companies<br>assurances about security, maintenance, and licensing for their dependencies.
123 - </sub>
124 -</div>
1 -/**
2 -Lowercase the keys of an object.
3 -
4 -@returns A new object with the keys lowercased.
5 -
6 -@example
7 -```
8 -import lowercaseKeys = require('lowercase-keys');
9 -
10 -lowercaseKeys({FOO: true, bAr: false});
11 -//=> {foo: true, bar: false}
12 -```
13 -*/
14 -declare function lowercaseKeys<T extends unknown>(object: {[key: string]: T}): {[key: string]: T};
15 -
16 -export = lowercaseKeys;
1 -'use strict';
2 -module.exports = object => {
3 - const result = {};
4 -
5 - for (const [key, value] of Object.entries(object)) {
6 - result[key.toLowerCase()] = value;
7 - }
8 -
9 - return result;
10 -};
1 -MIT License
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 of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
6 -
7 -The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
8 -
9 -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
1 -{
2 - "name": "lowercase-keys",
3 - "version": "2.0.0",
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": ">=8"
14 - },
15 - "scripts": {
16 - "test": "xo && ava && tsd"
17 - },
18 - "files": [
19 - "index.js",
20 - "index.d.ts"
21 - ],
22 - "keywords": [
23 - "object",
24 - "assign",
25 - "extend",
26 - "properties",
27 - "lowercase",
28 - "lower-case",
29 - "case",
30 - "keys",
31 - "key"
32 - ],
33 - "devDependencies": {
34 - "ava": "^1.4.1",
35 - "tsd": "^0.7.2",
36 - "xo": "^0.24.0"
37 - }
38 -}
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 lowercase-keys
10 -```
11 -
12 -
13 -## Usage
14 -
15 -```js
16 -const 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 -Returns a new object with the keys lowercased.
28 -
29 -
30 -## License
31 -
32 -MIT © [Sindre Sorhus](https://sindresorhus.com)
1 -{
2 - "name": "cacheable-request",
3 - "version": "6.1.0",
4 - "description": "Wrap native HTTP requests with RFC compliant cache support",
5 - "license": "MIT",
6 - "repository": "lukechilds/cacheable-request",
7 - "author": "Luke Childs <lukechilds123@gmail.com> (http://lukechilds.co.uk)",
8 - "main": "src/index.js",
9 - "engines": {
10 - "node": ">=8"
11 - },
12 - "scripts": {
13 - "test": "xo && nyc ava",
14 - "coverage": "nyc report --reporter=text-lcov | coveralls"
15 - },
16 - "files": [
17 - "src"
18 - ],
19 - "keywords": [
20 - "HTTP",
21 - "HTTPS",
22 - "cache",
23 - "caching",
24 - "layer",
25 - "cacheable",
26 - "RFC 7234",
27 - "RFC",
28 - "7234",
29 - "compliant"
30 - ],
31 - "dependencies": {
32 - "clone-response": "^1.0.2",
33 - "get-stream": "^5.1.0",
34 - "http-cache-semantics": "^4.0.0",
35 - "keyv": "^3.0.0",
36 - "lowercase-keys": "^2.0.0",
37 - "normalize-url": "^4.1.0",
38 - "responselike": "^1.0.2"
39 - },
40 - "devDependencies": {
41 - "@keyv/sqlite": "^2.0.0",
42 - "ava": "^1.1.0",
43 - "coveralls": "^3.0.0",
44 - "create-test-server": "3.0.0",
45 - "delay": "^4.0.0",
46 - "eslint-config-xo-lukechilds": "^1.0.0",
47 - "nyc": "^14.1.1",
48 - "pify": "^4.0.0",
49 - "sqlite3": "^4.0.2",
50 - "this": "^1.0.2",
51 - "xo": "^0.23.0"
52 - },
53 - "xo": {
54 - "extends": "xo-lukechilds"
55 - }
56 -}
1 -'use strict';
2 -
3 -const EventEmitter = require('events');
4 -const urlLib = require('url');
5 -const normalizeUrl = require('normalize-url');
6 -const getStream = require('get-stream');
7 -const CachePolicy = require('http-cache-semantics');
8 -const Response = require('responselike');
9 -const lowercaseKeys = require('lowercase-keys');
10 -const cloneResponse = require('clone-response');
11 -const Keyv = require('keyv');
12 -
13 -class CacheableRequest {
14 - constructor(request, cacheAdapter) {
15 - if (typeof request !== 'function') {
16 - throw new TypeError('Parameter `request` must be a function');
17 - }
18 -
19 - this.cache = new Keyv({
20 - uri: typeof cacheAdapter === 'string' && cacheAdapter,
21 - store: typeof cacheAdapter !== 'string' && cacheAdapter,
22 - namespace: 'cacheable-request'
23 - });
24 -
25 - return this.createCacheableRequest(request);
26 - }
27 -
28 - createCacheableRequest(request) {
29 - return (opts, cb) => {
30 - let url;
31 - if (typeof opts === 'string') {
32 - url = normalizeUrlObject(urlLib.parse(opts));
33 - opts = {};
34 - } else if (opts instanceof urlLib.URL) {
35 - url = normalizeUrlObject(urlLib.parse(opts.toString()));
36 - opts = {};
37 - } else {
38 - const [pathname, ...searchParts] = (opts.path || '').split('?');
39 - const search = searchParts.length > 0 ?
40 - `?${searchParts.join('?')}` :
41 - '';
42 - url = normalizeUrlObject({ ...opts, pathname, search });
43 - }
44 -
45 - opts = {
46 - headers: {},
47 - method: 'GET',
48 - cache: true,
49 - strictTtl: false,
50 - automaticFailover: false,
51 - ...opts,
52 - ...urlObjectToRequestOptions(url)
53 - };
54 - opts.headers = lowercaseKeys(opts.headers);
55 -
56 - const ee = new EventEmitter();
57 - const normalizedUrlString = normalizeUrl(
58 - urlLib.format(url),
59 - {
60 - stripWWW: false,
61 - removeTrailingSlash: false,
62 - stripAuthentication: false
63 - }
64 - );
65 - const key = `${opts.method}:${normalizedUrlString}`;
66 - let revalidate = false;
67 - let madeRequest = false;
68 -
69 - const makeRequest = opts => {
70 - madeRequest = true;
71 - let requestErrored = false;
72 - let requestErrorCallback;
73 -
74 - const requestErrorPromise = new Promise(resolve => {
75 - requestErrorCallback = () => {
76 - if (!requestErrored) {
77 - requestErrored = true;
78 - resolve();
79 - }
80 - };
81 - });
82 -
83 - const handler = response => {
84 - if (revalidate && !opts.forceRefresh) {
85 - response.status = response.statusCode;
86 - const revalidatedPolicy = CachePolicy.fromObject(revalidate.cachePolicy).revalidatedPolicy(opts, response);
87 - if (!revalidatedPolicy.modified) {
88 - const headers = revalidatedPolicy.policy.responseHeaders();
89 - response = new Response(revalidate.statusCode, headers, revalidate.body, revalidate.url);
90 - response.cachePolicy = revalidatedPolicy.policy;
91 - response.fromCache = true;
92 - }
93 - }
94 -
95 - if (!response.fromCache) {
96 - response.cachePolicy = new CachePolicy(opts, response, opts);
97 - response.fromCache = false;
98 - }
99 -
100 - let clonedResponse;
101 - if (opts.cache && response.cachePolicy.storable()) {
102 - clonedResponse = cloneResponse(response);
103 -
104 - (async () => {
105 - try {
106 - const bodyPromise = getStream.buffer(response);
107 -
108 - await Promise.race([
109 - requestErrorPromise,
110 - new Promise(resolve => response.once('end', resolve))
111 - ]);
112 -
113 - if (requestErrored) {
114 - return;
115 - }
116 -
117 - const body = await bodyPromise;
118 -
119 - const value = {
120 - cachePolicy: response.cachePolicy.toObject(),
121 - url: response.url,
122 - statusCode: response.fromCache ? revalidate.statusCode : response.statusCode,
123 - body
124 - };
125 -
126 - let ttl = opts.strictTtl ? response.cachePolicy.timeToLive() : undefined;
127 - if (opts.maxTtl) {
128 - ttl = ttl ? Math.min(ttl, opts.maxTtl) : opts.maxTtl;
129 - }
130 -
131 - await this.cache.set(key, value, ttl);
132 - } catch (error) {
133 - ee.emit('error', new CacheableRequest.CacheError(error));
134 - }
135 - })();
136 - } else if (opts.cache && revalidate) {
137 - (async () => {
138 - try {
139 - await this.cache.delete(key);
140 - } catch (error) {
141 - ee.emit('error', new CacheableRequest.CacheError(error));
142 - }
143 - })();
144 - }
145 -
146 - ee.emit('response', clonedResponse || response);
147 - if (typeof cb === 'function') {
148 - cb(clonedResponse || response);
149 - }
150 - };
151 -
152 - try {
153 - const req = request(opts, handler);
154 - req.once('error', requestErrorCallback);
155 - req.once('abort', requestErrorCallback);
156 - ee.emit('request', req);
157 - } catch (error) {
158 - ee.emit('error', new CacheableRequest.RequestError(error));
159 - }
160 - };
161 -
162 - (async () => {
163 - const get = async opts => {
164 - await Promise.resolve();
165 -
166 - const cacheEntry = opts.cache ? await this.cache.get(key) : undefined;
167 - if (typeof cacheEntry === 'undefined') {
168 - return makeRequest(opts);
169 - }
170 -
171 - const policy = CachePolicy.fromObject(cacheEntry.cachePolicy);
172 - if (policy.satisfiesWithoutRevalidation(opts) && !opts.forceRefresh) {
173 - const headers = policy.responseHeaders();
174 - const response = new Response(cacheEntry.statusCode, headers, cacheEntry.body, cacheEntry.url);
175 - response.cachePolicy = policy;
176 - response.fromCache = true;
177 -
178 - ee.emit('response', response);
179 - if (typeof cb === 'function') {
180 - cb(response);
181 - }
182 - } else {
183 - revalidate = cacheEntry;
184 - opts.headers = policy.revalidationHeaders(opts);
185 - makeRequest(opts);
186 - }
187 - };
188 -
189 - const errorHandler = error => ee.emit('error', new CacheableRequest.CacheError(error));
190 - this.cache.once('error', errorHandler);
191 - ee.on('response', () => this.cache.removeListener('error', errorHandler));
192 -
193 - try {
194 - await get(opts);
195 - } catch (error) {
196 - if (opts.automaticFailover && !madeRequest) {
197 - makeRequest(opts);
198 - }
199 -
200 - ee.emit('error', new CacheableRequest.CacheError(error));
201 - }
202 - })();
203 -
204 - return ee;
205 - };
206 - }
207 -}
208 -
209 -function urlObjectToRequestOptions(url) {
210 - const options = { ...url };
211 - options.path = `${url.pathname || '/'}${url.search || ''}`;
212 - delete options.pathname;
213 - delete options.search;
214 - return options;
215 -}
216 -
217 -function normalizeUrlObject(url) {
218 - // If url was parsed by url.parse or new URL:
219 - // - hostname will be set
220 - // - host will be hostname[:port]
221 - // - port will be set if it was explicit in the parsed string
222 - // Otherwise, url was from request options:
223 - // - hostname or host may be set
224 - // - host shall not have port encoded
225 - return {
226 - protocol: url.protocol,
227 - auth: url.auth,
228 - hostname: url.hostname || url.host || 'localhost',
229 - port: url.port,
230 - pathname: url.pathname,
231 - search: url.search
232 - };
233 -}
234 -
235 -CacheableRequest.RequestError = class extends Error {
236 - constructor(error) {
237 - super(error.message);
238 - this.name = 'RequestError';
239 - Object.assign(this, error);
240 - }
241 -};
242 -
243 -CacheableRequest.CacheError = class extends Error {
244 - constructor(error) {
245 - super(error.message);
246 - this.name = 'CacheError';
247 - Object.assign(this, error);
248 - }
249 -};
250 -
251 -module.exports = CacheableRequest;
1 -MIT License
2 -
3 -Copyright (c) 2017 Luke Childs
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 -# clone-response
2 -
3 -> Clone a Node.js HTTP response stream
4 -
5 -[![Build Status](https://travis-ci.org/lukechilds/clone-response.svg?branch=master)](https://travis-ci.org/lukechilds/clone-response)
6 -[![Coverage Status](https://coveralls.io/repos/github/lukechilds/clone-response/badge.svg?branch=master)](https://coveralls.io/github/lukechilds/clone-response?branch=master)
7 -[![npm](https://img.shields.io/npm/dm/clone-response.svg)](https://www.npmjs.com/package/clone-response)
8 -[![npm](https://img.shields.io/npm/v/clone-response.svg)](https://www.npmjs.com/package/clone-response)
9 -
10 -Returns a new stream and copies over all properties and methods from the original response giving you a complete duplicate.
11 -
12 -This is useful in situations where you need to consume the response stream but also want to pass an unconsumed stream somewhere else to be consumed later.
13 -
14 -## Install
15 -
16 -```shell
17 -npm install --save clone-response
18 -```
19 -
20 -## Usage
21 -
22 -```js
23 -const http = require('http');
24 -const cloneResponse = require('clone-response');
25 -
26 -http.get('http://example.com', response => {
27 - const clonedResponse = cloneResponse(response);
28 - response.pipe(process.stdout);
29 -
30 - setImmediate(() => {
31 - // The response stream has already been consumed by the time this executes,
32 - // however the cloned response stream is still available.
33 - doSomethingWithResponse(clonedResponse);
34 - });
35 -});
36 -```
37 -
38 -Please bear in mind that the process of cloning a stream consumes it. However, you can consume a stream multiple times in the same tick, therefore allowing you to create multiple clones. e.g:
39 -
40 -```js
41 -const clone1 = cloneResponse(response);
42 -const clone2 = cloneResponse(response);
43 -// response can still be consumed in this tick but cannot be consumed if passed
44 -// into any async callbacks. clone1 and clone2 can be passed around and be
45 -// consumed in the future.
46 -```
47 -
48 -## API
49 -
50 -### cloneResponse(response)
51 -
52 -Returns a clone of the passed in response.
53 -
54 -#### response
55 -
56 -Type: `stream`
57 -
58 -A [Node.js HTTP response stream](https://nodejs.org/api/http.html#http_class_http_incomingmessage) to clone.
59 -
60 -## License
61 -
62 -MIT © Luke Childs
1 -{
2 - "name": "clone-response",
3 - "version": "1.0.2",
4 - "description": "Clone a Node.js HTTP response stream",
5 - "main": "src/index.js",
6 - "scripts": {
7 - "test": "xo && nyc ava",
8 - "coverage": "nyc report --reporter=text-lcov | coveralls"
9 - },
10 - "xo": {
11 - "extends": "xo-lukechilds"
12 - },
13 - "repository": {
14 - "type": "git",
15 - "url": "git+https://github.com/lukechilds/clone-response.git"
16 - },
17 - "keywords": [
18 - "clone",
19 - "duplicate",
20 - "copy",
21 - "response",
22 - "HTTP",
23 - "stream"
24 - ],
25 - "author": "Luke Childs <lukechilds123@gmail.com> (http://lukechilds.co.uk)",
26 - "license": "MIT",
27 - "bugs": {
28 - "url": "https://github.com/lukechilds/clone-response/issues"
29 - },
30 - "homepage": "https://github.com/lukechilds/clone-response",
31 - "dependencies": {
32 - "mimic-response": "^1.0.0"
33 - },
34 - "devDependencies": {
35 - "ava": "^0.22.0",
36 - "coveralls": "^2.13.1",
37 - "create-test-server": "^2.0.1",
38 - "eslint-config-xo-lukechilds": "^1.0.0",
39 - "get-stream": "^3.0.0",
40 - "nyc": "^11.0.2",
41 - "pify": "^3.0.0",
42 - "xo": "^0.19.0"
43 - }
44 -}
1 -'use strict';
2 -
3 -const PassThrough = require('stream').PassThrough;
4 -const mimicResponse = require('mimic-response');
5 -
6 -const cloneResponse = response => {
7 - if (!(response && response.pipe)) {
8 - throw new TypeError('Parameter `response` must be a response stream.');
9 - }
10 -
11 - const clone = new PassThrough();
12 - mimicResponse(response, clone);
13 -
14 - return response.pipe(clone);
15 -};
16 -
17 -module.exports = cloneResponse;
1 -'use strict';
2 -const path = require('path');
3 -const os = require('os');
4 -const fs = require('graceful-fs');
5 -const makeDir = require('make-dir');
6 -const xdgBasedir = require('xdg-basedir');
7 -const writeFileAtomic = require('write-file-atomic');
8 -const dotProp = require('dot-prop');
9 -const uniqueString = require('unique-string');
10 -
11 -const configDir = xdgBasedir.config || path.join(os.tmpdir(), uniqueString());
12 -const permissionError = 'You don\'t have access to this file.';
13 -const makeDirOptions = {mode: 0o0700};
14 -const writeFileOptions = {mode: 0o0600};
15 -
16 -class Configstore {
17 - constructor(id, defaults, options = {}) {
18 - const pathPrefix = options.globalConfigPath ?
19 - path.join(id, 'config.json') :
20 - path.join('configstore', `${id}.json`);
21 -
22 - this.path = options.configPath || path.join(configDir, pathPrefix);
23 -
24 - if (defaults) {
25 - this.all = Object.assign({}, defaults, this.all);
26 - }
27 - }
28 -
29 - get all() {
30 - try {
31 - return JSON.parse(fs.readFileSync(this.path, 'utf8'));
32 - } catch (error) {
33 - // Create directory if it doesn't exist
34 - if (error.code === 'ENOENT') {
35 - return {};
36 - }
37 -
38 - // Improve the message of permission errors
39 - if (error.code === 'EACCES') {
40 - error.message = `${error.message}\n${permissionError}\n`;
41 - }
42 -
43 - // Empty the file if it encounters invalid JSON
44 - if (error.name === 'SyntaxError') {
45 - writeFileAtomic.sync(this.path, '', writeFileOptions);
46 - return {};
47 - }
48 -
49 - throw error;
50 - }
51 - }
52 -
53 - set all(value) {
54 - try {
55 - // Make sure the folder exists as it could have been deleted in the meantime
56 - makeDir.sync(path.dirname(this.path), makeDirOptions);
57 -
58 - writeFileAtomic.sync(this.path, JSON.stringify(value, null, '\t'), writeFileOptions);
59 - } catch (error) {
60 - // Improve the message of permission errors
61 - if (error.code === 'EACCES') {
62 - error.message = `${error.message}\n${permissionError}\n`;
63 - }
64 -
65 - throw error;
66 - }
67 - }
68 -
69 - get size() {
70 - return Object.keys(this.all || {}).length;
71 - }
72 -
73 - get(key) {
74 - return dotProp.get(this.all, key);
75 - }
76 -
77 - set(key, value) {
78 - const config = this.all;
79 -
80 - if (arguments.length === 1) {
81 - for (const k of Object.keys(key)) {
82 - dotProp.set(config, k, key[k]);
83 - }
84 - } else {
85 - dotProp.set(config, key, value);
86 - }
87 -
88 - this.all = config;
89 - }
90 -
91 - has(key) {
92 - return dotProp.has(this.all, key);
93 - }
94 -
95 - delete(key) {
96 - const config = this.all;
97 - dotProp.delete(config, key);
98 - this.all = config;
99 - }
100 -
101 - clear() {
102 - this.all = {};
103 - }
104 -}
105 -
106 -module.exports = Configstore;
1 -BSD 2-Clause License
2 -
3 -Copyright (c) Google
4 -All rights reserved.
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 -
9 -* Redistributions of source code must retain the above copyright notice, this
10 - list of conditions and the following disclaimer.
11 -
12 -* Redistributions in binary form must reproduce the above copyright notice,
13 - this list of conditions and the following disclaimer in the documentation
14 - and/or other materials provided with the distribution.
15 -
16 -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17 -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
20 -FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 -DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
22 -SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
23 -CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24 -OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25 -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
1 -{
2 - "name": "configstore",
3 - "version": "4.0.0",
4 - "description": "Easily load and save config without having to think about where and how",
5 - "license": "BSD-2-Clause",
6 - "repository": "yeoman/configstore",
7 - "author": {
8 - "name": "Sindre Sorhus",
9 - "email": "sindresorhus@gmail.com",
10 - "url": "sindresorhus.com"
11 - },
12 - "engines": {
13 - "node": ">=6"
14 - },
15 - "scripts": {
16 - "test": "xo && ava"
17 - },
18 - "files": [
19 - "index.js"
20 - ],
21 - "keywords": [
22 - "config",
23 - "store",
24 - "storage",
25 - "conf",
26 - "configuration",
27 - "settings",
28 - "preferences",
29 - "json",
30 - "data",
31 - "persist",
32 - "persistent",
33 - "save"
34 - ],
35 - "dependencies": {
36 - "dot-prop": "^4.1.0",
37 - "graceful-fs": "^4.1.2",
38 - "make-dir": "^1.0.0",
39 - "unique-string": "^1.0.0",
40 - "write-file-atomic": "^2.0.0",
41 - "xdg-basedir": "^3.0.0"
42 - },
43 - "devDependencies": {
44 - "ava": "*",
45 - "xo": "*"
46 - }
47 -}
1 -# configstore [![Build Status](https://travis-ci.org/yeoman/configstore.svg?branch=master)](https://travis-ci.org/yeoman/configstore)
2 -
3 -> Easily load and persist config without having to think about where and how
4 -
5 -Config is stored in a JSON file located in `$XDG_CONFIG_HOME` or `~/.config`.<br>
6 -Example: `~/.config/configstore/some-id.json`
7 -
8 -*If you need this for Electron, check out [`electron-store`](https://github.com/sindresorhus/electron-store) instead.*
9 -
10 -
11 -## Install
12 -
13 -```
14 -$ npm install configstore
15 -```
16 -
17 -
18 -## Usage
19 -
20 -```js
21 -const Configstore = require('configstore');
22 -const pkg = require('./package.json');
23 -
24 -// create a Configstore instance with an unique ID e.g.
25 -// Package name and optionally some default values
26 -const conf = new Configstore(pkg.name, {foo: 'bar'});
27 -
28 -console.log(conf.get('foo'));
29 -//=> 'bar'
30 -
31 -conf.set('awesome', true);
32 -console.log(conf.get('awesome'));
33 -//=> true
34 -
35 -// Use dot-notation to access nested properties
36 -conf.set('bar.baz', true);
37 -console.log(conf.get('bar'));
38 -//=> {baz: true}
39 -
40 -conf.delete('awesome');
41 -console.log(conf.get('awesome'));
42 -//=> undefined
43 -```
44 -
45 -
46 -## API
47 -
48 -### Configstore(packageName, [defaults], [options])
49 -
50 -Returns a new instance.
51 -
52 -#### packageName
53 -
54 -Type: `string`
55 -
56 -Name of your package.
57 -
58 -#### defaults
59 -
60 -Type: `Object`
61 -
62 -Default config.
63 -
64 -#### options
65 -
66 -##### globalConfigPath
67 -
68 -Type: `boolean`<br>
69 -Default: `false`
70 -
71 -Store the config at `$CONFIG/package-name/config.json` instead of the default `$CONFIG/configstore/package-name.json`. This is not recommended as you might end up conflicting with other tools, rendering the "without having to think" idea moot.
72 -
73 -##### configPath
74 -
75 -Type: `string`<br>
76 -Default: Automatic
77 -
78 -**Please don't use this option unless absolutely necessary and you know what you're doing.**
79 -
80 -Set the path of the config file. Overrides the `packageName` and `globalConfigPath` options.
81 -
82 -### Instance
83 -
84 -You can use [dot-notation](https://github.com/sindresorhus/dot-prop) in a `key` to access nested properties.
85 -
86 -### .set(key, value)
87 -
88 -Set an item.
89 -
90 -### .set(object)
91 -
92 -Set multiple items at once.
93 -
94 -### .get(key)
95 -
96 -Get an item.
97 -
98 -### .has(key)
99 -
100 -Check if an item exists.
101 -
102 -### .delete(key)
103 -
104 -Delete an item.
105 -
106 -### .clear()
107 -
108 -Delete all items.
109 -
110 -### .size
111 -
112 -Get the item count.
113 -
114 -### .path
115 -
116 -Get the path to the config file. Can be used to show the user where the config file is located or even better open it for them.
117 -
118 -### .all
119 -
120 -Get all the config as an object or replace the current config with an object:
121 -
122 -```js
123 -conf.all = {
124 - hello: 'world'
125 -};
126 -```
127 -
128 -
129 -## License
130 -
131 -[BSD license](http://opensource.org/licenses/bsd-license.php)<br>
132 -Copyright Google
1 -'use strict';
2 -const crypto = require('crypto');
3 -
4 -module.exports = len => {
5 - if (!Number.isFinite(len)) {
6 - throw new TypeError('Expected a finite number');
7 - }
8 -
9 - return crypto.randomBytes(Math.ceil(len / 2)).toString('hex').slice(0, len);
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": "crypto-random-string",
3 - "version": "1.0.0",
4 - "description": "Generate a cryptographically strong random string",
5 - "license": "MIT",
6 - "repository": "sindresorhus/crypto-random-string",
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 - ],
21 - "keywords": [
22 - "random",
23 - "string",
24 - "str",
25 - "rand",
26 - "text",
27 - "id",
28 - "identifier",
29 - "slug",
30 - "salt",
31 - "crypto",
32 - "strong",
33 - "secure",
34 - "hex"
35 - ],
36 - "devDependencies": {
37 - "ava": "*",
38 - "xo": "*"
39 - },
40 - "xo": {
41 - "esnext": true
42 - }
43 -}
1 -# crypto-random-string [![Build Status](https://travis-ci.org/sindresorhus/crypto-random-string.svg?branch=master)](https://travis-ci.org/sindresorhus/crypto-random-string)
2 -
3 -> Generate a [cryptographically strong](https://en.m.wikipedia.org/wiki/Strong_cryptography) random string
4 -
5 -Can be useful for creating an identifier, slug, salt, fixture, etc.
6 -
7 -
8 -## Install
9 -
10 -```
11 -$ npm install --save crypto-random-string
12 -```
13 -
14 -
15 -## Usage
16 -
17 -```js
18 -const cryptoRandomString = require('crypto-random-string');
19 -
20 -cryptoRandomString(10);
21 -//=> '2cf05d94db'
22 -```
23 -
24 -
25 -## API
26 -
27 -### cryptoRandomString(length)
28 -
29 -#### length
30 -
31 -Type: `number`
32 -
33 -Length of the returned string.
34 -
35 -
36 -## Related
37 -
38 -- [random-int](https://github.com/sindresorhus/random-int) - Generate a random integer
39 -- [random-float](https://github.com/sindresorhus/random-float) - Generate a random float
40 -- [random-item](https://github.com/sindresorhus/random-item) - Get a random item from an array
41 -- [random-boolean](https://github.com/arthurvr/random-boolean) - Get a random boolean
42 -- [random-obj-key](https://github.com/sindresorhus/random-obj-key) - Get a random key from an object
43 -- [random-obj-prop](https://github.com/sindresorhus/random-obj-prop) - Get a random property from an object
44 -- [unique-random](https://github.com/sindresorhus/unique-random) - Generate random numbers that are consecutively unique
45 -
46 -
47 -## License
48 -
49 -MIT © [Sindre Sorhus](https://sindresorhus.com)
1 -'use strict';
2 -const PassThrough = require('stream').PassThrough;
3 -const zlib = require('zlib');
4 -const mimicResponse = require('mimic-response');
5 -
6 -module.exports = response => {
7 - // TODO: Use Array#includes when targeting Node.js 6
8 - if (['gzip', 'deflate'].indexOf(response.headers['content-encoding']) === -1) {
9 - return response;
10 - }
11 -
12 - const unzip = zlib.createUnzip();
13 - const stream = new PassThrough();
14 -
15 - mimicResponse(response, stream);
16 -
17 - unzip.on('error', err => {
18 - if (err.code === 'Z_BUF_ERROR') {
19 - stream.end();
20 - return;
21 - }
22 -
23 - stream.emit('error', err);
24 - });
25 -
26 - response.pipe(unzip).pipe(stream);
27 -
28 - return stream;
29 -};
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": "decompress-response",
3 - "version": "3.3.0",
4 - "description": "Decompress a HTTP response if needed",
5 - "license": "MIT",
6 - "repository": "sindresorhus/decompress-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 - "decompress",
30 - "response",
31 - "http",
32 - "https",
33 - "zlib",
34 - "gzip",
35 - "zip",
36 - "deflate",
37 - "unzip",
38 - "ungzip",
39 - "incoming",
40 - "message",
41 - "stream",
42 - "compressed"
43 - ],
44 - "dependencies": {
45 - "mimic-response": "^1.0.0"
46 - },
47 - "devDependencies": {
48 - "ava": "*",
49 - "get-stream": "^3.0.0",
50 - "pify": "^3.0.0",
51 - "xo": "*"
52 - }
53 -}
1 -# decompress-response [![Build Status](https://travis-ci.org/sindresorhus/decompress-response.svg?branch=master)](https://travis-ci.org/sindresorhus/decompress-response)
2 -
3 -> Decompress a HTTP response if needed
4 -
5 -Decompresses the [response](https://nodejs.org/api/http.html#http_class_http_incomingmessage) from [`http.request`](https://nodejs.org/api/http.html#http_http_request_options_callback) if it's gzipped or deflated, otherwise just passes it through.
6 -
7 -Used by [`got`](https://github.com/sindresorhus/got).
8 -
9 -
10 -## Install
11 -
12 -```
13 -$ npm install decompress-response
14 -```
15 -
16 -
17 -## Usage
18 -
19 -```js
20 -const http = require('http');
21 -const decompressResponse = require('decompress-response');
22 -
23 -http.get('http://sindresorhus.com', response => {
24 - response = decompressResponse(response);
25 -});
26 -```
27 -
28 -
29 -## License
30 -
31 -MIT © [Sindre Sorhus](https://sindresorhus.com)
1 -MIT License
2 -
3 -Copyright (c) 2018 Szymon Marczak
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 -# defer-to-connect
2 -
3 -> The safe way to handle the `connect` socket event
4 -
5 -[![Coverage Status](https://coveralls.io/repos/github/szmarczak/defer-to-connect/badge.svg?branch=master)](https://coveralls.io/github/szmarczak/defer-to-connect?branch=master)
6 -
7 -Once you receive the socket, it may be already connected (or disconnected).<br>
8 -To avoid checking that, use `defer-to-connect`. It'll do that for you.
9 -
10 -## Usage
11 -
12 -```js
13 -const deferToConnect = require('defer-to-connect');
14 -
15 -deferToConnect(socket, () => {
16 - console.log('Connected!');
17 -});
18 -```
19 -
20 -## API
21 -
22 -### deferToConnect(socket, connectListener)
23 -
24 -Calls `connectListener()` when connected.
25 -
26 -### deferToConnect(socket, listeners)
27 -
28 -#### listeners
29 -
30 -An object representing `connect`, `secureConnect` and `close` properties.
31 -
32 -Calls `connect()` when the socket is connected.<br>
33 -Calls `secureConnect()` when the socket is securely connected.<br>
34 -Calls `close()` when the socket is destroyed.
35 -
36 -## License
37 -
38 -MIT
1 -/// <reference types="node" />
2 -import { Socket } from 'net';
3 -import { TLSSocket } from 'tls';
4 -interface Listeners {
5 - connect?: () => void;
6 - secureConnect?: () => void;
7 - close?: (hadError: boolean) => void;
8 -}
9 -declare const deferToConnect: (socket: Socket | TLSSocket, fn: Listeners | (() => void)) => void;
10 -export default deferToConnect;
1 -"use strict";
2 -Object.defineProperty(exports, "__esModule", { value: true });
3 -const tls_1 = require("tls");
4 -const deferToConnect = (socket, fn) => {
5 - let listeners;
6 - if (typeof fn === 'function') {
7 - const connect = fn;
8 - listeners = { connect };
9 - }
10 - else {
11 - listeners = fn;
12 - }
13 - const hasConnectListener = typeof listeners.connect === 'function';
14 - const hasSecureConnectListener = typeof listeners.secureConnect === 'function';
15 - const hasCloseListener = typeof listeners.close === 'function';
16 - const onConnect = () => {
17 - if (hasConnectListener) {
18 - listeners.connect();
19 - }
20 - if (socket instanceof tls_1.TLSSocket && hasSecureConnectListener) {
21 - if (socket.authorized) {
22 - listeners.secureConnect();
23 - }
24 - else if (!socket.authorizationError) {
25 - socket.once('secureConnect', listeners.secureConnect);
26 - }
27 - }
28 - if (hasCloseListener) {
29 - socket.once('close', listeners.close);
30 - }
31 - };
32 - if (socket.writable && !socket.connecting) {
33 - onConnect();
34 - }
35 - else if (socket.connecting) {
36 - socket.once('connect', onConnect);
37 - }
38 - else if (socket.destroyed && hasCloseListener) {
39 - listeners.close(socket._hadError);
40 - }
41 -};
42 -exports.default = deferToConnect;
43 -// For CommonJS default export support
44 -module.exports = deferToConnect;
45 -module.exports.default = deferToConnect;
1 -{
2 - "name": "defer-to-connect",
3 - "version": "1.1.3",
4 - "description": "The safe way to handle the `connect` socket event",
5 - "main": "dist",
6 - "files": [
7 - "dist"
8 - ],
9 - "scripts": {
10 - "build": "del-cli dist && tsc",
11 - "prepublishOnly": "npm run build",
12 - "test": "xo && nyc ava",
13 - "coveralls": "nyc report --reporter=text-lcov | coveralls"
14 - },
15 - "keywords": [
16 - "socket",
17 - "connect",
18 - "event"
19 - ],
20 - "author": "Szymon Marczak",
21 - "license": "MIT",
22 - "repository": {
23 - "type": "git",
24 - "url": "git+https://github.com/szmarczak/defer-to-connect.git"
25 - },
26 - "bugs": {
27 - "url": "https://github.com/szmarczak/defer-to-connect/issues"
28 - },
29 - "homepage": "https://github.com/szmarczak/defer-to-connect#readme",
30 - "xo": {
31 - "extends": "xo-typescript",
32 - "extensions": [
33 - "ts"
34 - ],
35 - "rules": {
36 - "ava/no-ignored-test-files": "off"
37 - }
38 - },
39 - "devDependencies": {
40 - "@sindresorhus/tsconfig": "^0.5.0",
41 - "@types/node": "^12.12.4",
42 - "@typescript-eslint/eslint-plugin": "^1.11.0",
43 - "@typescript-eslint/parser": "^1.11.0",
44 - "ava": "^2.1.0",
45 - "coveralls": "^3.0.7",
46 - "create-cert": "^1.0.6",
47 - "del-cli": "^3.0.0",
48 - "eslint-config-xo-typescript": "^0.15.0",
49 - "nyc": "^14.0.0",
50 - "p-event": "^4.1.0",
51 - "ts-node": "^8.1.0",
52 - "typescript": "^3.6.4",
53 - "xo": "^0.25.3"
54 - },
55 - "nyc": {
56 - "extension": [
57 - ".ts"
58 - ]
59 - },
60 - "ava": {
61 - "babel": false,
62 - "compileEnhancements": false,
63 - "extensions": [
64 - "ts"
65 - ],
66 - "require": [
67 - "ts-node/register"
68 - ],
69 - "files": [
70 - "!dist/tests/test.d.ts"
71 - ]
72 - },
73 - "types": "dist"
74 -}
1 -'use strict';
2 -const isObj = require('is-obj');
3 -
4 -const disallowedKeys = [
5 - '__proto__',
6 - 'prototype',
7 - 'constructor'
8 -];
9 -
10 -const isValidPath = pathSegments => !pathSegments.some(segment => disallowedKeys.includes(segment));
11 -
12 -function getPathSegments(path) {
13 - const pathArr = path.split('.');
14 - const parts = [];
15 -
16 - for (let i = 0; i < pathArr.length; i++) {
17 - let p = pathArr[i];
18 -
19 - while (p[p.length - 1] === '\\' && pathArr[i + 1] !== undefined) {
20 - p = p.slice(0, -1) + '.';
21 - p += pathArr[++i];
22 - }
23 -
24 - parts.push(p);
25 - }
26 -
27 - if (!isValidPath(parts)) {
28 - return [];
29 - }
30 -
31 - return parts;
32 -}
33 -
34 -module.exports = {
35 - get(obj, path, value) {
36 - if (!isObj(obj) || typeof path !== 'string') {
37 - return value === undefined ? obj : value;
38 - }
39 -
40 - const pathArr = getPathSegments(path);
41 - if (pathArr.length === 0) {
42 - return;
43 - }
44 -
45 - for (let i = 0; i < pathArr.length; i++) {
46 - if (!Object.prototype.propertyIsEnumerable.call(obj, pathArr[i])) {
47 - return value;
48 - }
49 -
50 - obj = obj[pathArr[i]];
51 -
52 - if (obj === undefined || obj === null) {
53 - // `obj` is either `undefined` or `null` so we want to stop the loop, and
54 - // if this is not the last bit of the path, and
55 - // if it did't return `undefined`
56 - // it would return `null` if `obj` is `null`
57 - // but we want `get({foo: null}, 'foo.bar')` to equal `undefined`, or the supplied value, not `null`
58 - if (i !== pathArr.length - 1) {
59 - return value;
60 - }
61 -
62 - break;
63 - }
64 - }
65 -
66 - return obj;
67 - },
68 -
69 - set(obj, path, value) {
70 - if (!isObj(obj) || typeof path !== 'string') {
71 - return obj;
72 - }
73 -
74 - const root = obj;
75 - const pathArr = getPathSegments(path);
76 - if (pathArr.length === 0) {
77 - return;
78 - }
79 -
80 - for (let i = 0; i < pathArr.length; i++) {
81 - const p = pathArr[i];
82 -
83 - if (!isObj(obj[p])) {
84 - obj[p] = {};
85 - }
86 -
87 - if (i === pathArr.length - 1) {
88 - obj[p] = value;
89 - }
90 -
91 - obj = obj[p];
92 - }
93 -
94 - return root;
95 - },
96 -
97 - delete(obj, path) {
98 - if (!isObj(obj) || typeof path !== 'string') {
99 - return;
100 - }
101 -
102 - const pathArr = getPathSegments(path);
103 -
104 - for (let i = 0; i < pathArr.length; i++) {
105 - const p = pathArr[i];
106 -
107 - if (i === pathArr.length - 1) {
108 - delete obj[p];
109 - return;
110 - }
111 -
112 - obj = obj[p];
113 -
114 - if (!isObj(obj)) {
115 - return;
116 - }
117 - }
118 - },
119 -
120 - has(obj, path) {
121 - if (!isObj(obj) || typeof path !== 'string') {
122 - return false;
123 - }
124 -
125 - const pathArr = getPathSegments(path);
126 -
127 - for (let i = 0; i < pathArr.length; i++) {
128 - if (isObj(obj)) {
129 - if (!(pathArr[i] in obj)) {
130 - return false;
131 - }
132 -
133 - obj = obj[pathArr[i]];
134 - } else {
135 - return false;
136 - }
137 - }
138 -
139 - return true;
140 - }
141 -};
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": "dot-prop",
3 - "version": "4.2.1",
4 - "description": "Get, set, or delete a property from a nested object using a dot path",
5 - "license": "MIT",
6 - "repository": "sindresorhus/dot-prop",
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 - "bench": "matcha bench.js"
18 - },
19 - "files": [
20 - "index.js"
21 - ],
22 - "keywords": [
23 - "obj",
24 - "object",
25 - "prop",
26 - "property",
27 - "dot",
28 - "path",
29 - "get",
30 - "set",
31 - "delete",
32 - "del",
33 - "access",
34 - "notation",
35 - "dotty"
36 - ],
37 - "dependencies": {
38 - "is-obj": "^1.0.0"
39 - },
40 - "devDependencies": {
41 - "ava": "1.4.1",
42 - "matcha": "^0.7.0",
43 - "xo": "0.24.0"
44 - },
45 - "xo": {
46 - "esnext": true
47 - }
48 -}
1 -# dot-prop [![Build Status](https://travis-ci.org/sindresorhus/dot-prop.svg?branch=master)](https://travis-ci.org/sindresorhus/dot-prop)
2 -
3 -> Get, set, or delete a property from a nested object using a dot path
4 -
5 -
6 -## Install
7 -
8 -```
9 -$ npm install --save dot-prop
10 -```
11 -
12 -
13 -## Usage
14 -
15 -```js
16 -const dotProp = require('dot-prop');
17 -
18 -// getter
19 -dotProp.get({foo: {bar: 'unicorn'}}, 'foo.bar');
20 -//=> 'unicorn'
21 -
22 -dotProp.get({foo: {bar: 'a'}}, 'foo.notDefined.deep');
23 -//=> undefined
24 -
25 -dotProp.get({foo: {bar: 'a'}}, 'foo.notDefined.deep', 'default value');
26 -//=> 'default value'
27 -
28 -dotProp.get({foo: {'dot.dot': 'unicorn'}}, 'foo.dot\\.dot');
29 -//=> 'unicorn'
30 -
31 -// setter
32 -const obj = {foo: {bar: 'a'}};
33 -dotProp.set(obj, 'foo.bar', 'b');
34 -console.log(obj);
35 -//=> {foo: {bar: 'b'}}
36 -
37 -const foo = dotProp.set({}, 'foo.bar', 'c');
38 -console.log(foo);
39 -//=> {foo: {bar: 'c'}}
40 -
41 -dotProp.set(obj, 'foo.baz', 'x');
42 -console.log(obj);
43 -//=> {foo: {bar: 'b', baz: 'x'}}
44 -
45 -// has
46 -dotProp.has({foo: {bar: 'unicorn'}}, 'foo.bar');
47 -//=> true
48 -
49 -// deleter
50 -const obj = {foo: {bar: 'a'}};
51 -dotProp.delete(obj, 'foo.bar');
52 -console.log(obj);
53 -//=> {foo: {}}
54 -
55 -obj.foo.bar = {x: 'y', y: 'x'};
56 -dotProp.delete(obj, 'foo.bar.x');
57 -console.log(obj);
58 -//=> {foo: {bar: {y: 'x'}}}
59 -```
60 -
61 -
62 -## API
63 -
64 -### get(obj, path, [defaultValue])
65 -
66 -### set(obj, path, value)
67 -
68 -Returns the object.
69 -
70 -### has(obj, path)
71 -
72 -### delete(obj, path)
73 -
74 -#### obj
75 -
76 -Type: `Object`
77 -
78 -Object to get, set, or delete the `path` value.
79 -
80 -#### path
81 -
82 -Type: `string`
83 -
84 -Path of the property in the object, using `.` to separate each nested key.
85 -
86 -Use `\\.` if you have a `.` in the key.
87 -
88 -The following path components are invalid and results in `undefined` being returned: `__proto__`, `prototype`, `constructor`.
89 -
90 -#### value
91 -
92 -Type: `any`
93 -
94 -Value to set at `path`.
95 -
96 -#### defaultValue
97 -
98 -Type: `any`
99 -
100 -Default value.
101 -
102 -
103 -## License
104 -
105 -MIT © [Sindre Sorhus](https://sindresorhus.com)
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 Mathias Buus
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.
...\ No newline at end of file ...\ No newline at end of file
1 -# end-of-stream
2 -
3 -A node module that calls a callback when a readable/writable/duplex stream has completed or failed.
4 -
5 - npm install end-of-stream
6 -
7 -[![Build status](https://travis-ci.org/mafintosh/end-of-stream.svg?branch=master)](https://travis-ci.org/mafintosh/end-of-stream)
8 -
9 -## Usage
10 -
11 -Simply pass a stream and a callback to the `eos`.
12 -Both legacy streams, streams2 and stream3 are supported.
13 -
14 -``` js
15 -var eos = require('end-of-stream');
16 -
17 -eos(readableStream, function(err) {
18 - // this will be set to the stream instance
19 - if (err) return console.log('stream had an error or closed early');
20 - console.log('stream has ended', this === readableStream);
21 -});
22 -
23 -eos(writableStream, function(err) {
24 - if (err) return console.log('stream had an error or closed early');
25 - console.log('stream has finished', this === writableStream);
26 -});
27 -
28 -eos(duplexStream, function(err) {
29 - if (err) return console.log('stream had an error or closed early');
30 - console.log('stream has ended and finished', this === duplexStream);
31 -});
32 -
33 -eos(duplexStream, {readable:false}, function(err) {
34 - if (err) return console.log('stream had an error or closed early');
35 - console.log('stream has finished but might still be readable');
36 -});
37 -
38 -eos(duplexStream, {writable:false}, function(err) {
39 - if (err) return console.log('stream had an error or closed early');
40 - console.log('stream has ended but might still be writable');
41 -});
42 -
43 -eos(readableStream, {error:false}, function(err) {
44 - // do not treat emit('error', err) as a end-of-stream
45 -});
46 -```
47 -
48 -## License
49 -
50 -MIT
51 -
52 -## Related
53 -
54 -`end-of-stream` is part of the [mississippi stream utility collection](https://github.com/maxogden/mississippi) which includes more useful stream modules similar to this one.
1 -var once = require('once');
2 -
3 -var noop = function() {};
4 -
5 -var isRequest = function(stream) {
6 - return stream.setHeader && typeof stream.abort === 'function';
7 -};
8 -
9 -var isChildProcess = function(stream) {
10 - return stream.stdio && Array.isArray(stream.stdio) && stream.stdio.length === 3
11 -};
12 -
13 -var eos = function(stream, opts, callback) {
14 - if (typeof opts === 'function') return eos(stream, null, opts);
15 - if (!opts) opts = {};
16 -
17 - callback = once(callback || noop);
18 -
19 - var ws = stream._writableState;
20 - var rs = stream._readableState;
21 - var readable = opts.readable || (opts.readable !== false && stream.readable);
22 - var writable = opts.writable || (opts.writable !== false && stream.writable);
23 - var cancelled = false;
24 -
25 - var onlegacyfinish = function() {
26 - if (!stream.writable) onfinish();
27 - };
28 -
29 - var onfinish = function() {
30 - writable = false;
31 - if (!readable) callback.call(stream);
32 - };
33 -
34 - var onend = function() {
35 - readable = false;
36 - if (!writable) callback.call(stream);
37 - };
38 -
39 - var onexit = function(exitCode) {
40 - callback.call(stream, exitCode ? new Error('exited with error code: ' + exitCode) : null);
41 - };
42 -
43 - var onerror = function(err) {
44 - callback.call(stream, err);
45 - };
46 -
47 - var onclose = function() {
48 - process.nextTick(onclosenexttick);
49 - };
50 -
51 - var onclosenexttick = function() {
52 - if (cancelled) return;
53 - if (readable && !(rs && (rs.ended && !rs.destroyed))) return callback.call(stream, new Error('premature close'));
54 - if (writable && !(ws && (ws.ended && !ws.destroyed))) return callback.call(stream, new Error('premature close'));
55 - };
56 -
57 - var onrequest = function() {
58 - stream.req.on('finish', onfinish);
59 - };
60 -
61 - if (isRequest(stream)) {
62 - stream.on('complete', onfinish);
63 - stream.on('abort', onclose);
64 - if (stream.req) onrequest();
65 - else stream.on('request', onrequest);
66 - } else if (writable && !ws) { // legacy streams
67 - stream.on('end', onlegacyfinish);
68 - stream.on('close', onlegacyfinish);
69 - }
70 -
71 - if (isChildProcess(stream)) stream.on('exit', onexit);
72 -
73 - stream.on('end', onend);
74 - stream.on('finish', onfinish);
75 - if (opts.error !== false) stream.on('error', onerror);
76 - stream.on('close', onclose);
77 -
78 - return function() {
79 - cancelled = true;
80 - stream.removeListener('complete', onfinish);
81 - stream.removeListener('abort', onclose);
82 - stream.removeListener('request', onrequest);
83 - if (stream.req) stream.req.removeListener('finish', onfinish);
84 - stream.removeListener('end', onlegacyfinish);
85 - stream.removeListener('close', onlegacyfinish);
86 - stream.removeListener('finish', onfinish);
87 - stream.removeListener('exit', onexit);
88 - stream.removeListener('end', onend);
89 - stream.removeListener('error', onerror);
90 - stream.removeListener('close', onclose);
91 - };
92 -};
93 -
94 -module.exports = eos;
1 -{
2 - "name": "end-of-stream",
3 - "version": "1.4.4",
4 - "description": "Call a callback when a readable/writable/duplex stream has completed or failed.",
5 - "repository": {
6 - "type": "git",
7 - "url": "git://github.com/mafintosh/end-of-stream.git"
8 - },
9 - "dependencies": {
10 - "once": "^1.4.0"
11 - },
12 - "scripts": {
13 - "test": "node test.js"
14 - },
15 - "files": [
16 - "index.js"
17 - ],
18 - "keywords": [
19 - "stream",
20 - "streams",
21 - "callback",
22 - "finish",
23 - "close",
24 - "end",
25 - "wait"
26 - ],
27 - "bugs": {
28 - "url": "https://github.com/mafintosh/end-of-stream/issues"
29 - },
30 - "homepage": "https://github.com/mafintosh/end-of-stream",
31 - "main": "index.js",
32 - "author": "Mathias Buus <mathiasbuus@gmail.com>",
33 - "license": "MIT",
34 - "devDependencies": {
35 - "tape": "^4.11.0"
36 - }
37 -}
1 -'use strict';
2 -const {PassThrough} = require('stream');
3 -
4 -module.exports = options => {
5 - options = Object.assign({}, options);
6 -
7 - const {array} = options;
8 - let {encoding} = options;
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 pump = require('pump');
3 -const bufferStream = require('./buffer-stream');
4 -
5 -class MaxBufferError extends Error {
6 - constructor() {
7 - super('maxBuffer exceeded');
8 - this.name = 'MaxBufferError';
9 - }
10 -}
11 -
12 -function getStream(inputStream, options) {
13 - if (!inputStream) {
14 - return Promise.reject(new Error('Expected a stream'));
15 - }
16 -
17 - options = Object.assign({maxBuffer: Infinity}, options);
18 -
19 - const {maxBuffer} = options;
20 -
21 - let stream;
22 - return new Promise((resolve, reject) => {
23 - const rejectPromise = error => {
24 - if (error) { // A null check
25 - error.bufferedData = stream.getBufferedValue();
26 - }
27 - reject(error);
28 - };
29 -
30 - stream = pump(inputStream, bufferStream(options), error => {
31 - if (error) {
32 - rejectPromise(error);
33 - return;
34 - }
35 -
36 - resolve();
37 - });
38 -
39 - stream.on('data', () => {
40 - if (stream.getBufferedLength() > maxBuffer) {
41 - rejectPromise(new MaxBufferError());
42 - }
43 - });
44 - }).then(() => stream.getBufferedValue());
45 -}
46 -
47 -module.exports = getStream;
48 -module.exports.buffer = (stream, options) => getStream(stream, Object.assign({}, options, {encoding: 'buffer'}));
49 -module.exports.array = (stream, options) => getStream(stream, Object.assign({}, options, {array: true}));
50 -module.exports.MaxBufferError = MaxBufferError;
1 -MIT License
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 of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
6 -
7 -The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
8 -
9 -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
1 -{
2 - "name": "get-stream",
3 - "version": "4.1.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": ">=6"
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 - "text",
29 - "buffer",
30 - "read",
31 - "data",
32 - "consume",
33 - "readable",
34 - "readablestream",
35 - "array",
36 - "object"
37 - ],
38 - "dependencies": {
39 - "pump": "^3.0.0"
40 - },
41 - "devDependencies": {
42 - "ava": "*",
43 - "into-stream": "^3.0.0",
44 - "xo": "*"
45 - }
46 -}
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 get-stream
10 -```
11 -
12 -
13 -## Usage
14 -
15 -```js
16 -const fs = require('fs');
17 -const getStream = require('get-stream');
18 -
19 -(async () => {
20 - const stream = fs.createReadStream('unicorn.txt');
21 -
22 - console.log(await getStream(stream));
23 - /*
24 - ,,))))))));,
25 - __)))))))))))))),
26 - \|/ -\(((((''''((((((((.
27 - -*-==//////(('' . `)))))),
28 - /|\ ))| o ;-. '((((( ,(,
29 - ( `| / ) ;))))' ,_))^;(~
30 - | | | ,))((((_ _____------~~~-. %,;(;(>';'~
31 - o_); ; )))(((` ~---~ `:: \ %%~~)(v;(`('~
32 - ; ''''```` `: `:::|\,__,%% );`'; ~
33 - | _ ) / `:|`----' `-'
34 - ______/\/~ | / /
35 - /~;;.____/;;' / ___--,-( `;;;/
36 - / // _;______;'------~~~~~ /;;/\ /
37 - // | | / ; \;;,\
38 - (<_ | ; /',/-----' _>
39 - \_| ||_ //~;~~~~~~~~~
40 - `\_| (,~~
41 - \~\
42 - ~~
43 - */
44 -})();
45 -```
46 -
47 -
48 -## API
49 -
50 -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.
51 -
52 -### getStream(stream, [options])
53 -
54 -Get the `stream` as a string.
55 -
56 -#### options
57 -
58 -Type: `Object`
59 -
60 -##### encoding
61 -
62 -Type: `string`<br>
63 -Default: `utf8`
64 -
65 -[Encoding](https://nodejs.org/api/buffer.html#buffer_buffer) of the incoming stream.
66 -
67 -##### maxBuffer
68 -
69 -Type: `number`<br>
70 -Default: `Infinity`
71 -
72 -Maximum length of the returned string. If it exceeds this value before the stream ends, the promise will be rejected with a `getStream.MaxBufferError` error.
73 -
74 -### getStream.buffer(stream, [options])
75 -
76 -Get the `stream` as a buffer.
77 -
78 -It honors the `maxBuffer` option as above, but it refers to byte length rather than string length.
79 -
80 -### getStream.array(stream, [options])
81 -
82 -Get the `stream` as an array of values.
83 -
84 -It honors both the `maxBuffer` and `encoding` options. The behavior changes slightly based on the encoding chosen:
85 -
86 -- 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).
87 -
88 -- 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.
89 -
90 -- 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.
91 -
92 -
93 -## Errors
94 -
95 -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.
96 -
97 -```js
98 -(async () => {
99 - try {
100 - await getStream(streamThatErrorsAtTheEnd('unicorn'));
101 - } catch (error) {
102 - console.log(error.bufferedData);
103 - //=> 'unicorn'
104 - }
105 -})()
106 -```
107 -
108 -
109 -## FAQ
110 -
111 -### How is this different from [`concat-stream`](https://github.com/maxogden/concat-stream)?
112 -
113 -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.
114 -
115 -
116 -## Related
117 -
118 -- [get-stdin](https://github.com/sindresorhus/get-stdin) - Get stdin as a string or buffer
119 -
120 -
121 -## License
122 -
123 -MIT © [Sindre Sorhus](https://sindresorhus.com)
1 -MIT License
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 of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
6 -
7 -The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
8 -
9 -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
1 -/// <reference types="node" />
2 -/// <reference lib="es2016" />
3 -/// <reference lib="es2017.sharedmemory" />
4 -/// <reference lib="esnext.asynciterable" />
5 -/// <reference lib="dom" />
6 -declare type TypedArray = Int8Array | Uint8Array | Uint8ClampedArray | Int16Array | Uint16Array | Int32Array | Uint32Array | Float32Array | Float64Array;
7 -declare type Primitive = null | undefined | string | number | boolean | Symbol;
8 -export interface ArrayLike {
9 - length: number;
10 -}
11 -export interface Class<T = unknown> {
12 - new (...args: any[]): T;
13 -}
14 -declare type DomElement = object & {
15 - nodeType: 1;
16 - nodeName: string;
17 -};
18 -declare type NodeStream = object & {
19 - pipe: Function;
20 -};
21 -export declare const enum TypeName {
22 - null = "null",
23 - boolean = "boolean",
24 - undefined = "undefined",
25 - string = "string",
26 - number = "number",
27 - symbol = "symbol",
28 - Function = "Function",
29 - GeneratorFunction = "GeneratorFunction",
30 - AsyncFunction = "AsyncFunction",
31 - Observable = "Observable",
32 - Array = "Array",
33 - Buffer = "Buffer",
34 - Object = "Object",
35 - RegExp = "RegExp",
36 - Date = "Date",
37 - Error = "Error",
38 - Map = "Map",
39 - Set = "Set",
40 - WeakMap = "WeakMap",
41 - WeakSet = "WeakSet",
42 - Int8Array = "Int8Array",
43 - Uint8Array = "Uint8Array",
44 - Uint8ClampedArray = "Uint8ClampedArray",
45 - Int16Array = "Int16Array",
46 - Uint16Array = "Uint16Array",
47 - Int32Array = "Int32Array",
48 - Uint32Array = "Uint32Array",
49 - Float32Array = "Float32Array",
50 - Float64Array = "Float64Array",
51 - ArrayBuffer = "ArrayBuffer",
52 - SharedArrayBuffer = "SharedArrayBuffer",
53 - DataView = "DataView",
54 - Promise = "Promise",
55 - URL = "URL"
56 -}
57 -declare function is(value: unknown): TypeName;
58 -declare namespace is {
59 - const undefined: (value: unknown) => value is undefined;
60 - const string: (value: unknown) => value is string;
61 - const number: (value: unknown) => value is number;
62 - const function_: (value: unknown) => value is Function;
63 - const null_: (value: unknown) => value is null;
64 - const class_: (value: unknown) => value is Class<unknown>;
65 - const boolean: (value: unknown) => value is boolean;
66 - const symbol: (value: unknown) => value is Symbol;
67 - const numericString: (value: unknown) => boolean;
68 - const array: (arg: any) => arg is any[];
69 - const buffer: (input: unknown) => input is Buffer;
70 - const nullOrUndefined: (value: unknown) => value is null | undefined;
71 - const object: (value: unknown) => value is object;
72 - const iterable: (value: unknown) => value is IterableIterator<unknown>;
73 - const asyncIterable: (value: unknown) => value is AsyncIterableIterator<unknown>;
74 - const generator: (value: unknown) => value is Generator;
75 - const nativePromise: (value: unknown) => value is Promise<unknown>;
76 - const promise: (value: unknown) => value is Promise<unknown>;
77 - const generatorFunction: (value: unknown) => value is GeneratorFunction;
78 - const asyncFunction: (value: unknown) => value is Function;
79 - const boundFunction: (value: unknown) => value is Function;
80 - const regExp: (value: unknown) => value is RegExp;
81 - const date: (value: unknown) => value is Date;
82 - const error: (value: unknown) => value is Error;
83 - const map: (value: unknown) => value is Map<unknown, unknown>;
84 - const set: (value: unknown) => value is Set<unknown>;
85 - const weakMap: (value: unknown) => value is WeakMap<object, unknown>;
86 - const weakSet: (value: unknown) => value is WeakSet<object>;
87 - const int8Array: (value: unknown) => value is Int8Array;
88 - const uint8Array: (value: unknown) => value is Uint8Array;
89 - const uint8ClampedArray: (value: unknown) => value is Uint8ClampedArray;
90 - const int16Array: (value: unknown) => value is Int16Array;
91 - const uint16Array: (value: unknown) => value is Uint16Array;
92 - const int32Array: (value: unknown) => value is Int32Array;
93 - const uint32Array: (value: unknown) => value is Uint32Array;
94 - const float32Array: (value: unknown) => value is Float32Array;
95 - const float64Array: (value: unknown) => value is Float64Array;
96 - const arrayBuffer: (value: unknown) => value is ArrayBuffer;
97 - const sharedArrayBuffer: (value: unknown) => value is SharedArrayBuffer;
98 - const dataView: (value: unknown) => value is DataView;
99 - const directInstanceOf: <T>(instance: unknown, klass: Class<T>) => instance is T;
100 - const urlInstance: (value: unknown) => value is URL;
101 - const urlString: (value: unknown) => boolean;
102 - const truthy: (value: unknown) => boolean;
103 - const falsy: (value: unknown) => boolean;
104 - const nan: (value: unknown) => boolean;
105 - const primitive: (value: unknown) => value is Primitive;
106 - const integer: (value: unknown) => value is number;
107 - const safeInteger: (value: unknown) => value is number;
108 - const plainObject: (value: unknown) => boolean;
109 - const typedArray: (value: unknown) => value is TypedArray;
110 - const arrayLike: (value: unknown) => value is ArrayLike;
111 - const inRange: (value: number, range: number | number[]) => boolean;
112 - const domElement: (value: unknown) => value is DomElement;
113 - const observable: (value: unknown) => boolean;
114 - const nodeStream: (value: unknown) => value is NodeStream;
115 - const infinite: (value: unknown) => boolean;
116 - const even: (value: number) => boolean;
117 - const odd: (value: number) => boolean;
118 - const emptyArray: (value: unknown) => boolean;
119 - const nonEmptyArray: (value: unknown) => boolean;
120 - const emptyString: (value: unknown) => boolean;
121 - const nonEmptyString: (value: unknown) => boolean;
122 - const emptyStringOrWhitespace: (value: unknown) => boolean;
123 - const emptyObject: (value: unknown) => boolean;
124 - const nonEmptyObject: (value: unknown) => boolean;
125 - const emptySet: (value: unknown) => boolean;
126 - const nonEmptySet: (value: unknown) => boolean;
127 - const emptyMap: (value: unknown) => boolean;
128 - const nonEmptyMap: (value: unknown) => boolean;
129 - const any: (predicate: unknown, ...values: unknown[]) => boolean;
130 - const all: (predicate: unknown, ...values: unknown[]) => boolean;
131 -}
132 -export default is;
1 -MIT License
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 of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
6 -
7 -The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
8 -
9 -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
1 -{
2 - "name": "@sindresorhus/is",
3 - "version": "0.14.0",
4 - "description": "Type check values: `is.string('🦄') //=> true`",
5 - "license": "MIT",
6 - "repository": "sindresorhus/is",
7 - "author": {
8 - "name": "Sindre Sorhus",
9 - "email": "sindresorhus@gmail.com",
10 - "url": "sindresorhus.com"
11 - },
12 - "main": "dist/index.js",
13 - "engines": {
14 - "node": ">=6"
15 - },
16 - "scripts": {
17 - "lint": "tslint --format stylish --project .",
18 - "build": "del dist && tsc",
19 - "test": "npm run lint && npm run build && ava dist/tests",
20 - "prepublish": "npm run build && del dist/tests"
21 - },
22 - "files": [
23 - "dist"
24 - ],
25 - "keywords": [
26 - "type",
27 - "types",
28 - "is",
29 - "check",
30 - "checking",
31 - "validate",
32 - "validation",
33 - "utility",
34 - "util",
35 - "typeof",
36 - "instanceof",
37 - "object",
38 - "assert",
39 - "assertion",
40 - "test",
41 - "kind",
42 - "primitive",
43 - "verify",
44 - "compare"
45 - ],
46 - "devDependencies": {
47 - "@sindresorhus/tsconfig": "^0.1.0",
48 - "@types/jsdom": "^11.12.0",
49 - "@types/node": "^10.12.10",
50 - "@types/tempy": "^0.2.0",
51 - "@types/zen-observable": "^0.8.0",
52 - "ava": "^0.25.0",
53 - "del-cli": "^1.1.0",
54 - "jsdom": "^11.6.2",
55 - "rxjs": "^6.3.3",
56 - "tempy": "^0.2.1",
57 - "tslint": "^5.9.1",
58 - "tslint-xo": "^0.10.0",
59 - "typescript": "^3.2.1",
60 - "zen-observable": "^0.8.8"
61 - },
62 - "types": "dist/index.d.ts"
63 -}
This diff is collapsed. Click to expand it.
1 -{
2 - "name": "got",
3 - "version": "9.6.0",
4 - "description": "Simplified HTTP requests",
5 - "license": "MIT",
6 - "repository": "sindresorhus/got",
7 - "main": "source",
8 - "engines": {
9 - "node": ">=8.6"
10 - },
11 - "scripts": {
12 - "test": "xo && nyc ava",
13 - "release": "np"
14 - },
15 - "files": [
16 - "source"
17 - ],
18 - "keywords": [
19 - "http",
20 - "https",
21 - "get",
22 - "got",
23 - "url",
24 - "uri",
25 - "request",
26 - "util",
27 - "utility",
28 - "simple",
29 - "curl",
30 - "wget",
31 - "fetch",
32 - "net",
33 - "network",
34 - "electron"
35 - ],
36 - "dependencies": {
37 - "@sindresorhus/is": "^0.14.0",
38 - "@szmarczak/http-timer": "^1.1.2",
39 - "cacheable-request": "^6.0.0",
40 - "decompress-response": "^3.3.0",
41 - "duplexer3": "^0.1.4",
42 - "get-stream": "^4.1.0",
43 - "lowercase-keys": "^1.0.1",
44 - "mimic-response": "^1.0.1",
45 - "p-cancelable": "^1.0.0",
46 - "to-readable-stream": "^1.0.0",
47 - "url-parse-lax": "^3.0.0"
48 - },
49 - "devDependencies": {
50 - "ava": "^1.1.0",
51 - "coveralls": "^3.0.0",
52 - "delay": "^4.1.0",
53 - "form-data": "^2.3.3",
54 - "get-port": "^4.0.0",
55 - "np": "^3.1.0",
56 - "nyc": "^13.1.0",
57 - "p-event": "^2.1.0",
58 - "pem": "^1.13.2",
59 - "proxyquire": "^2.0.1",
60 - "sinon": "^7.2.2",
61 - "slow-stream": "0.0.4",
62 - "tempfile": "^2.0.0",
63 - "tempy": "^0.2.1",
64 - "tough-cookie": "^3.0.0",
65 - "xo": "^0.24.0"
66 - },
67 - "ava": {
68 - "concurrency": 4
69 - },
70 - "browser": {
71 - "decompress-response": false,
72 - "electron": false
73 - }
74 -}
This diff is collapsed. Click to expand it.
1 -'use strict';
2 -const EventEmitter = require('events');
3 -const getStream = require('get-stream');
4 -const is = require('@sindresorhus/is');
5 -const PCancelable = require('p-cancelable');
6 -const requestAsEventEmitter = require('./request-as-event-emitter');
7 -const {HTTPError, ParseError, ReadError} = require('./errors');
8 -const {options: mergeOptions} = require('./merge');
9 -const {reNormalize} = require('./normalize-arguments');
10 -
11 -const asPromise = options => {
12 - const proxy = new EventEmitter();
13 -
14 - const promise = new PCancelable((resolve, reject, onCancel) => {
15 - const emitter = requestAsEventEmitter(options);
16 -
17 - onCancel(emitter.abort);
18 -
19 - emitter.on('response', async response => {
20 - proxy.emit('response', response);
21 -
22 - const stream = is.null(options.encoding) ? getStream.buffer(response) : getStream(response, options);
23 -
24 - let data;
25 - try {
26 - data = await stream;
27 - } catch (error) {
28 - reject(new ReadError(error, options));
29 - return;
30 - }
31 -
32 - const limitStatusCode = options.followRedirect ? 299 : 399;
33 -
34 - response.body = data;
35 -
36 - try {
37 - for (const [index, hook] of Object.entries(options.hooks.afterResponse)) {
38 - // eslint-disable-next-line no-await-in-loop
39 - response = await hook(response, updatedOptions => {
40 - updatedOptions = reNormalize(mergeOptions(options, {
41 - ...updatedOptions,
42 - retry: 0,
43 - throwHttpErrors: false
44 - }));
45 -
46 - // Remove any further hooks for that request, because we we'll call them anyway.
47 - // The loop continues. We don't want duplicates (asPromise recursion).
48 - updatedOptions.hooks.afterResponse = options.hooks.afterResponse.slice(0, index);
49 -
50 - return asPromise(updatedOptions);
51 - });
52 - }
53 - } catch (error) {
54 - reject(error);
55 - return;
56 - }
57 -
58 - const {statusCode} = response;
59 -
60 - if (options.json && response.body) {
61 - try {
62 - response.body = JSON.parse(response.body);
63 - } catch (error) {
64 - if (statusCode >= 200 && statusCode < 300) {
65 - const parseError = new ParseError(error, statusCode, options, data);
66 - Object.defineProperty(parseError, 'response', {value: response});
67 - reject(parseError);
68 - return;
69 - }
70 - }
71 - }
72 -
73 - if (statusCode !== 304 && (statusCode < 200 || statusCode > limitStatusCode)) {
74 - const error = new HTTPError(response, options);
75 - Object.defineProperty(error, 'response', {value: response});
76 - if (emitter.retry(error) === false) {
77 - if (options.throwHttpErrors) {
78 - reject(error);
79 - return;
80 - }
81 -
82 - resolve(response);
83 - }
84 -
85 - return;
86 - }
87 -
88 - resolve(response);
89 - });
90 -
91 - emitter.once('error', reject);
92 - [
93 - 'request',
94 - 'redirect',
95 - 'uploadProgress',
96 - 'downloadProgress'
97 - ].forEach(event => emitter.on(event, (...args) => proxy.emit(event, ...args)));
98 - });
99 -
100 - promise.on = (name, fn) => {
101 - proxy.on(name, fn);
102 - return promise;
103 - };
104 -
105 - return promise;
106 -};
107 -
108 -module.exports = asPromise;
1 -'use strict';
2 -const {PassThrough} = require('stream');
3 -const duplexer3 = require('duplexer3');
4 -const requestAsEventEmitter = require('./request-as-event-emitter');
5 -const {HTTPError, ReadError} = require('./errors');
6 -
7 -module.exports = options => {
8 - const input = new PassThrough();
9 - const output = new PassThrough();
10 - const proxy = duplexer3(input, output);
11 - const piped = new Set();
12 - let isFinished = false;
13 -
14 - options.retry.retries = () => 0;
15 -
16 - if (options.body) {
17 - proxy.write = () => {
18 - throw new Error('Got\'s stream is not writable when the `body` option is used');
19 - };
20 - }
21 -
22 - const emitter = requestAsEventEmitter(options, input);
23 -
24 - // Cancels the request
25 - proxy._destroy = emitter.abort;
26 -
27 - emitter.on('response', response => {
28 - const {statusCode} = response;
29 -
30 - response.on('error', error => {
31 - proxy.emit('error', new ReadError(error, options));
32 - });
33 -
34 - if (options.throwHttpErrors && statusCode !== 304 && (statusCode < 200 || statusCode > 299)) {
35 - proxy.emit('error', new HTTPError(response, options), null, response);
36 - return;
37 - }
38 -
39 - isFinished = true;
40 -
41 - response.pipe(output);
42 -
43 - for (const destination of piped) {
44 - if (destination.headersSent) {
45 - continue;
46 - }
47 -
48 - for (const [key, value] of Object.entries(response.headers)) {
49 - // Got gives *decompressed* data. Overriding `content-encoding` header would result in an error.
50 - // It's not possible to decompress already decompressed data, is it?
51 - const allowed = options.decompress ? key !== 'content-encoding' : true;
52 - if (allowed) {
53 - destination.setHeader(key, value);
54 - }
55 - }
56 -
57 - destination.statusCode = response.statusCode;
58 - }
59 -
60 - proxy.emit('response', response);
61 - });
62 -
63 - [
64 - 'error',
65 - 'request',
66 - 'redirect',
67 - 'uploadProgress',
68 - 'downloadProgress'
69 - ].forEach(event => emitter.on(event, (...args) => proxy.emit(event, ...args)));
70 -
71 - const pipe = proxy.pipe.bind(proxy);
72 - const unpipe = proxy.unpipe.bind(proxy);
73 - proxy.pipe = (destination, options) => {
74 - if (isFinished) {
75 - throw new Error('Failed to pipe. The response has been emitted already.');
76 - }
77 -
78 - const result = pipe(destination, options);
79 -
80 - if (Reflect.has(destination, 'setHeader')) {
81 - piped.add(destination);
82 - }
83 -
84 - return result;
85 - };
86 -
87 - proxy.unpipe = stream => {
88 - piped.delete(stream);
89 - return unpipe(stream);
90 - };
91 -
92 - return proxy;
93 -};
1 -'use strict';
2 -const errors = require('./errors');
3 -const asStream = require('./as-stream');
4 -const asPromise = require('./as-promise');
5 -const normalizeArguments = require('./normalize-arguments');
6 -const merge = require('./merge');
7 -const deepFreeze = require('./utils/deep-freeze');
8 -
9 -const getPromiseOrStream = options => options.stream ? asStream(options) : asPromise(options);
10 -
11 -const aliases = [
12 - 'get',
13 - 'post',
14 - 'put',
15 - 'patch',
16 - 'head',
17 - 'delete'
18 -];
19 -
20 -const create = defaults => {
21 - defaults = merge({}, defaults);
22 - normalizeArguments.preNormalize(defaults.options);
23 -
24 - if (!defaults.handler) {
25 - // This can't be getPromiseOrStream, because when merging
26 - // the chain would stop at this point and no further handlers would be called.
27 - defaults.handler = (options, next) => next(options);
28 - }
29 -
30 - function got(url, options) {
31 - try {
32 - return defaults.handler(normalizeArguments(url, options, defaults), getPromiseOrStream);
33 - } catch (error) {
34 - if (options && options.stream) {
35 - throw error;
36 - } else {
37 - return Promise.reject(error);
38 - }
39 - }
40 - }
41 -
42 - got.create = create;
43 - got.extend = options => {
44 - let mutableDefaults;
45 - if (options && Reflect.has(options, 'mutableDefaults')) {
46 - mutableDefaults = options.mutableDefaults;
47 - delete options.mutableDefaults;
48 - } else {
49 - mutableDefaults = defaults.mutableDefaults;
50 - }
51 -
52 - return create({
53 - options: merge.options(defaults.options, options),
54 - handler: defaults.handler,
55 - mutableDefaults
56 - });
57 - };
58 -
59 - got.mergeInstances = (...args) => create(merge.instances(args));
60 -
61 - got.stream = (url, options) => got(url, {...options, stream: true});
62 -
63 - for (const method of aliases) {
64 - got[method] = (url, options) => got(url, {...options, method});
65 - got.stream[method] = (url, options) => got.stream(url, {...options, method});
66 - }
67 -
68 - Object.assign(got, {...errors, mergeOptions: merge.options});
69 - Object.defineProperty(got, 'defaults', {
70 - value: defaults.mutableDefaults ? defaults : deepFreeze(defaults),
71 - writable: defaults.mutableDefaults,
72 - configurable: defaults.mutableDefaults,
73 - enumerable: true
74 - });
75 -
76 - return got;
77 -};
78 -
79 -module.exports = create;
1 -'use strict';
2 -const urlLib = require('url');
3 -const http = require('http');
4 -const PCancelable = require('p-cancelable');
5 -const is = require('@sindresorhus/is');
6 -
7 -class GotError extends Error {
8 - constructor(message, error, options) {
9 - super(message);
10 - Error.captureStackTrace(this, this.constructor);
11 - this.name = 'GotError';
12 -
13 - if (!is.undefined(error.code)) {
14 - this.code = error.code;
15 - }
16 -
17 - Object.assign(this, {
18 - host: options.host,
19 - hostname: options.hostname,
20 - method: options.method,
21 - path: options.path,
22 - socketPath: options.socketPath,
23 - protocol: options.protocol,
24 - url: options.href,
25 - gotOptions: options
26 - });
27 - }
28 -}
29 -
30 -module.exports.GotError = GotError;
31 -
32 -module.exports.CacheError = class extends GotError {
33 - constructor(error, options) {
34 - super(error.message, error, options);
35 - this.name = 'CacheError';
36 - }
37 -};
38 -
39 -module.exports.RequestError = class extends GotError {
40 - constructor(error, options) {
41 - super(error.message, error, options);
42 - this.name = 'RequestError';
43 - }
44 -};
45 -
46 -module.exports.ReadError = class extends GotError {
47 - constructor(error, options) {
48 - super(error.message, error, options);
49 - this.name = 'ReadError';
50 - }
51 -};
52 -
53 -module.exports.ParseError = class extends GotError {
54 - constructor(error, statusCode, options, data) {
55 - super(`${error.message} in "${urlLib.format(options)}": \n${data.slice(0, 77)}...`, error, options);
56 - this.name = 'ParseError';
57 - this.statusCode = statusCode;
58 - this.statusMessage = http.STATUS_CODES[this.statusCode];
59 - }
60 -};
61 -
62 -module.exports.HTTPError = class extends GotError {
63 - constructor(response, options) {
64 - const {statusCode} = response;
65 - let {statusMessage} = response;
66 -
67 - if (statusMessage) {
68 - statusMessage = statusMessage.replace(/\r?\n/g, ' ').trim();
69 - } else {
70 - statusMessage = http.STATUS_CODES[statusCode];
71 - }
72 -
73 - super(`Response code ${statusCode} (${statusMessage})`, {}, options);
74 - this.name = 'HTTPError';
75 - this.statusCode = statusCode;
76 - this.statusMessage = statusMessage;
77 - this.headers = response.headers;
78 - this.body = response.body;
79 - }
80 -};
81 -
82 -module.exports.MaxRedirectsError = class extends GotError {
83 - constructor(statusCode, redirectUrls, options) {
84 - super('Redirected 10 times. Aborting.', {}, options);
85 - this.name = 'MaxRedirectsError';
86 - this.statusCode = statusCode;
87 - this.statusMessage = http.STATUS_CODES[this.statusCode];
88 - this.redirectUrls = redirectUrls;
89 - }
90 -};
91 -
92 -module.exports.UnsupportedProtocolError = class extends GotError {
93 - constructor(options) {
94 - super(`Unsupported protocol "${options.protocol}"`, {}, options);
95 - this.name = 'UnsupportedProtocolError';
96 - }
97 -};
98 -
99 -module.exports.TimeoutError = class extends GotError {
100 - constructor(error, options) {
101 - super(error.message, {code: 'ETIMEDOUT'}, options);
102 - this.name = 'TimeoutError';
103 - this.event = error.event;
104 - }
105 -};
106 -
107 -module.exports.CancelError = PCancelable.CancelError;
1 -'use strict';
2 -const decompressResponse = require('decompress-response');
3 -const is = require('@sindresorhus/is');
4 -const mimicResponse = require('mimic-response');
5 -const progress = require('./progress');
6 -
7 -module.exports = (response, options, emitter) => {
8 - const downloadBodySize = Number(response.headers['content-length']) || null;
9 -
10 - const progressStream = progress.download(response, emitter, downloadBodySize);
11 -
12 - mimicResponse(response, progressStream);
13 -
14 - const newResponse = options.decompress === true &&
15 - is.function(decompressResponse) &&
16 - options.method !== 'HEAD' ? decompressResponse(progressStream) : progressStream;
17 -
18 - if (!options.decompress && ['gzip', 'deflate'].includes(response.headers['content-encoding'])) {
19 - options.encoding = null;
20 - }
21 -
22 - emitter.emit('response', newResponse);
23 -
24 - emitter.emit('downloadProgress', {
25 - percent: 0,
26 - transferred: 0,
27 - total: downloadBodySize
28 - });
29 -
30 - response.pipe(progressStream);
31 -};
1 -'use strict';
2 -const pkg = require('../package.json');
3 -const create = require('./create');
4 -
5 -const defaults = {
6 - options: {
7 - retry: {
8 - retries: 2,
9 - methods: [
10 - 'GET',
11 - 'PUT',
12 - 'HEAD',
13 - 'DELETE',
14 - 'OPTIONS',
15 - 'TRACE'
16 - ],
17 - statusCodes: [
18 - 408,
19 - 413,
20 - 429,
21 - 500,
22 - 502,
23 - 503,
24 - 504
25 - ],
26 - errorCodes: [
27 - 'ETIMEDOUT',
28 - 'ECONNRESET',
29 - 'EADDRINUSE',
30 - 'ECONNREFUSED',
31 - 'EPIPE',
32 - 'ENOTFOUND',
33 - 'ENETUNREACH',
34 - 'EAI_AGAIN'
35 - ]
36 - },
37 - headers: {
38 - 'user-agent': `${pkg.name}/${pkg.version} (https://github.com/sindresorhus/got)`
39 - },
40 - hooks: {
41 - beforeRequest: [],
42 - beforeRedirect: [],
43 - beforeRetry: [],
44 - afterResponse: []
45 - },
46 - decompress: true,
47 - throwHttpErrors: true,
48 - followRedirect: true,
49 - stream: false,
50 - form: false,
51 - json: false,
52 - cache: false,
53 - useElectronNet: false
54 - },
55 - mutableDefaults: false
56 -};
57 -
58 -const got = create(defaults);
59 -
60 -module.exports = got;
1 -'use strict';
2 -
3 -module.exports = [
4 - 'beforeError',
5 - 'init',
6 - 'beforeRequest',
7 - 'beforeRedirect',
8 - 'beforeRetry',
9 - 'afterResponse'
10 -];
1 -'use strict';
2 -const {URL} = require('url');
3 -const is = require('@sindresorhus/is');
4 -const knownHookEvents = require('./known-hook-events');
5 -
6 -const merge = (target, ...sources) => {
7 - for (const source of sources) {
8 - for (const [key, sourceValue] of Object.entries(source)) {
9 - if (is.undefined(sourceValue)) {
10 - continue;
11 - }
12 -
13 - const targetValue = target[key];
14 - if (is.urlInstance(targetValue) && (is.urlInstance(sourceValue) || is.string(sourceValue))) {
15 - target[key] = new URL(sourceValue, targetValue);
16 - } else if (is.plainObject(sourceValue)) {
17 - if (is.plainObject(targetValue)) {
18 - target[key] = merge({}, targetValue, sourceValue);
19 - } else {
20 - target[key] = merge({}, sourceValue);
21 - }
22 - } else if (is.array(sourceValue)) {
23 - target[key] = merge([], sourceValue);
24 - } else {
25 - target[key] = sourceValue;
26 - }
27 - }
28 - }
29 -
30 - return target;
31 -};
32 -
33 -const mergeOptions = (...sources) => {
34 - sources = sources.map(source => source || {});
35 - const merged = merge({}, ...sources);
36 -
37 - const hooks = {};
38 - for (const hook of knownHookEvents) {
39 - hooks[hook] = [];
40 - }
41 -
42 - for (const source of sources) {
43 - if (source.hooks) {
44 - for (const hook of knownHookEvents) {
45 - hooks[hook] = hooks[hook].concat(source.hooks[hook]);
46 - }
47 - }
48 - }
49 -
50 - merged.hooks = hooks;
51 -
52 - return merged;
53 -};
54 -
55 -const mergeInstances = (instances, methods) => {
56 - const handlers = instances.map(instance => instance.defaults.handler);
57 - const size = instances.length - 1;
58 -
59 - return {
60 - methods,
61 - options: mergeOptions(...instances.map(instance => instance.defaults.options)),
62 - handler: (options, next) => {
63 - let iteration = -1;
64 - const iterate = options => handlers[++iteration](options, iteration === size ? next : iterate);
65 -
66 - return iterate(options);
67 - }
68 - };
69 -};
70 -
71 -module.exports = merge;
72 -module.exports.options = mergeOptions;
73 -module.exports.instances = mergeInstances;
1 -'use strict';
2 -const {URL, URLSearchParams} = require('url'); // TODO: Use the `URL` global when targeting Node.js 10
3 -const urlLib = require('url');
4 -const is = require('@sindresorhus/is');
5 -const urlParseLax = require('url-parse-lax');
6 -const lowercaseKeys = require('lowercase-keys');
7 -const urlToOptions = require('./utils/url-to-options');
8 -const isFormData = require('./utils/is-form-data');
9 -const merge = require('./merge');
10 -const knownHookEvents = require('./known-hook-events');
11 -
12 -const retryAfterStatusCodes = new Set([413, 429, 503]);
13 -
14 -// `preNormalize` handles static options (e.g. headers).
15 -// For example, when you create a custom instance and make a request
16 -// with no static changes, they won't be normalized again.
17 -//
18 -// `normalize` operates on dynamic options - they cannot be saved.
19 -// For example, `body` is everytime different per request.
20 -// When it's done normalizing the new options, it performs merge()
21 -// on the prenormalized options and the normalized ones.
22 -
23 -const preNormalize = (options, defaults) => {
24 - if (is.nullOrUndefined(options.headers)) {
25 - options.headers = {};
26 - } else {
27 - options.headers = lowercaseKeys(options.headers);
28 - }
29 -
30 - if (options.baseUrl && !options.baseUrl.toString().endsWith('/')) {
31 - options.baseUrl += '/';
32 - }
33 -
34 - if (options.stream) {
35 - options.json = false;
36 - }
37 -
38 - if (is.nullOrUndefined(options.hooks)) {
39 - options.hooks = {};
40 - } else if (!is.object(options.hooks)) {
41 - throw new TypeError(`Parameter \`hooks\` must be an object, not ${is(options.hooks)}`);
42 - }
43 -
44 - for (const event of knownHookEvents) {
45 - if (is.nullOrUndefined(options.hooks[event])) {
46 - if (defaults) {
47 - options.hooks[event] = [...defaults.hooks[event]];
48 - } else {
49 - options.hooks[event] = [];
50 - }
51 - }
52 - }
53 -
54 - if (is.number(options.timeout)) {
55 - options.gotTimeout = {request: options.timeout};
56 - } else if (is.object(options.timeout)) {
57 - options.gotTimeout = options.timeout;
58 - }
59 -
60 - delete options.timeout;
61 -
62 - const {retry} = options;
63 - options.retry = {
64 - retries: 0,
65 - methods: [],
66 - statusCodes: [],
67 - errorCodes: []
68 - };
69 -
70 - if (is.nonEmptyObject(defaults) && retry !== false) {
71 - options.retry = {...defaults.retry};
72 - }
73 -
74 - if (retry !== false) {
75 - if (is.number(retry)) {
76 - options.retry.retries = retry;
77 - } else {
78 - options.retry = {...options.retry, ...retry};
79 - }
80 - }
81 -
82 - if (options.gotTimeout) {
83 - options.retry.maxRetryAfter = Math.min(...[options.gotTimeout.request, options.gotTimeout.connection].filter(n => !is.nullOrUndefined(n)));
84 - }
85 -
86 - if (is.array(options.retry.methods)) {
87 - options.retry.methods = new Set(options.retry.methods.map(method => method.toUpperCase()));
88 - }
89 -
90 - if (is.array(options.retry.statusCodes)) {
91 - options.retry.statusCodes = new Set(options.retry.statusCodes);
92 - }
93 -
94 - if (is.array(options.retry.errorCodes)) {
95 - options.retry.errorCodes = new Set(options.retry.errorCodes);
96 - }
97 -
98 - return options;
99 -};
100 -
101 -const normalize = (url, options, defaults) => {
102 - if (is.plainObject(url)) {
103 - options = {...url, ...options};
104 - url = options.url || {};
105 - delete options.url;
106 - }
107 -
108 - if (defaults) {
109 - options = merge({}, defaults.options, options ? preNormalize(options, defaults.options) : {});
110 - } else {
111 - options = merge({}, preNormalize(options));
112 - }
113 -
114 - if (!is.string(url) && !is.object(url)) {
115 - throw new TypeError(`Parameter \`url\` must be a string or object, not ${is(url)}`);
116 - }
117 -
118 - if (is.string(url)) {
119 - if (options.baseUrl) {
120 - if (url.toString().startsWith('/')) {
121 - url = url.toString().slice(1);
122 - }
123 -
124 - url = urlToOptions(new URL(url, options.baseUrl));
125 - } else {
126 - url = url.replace(/^unix:/, 'http://$&');
127 - url = urlParseLax(url);
128 - }
129 - } else if (is(url) === 'URL') {
130 - url = urlToOptions(url);
131 - }
132 -
133 - // Override both null/undefined with default protocol
134 - options = merge({path: ''}, url, {protocol: url.protocol || 'https:'}, options);
135 -
136 - for (const hook of options.hooks.init) {
137 - const called = hook(options);
138 -
139 - if (is.promise(called)) {
140 - throw new TypeError('The `init` hook must be a synchronous function');
141 - }
142 - }
143 -
144 - const {baseUrl} = options;
145 - Object.defineProperty(options, 'baseUrl', {
146 - set: () => {
147 - throw new Error('Failed to set baseUrl. Options are normalized already.');
148 - },
149 - get: () => baseUrl
150 - });
151 -
152 - const {query} = options;
153 - if (is.nonEmptyString(query) || is.nonEmptyObject(query) || query instanceof URLSearchParams) {
154 - if (!is.string(query)) {
155 - options.query = (new URLSearchParams(query)).toString();
156 - }
157 -
158 - options.path = `${options.path.split('?')[0]}?${options.query}`;
159 - delete options.query;
160 - }
161 -
162 - if (options.hostname === 'unix') {
163 - const matches = /(.+?):(.+)/.exec(options.path);
164 -
165 - if (matches) {
166 - const [, socketPath, path] = matches;
167 - options = {
168 - ...options,
169 - socketPath,
170 - path,
171 - host: null
172 - };
173 - }
174 - }
175 -
176 - const {headers} = options;
177 - for (const [key, value] of Object.entries(headers)) {
178 - if (is.nullOrUndefined(value)) {
179 - delete headers[key];
180 - }
181 - }
182 -
183 - if (options.json && is.undefined(headers.accept)) {
184 - headers.accept = 'application/json';
185 - }
186 -
187 - if (options.decompress && is.undefined(headers['accept-encoding'])) {
188 - headers['accept-encoding'] = 'gzip, deflate';
189 - }
190 -
191 - const {body} = options;
192 - if (is.nullOrUndefined(body)) {
193 - options.method = options.method ? options.method.toUpperCase() : 'GET';
194 - } else {
195 - const isObject = is.object(body) && !is.buffer(body) && !is.nodeStream(body);
196 - if (!is.nodeStream(body) && !is.string(body) && !is.buffer(body) && !(options.form || options.json)) {
197 - throw new TypeError('The `body` option must be a stream.Readable, string or Buffer');
198 - }
199 -
200 - if (options.json && !(isObject || is.array(body))) {
201 - throw new TypeError('The `body` option must be an Object or Array when the `json` option is used');
202 - }
203 -
204 - if (options.form && !isObject) {
205 - throw new TypeError('The `body` option must be an Object when the `form` option is used');
206 - }
207 -
208 - if (isFormData(body)) {
209 - // Special case for https://github.com/form-data/form-data
210 - headers['content-type'] = headers['content-type'] || `multipart/form-data; boundary=${body.getBoundary()}`;
211 - } else if (options.form) {
212 - headers['content-type'] = headers['content-type'] || 'application/x-www-form-urlencoded';
213 - options.body = (new URLSearchParams(body)).toString();
214 - } else if (options.json) {
215 - headers['content-type'] = headers['content-type'] || 'application/json';
216 - options.body = JSON.stringify(body);
217 - }
218 -
219 - options.method = options.method ? options.method.toUpperCase() : 'POST';
220 - }
221 -
222 - if (!is.function(options.retry.retries)) {
223 - const {retries} = options.retry;
224 -
225 - options.retry.retries = (iteration, error) => {
226 - if (iteration > retries) {
227 - return 0;
228 - }
229 -
230 - if ((!error || !options.retry.errorCodes.has(error.code)) && (!options.retry.methods.has(error.method) || !options.retry.statusCodes.has(error.statusCode))) {
231 - return 0;
232 - }
233 -
234 - if (Reflect.has(error, 'headers') && Reflect.has(error.headers, 'retry-after') && retryAfterStatusCodes.has(error.statusCode)) {
235 - let after = Number(error.headers['retry-after']);
236 - if (is.nan(after)) {
237 - after = Date.parse(error.headers['retry-after']) - Date.now();
238 - } else {
239 - after *= 1000;
240 - }
241 -
242 - if (after > options.retry.maxRetryAfter) {
243 - return 0;
244 - }
245 -
246 - return after;
247 - }
248 -
249 - if (error.statusCode === 413) {
250 - return 0;
251 - }
252 -
253 - const noise = Math.random() * 100;
254 - return ((2 ** (iteration - 1)) * 1000) + noise;
255 - };
256 - }
257 -
258 - return options;
259 -};
260 -
261 -const reNormalize = options => normalize(urlLib.format(options), options);
262 -
263 -module.exports = normalize;
264 -module.exports.preNormalize = preNormalize;
265 -module.exports.reNormalize = reNormalize;
1 -'use strict';
2 -const {Transform} = require('stream');
3 -
4 -module.exports = {
5 - download(response, emitter, downloadBodySize) {
6 - let downloaded = 0;
7 -
8 - return new Transform({
9 - transform(chunk, encoding, callback) {
10 - downloaded += chunk.length;
11 -
12 - const percent = downloadBodySize ? downloaded / downloadBodySize : 0;
13 -
14 - // Let `flush()` be responsible for emitting the last event
15 - if (percent < 1) {
16 - emitter.emit('downloadProgress', {
17 - percent,
18 - transferred: downloaded,
19 - total: downloadBodySize
20 - });
21 - }
22 -
23 - callback(null, chunk);
24 - },
25 -
26 - flush(callback) {
27 - emitter.emit('downloadProgress', {
28 - percent: 1,
29 - transferred: downloaded,
30 - total: downloadBodySize
31 - });
32 -
33 - callback();
34 - }
35 - });
36 - },
37 -
38 - upload(request, emitter, uploadBodySize) {
39 - const uploadEventFrequency = 150;
40 - let uploaded = 0;
41 - let progressInterval;
42 -
43 - emitter.emit('uploadProgress', {
44 - percent: 0,
45 - transferred: 0,
46 - total: uploadBodySize
47 - });
48 -
49 - request.once('error', () => {
50 - clearInterval(progressInterval);
51 - });
52 -
53 - request.once('response', () => {
54 - clearInterval(progressInterval);
55 -
56 - emitter.emit('uploadProgress', {
57 - percent: 1,
58 - transferred: uploaded,
59 - total: uploadBodySize
60 - });
61 - });
62 -
63 - request.once('socket', socket => {
64 - const onSocketConnect = () => {
65 - progressInterval = setInterval(() => {
66 - const lastUploaded = uploaded;
67 - /* istanbul ignore next: see #490 (occurs randomly!) */
68 - const headersSize = request._header ? Buffer.byteLength(request._header) : 0;
69 - uploaded = socket.bytesWritten - headersSize;
70 -
71 - // Don't emit events with unchanged progress and
72 - // prevent last event from being emitted, because
73 - // it's emitted when `response` is emitted
74 - if (uploaded === lastUploaded || uploaded === uploadBodySize) {
75 - return;
76 - }
77 -
78 - emitter.emit('uploadProgress', {
79 - percent: uploadBodySize ? uploaded / uploadBodySize : 0,
80 - transferred: uploaded,
81 - total: uploadBodySize
82 - });
83 - }, uploadEventFrequency);
84 - };
85 -
86 - /* istanbul ignore next: hard to test */
87 - if (socket.connecting) {
88 - socket.once('connect', onSocketConnect);
89 - } else if (socket.writable) {
90 - // The socket is being reused from pool,
91 - // so the connect event will not be emitted
92 - onSocketConnect();
93 - }
94 - });
95 - }
96 -};
1 -'use strict';
2 -const {URL} = require('url'); // TODO: Use the `URL` global when targeting Node.js 10
3 -const util = require('util');
4 -const EventEmitter = require('events');
5 -const http = require('http');
6 -const https = require('https');
7 -const urlLib = require('url');
8 -const CacheableRequest = require('cacheable-request');
9 -const toReadableStream = require('to-readable-stream');
10 -const is = require('@sindresorhus/is');
11 -const timer = require('@szmarczak/http-timer');
12 -const timedOut = require('./utils/timed-out');
13 -const getBodySize = require('./utils/get-body-size');
14 -const getResponse = require('./get-response');
15 -const progress = require('./progress');
16 -const {CacheError, UnsupportedProtocolError, MaxRedirectsError, RequestError, TimeoutError} = require('./errors');
17 -const urlToOptions = require('./utils/url-to-options');
18 -
19 -const getMethodRedirectCodes = new Set([300, 301, 302, 303, 304, 305, 307, 308]);
20 -const allMethodRedirectCodes = new Set([300, 303, 307, 308]);
21 -
22 -module.exports = (options, input) => {
23 - const emitter = new EventEmitter();
24 - const redirects = [];
25 - let currentRequest;
26 - let requestUrl;
27 - let redirectString;
28 - let uploadBodySize;
29 - let retryCount = 0;
30 - let shouldAbort = false;
31 -
32 - const setCookie = options.cookieJar ? util.promisify(options.cookieJar.setCookie.bind(options.cookieJar)) : null;
33 - const getCookieString = options.cookieJar ? util.promisify(options.cookieJar.getCookieString.bind(options.cookieJar)) : null;
34 - const agents = is.object(options.agent) ? options.agent : null;
35 -
36 - const emitError = async error => {
37 - try {
38 - for (const hook of options.hooks.beforeError) {
39 - // eslint-disable-next-line no-await-in-loop
40 - error = await hook(error);
41 - }
42 -
43 - emitter.emit('error', error);
44 - } catch (error2) {
45 - emitter.emit('error', error2);
46 - }
47 - };
48 -
49 - const get = async options => {
50 - const currentUrl = redirectString || requestUrl;
51 -
52 - if (options.protocol !== 'http:' && options.protocol !== 'https:') {
53 - throw new UnsupportedProtocolError(options);
54 - }
55 -
56 - decodeURI(currentUrl);
57 -
58 - let fn;
59 - if (is.function(options.request)) {
60 - fn = {request: options.request};
61 - } else {
62 - fn = options.protocol === 'https:' ? https : http;
63 - }
64 -
65 - if (agents) {
66 - const protocolName = options.protocol === 'https:' ? 'https' : 'http';
67 - options.agent = agents[protocolName] || options.agent;
68 - }
69 -
70 - /* istanbul ignore next: electron.net is broken */
71 - if (options.useElectronNet && process.versions.electron) {
72 - const r = ({x: require})['yx'.slice(1)]; // Trick webpack
73 - const electron = r('electron');
74 - fn = electron.net || electron.remote.net;
75 - }
76 -
77 - if (options.cookieJar) {
78 - const cookieString = await getCookieString(currentUrl, {});
79 -
80 - if (is.nonEmptyString(cookieString)) {
81 - options.headers.cookie = cookieString;
82 - }
83 - }
84 -
85 - let timings;
86 - const handleResponse = async response => {
87 - try {
88 - /* istanbul ignore next: fixes https://github.com/electron/electron/blob/cbb460d47628a7a146adf4419ed48550a98b2923/lib/browser/api/net.js#L59-L65 */
89 - if (options.useElectronNet) {
90 - response = new Proxy(response, {
91 - get: (target, name) => {
92 - if (name === 'trailers' || name === 'rawTrailers') {
93 - return [];
94 - }
95 -
96 - const value = target[name];
97 - return is.function(value) ? value.bind(target) : value;
98 - }
99 - });
100 - }
101 -
102 - const {statusCode} = response;
103 - response.url = currentUrl;
104 - response.requestUrl = requestUrl;
105 - response.retryCount = retryCount;
106 - response.timings = timings;
107 - response.redirectUrls = redirects;
108 - response.request = {
109 - gotOptions: options
110 - };
111 -
112 - const rawCookies = response.headers['set-cookie'];
113 - if (options.cookieJar && rawCookies) {
114 - await Promise.all(rawCookies.map(rawCookie => setCookie(rawCookie, response.url)));
115 - }
116 -
117 - if (options.followRedirect && 'location' in response.headers) {
118 - if (allMethodRedirectCodes.has(statusCode) || (getMethodRedirectCodes.has(statusCode) && (options.method === 'GET' || options.method === 'HEAD'))) {
119 - response.resume(); // We're being redirected, we don't care about the response.
120 -
121 - if (statusCode === 303) {
122 - // Server responded with "see other", indicating that the resource exists at another location,
123 - // and the client should request it from that location via GET or HEAD.
124 - options.method = 'GET';
125 - }
126 -
127 - if (redirects.length >= 10) {
128 - throw new MaxRedirectsError(statusCode, redirects, options);
129 - }
130 -
131 - // Handles invalid URLs. See https://github.com/sindresorhus/got/issues/604
132 - const redirectBuffer = Buffer.from(response.headers.location, 'binary').toString();
133 - const redirectURL = new URL(redirectBuffer, currentUrl);
134 - redirectString = redirectURL.toString();
135 -
136 - redirects.push(redirectString);
137 -
138 - const redirectOptions = {
139 - ...options,
140 - ...urlToOptions(redirectURL)
141 - };
142 -
143 - for (const hook of options.hooks.beforeRedirect) {
144 - // eslint-disable-next-line no-await-in-loop
145 - await hook(redirectOptions);
146 - }
147 -
148 - emitter.emit('redirect', response, redirectOptions);
149 -
150 - await get(redirectOptions);
151 - return;
152 - }
153 - }
154 -
155 - getResponse(response, options, emitter);
156 - } catch (error) {
157 - emitError(error);
158 - }
159 - };
160 -
161 - const handleRequest = request => {
162 - if (shouldAbort) {
163 - request.once('error', () => {});
164 - request.abort();
165 - return;
166 - }
167 -
168 - currentRequest = request;
169 -
170 - request.once('error', error => {
171 - if (request.aborted) {
172 - return;
173 - }
174 -
175 - if (error instanceof timedOut.TimeoutError) {
176 - error = new TimeoutError(error, options);
177 - } else {
178 - error = new RequestError(error, options);
179 - }
180 -
181 - if (emitter.retry(error) === false) {
182 - emitError(error);
183 - }
184 - });
185 -
186 - timings = timer(request);
187 -
188 - progress.upload(request, emitter, uploadBodySize);
189 -
190 - if (options.gotTimeout) {
191 - timedOut(request, options.gotTimeout, options);
192 - }
193 -
194 - emitter.emit('request', request);
195 -
196 - const uploadComplete = () => {
197 - request.emit('upload-complete');
198 - };
199 -
200 - try {
201 - if (is.nodeStream(options.body)) {
202 - options.body.once('end', uploadComplete);
203 - options.body.pipe(request);
204 - options.body = undefined;
205 - } else if (options.body) {
206 - request.end(options.body, uploadComplete);
207 - } else if (input && (options.method === 'POST' || options.method === 'PUT' || options.method === 'PATCH')) {
208 - input.once('end', uploadComplete);
209 - input.pipe(request);
210 - } else {
211 - request.end(uploadComplete);
212 - }
213 - } catch (error) {
214 - emitError(new RequestError(error, options));
215 - }
216 - };
217 -
218 - if (options.cache) {
219 - const cacheableRequest = new CacheableRequest(fn.request, options.cache);
220 - const cacheRequest = cacheableRequest(options, handleResponse);
221 -
222 - cacheRequest.once('error', error => {
223 - if (error instanceof CacheableRequest.RequestError) {
224 - emitError(new RequestError(error, options));
225 - } else {
226 - emitError(new CacheError(error, options));
227 - }
228 - });
229 -
230 - cacheRequest.once('request', handleRequest);
231 - } else {
232 - // Catches errors thrown by calling fn.request(...)
233 - try {
234 - handleRequest(fn.request(options, handleResponse));
235 - } catch (error) {
236 - emitError(new RequestError(error, options));
237 - }
238 - }
239 - };
240 -
241 - emitter.retry = error => {
242 - let backoff;
243 -
244 - try {
245 - backoff = options.retry.retries(++retryCount, error);
246 - } catch (error2) {
247 - emitError(error2);
248 - return;
249 - }
250 -
251 - if (backoff) {
252 - const retry = async options => {
253 - try {
254 - for (const hook of options.hooks.beforeRetry) {
255 - // eslint-disable-next-line no-await-in-loop
256 - await hook(options, error, retryCount);
257 - }
258 -
259 - await get(options);
260 - } catch (error) {
261 - emitError(error);
262 - }
263 - };
264 -
265 - setTimeout(retry, backoff, {...options, forceRefresh: true});
266 - return true;
267 - }
268 -
269 - return false;
270 - };
271 -
272 - emitter.abort = () => {
273 - if (currentRequest) {
274 - currentRequest.once('error', () => {});
275 - currentRequest.abort();
276 - } else {
277 - shouldAbort = true;
278 - }
279 - };
280 -
281 - setImmediate(async () => {
282 - try {
283 - // Convert buffer to stream to receive upload progress events (#322)
284 - const {body} = options;
285 - if (is.buffer(body)) {
286 - options.body = toReadableStream(body);
287 - uploadBodySize = body.length;
288 - } else {
289 - uploadBodySize = await getBodySize(options);
290 - }
291 -
292 - if (is.undefined(options.headers['content-length']) && is.undefined(options.headers['transfer-encoding'])) {
293 - if ((uploadBodySize > 0 || options.method === 'PUT') && !is.null(uploadBodySize)) {
294 - options.headers['content-length'] = uploadBodySize;
295 - }
296 - }
297 -
298 - for (const hook of options.hooks.beforeRequest) {
299 - // eslint-disable-next-line no-await-in-loop
300 - await hook(options);
301 - }
302 -
303 - requestUrl = options.href || (new URL(options.path, urlLib.format(options))).toString();
304 -
305 - await get(options);
306 - } catch (error) {
307 - emitError(error);
308 - }
309 - });
310 -
311 - return emitter;
312 -};
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.