[![NPM](http://img.shields.io/npm/v/nano.svg?style=flat-square)](https://www.npmjs.com/package/nano)

# Nano

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

> Note: Nano >=11.0.0 is a **breaking change for Node.js versions 16 and older**. Nano 11 uses Node.js's built-in "fetch" HTTP client but this is only available in Node.js versions 18 or later. If you are using Node 16 or older then continue using Nano 10.
> See our [migration guide](migration_guide_v10_to_v11.md) for moving from Nano 10 to Nano 11.

Features:

* **Minimalistic** - There is only a minimum of abstraction between you and
  CouchDB.
* **Pipes** - Proxy requests from CouchDB directly to your end user. ( `...AsStream` functions only)
* **Promises** - The vast majority of library calls return native Promises.
* **TypeScript** - Detailed TypeScript definitions are built in.
* **Errors** - Errors are proxied directly from CouchDB: if you know CouchDB
  you already know `nano`.

## Installation

1. Install [npm][1]
2. `npm install nano`

or save `nano` as a dependency of your project with

    npm install --save nano

Note the minimum required version of Node.js is 10.

## Table of contents

- [Getting started](#getting-started)
- [Tutorials & screencasts](#tutorials-examples-in-the-wild--screencasts)
- [Configuration](#configuration)
- [Database functions](#database-functions)
  - [nano.db.create(name)](#nanodbcreatename)
  - [nano.db.get(name)](#nanodbgetname)
  - [nano.db.destroy(name)](#nanodbdestroyname)
  - [nano.db.list()](#nanodblist)
  - [nano.db.listAsStream()](#nanodblistasstream)
  - [nano.db.compact(name, [designname])](#nanodbcompactname-designname)
  - [nano.db.replicate(source, target, [opts])](#nanodbreplicatesource-target-opts)
  - [nano.db.replication.enable(source, target, [opts])](#nanodbreplicationenablesource-target-opts)
  - [nano.db.replication.query(id, [opts])](#nanodbreplicationenablesource-target-opts)
  - [nano.db.replication.disable(id, [opts])](#nanodbreplicationdisableid-opts)
  - [nano.db.changes(name, [params])](#nanodbchangesname-params)
  - [nano.db.changesAsStream(name, [params])](#nanodbchangesasstreamname-params)
  - [nano.db.info()](#nanodbinfo)
  - [nano.use(name)](#nanousename)
  - [nano.request(opts)](#nanorequestopts)
  - [nano.config](#nanoconfig)
  - [nano.updates([params])](#nanoupdatesparams)
  - [nano.info()](#nanoinfo)

- [Document functions](#document-functions)
  - [db.insert(doc, [params])](#dbinsertdoc-params)
  - [db.destroy(docname, rev)](#dbdestroydocname-rev)
  - [db.get(docname, [params])](#dbgetdocname-params)
  - [db.head(docname)](#dbheaddocname)
  - [db.bulk(docs, [params])](#dbbulkdocs-params)
  - [db.list([params])](#dblistparams)
  - [db.listAsStream([params])](#dblistasstreamparams)
  - [db.fetch(docnames, [params])](#dbfetchdocnames-params)
  - [db.fetchRevs(docnames, [params])](#dbfetchrevsdocnames-params)
  - [db.createIndex(indexDef)](#dbcreateindexindexdef)
  - [db.changesReader](#reading-changes-feed)
- [Partitioned database functions](#partition-functions)
  - [db.partitionInfo(partitionKey)](#dbpartitioninfopartitionkey))
  - [db.partitionedList(partitionKey, [params])](#dbpartitionedlistpartitionkey-params)
  - [db.partitionedListAsStream(partitionKey, [params])](#dbpartitionedlistasstreampartitionkey-params)
  - [db.partitionedFind(partitionKey, query)](#dbpartitionedfindpartitionkey-query-params)
  - [db.partitionedFindAsStream(partitionKey, query)](#dbpartitionedfindasstreampartitionkey-query)
  - [db.partitionedSearch(partitionKey, designName, searchName, params)](#dbpartitionedsearchpartitioney-designname-searchname-params)
  - [db.partitionedSearchAsStream(partitionKey, designName, searchName, params)](#dbpartitionedsearchasstreampartitionkey-designName-searchName-params)
  - [db.partitionedView(partitionKey, designName, viewName, [params])](#dbpartitionediewpartitionkey-designname-viewname-params)
  - [db.partitionedViewAsStream(partitionKey, designName, viewName, [params])](#dbpartitionediewasstreampartitionkey-designname-viewname-params)
- [Multipart functions](#multipart-functions)
  - [db.multipart.insert(doc, attachments, [params])](#dbmultipartinsertdoc-attachments-params)
  - [db.multipart.get(docname, [params])](#dbmultipartgetdocname-params)
- [Attachments functions](#attachments-functions)
  - [db.attachment.insert(docname, attname, att, contenttype, [params])](#dbattachmentinsertdocname-attname-att-contenttype-params)
  - [db.attachment.insertAsStream(docname, attname, att, contenttype, [params])](#dbattachmentinsertasstreamdocname-attname-att-contenttype-params)
  - [db.attachment.get(docname, attname, [params])](#dbattachmentgetdocname-attname-params)
  - [db.attachment.getAsStream(docname, attname, [params])](#dbattachmentgetasstreamdocname-attname-params)
  - [db.attachment.destroy(docname, attname, [params])](#dbattachmentdestroydocname-attname-params)
- [Views and design functions](#views-and-design-functions)
  - [db.view(designname, viewname, [params])](#dbviewdesignname-viewname-params)
  - [db.viewAsStream(designname, viewname, [params])](#dbviewasstreamdesignname-viewname-params)
  - [db.viewWithList(designname, viewname, listname, [params])](#dbviewwithlistdesignname-viewname-params)
  - [db.viewWithListAsStream(designname__viewname, listname, [params])](#dbviewwithlistasstreamdesignname-viewname-params)
  - [db.show(designname, showname, doc_id, [params])](#dbshowdesignname-showname-doc_id-params)
  - [db.atomic(designname, updatename, docname, [body])](#dbatomicdesignname-updatename-docname-body)
  - [db.search(designname, viewname, params)](#dbsearchdesignname-searchname-params)
  - [db.searchAsStream(designname, viewname, params)](#dbsearchasstreamdesignname-searchname-params)
  - [db.find(selector)](#dbfindselector)
  - [db.findAsStream(selector)](#dbfindasstreamselector)
- [Using cookie authentication](#using-cookie-authentication)
- [Advanced features](#advanced-features)
  - [getting uuids](#getting-uuids)
  - [extending nano](#extending-nano)
  - [pipes](#pipes)
- [Tests](#tests)
- [Release](#release)

## Getting started

To use `nano` you need to connect it to your CouchDB install, to do that:

```js
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.

To create a new database:

```js
nano.db.create('alice');
```

and to use an existing database:

```js
const alice = nano.db.use('alice');
```

Under-the-hood, calls like `nano.db.create` are making HTTP API calls to the CouchDB service. Such operations are *asynchronous*. There are two ways to receive the asynchronous data back from the library

1) Promises

```js
nano.db.create('alice').then((data) => {
  // success - response is in 'data'
}).catch((err) => {
  // failure - error information is in 'err'
})
```

2) or in the async/await style:

```js
try {
  const response = await nano.db.create('alice')
  // succeeded
  console.log(response)
} catch (e) {
  // failed
  console.error(e)
}
```

The documentation will follow the *async/await* style.

------------------


A simple but complete example in the [async/await](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function) style:

```js
async function asyncCall() {
  await nano.db.destroy('alice')
  await nano.db.create('alice')
  const alice = nano.use('alice')
  const response = await alice.insert({ happy: true }, 'rabbit')
  return response
}
asyncCall()
```

Running this example will produce:

```
you have inserted a document with an _id of rabbit.
{ ok: true,
  id: 'rabbit',
  rev: '1-6e4cb465d49c0368ac3946506d26335d' }
```

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://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://127.0.0.1:5984/foo');
```

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://127.0.0.1:5984/prefix" is the CouchDB server root
const couch = require('nano')(
  { 
    url : "http://127.0.0.1:5984/prefix"
    parseUrl : false
  });
const db = couch.use('foo');
```

### Pool size and open sockets

To specify the number of connections, timeouts and pool size, supply an `agentOptions` object when starting up Nano. 

```js
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 })
```

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

There is a full TypeScript definition included in the the *nano* package. Your TypeScript editor will show you hints as you write your code with the *nano* library with your own custom classes:

```ts
import * as Nano  from 'nano'

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

interface iPerson extends Nano.MaybeDocument {
  name: string,
  dob: string
}

class Person implements iPerson {
  _id: string
  _rev: string
  name: string
  dob: string

  constructor(name: string, dob: string) {
    this._id = undefined
    this._rev = undefined
    this.name = name
    this.dob = dob
  }

  processAPIResponse(response: Nano.DocumentInsertResponse) {
    if (response.ok === true) {
      this._id = response.id
      this._rev = response.rev
    }
  }
}

let p = new Person('Bob', '2015-02-04')
db.insert(p).then((response) => {
  p.processAPIResponse(response)
  console.log(p)
})
```

## Database functions

### nano.db.create(name, [opts])

Creates a CouchDB database with the given `name`, with options `opts`.

```js
await nano.db.create('alice', { n: 3 })
```

### nano.db.get(name)

Get information about the database `name`:

```js
const info = await nano.db.get('alice')
```

### nano.db.destroy(name)

Destroys the database `name`:

```js
await nano.db.destroy('alice')
```

### nano.db.list()

Lists all the CouchDB databases:

```js
const dblist = await nano.db.list()
```

### nano.db.listAsStream()

Lists all the CouchDB databases as a stream:

```js
nano.db.listAsStream()
  .on('error', (e) => console.error('error', e))
  .pipe(process.stdout);
```

### nano.db.compact(name, [designname])

Compacts `name`, if `designname` is specified also compacts its views.

### nano.db.replicate(source, target, [opts])

Replicates `source` to `target` with options `opts`. The `target`database
has to exist, add `create_target:true` to `opts` to create it prior to
replication:

```js
const response = await nano.db.replicate('alice',
                  'http://admin:password@otherhost.com:5984/alice',
                  { create_target:true })
```

### nano.db.replication.enable(source, target, [opts])

Enables replication using the new CouchDB api from `source` to `target`
with options `opts`. `target` has to exist, add `create_target:true` to
`opts` to create it prior to replication. Replication will survive server restarts.

```js
const response = await nano.db.replication.enable('alice',
                  'http://admin:password@otherhost.com:5984/alice',
                  { create_target:true })
```

### nano.db.replication.query(id, [opts])

Queries the state of replication using the new CouchDB API. The `id` comes from the response
given by the call to `replication.enable`:

```js
const r = await nano.db.replication.enable('alice',
                  'http://admin:password@otherhost.com:5984/alice',
                   { create_target:true })
const q = await nano.db.replication.query(r.id)
```

### nano.db.replication.disable(id, [opts])

Disables replication using the new CouchDB API. The `id` comes from the response given
by the call to `replication.enable`:

```js
const r = await nano.db.replication.enable('alice',
                   'http://admin:password@otherhost.com:5984/alice',
                   { create_target:true })
await nano.db.replication.disable(r.id);
```

### nano.db.changes(name, [params])

Asks for the changes feed of `name`, `params` contains additions
to the query string.

```js
const c = await nano.db.changes('alice')
```

### nano.db.changesAsStream(name, [params])

Same as `nano.db.changes` but returns a stream.

```js
nano.db.changes('alice').pipe(process.stdout);
```

### nano.db.info()

Gets database information:

```js
const info = await nano.db.info()
```

### nano.use(name)

Returns a database object that allows you to perform operations against that database:

```js
const alice = nano.use('alice');
await alice.insert({ happy: true }, 'rabbit')
```

The database object can be used to access the [Document Functions](#document-functions).

### nano.db.use(name)

Alias for `nano.use`

### nano.db.scope(name)

Alias for `nano.use`

### nano.scope(name)

Alias for `nano.use`

### nano.request(opts)

Makes a custom request to CouchDB. This can be used to create your own HTTP request to the CouchDB
server, to perform operations where there is no `nano` function that encapsulates it. The available `opts` are:

* `opts.db` – the database name
* `opts.method` – the http method, defaults to `get`
* `opts.path` – the full path of the request, overrides `opts.doc` and
  `opts.att`
* `opts.doc` – the document name
* `opts.att` – the attachment name
* `opts.qs` – query string parameters, appended after any existing `opts.path`, `opts.doc`, or `opts.att`
* `opts.content_type` – the content type of the request, default to `json`
* `opts.headers` – additional http headers, overrides existing ones
* `opts.body` – the document or attachment body
* `opts.encoding` – the encoding for attachments
* `opts.multipart` – array of objects for multipart request
* `opts.stream` - if `true`, a `request` object is returned. Default `false` and a Promise is returned.

### nano.relax(opts)

Alias for `nano.request`

### nano.config

An object containing the `nano` configurations, possible keys are:

* `url` - the CouchDB URL
* `db` - the database name

### nano.updates([params])

Listen to db updates, the available `params` are:

* `params.feed` – Type of feed. Can be one of
 * `longpoll`: Closes the connection after the first event.
 * `continuous`: Send a line of JSON per event. Keeps the socket open until timeout.
 * `eventsource`: Like, continuous, but sends the events in EventSource format.
* `params.timeout` – Number of seconds until CouchDB closes the connection. Default is 60.
* `params.heartbeat` – Whether CouchDB will send a newline character (\n) on timeout. Default is true.

### nano.info()

Fetch information about the CouchDB cluster:

```js
const info = await nano.info()
```

The response is an object with [CouchDB cluster information](https://docs.couchdb.org/en/stable/intro/api.html#server).

## Document functions

### db.insert(doc, [params])

Inserts `doc` in the database with optional `params`. If params is a string, it's assumed it is the intended document `_id`. If params is an object, it's passed as query string parameters and `docName` is checked for defining the document `_id`:

```js
const alice = nano.use('alice');
const response = await alice.insert({ happy: true }, 'rabbit')
```

The `insert` function can also be used with the method signature `db.insert(doc,)`, where the `doc` contains the `_id` field e.g.

```js
const alice = nano.use('alice')
const response = await alice.insert({ _id: 'myid', happy: true })
```

and also used to update an existing document, by including the `_rev` token in the document being saved:

```js
const alice = nano.use('alice')
const response = await alice.insert({ _id: 'myid', _rev: '1-23202479633c2b380f79507a776743d5', happy: false })
```

### db.destroy(docname, rev)

Removes a document from CouchDB whose `_id` is `docname` and whose revision (`_rev`) is `rev`:

```js
const response = await alice.destroy('rabbit', '3-66c01cdf99e84c83a9b3fe65b88db8c0')
```

### db.get(docname, [params])

Gets a document from CouchDB whose `_id` is `docname`:

```js
const doc = await alice.get('rabbit')
```

or with optional [query string `params`](https://docs.couchdb.org/en/stable/api/document/common.html#get--db-docid):

```js
const doc = await alice.get('rabbit', { revs_info: true })
```

If you pass `attachments=true`, the `doc._attachments.attachmentNameN.data` fields will contain the 
[base-64 encoded attachments](https://docs.couchdb.org/en/stable/json-structure.html#document-with-attachments).
Or, you can use [`db.multipart.get`](https://github.com/DougReeder/couchdb-nano#dbmultipartgetdocname-params)
and parse the returned buffer to get the document and attachments.

See the [attachments methods](https://github.com/apache/couchdb-nano#attachments-functions) to retrieve
*just* an attachment.

### db.head(docname)

Same as `get` but lightweight version that returns headers only:

```js
const headers = await alice.head('rabbit')
```

### db.bulk(docs, [params])

Bulk operations(update/delete/insert) on the database, refer to the
[CouchDB doc](https://docs.couchdb.org/en/stable/api/database/bulk-api.html#post--db-_bulk_docs) e.g:

```js
const documents = [
  { a:1, b:2 },
  { _id: 'tiger', striped: true}
];
const response = await alice.bulk({ docs: documents })
```

### db.list([params])

List all the docs in the database .

```js
const doclist = await alice.list().then((body)=>{
    body.rows.forEach((doc) => {
        console.log(doc);
    })
});
```

or with optional query string additions `params`:

```js
const doclist = await alice.list({include_docs: true})
```

### db.listAsStream([params])

List all the docs in the database as a stream.

```js
alice.listAsStream()
  .on('error', (e) => console.error('error', e))
  .pipe(process.stdout)
```

### db.fetch(docnames, [params])

Bulk fetch of the database documents, `docnames` are specified as per
[CouchDB doc](https://docs.couchdb.org/en/latest/api/database/bulk-api.html#post--db-_all_docs).
additional query string `params` can be specified, `include_docs` is always set
to `true`.

```js
const keys = ['tiger', 'zebra', 'donkey'];
const datat = await alice.fetch({keys: keys})
```

### db.fetchRevs(docnames, [params])

** changed in version 6 **

Bulk fetch of the revisions of the database documents, `docnames` are specified as per
[CouchDB doc](https://docs.couchdb.org/en/latest/api/database/bulk-api.html#post--db-_all_docs).
additional query string `params` can be specified, this is the same method as fetch but
 `include_docs` is not automatically set to `true`.

### db.createIndex(indexDef)

Create index on database fields, as specified in
[CouchDB doc](https://docs.couchdb.org/en/latest/api/database/find.html#db-index).

```js
const indexDef = {
  index: { fields: ['foo'] },
  name: 'fooindex'
};
const response = await alice.createIndex(indexDef)
```

## Reading Changes Feed

Nano provides a low-level API for making calls to CouchDB's changes feed, or if you want a 
reliable, resumable changes feed follower, then you need the `changesReader`.

There are three ways to start listening to the changes feed:

1. `changesReader.start()` - to listen to changes indefinitely by repeated "long poll" requests. This mode continues to poll for changes until `changesReader.stop()` is called, at which point any active long poll will be canceled.
2. `changesReader.get()` - to listen to changes until the end of the changes feed is reached, by repeated "long poll" requests. Once a response with zero changes is received, the 'end' event will indicate the end of the changes and polling will stop.
3. `changesReader.spool()` - listen to changes in one long HTTP request. (as opposed to repeated round trips) - spool is faster but less reliable.

> Note: for `.get()` & `.start()`, the sequence of API calls can be paused by calling `changesReader.pause()` and resumed by calling `changesReader.resume()`.

Set up your database connection and then choose `changesReader.start()` to listen to that database's changes:

```js
const db = nano.db.use('mydb')
db.changesReader.start()
  .on('change', (change) => { console.log(change) })
  .on('batch', (b) => {
    console.log('a batch of', b.length, 'changes has arrived');
  }).on('seq', (s) => {
    console.log('sequence token', s);
  }).on('error', (e) => {
    console.error('error', e);
  })
```

> Note: you probably want to monitor *either* the `change` or `batch` event, not both.

If you want `changesReader` to hold off making the next `_changes` API call until you are ready, then supply `wait:true` in the options to `get`/`start`. The next request will only fire when you call `changesReader.resume()`:

```js
db.changesReader.get({wait: true})
  .on('batch', (b) => {
    console.log('a batch of', b.length, 'changes has arrived');
    // do some asynchronous work here and call "changesReader.resume()"
    // when you're ready for the next API call to be dispatched.
    // In this case, wait 5s before the next changes feed request.
    setTimeout( () => {
      db.changesReader.resume()
    }, 5000)
  }).on('end', () => {
    console.log('changes feed monitoring has stopped');
  });
```

You may supply a number of options when you start to listen to the changes feed:

| Parameter | Description                                                                                                                                                                             | Default value | e.g.                            |   |
|-----------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------------|---------------------------------|---|
| batchSize | The maximum number of changes to ask CouchDB for per HTTP request. This is the maximum number of changes you will receive in a `batch` event. | 100           | 500                             |   |
| since     | The position in the changes feed to start from where `0` means the beginning of time, `now` means the current position or a string token indicates a fixed position in the changes feed | now           | 390768-g1AAAAGveJzLYWBgYMlgTmGQ |   |
| includeDocs | Whether to include document bodies or not | false | e.g. true |
| wait | For `get`/`start` mode, automatically pause the changes reader after each request. When the the user calls `resume()`, the changes reader will resume.  | false | e.g. true |
| fastChanges | Adds a seq_interval parameter to fetch changes more quickly | false           | true                             |   |
| selector | Filters the changes feed with the supplied Mango selector |    null       | {"name":"fred}                            |   |
| timeout | The number of milliseconds a changes feed request waits for data| 60000         | 10000    |

The events it emits are as follows:s

| Event  | Description                                                                                                                                                               | Data                       |   |
|--------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------|----------------------------|---|
| change | Each detected change is emitted individually. Only available in `get`/`start` modes.                                                                                                                          | A change object            |   |
| batch  | Each batch of changes is emitted in bulk in quantities up to `batchSize`.                                                                                                                              | An array of change objects |   |
| seq    | Each new sequence token (per HTTP request). This token can be passed into `ChangesReader` as the `since` parameter to resume changes feed consumption from a known point. Only available in `get`/`start` modes. | String                     |   |
| error  | On a fatal error, a descriptive object is returned and change consumption stops.                                                                                         | Error object               |   |
| end    | Emitted when the end of the changes feed is reached. `ChangesReader.get()` mode only,                                                                                     | Nothing                    |   |

The *ChangesReader* library will handle many temporal errors such as network connectivity, service capacity limits and malformed data but it will emit an `error` event and exit when fed incorrect authentication credentials or an invalid `since` token.

The `change` event delivers a change object that looks like this:

```js
{
	"seq": "8-g1AAAAYIeJyt1M9NwzAUBnALKiFOdAO4gpRix3X",
	"id": "2451be085772a9e588c26fb668e1cc52",
	"changes": [{
		"rev": "4-061b768b6c0b6efe1bad425067986587"
	}],
	"doc": {
		"_id": "2451be085772a9e588c26fb668e1cc52",
		"_rev": "4-061b768b6c0b6efe1bad425067986587",
		"a": 3
	}
}
```

N.B

- `doc` is only present if `includeDocs:true` is supplied
- `seq` is not present for every change

The `id` is the unique identifier of the document that changed and the `changes` array contains the document revision tokens that were written to the database.

The `batch` event delivers an array of change objects.

## Partition Functions

Functions related to [partitioned databases](https://docs.couchdb.org/en/latest/partitioned-dbs/index.html).

Create a partitioned database by passing `{ partitioned: true }` to `db.create`:

```js
await nano.db.create('my-partitioned-db', { partitioned: true })
```

The database can be used as normal:

```js
const db = nano.db.use('my-partitioned-db')
```

but documents must have a two-part `_id` made up of `<partition key>:<document id>`. They are insert with `db.insert` as normal:

```js
const doc = { _id: 'canidae:dog', name: 'Dog', latin: 'Canis lupus familiaris' }
await db.insert(doc)
```

Documents can be retrieved by their `_id` using `db.get`:

```js
const doc = db.get('canidae:dog')
```

Mango indexes can be created to operate on a per-partition index by supplying `partitioned: true` on creation:

```js
const i = {
  ddoc: 'partitioned-query',
  index: { fields: ['name'] },
  name: 'name-index',
  partitioned: true,
  type: 'json'
}

// instruct CouchDB to create the index
await db.index(i)
```

Search indexes can be created by writing a design document with `opts.partitioned = true`:

```js
// the search definition
const func = function(doc) {
  index('name', doc.name)
  index('latin', doc.latin)
}

// the design document containing the search definition function
const ddoc = {
  _id: '_design/search-ddoc',
  indexes: {
    search-index: {
      index: func.toString()
    }
  },
  options: {
    partitioned: true
  }
}
 
await db.insert(ddoc)
```

MapReduce views can be created by writing a design document with `opts.partitioned = true`:

```js
const func = function(doc) {
  emit(doc.family, doc.weight)
}

// Design Document
const ddoc = {
  _id: '_design/view-ddoc',
  views: {
    family-weight: {
      map: func.toString(),
      reduce: '_sum'
    }
  },
  options: {
    partitioned: true
  }
}

// create design document
await db.insert(ddoc)
```

### db.partitionInfo(partitionKey)

Fetch the stats of a single partition:

```js
const stats = await alice.partitionInfo('canidae')
```

### db.partitionedList(partitionKey, [params])

Fetch documents from a database partition:

```js
// fetch document id/revs from a partition
const docs = await alice.partitionedList('canidae')

// add document bodies but limit size of response
const docs = await alice.partitionedList('canidae', { include_docs: true, limit: 5 })
```

### db.partitionedListAsStream(partitionKey, [params])

Fetch documents from a partition as a stream:

```js
// fetch document id/revs from a partition
nano.db.partitionedListAsStream('canidae')
  .on('error', (e) => console.error('error', e))
  .pipe(process.stdout)

// add document bodies but limit size of response
nano.db.partitionedListAsStream('canidae', { include_docs: true, limit: 5 })
  .on('error', (e) => console.error('error', e))
  .pipe(process.stdout)
```

### db.partitionedFind(partitionKey, query, [params])

Query documents from a partition by supplying a Mango selector:

```js
// find document whose name is 'wolf' in the 'canidae' partition
await db.partitionedFind('canidae', { 'selector' : { 'name': 'Wolf' }})
```

### db.partitionedFindAsStream(partitionKey, query)

Query documents from a partition by supplying a Mango selector as a stream:

```js
// find document whose name is 'wolf' in the 'canidae' partition
db.partitionedFindAsStream('canidae', { 'selector' : { 'name': 'Wolf' }})
  .on('error', (e) => console.error('error', e))
  .pipe(process.stdout)
```

### db.partitionedSearch(partitionKey, designName, searchName, params)

Search documents from a partition by supplying a Lucene query:

```js
const params = {
  q: 'name:\'Wolf\''
}
await db.partitionedSearch('canidae', 'search-ddoc', 'search-index', params)
// { total_rows: ... , bookmark: ..., rows: [ ...] }
```

### db.partitionedSearchAsStream(partitionKey, designName, searchName, params)

Search documents from a partition by supplying a Lucene query as a stream:

```js
const params = {
  q: 'name:\'Wolf\''
}
db.partitionedSearchAsStream('canidae', 'search-ddoc', 'search-index', params)
  .on('error', (e) => console.error('error', e))
  .pipe(process.stdout)
// { total_rows: ... , bookmark: ..., rows: [ ...] }
```

### db.partitionedView(partitionKey, designName, viewName, params)

Fetch documents from a MapReduce view from a partition:

```js
const params = {
  startkey: 'a',
  endkey: 'b',
  limit: 1
}
await db.partitionedView('canidae', 'view-ddoc', 'view-name', params)
// { rows: [ { key: ... , value: [Object] } ] }
```

### db.partitionedViewAsStream(partitionKey, designName, viewName, params)

Fetch documents from a MapReduce view from a partition as a stream:

```js
const params = {
  startkey: 'a',
  endkey: 'b',
  limit: 1
}
db.partitionedViewAsStream('canidae', 'view-ddoc', 'view-name', params)
  .on('error', (e) => console.error('error', e))
  .pipe(process.stdout)
// { rows: [ { key: ... , value: [Object] } ] }
```

## Multipart functions

### db.multipart.insert(doc, attachments, params)

Inserts a `doc` together with `attachments` and `params`. If params is a string, it's assumed as the intended document `_id`. If params is an object, its passed as query string parameters and `docName` is checked for defining the `_id`. Refer to the [doc](https://docs.couchdb.org/en/stable/api/document/common.html) for more details.
 The `attachments` parameter must be an array of objects with `name`, `data` and `content_type` properties.

```js
const fs = require('fs');

fs.readFile('rabbit.png', (err, data) => {
  if (!err) {
    await alice.multipart.insert({ foo: 'bar' }, [{name: 'rabbit.png', data: data, content_type: 'image/png'}], 'mydoc')
  }
});
```

### db.multipart.get(docname, [params])

Get `docname` together with its attachments via `multipart/related` request with optional [query string additions](https://docs.couchdb.org/en/stable/api/document/common.html#get--db-docid). The multipart response body is a `Buffer`.

```js
const response = await alice.multipart.get('rabbit')
```

## Attachments functions

### db.attachment.insert(docname, attname, att, contenttype, [params])

Inserts an attachment `attname` to `docname`, in most cases
 `params.rev` is required. Refer to the
 [CouchDB doc](https://docs.couchdb.org/en/latest/api/document/attachments.html#db-doc-attachment) for more details.

```js
const fs = require('fs');

fs.readFile('rabbit.png', (err, data) => {
  if (!err) {
    await alice.attachment.insert('rabbit', 
      'rabbit.png', 
      data, 
      'image/png',
      { rev: '12-150985a725ec88be471921a54ce91452' })
  }
});
```

### db.attachment.insertAsStream(docname, attname, att, contenttype, [params])

As of Nano 9.x, the function `db.attachment.insertAsStream` is now deprecated. Now simply pass
a readable stream to `db.attachment.insert` as the third paramseter.

### db.attachment.get(docname, attname, [params])

Get `docname`'s attachment `attname` with optional query string additions
`params`.

```js
const fs = require('fs');

const body = await alice.attachment.get('rabbit', 'rabbit.png')
fs.writeFile('rabbit.png', body)
```

### db.attachment.getAsStream(docname, attname, [params])

```js
const fs = require('fs');
alice.attachment.getAsStream('rabbit', 'rabbit.png')
  .on('error', e => console.error)
  .pipe(fs.createWriteStream('rabbit.png'));
```

### db.attachment.destroy(docname, attname, [params])

**changed in version 6**

Destroy attachment `attname` of `docname`'s revision `rev`.

```js
const response = await alice.attachment.destroy('rabbit', 'rabbit.png', {rev: '1-4701d73a08ce5c2f2983bf7c9ffd3320'})
```

## Views and design functions

### db.view(designname, viewname, [params])

Calls a view of the specified `designname` with optional query string `params`. If you're looking to filter the view results by key(s) pass an array of keys, e.g
`{ keys: ['key1', 'key2', 'key_n'] }`, as `params`.

```js
const body = await alice.view('characters', 'happy_ones', { key: 'Tea Party', include_docs: true })
body.rows.forEach((doc) => {
  console.log(doc.value)
})
```

or

```js
const body = await alice.view('characters', 'soldiers', { keys: ['Hearts', 'Clubs'] })
```

When `params` is not supplied, or no keys are specified, it will simply return all documents in the view:

```js
const body = await alice.view('characters', 'happy_ones')
```

```js
const body = alice.view('characters', 'happy_ones', { include_docs: true })
```

### db.viewAsStream(designname, viewname, [params])

Same as `db.view` but returns a stream:

```js
alice.viewAsStream('characters', 'happy_ones', {reduce: false})
  .on('error', (e) => console.error('error', e))
  .pipe(process.stdout);
```

### db.viewWithList(designname, viewname, listname, [params])

Calls a list function fed by the given view from the specified design document.

```js
const body = await alice.viewWithList('characters', 'happy_ones', 'my_list')
```

### db.viewWithListAsStream(designname, viewname, listname, [params])

Calls a list function fed by the given view from the specified design document as a stream.

```js
alice.viewWithListAsStream('characters', 'happy_ones', 'my_list')
  .on('error', (e) => console.error('error', e))
  .pipe(process.stdout);
```

### db.show(designname, showname, doc_id, [params])

Calls a show function from the specified design for the document specified by doc_id with
optional query string additions `params`.

```js
const doc = await alice.show('characters', 'format_doc', '3621898430')
```

Take a look at the [CouchDB wiki](https://guide.couchdb.org/draft/show.html)
for possible query paramaters and more information on show functions.

### db.atomic(designname, updatename, docname, [body])

Calls the design's update function with the specified doc in input.

```js
const response = await db.atomic('update', 'inplace', 'foobar', {field: 'foo', value: 'bar'})
```

Note that the data is sent in the body of the request.
An example update handler follows:

```js
"updates": {
  "in-place" : "function(doc, req) {
      var request_body = JSON.parse(req.body)
      var field = request_body.field
      var value = request_body.value
      var message = 'set ' + field + ' to ' + value
      doc[field] = value
      return [doc, message]
  }"
}
```

### db.search(designname, searchname, params)

Calls a view of the specified design with optional query string additions `params`.

```js
const response = await alice.search('characters', 'happy_ones', { q: 'cat' })
```

or

```js
const drilldown = [['author', 'Dickens']['publisher','Penguin']]
const response = await alice.search('inventory', 'books', { q: '*:*', drilldown: drilldown })
```

Check out the tests for a fully functioning example.

### db.searchAsStream(designname, searchname, params)

Calls a view of the specified design with optional query string additions `params`. Returns stream.

```js
alice.search('characters', 'happy_ones', { q: 'cat' }).pipe(process.stdout);
```

### db.find(selector)

Perform a ["Mango" query](https://docs.couchdb.org/en/2.1.1/api/database/find.html) by supplying a JavaScript object containing a selector:

```js
// find documents where the name = "Brian" and age > 25.
const q = {
  selector: {
    name: { "$eq": "Brian"},
    age : { "$gt": 25 }
  },
  fields: [ "name", "age", "tags", "url" ],
  limit:50
};
const response = await alice.find(q)
```

### db.findAsStream(selector)

Perform a ["Mango" query](http://docs.couchdb.org/en/2.1.1/api/database/find.html) by supplying a JavaScript object containing a selector, but return a stream:

```js
// find documents where the name = "Brian" and age > 25.
const q = {
  selector: {
    name: { "$eq": "Brian"},
    age : { "$gt": 25 }
  },
  fields: [ "name", "age", "tags", "url" ],
  limit:50
};
alice.findAsStream(q)
  .on('error', (e) => console.error('error', e))
  .pipe(process.stdout);
```

## using cookie authentication

Nano supports making requests using CouchDB's [cookie authentication](http://guide.couchdb.org/editions/1/en/security.html#cookies) functionality. If you initialise *Nano* so that it is cookie-aware, you may call `nano.auth` first to get a session cookie. Nano will behave like a web browser, remembering your session cookie and refreshing it if a new one is received in a future HTTP response.

```js
const nano = require('nano')({
  url: 'http://127.0.0.1:5984'
})
const username = 'user'
const userpass = 'pass'
const db = nano.db.use('mydb')

// authenticate
await nano.auth(username, userpass)

// requests from now on are authenticated
const doc = await db.get('mydoc')
console.log(doc)
```

The second request works because the `nano` library has remembered the `AuthSession` cookie that was invisibily returned by the `nano.auth` call.

When you have a session, you can see what permissions you have by calling the `nano.session` function

```js
const doc = await nano.session()
// { userCtx: { roles: [ '_admin', '_reader', '_writer' ], name: 'rita' },  ok: true }
```

## Advanced features

### Getting uuids

If your application needs to generate UUIDs, then CouchDB can provide some for you

```js
const response = await nano.uuids(3)
// { uuids: [
// '5d1b3ef2bc7eea51f660c091e3dffa23',
// '5d1b3ef2bc7eea51f660c091e3e006ff',
// '5d1b3ef2bc7eea51f660c091e3e007f0',
//]}
```

The first parameter is the number of uuids to generate. If omitted, it defaults to 1.

### Extending nano

`nano` is minimalistic but you can add your own features with
`nano.request(opts)`

For example, to create a function to retrieve a specific revision of the
`rabbit` document:

```js
function getrabbitrev(rev) {
  return nano.request({ db: 'alice',
                 doc: 'rabbit',
                 method: 'get',
                 params: { rev: rev }
               });
}

getrabbitrev('4-2e6cdc4c7e26b745c2881a24e0eeece2').then((body) => {
  console.log(body);
});
```

### Pipes

You can pipe the return values of certain nano functions like other stream. For example if our `rabbit` document has an attachment with name `picture.png` you can pipe it to a `writable stream`:

```js
const fs = require('fs');
const nano = require('nano')('http://127.0.0.1:5984/');
const alice = nano.use('alice');
alice.attachment.getAsStream('rabbit', 'picture.png')
  .on('error', (e) => console.error('error', e))
  .pipe(fs.createWriteStream('/tmp/rabbit.png'));
```

then open `/tmp/rabbit.png` and you will see the rabbit picture.

Functions that return streams instead of a Promise are:

- nano.db.listAsStream

attachment functions:

- db.attachment.getAsStream
- db.attachment.insertAsStream

and document level functions

- db.listAsStream

### Logging

When instantiating Nano, you may supply the function that will perform the logging of requests and responses. In its simplest for, simply pass `console.log` as your logger:

```js
const nano = Nano({ url: process.env.COUCH_URL, log: console.log })
// all requests and responses will be sent to console.log
```

You may supply your own logging function to format the data before output:

```js
const url = require('url')
const logger = (data) => {
  // only output logging if there is an environment variable set
  if (process.env.LOG === 'nano') {
    // if this is a request
    if (typeof data.err === 'undefined') {
      const u = new url.URL(data.uri)
      console.log(data.method, u.pathname, data.qs)
    } else {
      // this is a response
      const prefix = data.err ? 'ERR' : 'OK'
      console.log(prefix, data.headers.statusCode, JSON.stringify(data.body).length)
    }
  }
}
const nano = Nano({ url: process.env.COUCH_URL, log: logger })
// all requests and responses will be formatted by my code
// GET /cities/_all_docs { limit: 5 }
// OK 200 468
```

## Tutorials, examples in the wild & screencasts

* article: [nano - a minimalistic CouchDB client for nodejs](https://writings.nunojob.com/2011/08/nano-minimalistic-couchdb-client-for-nodejs.html)
* article: [getting started with Node.js and CouchDB](https://writings.nunojob.com/2011/09/getting-started-with-nodejs-and-couchdb.html)
* article: [nano 3](https://writings.nunojob.com/2012/05/Nano-3.html)
* article: [how to update a document with nano](https://writings.nunojob.com/2012/07/How-To-Update-A-Document-With-Nano-The-CouchDB-Client-for-Node.js.html)
* article: [thoughts on development using CouchDB with Node.js](https://tbranyen.com/post/thoughts-on-development-using-couchdb-with-nodejs)
* example in the wild: [nanoblog](https://github.com/grabbeh/nanoblog)

## Roadmap

Check [issues][2]

## Tests

To run (and configure) the test suite simply:

``` sh
cd nano
npm install
npm run test
```

## Meta

* code: `git clone git://github.com/apache/couchdb-nano.git`
* home: <https://github.com/apache/couchdb-nano>
* bugs: <https://github.com/apache/couchdb-nano/issues>
* chat: [Freenode IRC @ #couchdb-dev][8]

[1]: https://npmjs.org
[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

https://freenode.org/

## Release

To create a new release of nano. Run the following commands on the main branch

```sh
  npm version {patch|minor|major}
  github push  origin main --tags
  npm publish
```
