Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use fetch instead of axios #314

Open
wants to merge 39 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 34 commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
a30e3a5
working with fetch
Dec 12, 2022
fffb593
fix cookie renewal bug
Dec 12, 2022
5cbf072
removed unwanted request/axios code
Dec 13, 2022
529f506
tidy up
Dec 13, 2022
b91594c
remove tough-cookie and its patch
Dec 14, 2022
cb06484
log headers object instead of map
Dec 14, 2022
ae36ca6
http/https bug fix
Dec 14, 2022
1ad4561
added typescript parsing
Dec 14, 2022
fbed7ab
bug fixes for node16.8
Dec 14, 2022
6d800c3
custom agent and agentOptions with tests
Dec 14, 2022
2b5e5af
tidy up
Dec 15, 2022
a8a0825
show warning when requestDefaults is supplied
Dec 16, 2022
c329cc1
added description of each agentOptions attribute
Dec 16, 2022
c40a4a3
added missing test file
Dec 16, 2022
d14ff63
ensure "fetch" works on 16/18/19
Dec 20, 2022
f5280d5
fix test
Dec 20, 2022
aa9506d
nvm use 16.18.1
Dec 20, 2022
f692e14
rebase from main
Jan 9, 2023
3208204
remove node 14 support
Jan 9, 2023
7e8ffb8
upgrade undici to 5.15.0
Jan 11, 2023
999c6af
merge in latest changes
Jan 11, 2023
cffcd42
merge in latest changes
Jan 11, 2023
5a4ff3f
rebase on 10.1.2
Jan 26, 2023
0e7c06b
dependency bump
Feb 14, 2023
aba321c
fix cookie handling bug
Feb 14, 2023
e0c738a
dependency bump
Mar 6, 2023
aa4cc70
bump undici
Mar 24, 2023
46e08ba
dependency bump
May 22, 2023
c181a39
add node 20 to testing matrix
May 22, 2023
9c42fc3
pre v11 release tidy up
Sep 18, 2023
cead34a
prepare for merge
Sep 19, 2023
e16ad54
latest dependencies
Jan 2, 2024
6ee2510
allow clean merge
Aug 14, 2024
b7c560c
add Node v22 to the CI - it's been that long
Aug 14, 2024
47d4663
Update NOTICE
glynnbird Nov 4, 2024
c62d508
use contentType instead of ct
Nov 4, 2024
4f05cdb
beefed up the "breaking change" nature of Nano 11 for Node 16 (and ol…
Nov 4, 2024
e95b56b
assertion failures are rendered differently in Node 22, so the tests …
Nov 4, 2024
ff29111
added migration guide
Nov 4, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ jobs:

strategy:
matrix:
node-version: [14.x, 16.x, 18.x]
glynnbird marked this conversation as resolved.
Show resolved Hide resolved
node-version: [18.x, 20.x, 22.x]

steps:
- uses: actions/checkout@v3
Expand Down
2 changes: 1 addition & 1 deletion NOTICE
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
Apache CouchDB Nano
Copyright [2016-2018] The Apache Software Foundation
Copyright [2016-2013] The Apache Software Foundation
glynnbird marked this conversation as resolved.
Show resolved Hide resolved

This product includes software developed at
The Apache Software Foundation (http://www.apache.org/).
118 changes: 56 additions & 62 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

Offical [Apache CouchDB](https://couchdb.apache.org/) library for [Node.js](https://nodejs.org/).

> Note: Nano >=11.0.0 is for Node 18/20 and above. If you are using Node 16 or older, you need Nano 10.1.2.
glynnbird marked this conversation as resolved.
Show resolved Hide resolved

Features:

* **Minimalistic** - There is only a minimum of abstraction between you and
Expand Down Expand Up @@ -105,7 +107,7 @@ Note the minimum required version of Node.js is 10.
To use `nano` you need to connect it to your CouchDB install, to do that:

```js
const nano = require('nano')('http://localhost:5984');
const nano = require('nano')('http://127.0.0.1:5984');
```

> Note: Supplying authentication credentials in the URL e.g. `http://admin:mypassword@localhost:5984` is deprecated. Use `nano.auth` instead.
Expand Down Expand Up @@ -189,91 +191,87 @@ you have inserted a document with an _id of rabbit.
rev: '1-6e4cb465d49c0368ac3946506d26335d' }
```

You can also see your document in futon (http://localhost:5984/_utils).
You can also see your document in futon (http://127.0.0.1:5984/_utils).

## Configuration

Configuring nano to use your database server is as simple as:

```js
const nano = require('nano')('http://localhost:5984')
const nano = require('nano')('http://127.0.0.1:5984')
const db = nano.use('foo');
```

If you don't need to instrument database objects you can simply:

```js
// nano parses the URL and knows this is a database
const db = require('nano')('http://localhost:5984/foo');
```

You can also pass options to the require to specify further configuration options you can pass an object literal instead:

```js
// nano parses the URL and knows this is a database
const opts = {
url: 'http://localhost:5984/foo',
requestDefaults: {
proxy: {
protocol: 'http',
host: 'myproxy.net'
},
headers: {
customheader: 'MyCustomHeader'
}
}
};
const db = require('nano')(opts);
const db = require('nano')('http://127.0.0.1:5984/foo');
```

Nano works perfectly well over HTTPS as long as the SSL cert is signed by a certification authority known by your client operating system. If you have a custom or self-signed certificate, you may need to create your own HTTPS agent and pass it to Nano e.g.

```js
const httpsAgent = new https.Agent({
ca: '/path/to/cert',
rejectUnauthorized: true,
keepAlive: true,
maxSockets: 6
})
const nano = Nano({
url: process.env.COUCH_URL,
requestDefaults: {
agent: httpsAgent,
}
})
```

Please check [axios] for more information on the defaults. They support features like proxies, timeout etc.

You can tell nano to not parse the URL (maybe the server is behind a proxy, is accessed through a rewrite rule or other):

```js
// nano does not parse the URL and return the server api
// "http://localhost:5984/prefix" is the CouchDB server root
// "http://127.0.0.1:5984/prefix" is the CouchDB server root
const couch = require('nano')(
{ url : "http://localhost:5984/prefix"
{
url : "http://127.0.0.1:5984/prefix"
parseUrl : false
});
const db = couch.use('foo');
```

### Pool size and open sockets

A very important configuration parameter if you have a high traffic website and are using `nano` is the HTTP pool size. By default, the Node.js HTTP global agent has a infinite number of active connections that can run simultaneously. This can be limited to user-defined number (`maxSockets`) of requests that are "in flight", while others are kept in a queue. Here's an example explicitly using the Node.js HTTP agent configured with [custom options](https://nodejs.org/api/http.html#http_new_agent_options):
To specify the number of connections, timeouts and pool size, supply an `agentOptions` object when starting up Nano.

```js
const http = require('http')
const myagent = new http.Agent({
keepAlive: true,
maxSockets: 25
})
const agentOptions = {
bodyTimeout: 30000,
headersTimeout: 30000,
keepAliveMaxTimeout: 600000,
keepAliveTimeout: 30000,
keepAliveTimeoutThreshold: 1000,
maxHeaderSize: 16384,
maxResponseSize: -1,
pipelining: 6,
connect: {
timeout: 10000
},
strictContentLength: true,
connections: null,
maxRedirections: 0
}
const undici = require('undici')
const undiciOptions = new undici.Agent(agentOptions)
const nano = Nano({ url: 'http://127.0.0.1:5984', undiciOptions })
```

const db = require('nano')({
url: 'http://localhost:5984/foo',
requestDefaults : {
agent : myagent
}
});
The meanings of the agentOptions attributes is described [here](https://undici.nodejs.org/#/docs/api/Agent?id=new-undiciagentoptions), [here](https://undici.nodejs.org/#/docs/api/Pool?id=parameter-pooloptions) and [here](https://undici.nodejs.org/#/docs/api/Client?id=parameter-clientoptions)

You may also supply a pre-existing `undici.Agent` e.g.

```js
const agent = new undici.Agent({bodyTimeout: 30000 })
const nano = Nano({ url: 'http://127.0.0.1:5984', agentOptions: agent })
``

> Note `requestDefaults` is no longer supported.

## Custom headers

To supply customer headers with each request, supply a headers object when starting up Nano:


```js
const couch = require('nano')(
{
url : "http://127.0.0.1:5984/prefix"
headers: {
mycustomheader: '42'
}
});
```

## TypeScript
Expand All @@ -283,7 +281,7 @@ There is a full TypeScript definition included in the the *nano* package. Your T
```ts
import * as Nano from 'nano'

let n = Nano('http://USERNAME:PASSWORD@localhost:5984')
let n = Nano('http://USERNAME:PASSWORD@127.0.0.1:5984')
let db = n.db.use('people')

interface iPerson extends Nano.MaybeDocument {
Expand Down Expand Up @@ -1201,10 +1199,7 @@ Nano supports making requests using CouchDB's [cookie authentication](http://gui

```js
const nano = require('nano')({
url: 'http://localhost:5984',
requestDefaults: {
jar: true
}
url: 'http://127.0.0.1:5984'
})
const username = 'user'
const userpass = 'pass'
Expand Down Expand Up @@ -1361,7 +1356,6 @@ npm run test
[2]: https://github.com/apache/couchdb-nano/issues
[4]: https://github.com/apache/couchdb-nano/blob/main/cfg/couch.example.js
[8]: https://webchat.freenode.net?channels=%23couchdb-dev
[axios]: https://github.com/axios/axios

https://freenode.org/

Expand Down
2 changes: 1 addition & 1 deletion examples/bulk_transform.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
// License for the specific language governing permissions and limitations under
// the License.

const db = require('nano')('http://localhost:5984/emails')
const db = require('nano')('http://127.0.0.1:5984/emails')
const async = require('async')

function updateRow (row, cb) {
Expand Down
2 changes: 1 addition & 1 deletion examples/express.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
// the License.

const express = require('express')
const db = require('nano')('http://localhost:5984/my_couch')
const db = require('nano')('http://127.0.0.1:5984/my_couch')
const app = module.exports = express()

app.get('/', function (req, res) {
Expand Down
2 changes: 1 addition & 1 deletion examples/lazy_creation_of_views.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
// the License.

module.exports = function () {
const nano = require('nano')('http://localhost:5984')
const nano = require('nano')('http://127.0.0.1:5984')
const users = nano.use('users')
const VIEWS = {
by_twitter_id:
Expand Down
4 changes: 2 additions & 2 deletions examples/lazy_db_creation_and_replication.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@
const nano = require('nano')
const couch =
{
master: 'http://localhost:5984/landing_m',
replica: 'http://localhost:5984/landing_r'
master: 'http://127.0.0.1:5984/landing_m',
replica: 'http://127.0.0.1:5984/landing_r'
}

function insertWithRetry (db, email, retries, callback) {
Expand Down
2 changes: 1 addition & 1 deletion examples/pipe.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
// the License.

const express = require('express')
const nano = require('nano')('http://localhost:5984')
const nano = require('nano')('http://127.0.0.1:5984')
const app = express.createServer()
const dbName = 'test'
const db = nano.use(dbName)
Expand Down
8 changes: 4 additions & 4 deletions lib/changesreader.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
const EventEmitter = require('events').EventEmitter
const AbortController = global.AbortController || require('node-abort-controller').AbortController
const AbortController = global.AbortController
const stream = require('stream')
const EVENT_BATCH = 'batch'
const EVENT_CHANGE = 'change'
Expand Down Expand Up @@ -279,6 +279,9 @@ class ChangesReader {
const lin = liner()
const cp = changeProcessor(self.ee, self.batchSize)
self.request(req)
.on(EVENT_ERROR, (e) => {
self.ee.emit(EVENT_ERROR, e)
})
.pipe(lin)
.pipe(cp)
.on('finish', (lastSeq) => {
Expand All @@ -287,9 +290,6 @@ class ChangesReader {
self.ee.emit('end', cp.lastSeq)
}, 10)
})
.on(EVENT_ERROR, (e) => {
self.ee.emit(EVENT_ERROR, e)
})

return self.ee
}
Expand Down
75 changes: 60 additions & 15 deletions lib/nano.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,26 +19,71 @@
/// <reference types="node" />

import { EventEmitter } from "events";
import { ConnectionOptions } from "tls";
import undici from "undici";

/** nano entry function */
declare function nano(
config: nano.Configuration | string
): nano.ServerScope;

declare namespace nano {
/** RequestDefaults.auth options */
interface RequestDefaultOptionsAuth {
username: string,
password: string
}

/** RequestDefaults options */
interface RequestDefaultsOptions {
timeout?: number;
agent?: any;
headers?: object;
auth?: RequestDefaultOptionsAuth;
jar?: boolean;
/** AgentOptionsConnect options */
interface AgentOptionsConnect extends ConnectionOptions {
/** An IPC endpoint, either Unix domain socket or Windows named pipe.
* Default: null */
socketPath: string,
/** Maximum number of TLS cached sessions. Use 0 to disable TLS session
* caching. Default: 100 */
maxCachedSessions: number,
/** Connection timeout in ms. Default: 10000 */
timeout?: number,
/** Default: null */
servername: string
}
/** AgentOptions options */
interface AgentOptions {
/** The timeout after which a request will time out, in milliseconds.
* Monitors time between receiving body data. Use 0 to disable it entirely.
* Default: 30000 */
bodyTimeout?: number,
/** The amount of time the parser will wait to receive the complete
* HTTP headers while not sending the request. Default: 30000 */
headersTimeout?: number,
/** The maximum allowed keepAliveTimeout in ms when overridden by keep-alive hints
* from the server. Default: 600000 */
keepAliveMaxTimeout?: number,
/** The timeout in ms after which a socket without active requests will time out.
* Monitors time between activity on a connected socket. This value may be
* overridden by keep-alive hints from the server. Default: 4000 */
keepAliveTimeout?: number,
/** A number subtracted from server keep-alive hints when overriding
* keepAliveTimeout to account for timing inaccuracies caused by
* e.g. transport latency. Default: 1000 */
keepAliveTimeoutThreshold?: number,
/** The maximum length of request headers in bytes. Default: 16384 */
maxHeaderSize?: number,
/** The maximum length of response body in bytes. Set to -1 to disable. Default: -1 */
maxResponseSize?: number,
/** The amount of concurrent requests to be sent over the single TCP/TLS
* connection according to RFC7230. Carefully consider your workload and
* environment before enabling concurrent requests as pipelining may reduce
* performance if used incorrectly. Pipelining is sensitive to network stack
* settings as well as head of line blocking caused by e.g. long running r
* equests. Set to 0 to disable keep-alive connections. Default: 1 */
pipelining?: number,
/** Connection options */
connect?: AgentOptionsConnect,
/** Whether to treat request content length mismatches as errors. If true,
* an error is thrown when the request content-length header doesn't match
* the length of the request body. Default: true */
strictContentLength?: boolean,
/** The number of Client instances to create.
* When set to null, the Pool instance will create an unlimited amount
* of Client instances. */
connections: null,
/** The number of HTTP redirection to follow - Default: 0 */
maxRedirections?: null
}

/** Nano configuration */
Expand All @@ -49,10 +94,10 @@ declare namespace nano {
url: string;
/** For cookie authentication */
cookie?: string;
/** HTTP request options
/** HTTP Agent options
* @see README: {@link https://www.npmjs.com/package/nano#pool-size-and-open-sockets}
*/
requestDefaults?: RequestDefaultsOptions;
agentOptions?: AgentOptions | typeof undici.Agent | typeof undici.MockAgent | typeof undici.Dispatcher;
/** Logging function
* @see README: {@link https://www.npmjs.com/package/nano#logging}
*/
Expand Down
Loading
Loading