@teamhive/node-couchdb-client

This typescript module is designed to do handle the communication between NodeJS and CouchDB

Usage no npm install needed!

<script type="module">
  import teamhiveNodeCouchdbClient from 'https://cdn.skypack.dev/@teamhive/node-couchdb-client';
</script>

README

node-couchdb-client

A typescript package built around the CouchDB API for NodeJS using OOP practices. The foundation of this repo was inspired by pmorjan/couchdb-promise!

  • Written in typescript
  • Uses request-promise under the hood
  • Object Oriented for easy dependency injection

Getting started

npm i @teammaestro/node-couchdb-client

Once the package is installed, you just need to import it and use it!

import { CouchDB } from '@teammaestro/node-couchdb-client';

// Instatiate new CouchDB request class
const couchDb = new CouchDb({
    auth: {
        username: 'admin',
        password: 'password'
    }
});

Documentation

Overview

new CouchDb()

Parameters:

  • host (string | optional | default: 127.0.0.1) - The domain that the couchDb is located at
  • port (number | optional| default: 5984) - The port that couchDb is running on
  • auth (object | optional)
    • username (string) - The basic auth username
    • password (string) - The basic auth password
  • logging (boolean | optional | default: false) - Use this to turn on logging of all requests
  • defaultDatabase (string | optional) - You can set the default database for database specific calls

Request Example:

new CouchDb({
    host: 'https://couchdb.example.com';
    port: 1433;
    auth: {
        username: 'admin',
        password: 'password'
    },
    logging: true
    defaultDatabase: 'test'
})

.catch()

Whenever the API makes a call and runs into a catch block, you will get an error block that looks consistently like this:

  • error (Error) - The exception that was thrown
  • status (number) - The HTTP Status Code
  • message (string) - The HTTP error message (some are custom mapped)
  • duration (number) - How long the response took in miliseconds Response Example:
{
    error: Error
    status: 500,
    message: 'Internal Server Error',
    duration: 300
}

getInfo() GET /

This is essentially a "ping" endpoint .. just returns basic information if the server is up.

Request Example:

couchDb.getInfo()

Response Example:

{
    "couchdb": "Welcome",
    "uuid": "85fb71bf700c17267fef77535820e371",
    "vendor": {
        "name": "The Apache Software Foundation",
        "version": "1.3.1"
    },
    "version": "1.3.1"
}

Database

getDatabases() GET _all_dbs

This endpoint just returns an array of all the database names

Request Example:

couchDb.getDatabases()

Response Example:

[
   "_users",
   "contacts",
   "docs",
   "invoices",
   "locations"
]

getDatabase(dbName?: string) GET /{db}

Gets information about the specified database.

Parameters:

  • dbName (string | optional | _default: couchDb.defaultDatabase)

Request Example:

couchDb.getDatabase('testDB')

Response Example:

{
    "db_name": "test",
    "update_seq": "37-g1AAAABXeJ",
    "sizes": {
        "file": 172428,
        "external": 3427,
        "active": 13135
    },
    "purge_seq": 0,
    "other": {
        "data_size": 3427
    },
    "doc_del_count": 5,
    "doc_count": 23,
    "disk_size": 172428,
    "disk_format_version": 6,
    "data_size": 13135,
    "compact_running": false,
    "instance_start_time": "0"
}

getDatabaseRevisionLimit(dbName?: string) GET /{db}/_revs_limit

Gets the revision limit for the specified database.

Parameters:

  • dbName (string)

Request Example:

couchDb.getDatabaseRevisionLimit('testDB')

Response Example:

2

createDatabase(dbName?: string, options?: { revisionLimit: number; }) PUT /{db}

Creates a new database. If a revisionLimit is passed to the options object it will also set the revision limit for that database. The database name {db} must be composed by following next rules:

  • Name must begin with a lowercase letter (a-z)
  • Lowercase characters (a-z)
  • Digits (0-9)
  • Any of the characters _, $, (, ), +, -, and /.

Parameters:

  • dbName (string | optional | _default: couchDb.defaultDatabase)
  • options (object | optional)
    • revisionLimit (number)

Request Example:

couchDb.createDatabase('testDB', { revisionLimit: 2 })

Response Example:

{
    "ok": true
}

checkDatabaseExists(dbName?: string) HEAD /{db}

Returns the HTTP Headers containing a minimal amount of information about the specified database. Since the response body is empty, using the HEAD method is a lightweight way to check if the database exists already or not.

Parameters:

  • dbName (string | optional | _default: couchDb.defaultDatabase)

Request Example:

couchDb.checkDatabaseExists('testDB')

Response: This just returns a boolean if the database exists or not.

Response Example:

true

compactDatabase(dbName: string) POST /{db}/_compact

Request compaction of the specified database. Compaction compresses the disk database file by writing a new optimized version of the database and removing any old revisions, up to the database specific revision limit.

Parameters:

  • dbName (string)

Request Example:

couchDb.compactDatabase('testDB')

Response Example:

{
    "ok": true
}

setDatabaseRevisionLimit(dbName: string, revisionLimit: number) PUT /{db}/_revs_limit

Set the revision limit on the specified database.

Parameters:

  • dbName (string)
  • revisionLimit (number)

Request Example:

couchDb.setDatabaseRevisionLimit('testDB', 2)

Response Example:

{
    "ok": true
}

deleteDatabase(dbName?: string) DELETE /{db}

Deletes the specified database, and all the documents and attachments contained within it.

Parameters:

  • dbName (string | optional | _default: couchDb.defaultDatabase)

Request Example:

couchDb.deleteDatabase('testDB')

Response Example:

{
    "ok": true
}

updateDatabaseSecurity({ dbName?: string, admins: any, members: any }) PUT /{db}/_security

Sets the security object for the given database. Use the member permissions to lock down this database to either a username or role.

Parameters:

  • dbName (string | optional | _default: couchDb.defaultDatabase)
  • admins:
    • names (string[] | optional) - This is the list of usernames that have admin permissions
    • roles (string[] | optional) - This is the list of roles that have admin permissions
  • members:
    • names (string[] | optional) - This is the list of usernames that have member permissions
    • roles (string[] | optional) - This is the list of roles that have member permissions

Request Example:

couchDb.updateDatabaseSecurity({
    dbName: 'testDB',
    admins: {
        names: ['johnsmith']
    },
    members: {
        names: ['johnsmith']
    }
})

Response Example:

{
    "ok": true,

}

Users

createUser({ username: string, password: string, roles?: string[]}) POST /_users

This will create a member user which would be used to help lock down a database

Parameters:

  • username (string | required) - The users username
  • password (string | required) - The users password
  • roles (string[] | optional) - The users list of roles (These roles are made up by you .. used for Database security)

Request Example:

couchDb.createUser({
    username: 'johnsmith',
    password: 'password',
    roles: [
        'reporter'
    ]
})

Response Example:

{
    "ok": true,
    "id": "org.couchdb.user:johnsmith",
    "rev": "1-c7b59092b8e3e85eed24cce19e9350f7"
}

checkUserExists(username: string) HEAD /_users/org.couchdb.user:{username}

Returns a boolean for if the user exists or not.

Parameters:

  • username (string) - The user's username you are checking on

Request Example:

couchDb.checkUserExists(username)

Response: This just returns a boolean if the database exists or not.

Response Example:

true

getUser(username : string) GET /{db}/{docId}

Returns document by the specified docid from the specified db. Unless you request a specific revision, the latest revision of the document will always be returned.

Parameters (All optional):

  • dbName (string | _default: couchDb.defaultDatabase)
  • docId (string | required) - The documents Id

Request Example:

couchDb.getDocument({
    dbName: 'testDB',
    docId: '4342-432432-432432-4324'
})

Response:

  • _id (string) – Document ID
  • _rev (string) – Revision MVCC token
  • _deleted (boolean) – Deletion flag. Available if document was removed
  • _attachments (object) – Attachment’s stubs. Available if document has any attachments
  • _conflicts (array) – List of conflicted revisions. Available if requested with conflicts=true query * parameter
  • _deleted_conflicts (array) – List of deleted conflicted revisions. Available if requested with * deleted_conflicts=true query parameter
  • _local_seq (string) – Document’s update sequence in current database. Available if requested with * local_seq=true query parameter
  • _revs_info (array) – List of objects with information about local revisions and their status. * Available if requested with open_revs query parameter
  • _revisions (object) – List of local revision tokens without. Available if requested with revs=true query parameter

Response Example:

{
    "id": "16e458537602f5ef2a710089dffd9453",
    "rev": "1-967a00dff5e02add41819138abb3284d"
}

Documents

findDocuments({ dbName?: string, findOptions: any }) POST /{db}/_find

Find documents using a declarative JSON querying syntax. Queries can use the built-in _all_docs index or custom indices, specified using the _index endpoint.

Parameters:

  • dbName (string | optional | _default: couchDb.defaultDatabase)
  • findOptions:
    • selector (json | required) – A JSON object describing criteria used to select documents. More information provided in the section on selector syntax.
    • limit (number | otional) – Maximum number of results returned. Default is 25.
    • skip (number | optional) – Skip the first ‘n’ results, where ‘n’ is the value specified.
    • sort (json | optional) – JSON array following sort syntax.
    • fields (array | optional) – JSON array specifying which fields of each object should be returned. If it is omitted, the entire object is returned. More information provided in the section on filtering fields.
    • use_index (string|array | optional | default: 1) – Instruct a query to use a specific index. Specified either as "<design_document>" or ["<design_document>", "<index_name>"].
    • r (number | optional) – Read quorum needed for the result. This defaults to 1, in which case the document found in the index is returned. If set to a higher value, each document is read from at least that many replicas before it is returned in the results. This is likely to take more time than using only the document stored locally with the index.
    • bookmark (string | optional) – A string that enables you to specify which page of results you require. Used for paging through result sets. Every query returns an opaque string under the bookmark key that can then be passed back in a query to get the next page of results. If any part of the selector query changes between requests, the results are undefined.
    • update (boolean | optional) – Whether to update the index prior to returning the result. Default is true.
    • stable (boolean | optional) – Whether or not the view results should be returned from a “stable” set of shards.
    • stale (string | optional) – Combination of update=false and stable=true options. Possible options: "ok", false (default)
    • execution_stats (boolean | optional | default: false) – Include execution statistics in the query response.

Request Example:

couchDb.findDocuments({
    dbName: 'testDB',
    findOptions: {
        selector: {
            year: {'$gt': 2010}
        },
        fields: ['_id', '_rev', 'year', 'title'],
        sort: [{year: 'asc'}],
        limit: 2,
        skip: 0,
        execution_stats: true
    }
})

Response:

  • docs (any[]) – Array of documents matching the search. In each matching document, the fields specified in the fields part of the request body are listed, along with their values.
  • warning (string) – Execution warnings
  • execution_stats (object) – Execution statistics

Response Example:

{
    "docs": [
        {
            "_id": "176694",
            "_rev": "1-54f8e950cc338d2385d9b0cda2fd918e",
            "year": 2011,
            "title": "The Tragedy of Man"
        },
        {
            "_id": "780504",
            "_rev": "1-5f14bab1a1e9ac3ebdf85905f47fb084",
            "year": 2011,
            "title": "Drive"
        },
        ...
    ],
    "execution_stats": {
        "total_keys_examined": 0,
        "total_docs_examined": 200,
        "total_quorum_docs_examined": 0,
        "results_returned": 2,
        "execution_time_ms": 5.52
    }
}

getDocuments({ dbName?: string, options?: any }) GET /{db}/_all_docs

Returns a JSON structure of all of the documents in a given database. The information is returned as a JSON structure containing meta information about the return structure, including a list of all documents and basic contents, consisting the ID, revision and key. The key is the from the document’s _id.

Parameters (All optional):

  • dbName (string | _default: couchDb.defaultDatabase)
  • options:
    • conflicts (boolean | default: false) – Includes conflicts information in response. Ignored if include_docs isn’t true.
    • descending (boolean | default: false) – Return the documents in descending by key order.
    • endkey (string) – Stop returning records when the specified key is reached.
    • end_key (string) – Alias for endkey param.
    • endkey_docid (string) – Stop returning records when the specified document ID is reached.
    • end_key_doc_id (string) – Alias for endkey_docid param.
    • include_docs (boolean | default: false) – Include the full content of the documents in the return.
    • inclusive_end (boolean| default: true) – Specifies whether the specified end key should be included in the result.
    • key (string) – Return only documents that match the specified key.
    • keys (string) – Return only documents that match the specified keys.
    • limit (number) – Limit the number of the returned documents to the specified number.
    • skip (number | default: 0) – Skip this number of records before starting to return the results.
    • stale (string) – Allow the results from a stale view to be used, without triggering a rebuild of all views within the encompassing design doc. Supported values: ok and update_after.
    • startkey (string) – Return records starting with the specified key.
    • start_key (string) – Alias for startkey param.
    • startkey_docid (string) – Return records starting with the specified document ID.
    • start_key_doc_id (string) – Alias for startkey_docid param.
    • update_seq (boolean | default: false) – Response includes an update_seq value indicating which sequence id of the underlying database the view reflects.

Request Example:

couchDb.getDocuments({
    dbName: 'testDB',
    options: {
        startKey: 'user'
    }
})

Response:

  • offset (number) – Offset where the document list started
  • rows (array) – Array of view row objects. By default the information returned contains only the document ID and revision.
  • total_rows (number) – Number of documents in the database/view. Note that this is not the number of rows returned in the actual query.
  • update_seq (number) – Current update sequence for the database

Response Example:

{
    "offset": 0,
    "rows": [
        {
            "id": "16e458537602f5ef2a710089dffd9453",
            "key": "16e458537602f5ef2a710089dffd9453",
            "value": {
                "rev": "1-967a00dff5e02add41819138abb3284d"
            }
        },
        {
            "id": "a4c51cdfa2069f3e905c431114001aff",
            "key": "a4c51cdfa2069f3e905c431114001aff",
            "value": {
                "rev": "1-967a00dff5e02add41819138abb3284d"
            }
        },
        {
            "id": "a4c51cdfa2069f3e905c4311140034aa",
            "key": "a4c51cdfa2069f3e905c4311140034aa",
            "value": {
                "rev": "5-6182c9c954200ab5e3c6bd5e76a1549f"
            }
        }
    ],
    "total_rows": 3
}

getDocument({ dbName?: string, docId: string }) GET /{db}/{docId}

Returns document by the specified docid from the specified db. Unless you request a specific revision, the latest revision of the document will always be returned.

Parameters (All optional):

  • dbName (string | _default: couchDb.defaultDatabase)
  • docId (string | required) - The documents Id

Request Example:

couchDb.getDocument({
    dbName: 'testDB',
    docId: '4342-432432-432432-4324'
})

Response:

  • _id (string) – Document ID
  • _rev (string) – Revision MVCC token
  • _deleted (boolean) – Deletion flag. Available if document was removed
  • _attachments (object) – Attachment’s stubs. Available if document has any attachments
  • _conflicts (array) – List of conflicted revisions. Available if requested with conflicts=true query * parameter
  • _deleted_conflicts (array) – List of deleted conflicted revisions. Available if requested with * deleted_conflicts=true query parameter
  • _local_seq (string) – Document’s update sequence in current database. Available if requested with * local_seq=true query parameter
  • _revs_info (array) – List of objects with information about local revisions and their status. * Available if requested with open_revs query parameter
  • _revisions (object) – List of local revision tokens without. Available if requested with revs=true query parameter

Response Example:

{
    "id": "16e458537602f5ef2a710089dffd9453",
    "rev": "1-967a00dff5e02add41819138abb3284d"
}

checkDocumentExists({ dbName?: string, docId: string }) HEAD /{db}/{docId}

Returns the HTTP Headers containing a minimal amount of information about the specified document. The method supports the same query arguments as the GET /{db}/{docid} method, but only the header information (including document size, and the revision as an ETag), is returned.

The ETag header shows the current revision for the requested document, and the Content-Length specifies the length of the data, if the document were requested in full.

Adding any of the query arguments (see GET /{db}/{docid}), then the resulting HTTP Headers will correspond to what would be returned.

Parameters:

  • dbName (string | optional | _default: couchDb.defaultDatabase)
  • docId (string) - The document id

Request Example:

couchDb.checkDocumentExists({
    dbName: 'testDB',
    docId: 'user'
})

Response: This just returns a boolean if the database exists or not.

Response Example:

true

copyDocument({ dbName?: string, docId: string, newDocId: string }) COPY /{db}/{docId}

The COPY (which is non-standard HTTP) copies an existing document to a new or existing document. Copying a document is only possible within the same database.

The source document is specified on the request line, with the Destination header of the request specifying the target document.

Parameters:

  • dbName (string | optional | _default: couchDb.defaultDatabase)
  • docId (string | required) - The document id that you will be copying
  • newDocId (string | required) - The new document id

Request Example:

couchDb.copyDocuments({
    dbName: 'testDB',
    docId: 'user',
    newDocId: 'newUser'
})

Response Example:

{
    "id": "newUser",
    "ok": true,
    "rev": "1-e86fdf912560c2321a5fcefc6264e6d9"
}

createDocument({ dbName?: string, doc: any, docId?: string }) POST /{db}(/{docId})

Creates a new document in the specified database, using the supplied JSON document structure. It will also, create the document under the docId if specified.

If the JSON structure includes the _id field, then the document will be created with the specified document ID.

If the _id field is not specified, a new unique ID will be generated, following whatever UUID algorithm is configured for that server.

Parameters:

  • dbName (string | optional | _default: couchDb.defaultDatabase)
  • doc (any | required) - The document you want to create
  • docId (string | optional) - An optional ID you want to create the document with

Request Example:

couchDb.createDocument({
    dbName: 'testDB',
    doc: {
        firstName: 'John',
        lastName: 'Doe'
    },
    docId: 'currentUser'
})

Response Example:

{
    "id": "currentUser"
    "ok": true,
    "rev": "1-9c65296036141e575d32ba9c034dd3ee"
}

upsertDocuments({ dbName?: string, docs: any[] }) POST /{db}/_bulk_docs

The bulk document API allows you to create multiple documents at the same time within a single request. The basic operation is similar to creating single document, except that you batch the document structure and information. When creating new documents the document ID (_id) is optional.

Parameters:

  • dbName (string | optional | _default: couchDb.defaultDatabase)
  • docs (any[]) - An array of all the documents you are looking to create

Request Example:

couchDb.upsertDocuments({
    dbName: 'testDB',
    docs: [{
        firstName: 'John',
        lastName: 'Doe'
    }, {
        _id: '3f32022a25e9b2b81b67a766b9004517',
        _rev: '2-d538c7aaebdf4eb144b5d0070d3165ba',
        firstName: 'Jan',
        lastName: 'Doe'
    }]
})

Response Example:

{
    "ok": true
}

deleteDocument({ dbName?: string, docId: string, rev: string }) DELETE /{db}/{docId}

Marks the specified document as deleted by adding a field _deleted with the value true. Documents with this field will not be returned within requests anymore, but stay in the database. You must supply the current (latest) revision

Parameters:

  • dbName (string | optional | _default: couchDb.defaultDatabase)
  • docId (string | required) - The document Id
  • rev (string | required) - This is the revision

Request Example:

couchDb.deleteDocument({
    dbName: 'testDB',
    docId: 'currentUser',
    rev: '1-9c65296036141e575d32ba9c034dd3ee'
})

Response Example:

{
    "id": "currentUser",
    "ok": true,
    "rev": "1-9c65296036141e575d32ba9c034dd3ee"
}

Utils

getUuids(count: number) GET /_uuids

Requests one or more Universally Unique Identifiers (UUIDs) from the CouchDB instance. The response is a JSON object providing a list of UUIDs.

Parameters:

  • count (number | optional | default: 1)

Request Example:

couchDb.getUuids(2)

Response Example:

{
    "uuids":[
        "6e1295ed6c29495e54cc05947f18c8af",
        "4325432rfdf432weds3r4tregf454fg4"
    ]
}

Design Docs

getDesignDocument({dbName?: string, docId: string, options: any }) GET /_design

To come later

getDesignDocumentInfo({dbName?: string, docId: string }) GET /_design

To come later

createDesignDocument({dbName?: string, doc: any, docId: string }) GET /_design

To come later

deleteDesignDocument({dbName?: string, docId: string, rev: string }) GET /_design

To come later

getView({dbName?: string, docId: string, viewName: string, options?: any }) GET /_design

To come later

Index

getIndexes(dbName?: string) GET /{db}/_index

To come later

createIndex({ dbName?: string, index: any, name?: string }) POST /{db}/_index

To come later

deleteIndex({ dbName?: string, docId: string, indexName: string }) DELETE /{db}/_index/{docId}/json/{indexName}

To come later

Usuage

// Import package
import { CouchDB } from '@teammaestro/node-couchdb-client';

// Instatiate new CouchDB request class
const couchDb = new CouchDb({
    auth: {
        username: 'admin',
        password: 'password'
    }
});

// Async example
async function getAllDatabases() {
    try {
        const databases =  await this.couchDb.getAllDatabases();
        // do something
    }
    catch(error) {
        // catch error
    }
}

// Promise (ES6) example
couchDb.getDocuments('databaseName').then(docs => {
    // do something
}).catch(error => {
    // catch error
});

Contributors

John Pinkster
John Pinkster