WIP switch to fetch by default
diff --git a/.travis.yml b/.travis.yml
index 9d4ff62..7fdab38 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -13,6 +13,7 @@
false
addons:
+ firefox: latest
jwt:
secure: YlCp9qGHmnnATcScIQVyOt8eI9FxLhMGAz9iRTHh7r41ADjfGJUzyqkWoBLcCagiQWtqtUujukPAtRuOibbBp9SvmGp+IIdbwHVUDvSZNOvGxkQ1qczeGxJcnht+2YNoCwfzkHW4vFrNiGOULdjvbWAB4sAJ8N0AZPShURwXU1E=
@@ -80,13 +81,12 @@
# Testing in saucelabs
- CLIENT=saucelabs:chrome COMMAND=test
- - FETCH=1 CLIENT=selenium:firefox COMMAND=test
- SKIP_MIGRATION=true CLIENT=saucelabs:safari COMMAND=test
- CLIENT="saucelabs:internet explorer:10:Windows 8" COMMAND=test
# split up the android+iphone tests as it goes over time
- SKIP_MIGRATION=true CLIENT=saucelabs:iphone COMMAND=test
- - CLIENT="saucelabs:Android:5.1:Linux" COMMAND=test
+ - CLIENT="saucelabs:Android:6.0:Linux" COMMAND=test
# Test memory / fruitdown etc
- CLIENT="saucelabs:iphone:8.4:OS X 10.11" ADAPTERS=fruitdown COMMAND=test
@@ -135,6 +135,10 @@
# phantomjs doesnt like us upgrading to Apache Docker images
- env: CLIENT=selenium:phantomjs ADAPTERS=websql COMMAND=test
- env: AUTO_COMPACTION=true CLIENT=selenium:phantomjs ADAPTERS=websql COMMAND=test
+ - env: TYPE=mapreduce CLIENT=selenium:phantomjs ADAPTERS=websql COMMAND=test
+ # TODO: disabled as part of https://github.com/pouchdb/pouchdb/issues/6944
+ # but needs reenabled
+ - env: CLIENT="saucelabs:internet explorer:10:Windows 8" COMMAND=test
branches:
only:
diff --git a/package.json b/package.json
index 7df4b0a..c774f76 100644
--- a/package.json
+++ b/package.json
@@ -34,11 +34,13 @@
"test-webpack": "bash bin/test-webpack.sh"
},
"dependencies": {
+ "add-cors-to-couchdb": "0.0.6",
"argsarray": "0.0.1",
"buffer-from": "0.1.1",
"clone-buffer": "1.0.0",
"debug": "3.1.0",
"double-ended-queue": "2.1.0-0",
+ "fetch-cookie": "0.7.0",
"fruitdown": "1.0.2",
"immediate": "3.0.6",
"inherits": "2.0.3",
@@ -51,13 +53,15 @@
"localstorage-down": "0.6.7",
"ltgt": "2.2.0",
"memdown": "1.2.4",
+ "node-fetch": "^2.0.0",
"readable-stream": "1.0.33",
"request": "2.83.0",
"spark-md5": "3.0.0",
"through2": "2.0.3",
"uuid": "3.2.1",
"vuvuzela": "1.0.3",
- "websql": "0.4.4"
+ "websql": "0.4.4",
+ "whatwg-fetch": "2.0.3"
},
"devDependencies": {
"argsarray": "0.0.1",
@@ -94,7 +98,6 @@
"mocha": "3.5.0",
"mockery": "2.1.0",
"ncp": "2.0.0",
- "nock": "9.1.6",
"pouchdb-express-router": "0.0.10",
"query-string": "4.3.3",
"replace": "0.3.0",
diff --git a/packages/node_modules/pouchdb-abstract-mapreduce/src/index.js b/packages/node_modules/pouchdb-abstract-mapreduce/src/index.js
index c0ea6ca..ea229a9 100644
--- a/packages/node_modules/pouchdb-abstract-mapreduce/src/index.js
+++ b/packages/node_modules/pouchdb-abstract-mapreduce/src/index.js
@@ -16,6 +16,8 @@
parseIndexableString
} from 'pouchdb-collate';
+import { generateErrorFromResponse } from 'pouchdb-errors';
+import { Headers } from 'pouchdb-fetch';
import TaskQueue from './taskqueue';
import createView from './createView';
import {
@@ -229,6 +231,7 @@
var params = [];
var body;
var method = 'GET';
+ var ok, status;
// If opts.reduce exists and is defined, then add it to the list
// of parameters.
@@ -282,23 +285,28 @@
// We are referencing a query defined in the design doc
if (typeof fun === 'string') {
var parts = parseViewName(fun);
- return db.request({
+ return db.fetch('_design/' + parts[0] + '/_view/' + parts[1] + params, {
+ headers: new Headers({'Content-Type': 'application/json'}),
method: method,
- url: '_design/' + parts[0] + '/_view/' + parts[1] + params,
- body: body
- }).then(
- /* istanbul ignore next */
- function (result) {
- // fail the entire request if the result contains an error
- result.rows.forEach(function (row) {
- if (row.value && row.value.error && row.value.error === "builtin_reduce_error") {
- throw new Error(row.reason);
- }
- });
-
- return result;
- })
- .then(postprocessAttachments(opts));
+ body: JSON.stringify(body)
+ }).then(function (response) {
+ ok = response.ok;
+ status = response.status;
+ return response.json();
+ }).then(function (result) {
+ if (!ok) {
+ result.status = status;
+ throw generateErrorFromResponse(result);
+ }
+ // fail the entire request if the result contains an error
+ result.rows.forEach(function (row) {
+ /* istanbul ignore if */
+ if (row.value && row.value.error && row.value.error === "builtin_reduce_error") {
+ throw new Error(row.reason);
+ }
+ });
+ return result;
+ }).then(postprocessAttachments(opts));
}
// We are using a temporary view, terrible for performance, good for testing
@@ -310,10 +318,21 @@
body[key] = fun[key].toString();
}
});
- return db.request({
+
+ return db.fetch('_temp_view' + params, {
+ headers: new Headers({'Content-Type': 'application/json'}),
method: 'POST',
- url: '_temp_view' + params,
- body: body
+ body: JSON.stringify(body)
+ }).then(function (response) {
+ ok = response.ok;
+ status = response.status;
+ return response.json();
+ }).then(function (result) {
+ if (!ok) {
+ result.status = status;
+ throw generateErrorFromResponse(result);
+ }
+ return result;
}).then(postprocessAttachments(opts));
}
@@ -776,9 +795,11 @@
}
function httpViewCleanup(db) {
- return db.request({
- method: 'POST',
- url: '_view_cleanup'
+ return db.fetch('_view_cleanup', {
+ headers: new Headers({'Content-Type': 'application/json'}),
+ method: 'POST'
+ }).then(function (response) {
+ return response.json();
});
}
@@ -844,7 +865,7 @@
if (isRemote(db)) {
return httpQuery(db, fun, opts);
}
-
+
if (typeof fun !== 'string') {
// temp_view
checkQueryParseError(opts, fun);
@@ -946,4 +967,4 @@
};
}
-export default createAbstractMapReduce;
\ No newline at end of file
+export default createAbstractMapReduce;
diff --git a/packages/node_modules/pouchdb-adapter-http/src/index.js b/packages/node_modules/pouchdb-adapter-http/src/index.js
index 0af8907..104fb7d 100644
--- a/packages/node_modules/pouchdb-adapter-http/src/index.js
+++ b/packages/node_modules/pouchdb-adapter-http/src/index.js
@@ -5,8 +5,10 @@
var supportsBulkGetMap = {};
+import { generateErrorFromResponse } from 'pouchdb-errors';
import { nextTick } from 'pouchdb-utils';
-import ajaxCore from 'pouchdb-ajax';
+import { fetch, Headers, AbortController } from 'pouchdb-fetch';
+
import getArguments from 'argsarray';
import {
@@ -74,9 +76,7 @@
if (!opts.prefix) {
return false;
}
-
var protocol = parseUri(opts.prefix).protocol;
-
return protocol === 'http' || protocol === 'https';
}
@@ -151,44 +151,27 @@
var dbUrl = genDBUrl(host, '');
opts = clone(opts);
- var ajaxOpts = opts.ajax || {};
- if (opts.auth || host.auth) {
- var nAuth = opts.auth || host.auth;
- var str = nAuth.username + ':' + nAuth.password;
- var token = btoa(unescape(encodeURIComponent(str)));
- ajaxOpts.headers = ajaxOpts.headers || {};
- ajaxOpts.headers.Authorization = 'Basic ' + token;
- }
+ var ourFetch = function (url, options) {
- // Not strictly necessary, but we do this because numerous tests
- // rely on swapping ajax in and out.
- api._ajax = ajaxCore;
+ options = options || {};
+ options.headers = options.headers || new Headers();
- function ajax(userOpts, options, callback) {
- var reqAjax = (userOpts || {}).ajax || {};
- var reqOpts = Object.assign(clone(ajaxOpts), reqAjax, options);
- var defaultHeaders = clone(ajaxOpts.headers || {});
- reqOpts.headers = Object.assign(defaultHeaders, reqAjax.headers,
- options.headers || {});
- /* istanbul ignore if */
- if (api.constructor.listeners('debug').length) {
- api.constructor.emit('debug', ['http', reqOpts.method, reqOpts.url]);
+ if (opts.auth || host.auth) {
+ var nAuth = opts.auth || host.auth;
+ var str = nAuth.username + ':' + nAuth.password;
+ var token = btoa(unescape(encodeURIComponent(str)));
+ options.headers.set('Authorization', 'Basic ' + token);
}
- return api._ajax(reqOpts, callback);
- }
- function ajaxPromise(userOpts, opts) {
- return new Promise(function (resolve, reject) {
- ajax(userOpts, opts, function (err, res) {
- /* istanbul ignore if */
- if (err) {
- return reject(err);
- }
- resolve(res);
- });
+ var headers = opts.headers || {};
+ Object.keys(headers).forEach(function (key) {
+ options.headers.append(key, headers[key]);
});
- }
+
+ var fetchFun = opts.fetch || fetch;
+ return fetchFun(url, options);
+ };
function adapterFun(name, fun) {
return coreAdapterFun(name, getArguments(function (args) {
@@ -201,6 +184,54 @@
}));
}
+ function fetchJSON(url, options, callback) {
+
+ var result = {};
+
+ options = options || {};
+ options.headers = options.headers || new Headers();
+
+ if (!options.headers.get('Content-Type')) {
+ options.headers.set('Content-Type', 'application/json');
+ }
+ if (!options.headers.get('Accept')) {
+ options.headers.set('Accept', 'application/json');
+ }
+
+ return ourFetch(url, options).then(function (response) {
+ result.ok = response.ok;
+ result.status = response.status;
+ return response.json();
+ }).then(function (json) {
+ result.data = json;
+ if (!result.ok) {
+ result.data.status = result.status;
+ var err = generateErrorFromResponse(result.data);
+ if (callback) {
+ return callback(err);
+ } else {
+ throw err;
+ }
+ }
+
+ if (Array.isArray(result.data)) {
+ result.data = result.data.map(function (v) {
+ if (v.error || v.missing) {
+ return generateErrorFromResponse(v);
+ } else {
+ return v;
+ }
+ });
+ }
+
+ if (callback) {
+ callback(null, result.data);
+ } else {
+ return result;
+ }
+ });
+ }
+
var setupPromise;
function setup() {
@@ -215,12 +246,11 @@
return setupPromise;
}
- var checkExists = {method: 'GET', url: dbUrl};
- setupPromise = ajaxPromise({}, checkExists).catch(function (err) {
+ setupPromise = fetchJSON(dbUrl).catch(function (err) {
if (err && err.status && err.status === 404) {
// Doesnt exist, create it
explainError(404, 'PouchDB is just detecting if the remote exists.');
- return ajaxPromise({}, {method: 'PUT', url: dbUrl});
+ return fetchJSON(dbUrl, {method: 'PUT'});
} else {
return Promise.reject(err);
}
@@ -246,24 +276,24 @@
});
api._remote = true;
+
/* istanbul ignore next */
api.type = function () {
return 'http';
};
api.id = adapterFun('id', function (callback) {
- ajax({}, {method: 'GET', url: genUrl(host, '')}, function (err, result) {
+ ourFetch(genUrl(host, '')).then(function (response) {
+ return response.json();
+ }).then(function (result) {
var uuid = (result && result.uuid) ?
- (result.uuid + host.db) : genDBUrl(host, '');
+ (result.uuid + host.db) : genDBUrl(host, '');
callback(null, uuid);
+ }).catch(function (err) {
+ callback(err);
});
});
- api.request = adapterFun('request', function (options, callback) {
- options.url = genDBUrl(host, options.url);
- ajax({}, options, callback);
- });
-
// Sends a POST request to the host calling the couchdb _compact function
// version: The version of CouchDB it is running
api.compact = adapterFun('compact', function (opts, callback) {
@@ -272,10 +302,8 @@
opts = {};
}
opts = clone(opts);
- ajax(opts, {
- url: genDBUrl(host, '_compact'),
- method: 'POST'
- }, function () {
+
+ fetchJSON(genDBUrl(host, '_compact'), {method: 'POST'}).then(function () {
function ping() {
api.info(function (err, res) {
// CouchDB may send a "compact_running:true" if it's
@@ -308,18 +336,17 @@
if (opts.latest) {
params.latest = true;
}
- ajax(opts, {
- url: genDBUrl(host, '_bulk_get' + paramsToStr(params)),
+ fetchJSON(genDBUrl(host, '_bulk_get' + paramsToStr(params)), {
method: 'POST',
- body: { docs: opts.docs}
- }, function (err, result) {
- if (!err && opts.attachments && opts.binary) {
- result.results.forEach(function (res) {
+ body: JSON.stringify({ docs: opts.docs})
+ }).then(function (result) {
+ if (opts.attachments && opts.binary) {
+ result.data.results.forEach(function (res) {
res.docs.forEach(readAttachmentsAsBlobOrBuffer);
});
}
- cb(err, result);
- });
+ cb(null, result.data);
+ }).catch(cb);
}
/* istanbul ignore next */
@@ -342,7 +369,6 @@
for (var i = 0; i < numBatches; i++) {
var subOpts = pick(opts, ['revs', 'attachments', 'binary', 'latest']);
- subOpts.ajax = ajaxOpts;
subOpts.docs = opts.docs.slice(i * batchSize,
Math.min(opts.docs.length, (i + 1) * batchSize));
bulkGetShim(self, subOpts, onResult(i));
@@ -382,20 +408,21 @@
// version: The version of CouchDB it is running
api._info = function (callback) {
setup().then(function () {
- ajax({}, {
- method: 'GET',
- url: genDBUrl(host, '')
- }, function (err, res) {
- /* istanbul ignore next */
- if (err) {
- return callback(err);
- }
- res.host = genDBUrl(host, '');
- callback(null, res);
- });
+ return ourFetch(genDBUrl(host, ''));
+ }).then(function (response) {
+ return response.json();
+ }).then(function (info) {
+ info.host = genDBUrl(host, '');
+ callback(null, info);
}).catch(callback);
};
+ api.fetch = function (path, options) {
+ return setup().then(function () {
+ return ourFetch(genDBUrl(host, path), options);
+ });
+ };
+
// Get the document with the given id from the database given by host.
// The id could be solely the _id in the database, or it may be a
// _design/ID or _local/ID path
@@ -444,12 +471,6 @@
id = encodeDocId(id);
- // Set the options for the ajax call
- var options = {
- method: 'GET',
- url: genDBUrl(host, id + paramsToStr(params))
- };
-
function fetchAttachments(doc) {
var atts = doc._attachments;
var filenames = atts && Object.keys(atts);
@@ -460,16 +481,23 @@
// Sync Gateway would normally send it back as multipart/mixed,
// which we cannot parse. Also, this is more efficient than
// receiving attachments as base64-encoded strings.
- function fetch(filename) {
+ function fetchData(filename) {
var att = atts[filename];
var path = encodeDocId(doc._id) + '/' + encodeAttachmentId(filename) +
- '?rev=' + doc._rev;
- return ajaxPromise(opts, {
- method: 'GET',
- url: genDBUrl(host, path),
- binary: true
+ '?rev=' + doc._rev;
+ return ourFetch(genDBUrl(host, path)).then(function (response) {
+ if (typeof process !== 'undefined' && !process.browser) {
+ return response.buffer();
+ } else {
+ /* istanbul ignore next */
+ return response.blob();
+ }
}).then(function (blob) {
if (opts.binary) {
+ // TODO: Can we remove this?
+ if (typeof process !== 'undefined' && !process.browser) {
+ blob.type = att.content_type;
+ }
return blob;
}
return new Promise(function (resolve) {
@@ -484,7 +512,7 @@
var promiseFactories = filenames.map(function (filename) {
return function () {
- return fetch(filename);
+ return fetchData(filename);
};
});
@@ -504,13 +532,14 @@
return fetchAttachments(docOrDocs);
}
- ajaxPromise(opts, options).then(function (res) {
+ var url = genDBUrl(host, id + paramsToStr(params));
+ fetchJSON(url).then(function (res) {
return Promise.resolve().then(function () {
if (opts.attachments) {
- return fetchAllAttachments(res);
+ return fetchAllAttachments(res.data);
}
}).then(function () {
- callback(null, res);
+ callback(null, res.data);
});
}).catch(function (e) {
e.docId = id;
@@ -518,9 +547,9 @@
});
});
+
// Delete the document given by doc from the database given by host.
- api.remove = adapterFun('remove',
- function (docOrId, optsOrRev, opts, callback) {
+ api.remove = adapterFun('remove', function (docOrId, optsOrRev, opts, cb) {
var doc;
if (typeof optsOrRev === 'string') {
// id, rev, opts, callback style
@@ -529,28 +558,25 @@
_rev: optsOrRev
};
if (typeof opts === 'function') {
- callback = opts;
+ cb = opts;
opts = {};
}
} else {
// doc, opts, callback style
doc = docOrId;
if (typeof optsOrRev === 'function') {
- callback = optsOrRev;
+ cb = optsOrRev;
opts = {};
} else {
- callback = opts;
+ cb = opts;
opts = optsOrRev;
}
}
var rev = (doc._rev || opts.rev);
+ var url = genDBUrl(host, encodeDocId(doc._id)) + '?rev=' + rev;
- // Delete the document
- ajax(opts, {
- method: 'DELETE',
- url: genDBUrl(host, encodeDocId(doc._id)) + '?rev=' + rev
- }, callback);
+ fetchJSON(url, {method: 'DELETE'}, cb);
});
function encodeAttachmentId(attachmentId) {
@@ -558,43 +584,55 @@
}
// Get the attachment
- api.getAttachment =
- adapterFun('getAttachment', function (docId, attachmentId, opts,
- callback) {
+ api.getAttachment = adapterFun('getAttachment', function (docId, attachmentId,
+ opts, callback) {
if (typeof opts === 'function') {
callback = opts;
opts = {};
}
var params = opts.rev ? ('?rev=' + opts.rev) : '';
var url = genDBUrl(host, encodeDocId(docId)) + '/' +
- encodeAttachmentId(attachmentId) + params;
- ajax(opts, {
- method: 'GET',
- url: url,
- binary: true
- }, callback);
+ encodeAttachmentId(attachmentId) + params;
+ var contentType;
+ ourFetch(url, {method: 'GET'}).then(function (response) {
+ contentType = response.headers.get('content-type');
+ if (!response.ok) {
+ throw response;
+ } else {
+ if (typeof process !== 'undefined' && !process.browser) {
+ return response.buffer();
+ } else {
+ /* istanbul ignore next */
+ return response.blob();
+ }
+ }
+ }).then(function (blob) {
+ // TODO: also remove
+ if (typeof process !== 'undefined' && !process.browser) {
+ blob.type = contentType;
+ }
+ callback(null, blob);
+ }).catch(function (err) {
+ callback(err);
+ });
});
// Remove the attachment given by the id and rev
- api.removeAttachment =
- adapterFun('removeAttachment', function (docId, attachmentId, rev,
- callback) {
-
+ api.removeAttachment = adapterFun('removeAttachment', function (docId,
+ attachmentId,
+ rev,
+ callback) {
var url = genDBUrl(host, encodeDocId(docId) + '/' +
- encodeAttachmentId(attachmentId)) + '?rev=' + rev;
-
- ajax({}, {
- method: 'DELETE',
- url: url
- }, callback);
+ encodeAttachmentId(attachmentId)) + '?rev=' + rev;
+ fetchJSON(url, {method: 'DELETE'}, callback);
});
// Add the attachment given by blob and its contentType property
// to the document with the given id, the revision given by rev, and
// add it to the database given by host.
- api.putAttachment =
- adapterFun('putAttachment', function (docId, attachmentId, rev, blob,
- type, callback) {
+ api.putAttachment = adapterFun('putAttachment', function (docId, attachmentId,
+ rev, blob,
+ type, callback) {
if (typeof type === 'function') {
callback = type;
type = blob;
@@ -619,16 +657,12 @@
blob = binary ? binStringToBluffer(binary, type) : '';
}
- var opts = {
- headers: {'Content-Type': type},
- method: 'PUT',
- url: url,
- processData: false,
- body: blob,
- timeout: ajaxOpts.timeout || 60000
- };
// Add the attachment
- ajax({}, opts, callback);
+ fetchJSON(url, {
+ headers: new Headers({'Content-Type': type}),
+ method: 'PUT',
+ body: blob
+ }, callback);
});
// Update/create multiple documents given by req in the database
@@ -643,17 +677,10 @@
return Promise.all(req.docs.map(preprocessAttachments));
}).then(function () {
// Update/create the documents
- ajax(opts, {
+ return fetchJSON(genDBUrl(host, '_bulk_docs'), {
method: 'POST',
- url: genDBUrl(host, '_bulk_docs'),
- timeout: opts.timeout,
- body: req
- }, function (err, results) {
- if (err) {
- return callback(err);
- }
- callback(null, results);
- });
+ body: JSON.stringify(req)
+ }, callback);
}).catch(callback);
};
@@ -663,19 +690,16 @@
setup().then(function () {
return preprocessAttachments(doc);
}).then(function () {
- // Update/create the document
- ajax(opts, {
+ return fetchJSON(genDBUrl(host, encodeDocId(doc._id)), {
method: 'PUT',
- url: genDBUrl(host, encodeDocId(doc._id)),
- body: doc
- }, function (err, result) {
- if (err) {
- err.docId = doc && doc._id;
- return callback(err);
- }
- callback(null, result);
+ body: JSON.stringify(doc)
});
- }).catch(callback);
+ }).then(function (result) {
+ callback(null, result.data);
+ }).catch(function (err) {
+ err.docId = doc && doc._id;
+ callback(err);
+ });
};
@@ -754,16 +778,14 @@
body = {keys: opts.keys};
}
- // Get the document listing
- ajaxPromise(opts, {
- method: method,
- url: genDBUrl(host, '_all_docs' + paramStr),
- body: body
- }).then(function (res) {
+ fetchJSON(genDBUrl(host, '_all_docs' + paramStr), {
+ method: method,
+ body: JSON.stringify(body)
+ }).then(function (result) {
if (opts.include_docs && opts.attachments && opts.binary) {
- res.rows.forEach(readAttachmentsAsBlobOrBuffer);
+ result.data.rows.forEach(readAttachmentsAsBlobOrBuffer);
}
- callback(null, res);
+ callback(null, result.data);
}).catch(callback);
});
@@ -784,9 +806,7 @@
opts.heartbeat = DEFAULT_HEARTBEAT;
}
- var requestTimeout = ('timeout' in opts) ? opts.timeout :
- ('timeout' in ajaxOpts) ? ajaxOpts.timeout :
- 30 * 1000;
+ var requestTimeout = ('timeout' in opts) ? opts.timeout : 30 * 1000;
// ensure CHANGES_TIMEOUT_BUFFER applies
if ('timeout' in opts && opts.timeout &&
@@ -794,6 +814,7 @@
requestTimeout = opts.timeout + CHANGES_TIMEOUT_BUFFER;
}
+ /* istanbul ignore if */
if ('heartbeat' in opts && opts.heartbeat &&
(requestTimeout - opts.heartbeat) < CHANGES_TIMEOUT_BUFFER) {
requestTimeout = opts.heartbeat + CHANGES_TIMEOUT_BUFFER;
@@ -895,12 +916,12 @@
body = {selector: opts.selector };
}
- var xhr;
+ var controller = new AbortController();
var lastFetchedSeq;
// Get all the changes starting wtih the one immediately after the
// sequence number given by since.
- var fetch = function (since, callback) {
+ var fetchData = function (since, callback) {
if (opts.aborted) {
return;
}
@@ -921,11 +942,11 @@
}
// Set the options for the ajax call
- var xhrOpts = {
+ var url = genDBUrl(host, '_changes' + paramsToStr(params));
+ var fetchOpts = {
+ signal: controller.signal,
method: method,
- url: genDBUrl(host, '_changes' + paramsToStr(params)),
- timeout: requestTimeout,
- body: body
+ body: JSON.stringify(body)
};
lastFetchedSeq = since;
@@ -936,7 +957,7 @@
// Get the changes
setup().then(function () {
- xhr = ajax(opts, xhrOpts, callback);
+ return fetchJSON(url, fetchOpts, callback);
}).catch(callback);
};
@@ -1001,22 +1022,20 @@
if ((opts.continuous && !(limit && leftToFetch <= 0)) || !finished) {
// Queue a call to fetch again with the newest sequence number
- nextTick(function () { fetch(lastFetchedSeq, fetched); });
+ nextTick(function () { fetchData(lastFetchedSeq, fetched); });
} else {
// We're done, call the callback
opts.complete(null, results);
}
};
- fetch(opts.since || 0, fetched);
+ fetchData(opts.since || 0, fetched);
// Return a method to cancel this method from processing any more
return {
cancel: function () {
opts.aborted = true;
- if (xhr) {
- xhr.abort();
- }
+ controller.abort();
}
};
};
@@ -1032,10 +1051,9 @@
}
// Get the missing document/revision IDs
- ajax(opts, {
+ fetchJSON(genDBUrl(host, '_revs_diff'), {
method: 'POST',
- url: genDBUrl(host, '_revs_diff'),
- body: req
+ body: JSON.stringify(req)
}, callback);
});
@@ -1044,14 +1062,15 @@
};
api._destroy = function (options, callback) {
- ajax(options, {
- url: genDBUrl(host, ''),
- method: 'DELETE'
- }, function (err, resp) {
- if (err && err.status && err.status !== 404) {
- return callback(err);
+ fetchJSON(genDBUrl(host, ''), {method: 'DELETE'}).then(function (json) {
+ callback(null, json);
+ }).catch(function (err) {
+ /* istanbul ignore if */
+ if (err.status === 404) {
+ callback(null, {ok: true});
+ } else {
+ callback(err);
}
- callback(null, resp);
});
};
}
diff --git a/packages/node_modules/pouchdb-core/src/setup.js b/packages/node_modules/pouchdb-core/src/setup.js
index 376a1d5..ed085d5 100644
--- a/packages/node_modules/pouchdb-core/src/setup.js
+++ b/packages/node_modules/pouchdb-core/src/setup.js
@@ -1,8 +1,9 @@
-
+'use strict';
import PouchDB from './constructor';
import inherits from 'inherits';
import { EventEmitter as EE } from 'events';
+import { fetch } from 'pouchdb-fetch';
PouchDB.adapters = {};
PouchDB.preferredAdapters = [];
@@ -122,4 +123,8 @@
return PouchAlt;
};
+PouchDB.fetch = function (url, opts) {
+ return fetch(url, opts);
+};
+
export default PouchDB;
diff --git a/packages/node_modules/pouchdb-fetch/LICENSE b/packages/node_modules/pouchdb-fetch/LICENSE
new file mode 100644
index 0000000..f6cd2bc
--- /dev/null
+++ b/packages/node_modules/pouchdb-fetch/LICENSE
@@ -0,0 +1,202 @@
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ 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.
diff --git a/packages/node_modules/pouchdb-fetch/README.md b/packages/node_modules/pouchdb-fetch/README.md
new file mode 100644
index 0000000..5f18c47
--- /dev/null
+++ b/packages/node_modules/pouchdb-fetch/README.md
@@ -0,0 +1,24 @@
+pouchdb-fetch 
+======
+
+PouchDB's fetch() method.
+
+### Usage
+
+```bash
+npm install --save-exact pouchdb-fetch
+```
+
+For full API documentation and guides on PouchDB, see [PouchDB.com](http://pouchdb.com/). For details on PouchDB sub-packages, see the [Custom Builds documentation](http://pouchdb.com/custom.html).
+
+### Warning: semver-free zone!
+
+This package is conceptually an internal API used by PouchDB or its plugins. It does not follow semantic versioning (semver), and rather its version is pegged to PouchDB's. Use exact versions when installing, e.g. with `--save-exact`.
+
+### Source
+
+PouchDB and its sub-packages are distributed as a [monorepo](https://github.com/babel/babel/blob/master/doc/design/monorepo.md).
+
+For a full list of packages, see [the GitHub source](https://github.com/pouchdb/pouchdb/tree/master/packages).
+
+
diff --git a/packages/node_modules/pouchdb-fetch/package.json b/packages/node_modules/pouchdb-fetch/package.json
new file mode 100644
index 0000000..e4ee097
--- /dev/null
+++ b/packages/node_modules/pouchdb-fetch/package.json
@@ -0,0 +1,15 @@
+{
+ "name": "pouchdb-fetch",
+ "version": "7.0.0-prerelease",
+ "description": "PouchDB's fetch() method.",
+ "main": "./lib/index.js",
+ "keywords": [],
+ "author": "Dale Harvey <dale@arandomurl.com>",
+ "license": "Apache-2.0",
+ "repository": "https://github.com/pouchdb/pouchdb",
+ "jsnext:main": "./src/index.js",
+ "browser": {
+ "./lib/index.js": "./lib/index-browser.js",
+ "./src/fetch.js": "./src/fetch-browser.js"
+ }
+}
diff --git a/packages/node_modules/pouchdb-fetch/src/fetch-browser.js b/packages/node_modules/pouchdb-fetch/src/fetch-browser.js
new file mode 100644
index 0000000..02d2969
--- /dev/null
+++ b/packages/node_modules/pouchdb-fetch/src/fetch-browser.js
@@ -0,0 +1,12 @@
+'use strict';
+
+// AbortController was introduced quite a while after fetch and
+// isnt required for PouchDB to function so polyfill if needed
+var a = (typeof AbortController !== 'undefined')
+ ? AbortController
+ : function () { return {abort: function () {}}; };
+
+var f = fetch;
+var h = Headers;
+
+export {f as fetch, h as Headers, a as AbortController};
diff --git a/packages/node_modules/pouchdb-fetch/src/fetch.js b/packages/node_modules/pouchdb-fetch/src/fetch.js
new file mode 100644
index 0000000..1058676
--- /dev/null
+++ b/packages/node_modules/pouchdb-fetch/src/fetch.js
@@ -0,0 +1,15 @@
+'use strict';
+
+import nodeFetch from 'node-fetch';
+import fetchCookie from 'fetch-cookie';
+
+var fetch = fetchCookie(nodeFetch);
+
+/* We can fake the abort, the http adapter keeps track
+ of ignoring the result */
+function AbortController() {
+ return {abort: function () {}};
+}
+
+var Headers = nodeFetch.Headers;
+export {fetch, Headers, AbortController};
diff --git a/packages/node_modules/pouchdb-fetch/src/index.js b/packages/node_modules/pouchdb-fetch/src/index.js
new file mode 100644
index 0000000..f933006
--- /dev/null
+++ b/packages/node_modules/pouchdb-fetch/src/index.js
@@ -0,0 +1 @@
+export {fetch, Headers, AbortController} from './fetch';
diff --git a/packages/node_modules/pouchdb-find/src/adapters/http/index.js b/packages/node_modules/pouchdb-find/src/adapters/http/index.js
index 775db6f..6eae059 100644
--- a/packages/node_modules/pouchdb-find/src/adapters/http/index.js
+++ b/packages/node_modules/pouchdb-find/src/adapters/http/index.js
@@ -1,35 +1,50 @@
+import { generateErrorFromResponse } from 'pouchdb-errors';
+import { Headers } from 'pouchdb-fetch';
import massageCreateIndexRequest from '../../massageCreateIndexRequest';
+function dbFetch(db, path, opts, callback) {
+ var status, ok;
+ opts.headers = new Headers({'Content-type': 'application/json'});
+ db.fetch(path, opts).then(function (response) {
+ status = response.status;
+ ok = response.ok;
+ return response.json();
+ }).then(function (json) {
+ if (!ok) {
+ json.status = status;
+ var err = generateErrorFromResponse(json);
+ callback(err);
+ } else {
+ callback(null, json);
+ }
+ });
+}
+
function createIndex(db, requestDef, callback) {
requestDef = massageCreateIndexRequest(requestDef);
-
- db.request({
+ dbFetch(db, '_index', {
method: 'POST',
- url: '_index',
- body: requestDef
+ body: JSON.stringify(requestDef)
}, callback);
}
function find(db, requestDef, callback) {
- db.request({
+ dbFetch(db, '_find', {
method: 'POST',
- url: '_find',
- body: requestDef
+ body: JSON.stringify(requestDef)
}, callback);
}
function explain(db, requestDef, callback) {
- db.request({
+ dbFetch(db, '_explain', {
method: 'POST',
- url: '_explain',
- body: requestDef
+ body: JSON.stringify(requestDef)
}, callback);
}
function getIndexes(db, callback) {
- db.request({
- method: 'GET',
- url: '_index'
+ dbFetch(db, '_index', {
+ method: 'GET'
}, callback);
}
@@ -50,10 +65,7 @@
var url = '_index/' + [ddoc, type, name].map(encodeURIComponent).join('/');
- db.request({
- method: 'DELETE',
- url: url
- }, callback);
+ dbFetch(db, url, {method: 'DELETE'}, callback);
}
export {
diff --git a/packages/node_modules/pouchdb-for-coverage/src/index.js b/packages/node_modules/pouchdb-for-coverage/src/index.js
index 966a3c9..9476232 100644
--- a/packages/node_modules/pouchdb-for-coverage/src/index.js
+++ b/packages/node_modules/pouchdb-for-coverage/src/index.js
@@ -1,12 +1,10 @@
import PouchDB from './pouchdb';
-import ajax from 'pouchdb-ajax';
import utils from './utils';
import errors from './errors';
import * as collate from 'pouchdb-collate';
// explicitly include pouchdb-find so coverage captures it correctly
import find from 'pouchdb-find';
-PouchDB.ajax = ajax;
PouchDB.utils = utils;
PouchDB.Errors = errors;
PouchDB.collate = collate;
diff --git a/packages/node_modules/pouchdb-for-coverage/src/utils.js b/packages/node_modules/pouchdb-for-coverage/src/utils.js
index f50884d..5c2a559 100644
--- a/packages/node_modules/pouchdb-for-coverage/src/utils.js
+++ b/packages/node_modules/pouchdb-for-coverage/src/utils.js
@@ -5,8 +5,6 @@
// but for practical reasons (legacy code, test code, etc.) this is still here.
//
-import ajax from 'pouchdb-ajax';
-
import {
parseUri,
uuid,
@@ -50,7 +48,6 @@
import checkpointer from 'pouchdb-checkpointer';
export default {
- ajax: ajax,
blob: blob,
parseUri: parseUri,
uuid: uuid,
diff --git a/packages/node_modules/pouchdb-replication/src/backoff.js b/packages/node_modules/pouchdb-replication/src/backoff.js
index c480931..e956b7f 100644
--- a/packages/node_modules/pouchdb-replication/src/backoff.js
+++ b/packages/node_modules/pouchdb-replication/src/backoff.js
@@ -8,6 +8,7 @@
returnValue.removeAllListeners();
return;
}
+ /* istanbul ignore if */
if (typeof opts.back_off_function !== 'function') {
opts.back_off_function = defaultBackOff;
}
diff --git a/tests/component/test.ajax.js b/tests/component/test.ajax.js
index 37f13a5..d0661a3 100644
--- a/tests/component/test.ajax.js
+++ b/tests/component/test.ajax.js
@@ -16,23 +16,14 @@
}
});
server.listen(6000, function () {
- PouchDB.ajax({
- method: 'GET',
- url: 'http://127.0.0.1:6000/install-cookie',
- timeout: 10
- }, function (err, res) {
- should.equal(res.ok, true, "Server not responding");
-
- PouchDB.ajax({
- method: 'GET',
- url: 'http://127.0.0.1:6000/check-cookie',
- timeout: 10
- }, function (err, res) {
- server.close();
-
- should.equal(res.ok, true, "Cookie not set");
- done();
- });
+ PouchDB.fetch('http://127.0.0.1:6000/install-cookie').then(function () {
+ return PouchDB.fetch('http://127.0.0.1:6000/check-cookie');
+ }).then(function (response) {
+ return response.json();
+ }).then(function (res) {
+ server.close();
+ should.equal(res.ok, true, "Cookie not set");
+ done();
});
});
});
diff --git a/tests/component/test.auth.js b/tests/component/test.auth.js
index c66aeac..81b4547 100644
--- a/tests/component/test.auth.js
+++ b/tests/component/test.auth.js
@@ -13,8 +13,8 @@
before(function (done) {
server = http.createServer(function (req, res) {
headers = req.headers;
- res.writeHead(200, {'Content-Type': 'text/plain'});
- res.end('');
+ res.writeHead(200, {'Content-Type': 'application/json'});
+ res.end('{}');
});
server.listen(PORT, done);
});
diff --git a/tests/component/test.error_response.js b/tests/component/test.error_response.js
deleted file mode 100644
index 03d3aeb..0000000
--- a/tests/component/test.error_response.js
+++ /dev/null
@@ -1,23 +0,0 @@
-'use strict';
-
-var nock = require('nock');
-var PouchDB = require('../../packages/node_modules/pouchdb-for-coverage');
-
-require('chai').should();
-
-describe('test.error_response.js', function () {
-
- it('Test we get correct looking error', function () {
-
- nock('http://example.com')
- .get('/test/')
- .reply(200, {})
- .get('/test/test');
-
- var db = new PouchDB('http://example.com/test');
- return db.get('test').catch(function (err) {
- err.status.should.equal(404);
- });
- });
-
-});
diff --git a/tests/component/test.headers.js b/tests/component/test.headers.js
index 370707c..99dc9c5 100644
--- a/tests/component/test.headers.js
+++ b/tests/component/test.headers.js
@@ -24,7 +24,7 @@
});
it('Test headers are sent correctly', function () {
- var opts = {ajax: {headers: {foo: 'bar'}}};
+ var opts = {headers: {foo: 'bar'}};
var url = 'http://127.0.0.1:' + PORT;
return new PouchDB(url, opts).info().then(function () {
should.equal(headers.foo, 'bar');
@@ -39,48 +39,6 @@
});
});
- it('Test headers are sent correctly on GET request', function () {
- var db = new PouchDB('http://127.0.0.1:' + PORT);
- var opts = { ajax: { headers: { ick: "slick" } } };
- return db.get('fake', opts).then(function () {
- should.equal(headers.ick, 'slick');
- });
- });
-
- it('3491 Test headers are sent correctly on put', function () {
- var db = new PouchDB('http://127.0.0.1:' + PORT);
- var opts = { ajax: { headers: { ick: "slick" } } };
- return db.post({'fake': 'obj'}, opts).then(function () {
- should.equal(headers.ick, 'slick');
- });
- });
-
- it('3491 Test headers are sent correctly on changes', function () {
- var db = new PouchDB('http://127.0.0.1:' + PORT);
- var opts = { ajax: { headers: { ick: "slick" } } };
- return db.changes(opts).then(function () {
- should.equal(headers.ick, 'slick');
- });
- });
-
- it('3491 Test headers are sent correctly on destroy', function () {
- var db = new PouchDB('http://127.0.0.1:' + PORT);
- var opts = { ajax: { headers: { ick: "slick" } } };
- return db.destroy(opts).then(function () {
- should.equal(headers.ick, 'slick');
- });
- });
-
- it('Test that we combine local and global ajax options', function () {
- var opts = { ajax: { headers: { aheader: 'whyyes' } } };
- var db = new PouchDB('http://127.0.0.1:' + PORT, opts);
- var getOpts = {ajax: { headers: { ick: "slick", aheader: "override!" } } };
- return db.get('fake', getOpts).then(function () {
- should.equal(headers.ick, 'slick');
- should.equal(headers.aheader, 'override!');
- });
- });
-
it('4450 Test headers are sent correctly on put', function () {
var opts = {auth: {username: 'foo', password: 'bar'}};
var db = new PouchDB('http://127.0.0.1:' + PORT, opts);
diff --git a/tests/integration/index.html b/tests/integration/index.html
index 383faaf..7927601 100644
--- a/tests/integration/index.html
+++ b/tests/integration/index.html
@@ -8,6 +8,7 @@
<body>
<div id="mocha"></div>
<script src="../../node_modules/lie/dist/lie.polyfill.js"></script>
+ <script src="../../node_modules/whatwg-fetch/fetch.js"></script>
<script src="../../node_modules/mocha/mocha.js"></script>
<script src="../../node_modules/chai/chai.js"></script>
<script src="../../node_modules/chai-as-promised/lib/chai-as-promised.js"></script>
diff --git a/tests/integration/test.ajax.js b/tests/integration/test.ajax.js
deleted file mode 100644
index b9bab17..0000000
--- a/tests/integration/test.ajax.js
+++ /dev/null
@@ -1,30 +0,0 @@
-'use strict';
-
-var adapters = ['http', 'local'];
-
-
-adapters.forEach(function (adapter) {
-
- describe('test.ajax.js-' + adapter, function () {
-
- it('#5061 ajax returns ETIMEDOUT error on timeout', function (done) {
- this.timeout(240000);
- testUtils.ajax({
- method: 'GET',
- url: 'http://192.0.2.1/',
- timeout: 10
- }, function (err, res) {
- // here's the test, we should get an 'err' response
- should.exist(err);
- if (err.code) { // xhr
- err.code.should.match(/(ESOCKETTIMEDOUT|ETIMEDOUT|ENETUNREACH|EAGAIN|ECONNREFUSED)/);
- } else { // fetch
- err.status.should.equal(500);
- }
- should.not.exist(res);
- done();
- });
- });
- });
-});
-
diff --git a/tests/integration/test.attachments.js b/tests/integration/test.attachments.js
index b28c5e2..43f9f09 100644
--- a/tests/integration/test.attachments.js
+++ b/tests/integration/test.attachments.js
@@ -2644,14 +2644,6 @@
});
});
- it('Test synchronous getAttachment', function (done) {
- var db = new PouchDB(dbs.name);
- db.getAttachment('unexistent', 'attachment', function (err) {
- should.exist(err, 'Correctly returned error');
- done();
- });
- });
-
it('Test synchronous putAttachment with text data', function (done) {
var db = new PouchDB(dbs.name);
var blob = testUtils.makeBlob('foobaz', 'text/plain');
@@ -3069,61 +3061,6 @@
});
});
- if (typeof process === 'undefined' || process.browser) {
- it('test stored URL content type of png data', function (done) {
- var db = new PouchDB(dbs.name);
- db.put({ _id: 'foo' }, function () {
- db.get('foo', function (err, doc) {
- var data = pngAttDoc._attachments['foo.png'].data;
- var blob = testUtils.binaryStringToBlob(
- testUtils.atob(data), 'image/png');
- if (typeof URL === 'undefined') {
- // phantomjs doesn't have this, give up on this test
- return done();
- }
- var checkedOnce = false;
- function checkBlobType(blob, cb) {
- var url = URL.createObjectURL(blob);
- testUtils.ajax({
- url: url,
- cache: true,
- binary: true
- }, function (err, res) {
- if (err && err.status === 500) {
- // firefox won't let us use ajax to get the blob.
- // too bad, but firefox wasn't the problem anyway
- return done();
- }
- should.not.exist(err, 'ajax gotten');
- if (!checkedOnce) {
- checkedOnce = true;
- if (res.type !== 'image/png') {
- // in Safari/iOS 7, blob URLs are missing
- // the content type even without storing them.
- // so just give up.
- return done();
- }
- } else {
- res.type.should.equal('image/png');
- }
- cb();
- });
- }
- checkBlobType(blob, function () {
- db.putAttachment('foo', 'foo.png', doc._rev, blob, 'image/png',
- function (err) {
- should.not.exist(err, 'attachment inserted');
- db.getAttachment('foo', 'foo.png', function (err, blob) {
- should.not.exist(err, 'attachment gotten');
- checkBlobType(blob, done);
- });
- });
- });
- });
- });
- });
- }
-
it('#3008 test correct encoding/decoding of \\u0000 etc.', function () {
var base64 =
diff --git a/tests/integration/test.http.js b/tests/integration/test.http.js
index 7dda309..e1fa5b4 100644
--- a/tests/integration/test.http.js
+++ b/tests/integration/test.http.js
@@ -33,31 +33,29 @@
it('Issue 1269 redundant _changes requests', function (done) {
var docs = [];
var num = 100;
+ var callCount = 0;
for (var i = 0; i < num; i++) {
docs.push({
_id: 'doc_' + i,
foo: 'bar_' + i
});
}
- var db = new PouchDB(dbs.name);
+ var db = new PouchDB(dbs.name, {
+ fetch: function (url, opts) {
+ if (/_changes/.test(url)) {
+ callCount++;
+ }
+ return PouchDB.fetch(url, opts);
+ }
+ });
db.bulkDocs({ docs: docs }, function () {
db.info(function (err, info) {
var update_seq = info.update_seq;
-
- var callCount = 0;
- var ajax = db._ajax;
- db._ajax = function (opts) {
- if (/_changes/.test(opts.url)) {
- callCount++;
- }
- ajax.apply(this, arguments);
- };
db.changes({
since: update_seq
}).on('change', function () {
}).on('complete', function () {
callCount.should.equal(1, 'One _changes call to complete changes');
- db._ajax = ajax;
done();
}).on('error', done);
});
@@ -79,54 +77,13 @@
});
it('Properly escape url params #4008', function () {
- var db = new PouchDB(dbs.name);
- var ajax = db._ajax;
- db._ajax = function (opts) {
- opts.url.should.not.contain('[');
- ajax.apply(this, arguments);
- };
- return db.changes({doc_ids: ['1']}).then(function () {
- db._ajax = ajax;
- });
- });
-
- it('Allows the "ajax timeout" to extend "changes timeout"', function (done) {
- var timeout = 120000;
var db = new PouchDB(dbs.name, {
- skip_setup: true,
- ajax: {
- timeout: timeout
+ fetch: function (url, opts) {
+ url.should.not.contain('[');
+ return PouchDB.fetch(url, opts);
}
});
-
- var ajax = db._ajax;
- var ajaxOpts;
- db._ajax = function (opts) {
- if (/changes/.test(opts.url)) {
- ajaxOpts = opts;
- changes.cancel();
- }
- ajax.apply(this, arguments);
- };
-
- var changes = db.changes();
-
- changes.on('complete', function () {
- should.exist(ajaxOpts);
- ajaxOpts.timeout.should.equal(timeout);
- db._ajax = ajax;
- done();
- });
-
- });
-
- it('Test custom header', function () {
- var db = new PouchDB(dbs.name, {
- headers: {
- 'X-Custom': 'some-custom-header'
- }
- });
- return db.info();
+ return db.changes({doc_ids: ['1']});
});
it('test url too long error for allDocs()', function () {
@@ -179,70 +136,6 @@
});
});
- it('Issue 6132 - default headers not merged', function () {
- var db = new PouchDB(dbs.name, {
- ajax: {
- // need to use a header that CouchDB allows through CORS
- headers: { "x-csrf-token": "bar" }
- }
- });
-
- var ajax = db._ajax;
- var tested = false;
- db._ajax = function (opts) {
- if (opts.headers && opts.headers['Content-Type']) {
- if (opts.headers["x-csrf-token"] !== 'bar') {
- throw new Error('default header x-csrf-token expected');
- }
- tested = true;
- }
-
- ajax.apply(this, arguments);
- };
-
- return db.putAttachment('mydoc', 'att.txt', testUtils.btoa('abc'), 'text/plain')
- .then(function () {
- if (!tested) {
- throw new Error('header assertion skipped in test');
- }
- });
- });
-
- it('heartbeart cannot be > request timeout', function (done) {
- var timeout = 500;
- var heartbeat = 1000;
- var CHANGES_TIMEOUT_BUFFER = 5000;
- var db = new PouchDB(dbs.name, {
- skip_setup: true,
- ajax: {
- timeout: timeout
- }
- });
-
- var ajax = db._ajax;
- var ajaxOpts;
- db._ajax = function (opts) {
- if (/changes/.test(opts.url)) {
- ajaxOpts = opts;
- changes.cancel();
- }
- ajax.apply(this, arguments);
- };
-
- var changes = db.changes({
- heartbeat: heartbeat
- });
-
- changes.on('complete', function () {
- should.exist(ajaxOpts);
- ajaxOpts.timeout.should.equal(heartbeat + CHANGES_TIMEOUT_BUFFER);
- ajaxOpts.url.indexOf("heartbeat=" + heartbeat).should.not.equal(-1);
- db._ajax = ajax;
- done();
- });
-
- });
-
it('changes respects seq_interval', function (done) {
var docs = [
{_id: '0', integer: 0, string: '0'},
diff --git a/tests/integration/test.replication.js b/tests/integration/test.replication.js
index 988df53..012d236 100644
--- a/tests/integration/test.replication.js
+++ b/tests/integration/test.replication.js
@@ -4184,23 +4184,21 @@
return true;
}
- var db = new PouchDB(dbs.name);
- var remote = new PouchDB(dbs.remote);
-
var seenHeartBeat = false;
- var ajax = remote._ajax;
- remote._ajax = function (opts) {
- if (/heartbeat/.test(opts.url)) {
- seenHeartBeat = true;
+ var db = new PouchDB(dbs.name);
+ var remote = new PouchDB(dbs.remote, {
+ fetch: function (url, opts) {
+ if (/heartbeat/.test(url)) {
+ seenHeartBeat = true;
+ }
+ return PouchDB.fetch(url, opts);
}
- ajax.apply(this, arguments);
- };
+ });
return remote.bulkDocs([{foo: 'bar'}]).then(function () {
return db.replicate.from(remote, {heartbeat: 10});
}).then(function () {
seenHeartBeat.should.equal(true);
- remote._ajax = ajax;
});
});
@@ -4210,24 +4208,21 @@
return true;
}
+ var seenTimeout;
var db = new PouchDB(dbs.name);
- var remote = new PouchDB(dbs.remote);
-
- var seenTimeout = false;
- var ajax = remote._ajax;
- remote._ajax = function (opts) {
- // the http adapter takes 5s off the provided timeout
- if (/timeout=20000/.test(opts.url)) {
- seenTimeout = true;
+ var remote = new PouchDB(dbs.remote, {
+ fetch: function (url, opts) {
+ if (/timeout=20000/.test(url)) {
+ seenTimeout = true;
+ }
+ return PouchDB.fetch(url, opts);
}
- ajax.apply(this, arguments);
- };
+ });
return remote.bulkDocs([{foo: 'bar'}]).then(function () {
return db.replicate.from(remote, {timeout: 20000});
}).then(function () {
seenTimeout.should.equal(true);
- remote._ajax = ajax;
});
});
diff --git a/tests/integration/test.replicationBackoff.js b/tests/integration/test.replicationBackoff.js
index 726cb32..8c25288 100644
--- a/tests/integration/test.replicationBackoff.js
+++ b/tests/integration/test.replicationBackoff.js
@@ -21,15 +21,15 @@
it('Issue 5402 should not keep adding event listeners when backoff is firing', function (done) {
this.timeout(1500);
- var remote = new PouchDB(dbs.remote);
+ var remote = new PouchDB(dbs.remote, {
+ fetch: function () {
+ throw new Error('flunking you');
+ }
+ });
var db = new PouchDB(dbs.name);
var backOffCount = 0;
var numberOfActiveListeners = 0;
- remote._ajax = function (opts, cb) {
- cb(new Error('flunking you'));
- };
-
var replication = db.sync(remote, {
live: true,
retry: true,
diff --git a/tests/integration/test.replication_events.js b/tests/integration/test.replication_events.js
index 482752d..a2102fd 100644
--- a/tests/integration/test.replication_events.js
+++ b/tests/integration/test.replication_events.js
@@ -141,17 +141,16 @@
}
var db = new PouchDB(dbs.name);
- var remote = new PouchDB(dbs.remote);
- var rejectAjax = true;
- var ajax = remote._ajax;
-
- remote._ajax = function (opts, cb) {
- if (rejectAjax) {
- cb(new Error('flunking you'));
- } else {
- ajax.apply(this, arguments);
+ var remote = new PouchDB(dbs.remote, {
+ fetch: function (url, opts) {
+ if (rejectAjax) {
+ throw new Error('flunking you');
+ } else {
+ return PouchDB.fetch(url, opts);
+ }
}
- };
+ });
+ var rejectAjax = true;
db.bulkDocs([{_id: 'a'}, {_id: 'b'}]).then(function () {
@@ -164,7 +163,6 @@
var counter = 0;
repl.on('complete', function () {
- remote._ajax = ajax;
done();
});
@@ -292,39 +290,38 @@
});
describe('#5172 triggering error when replicating', replication401TestFunction('unauthorized'));
-
+
function replication401TestFunction(eventName) {
return function () {
- var securedDbs = [], source, dest, previousAjax;
+ var securedDbs = [], source, dest;
beforeEach(function () {
var err = {
'status': 401,
'name': eventName,
'message': 'You are not authorized to access this db.'
};
-
- source = new PouchDB(dbs.name);
- dest = new PouchDB(dbs.remote);
-
+
if (adapters[0] === 'http') {
- previousAjax = source._ajax;
- source._ajax = function (opts, cb) { cb(err); };
+ source = new PouchDB(dbs.name, {
+ fetch: function () {
+ throw err;
+ }
+ });
+ dest = new PouchDB(dbs.remote);
securedDbs.push(source);
}
if (adapters[1] === 'http') {
- previousAjax = dest._ajax;
- dest._ajax = function (opts, cb) { cb(err); };
+ source = new PouchDB(dbs.name);
+ dest = new PouchDB(dbs.remote, {
+ fetch: function () {
+ throw err;
+ }
+ });
securedDbs.push(dest);
}
});
- afterEach(function () {
- securedDbs.forEach(function (db) {
- db._ajax = previousAjax;
- });
- });
-
function attachHandlers(replication) {
var invokedHandlers = [];
['change', 'complete', 'paused', 'active', 'denied', 'error'].forEach(function (type) {
diff --git a/tests/integration/utils.js b/tests/integration/utils.js
index 6ab4546..5a4a75a 100644
--- a/tests/integration/utils.js
+++ b/tests/integration/utils.js
@@ -183,8 +183,9 @@
};
testUtils.isCouchDB = function (cb) {
- testUtils.ajax({url: testUtils.couchHost() + '/' }, function (err, res) {
- // either CouchDB or pouchdb-server qualify here
+ PouchDB.fetch(testUtils.couchHost(), {}).then(function (response) {
+ return response.json();
+ }).then(function (res) {
cb('couchdb' in res || 'express-pouchdb' in res);
});
};
diff --git a/tests/mapreduce/index.html b/tests/mapreduce/index.html
index cb0e488..e8536d2 100644
--- a/tests/mapreduce/index.html
+++ b/tests/mapreduce/index.html
@@ -8,6 +8,7 @@
<body>
<div id="mocha"></div>
<script src="../../node_modules/lie/dist/lie.polyfill.js"></script>
+<script src="../../node_modules/whatwg-fetch/fetch.js"></script>
<script src="../../node_modules/mocha/mocha.js"></script>
<script src="../../node_modules/chai/chai.js"></script>
<script src="../../node_modules/chai-as-promised/lib/chai-as-promised.js"></script>
diff --git a/tests/mapreduce/test.mapreduce.js b/tests/mapreduce/test.mapreduce.js
index 6180b00..39fd7d2 100644
--- a/tests/mapreduce/test.mapreduce.js
+++ b/tests/mapreduce/test.mapreduce.js
@@ -1325,7 +1325,12 @@
// Need to avoid the cache to workaround
// https://issues.apache.org/jira/browse/COUCHDB-2880
- var db = new PouchDB(dbName, {ajax: {cache: false}});
+ var db = new PouchDB(dbName, {
+ fetch: function (url, opts) {
+ opts.cache = 'no-store';
+ return PouchDB.fetch(url, opts);
+ }
+ });
var docs = [];
for (var i = 0; i < 5; i++) {
docs.push({
@@ -1366,7 +1371,12 @@
// Need to avoid the cache to workaround
// https://issues.apache.org/jira/browse/COUCHDB-2880
- var db = new PouchDB(dbName, {ajax: {cache: false}});
+ var db = new PouchDB(dbName, {
+ fetch: function (url, opts) {
+ opts.cache = 'no-store';
+ return PouchDB.fetch(url, opts);
+ }
+ });
var docs = [];
for (var i = 0; i < 5; i++) {
docs.push({
@@ -1659,8 +1669,7 @@
},
reduce: '_count'
}).then(function (queryFun) {
- return db.query(queryFun, {group_level: -1, reduce: true})
- .then(function (res) {
+ return db.query(queryFun, {group_level: -1, reduce: true}).then(function (res) {
res.should.not.exist('expected error on invalid group_level');
}).catch(function (err) {
err.status.should.equal(400);