JavaScript documentation

Alongside Python-PouchDB, a couple of PouchDB plug-ins are developed. They are also useful outside Python-PouchDB. The only thing that makes them different from ‘normal’ PouchDB plug-ins is the fact that most of their test suite is written in Python.

What follows is the JavaScript documentation for these plug-ins.

General

Before using any of the plug-ins below, you need to register them as a plug-in to PouchDB. That can be done using the PouchDB.plugin() function. In NodeJS, you can just pass in the result of the require() function. In the browser, you pass in the object the plug-in file created. The name of the NodeJS package, and the browser object, you can find in the tables after the plug-in section headers.

An example (using the list plug-in):

//NodeJS
PouchDB.plugin(require("pouchdb-list"));

//Browser - after the JavaScript file containing the plug-in has been
//included via a script tag (or something similar).
PouchDB.plugin(List);

All functions have two ways of returning the output to the user. One is a callback parameter, which should have the signature (err, resp). The other is the Promise all functions return. PouchDB itself uses the same system.

Pouchdb List plug-in

NodeJS package name: pouchdb-list
Browser object name: window.List

First, make sure you understand how list functions work in CouchDB. A good start is the CouchDB guide entry on lists.

List.list(listPath[, options[, callback]])

Runs a list function on a view. Both are specified via the listPath parameter.

Arguments:
  • listPath (string) – a url of the form "designDocName/listFuncName/viewName"
  • options (object) – this object is supplemented with defaults until a complete CouchDB request object has been formed, which is then passed into the list function.
Returns:

When succesful, the list function’s result in the form of a CouchDB response object. Otherwise, an error object with one of the following statuses: 400, 404, 406 or 500.

Pouchdb Rewrite plug-in

NodeJS package name: pouchdb-rewrite
Browser object name: window.Rewrite

First, make sure you understand CouchDB rewrites. A good starting point is the rewrite documentation.

Rewrite.rewrite(rewritePath[, options[, callback]])

Figures out where to redirect to, and then executes the corresponding PouchDB function, with the appropriate arguments gotten from the request object that has been generated from the options parameter.

Arguments:
  • rewritePath (string) – a path of the form "designDocName/rewrite/path". Specifies the design document to use the rewrites from, and the path you’d find in CouchDB after the /_rewrite part of the URL. Keep in mind that you can’t specify a query parameter in the url form (i.e. no ?a=b). Instead use the options.query parameter.
  • options (object) – A CouchDB request object stub. Important properties of those for rewrites are options.query and options.method. An additional boolean option is available: options.withValidation, if true, this function routes to db.validating* functions instead of db.* functions if relevant.
Returns:

whatever output the function that the rewrite routed to produced. Or, in the case of an ‘http’ database, a CouchDB response object.

Rewrite.rewriteResultRequestObject(rewritePath[, options[, callback]])

See the Rewrite.rewrite() function for information on the parameters. The difference with it is that this function doesn’t try to route the rewrite to a function.

Returns:A CouchDB request object that points to the resource obtained by following the redirect.

Pouchdb Show plug-in

NodeJS package name: pouchdb-show
Browser object name: window.Show

First, make sure you understand how show functions work in CouchDB. A good start is the CouchDB guide entry on shows.

Show.show(showPath[, options[, callback]])

Similar to the List.list() function, but then for show functions. Only differences are documented.

Arguments:
  • showPath (string) – specifies the show (and optionally the document) to use. Has the following form: designDocName/showName[/docId]

Pouchdb Update plug-in

NodeJS package name: pouchdb-update
Browser object name: window.Update

First, make sure you understand how update handlers work in CouchDB. A good start is the wiki entry on update handlers.

Update.update(updatePath[, options[, callback]])

Runs the update function specified by updatePath, saving part of its result in the database and returning the other part in the form of a CouchDB response object.

Arguments:
  • updatePath (string) – has the following form: "designDocName/updateHandlerName[/docId]". The last being optional, like in CouchDB.
  • options (object) – a request object stub. There’s also options.withValidation, if true, this function saves the update handler result using the Validation.validatingPut() function instead of using the PouchDB.prototype.put() function.

Pouchdb Validation plug-in

NodeJS package name: pouchdb-validation
Browser object name: window.Validation

First, make sure you understand how validation functions work in CouchDB. A good start is the CouchDB guide entry on validation functions.

Validation.validatingPut(doc[, options[, callback]])

Exactly the same as the PouchDB.prototype.put() function, but checks with all validation functions (‘validate_doc_update’) in all design documents of the current database if it is ok to save doc. In short, this method acts more like its CouchDB equivalent than the original PouchDB version does. The only thing you get to see of it is a few extra errors, i.e. of the ‘unauthorized’ or the ‘forbidden’ type.

Validation.validatingPost(doc[, options[, callback]])

See the Validation.validatingPut() function.

Validation.validatingRemove(doc[, options[, callback]])

See the Validation.validatingPut() function.

Validation.validatingBulkDocs(bulkDocs[, options[, callback]])

See the Validation.validatingPut() function. Returns an array, like PouchDB.prototype.bulkDocs(). The all_or_nothing attribute on bulkDocs is unsupported. Also, the result array might not be in the same order as bulkDocs.docs.

Validation.validatingPutAttachment(docId, attachmentId, rev, attachment, type[, options[, callback]])

See the Validation.validatingPut() function. Output is the same as PouchDB.prototype.putAttachment() (except for a few extra errors being possible.)

Validation.validatingRemoveAttachment(docId, attachmentId, rev[, options[, callback]])

See the Validation.validatingPut() function. Output is the same as PouchDB.prototype.removeAttachment() (except for a few extra errors being possible.)

Examples

The NodeJS test suite, which just does one basic check per function, but because of that provides nice and simple examples:

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
/*
	Copyright 2014, Marten de Vries

	Licensed under the Apache License, Version 2.0 (the "License");
	you may not use this file except in compliance with the License.
	You may obtain a copy of the License at

	http://www.apache.org/licenses/LICENSE-2.0

	Unless required by applicable law or agreed to in writing, software
	distributed under the License is distributed on an "AS IS" BASIS,
	WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
	See the License for the specific language governing permissions and
	limitations under the License.
*/

/*global emit, describe, before, PouchDB, after, it */

"use strict";

var chai = require('chai');
chai.should();

//python-pouchdb-js
require("../");

var CONFIG;
try {
  CONFIG = require("../../../pouchdb/tests/testconfig.json");
} catch (e) {
  CONFIG = {}
}
CONFIG.storage_dir = CONFIG.storage_dir || "dbs";
CONFIG.base_url = CONFIG.base_url || "http://localhost:5984";

var AUTH = null;
if (CONFIG.username) {
  AUTH = {
    username: CONFIG.username,
    password: CONFIG.password
  };
}

var db;
var DB_NAME = "node-python-pouchdb-tests";

function showTest(doc, req) {
  return "Hello World!";
}

function listTest(head, req) {
  throw new Error("Hello World!");
}

function viewTest(doc) {
  emit(doc._id);
}

function validateDocUpdateTest(newDoc, oldDoc, userCtx, secObj) {
  if (newDoc._id === "myid") {
    throw {"forbidden": "Mine!!!"};
  }
}

function updateTest(doc, req) {
  return [{_id: req.uuid, hello: "world!"}, req.uuid];
}

before(function () {
  db = new PouchDB(CONFIG.storage_dir + "/" + DB_NAME);
  return db.put({
    _id: "_design/test",
    shows: {
      test: showTest.toString()
    },
    lists: {
      test: listTest.toString()
    },
    views: {
      ids: {
        map: viewTest.toString()
      }
    },
    updates: {
      test: updateTest.toString()
    },
    rewrites: [
      {
        from: "/test/all",
        to: "_list/test/ids"
      }
    ],
    validate_doc_update: validateDocUpdateTest.toString()
  });
});
after(function () {
  return db.destroy().then(function () {
    return PouchDB.resetAllDbs();
  });
});

function checkListError(err) {
  err.name.should.equal("Error");
  err.message.should.contain("Hello World!");
  err.status.should.equal(500);
}


describe("plugin tests", function () {
  it("should give the show result", function () {
    return db.show("test/test").then(function (resp) {
      resp.body.should.equal("Hello World!")
      resp.code.should.equal(200);
    });
  });
  it("should get the show result from couchdb", function () {
    var http = new PouchDB(CONFIG.base_url + "/" + DB_NAME, {auth: AUTH});
    return http.replicate.from(db).then(function () {
      return db.show("test/test");
    }).then(function (resp) {
      resp.body.should.equal("Hello World!")
      resp.code.should.equal(200);
    }).then(function () {
      http.destroy();
    });
  });
  it("should give the list error", function () {
    return db.list("test/test/ids").catch(function (err) {
      checkListError(err);
    });
  });
  it("should reject the document", function () {
    return db.validatingPut({"_id": "myid"}).catch(function (err) {
      err.name.should.equal("forbidden");
      err.message.should.equal("Mine!!!");
      err.status.should.equal(403);
    });
  });
  it("should accept the document", function () {
    return db.validatingPost({}).then(function (resp) {
      resp.ok.should.be.ok;
      resp.id.should.be.ok;
      resp.rev.should.be.ok;
    });
  });
  it("should save a document via the update handler", function () {
    return db.update("test/test").then(function (resp) {
      return db.get(resp.body);
    }).then(function (resp) {
      resp.hello.should.equal("world!");
    });
  });
  it("should rewrite the url", function () {
    return db.rewriteResultRequestObject("test/test/all", {query: {"k": "v"}}).then(function (req) {
      req.raw_path.should.equal("/" + encodeURIComponent(CONFIG.storage_dir + "/" + DB_NAME) + "/_design/test/_list/test/ids?k=v");
    });
  });
  it("should return the list function result", function () {
    return db.rewrite("test/test/all").catch(function (err) {
      checkListError(err);
    });
  });
});