diff --git a/lib/ajax-browser.js b/lib/ajax-browser.js deleted file mode 100644 index d345ee5..0000000 --- a/lib/ajax-browser.js +++ /dev/null @@ -1,238 +0,0 @@ -// taken from pouchdb -"use strict"; - -var createBlob = require('./blob.js'); -var errors = require('./errors'); -var utils = require("./utils"); -var hasUpload; - -function ajax(options, adapterCallback) { - - var requestCompleted = false; - var callback = utils.getArguments(function (args) { - if (requestCompleted) { - return; - } - adapterCallback.apply(this, args); - requestCompleted = true; - }); - - if (typeof options === "function") { - callback = options; - options = {}; - } - - options = utils.clone(options); - - var defaultOptions = { - method : "GET", - headers: {}, - json: true, - processData: true, - timeout: 10000, - cache: false - }; - - options = utils.extend(true, defaultOptions, options); - - // cache-buster, specifically designed to work around IE's aggressive caching - // see http://www.dashbay.com/2011/05/internet-explorer-caches-ajax/ - if (options.method === 'GET' && !options.cache) { - var hasArgs = options.url.indexOf('?') !== -1; - options.url += (hasArgs ? '&' : '?') + '_nonce=' + utils.uuid(16); - } - - function onSuccess(obj, resp, cb) { - if (!options.binary && !options.json && options.processData && - typeof obj !== 'string') { - obj = JSON.stringify(obj); - } else if (!options.binary && options.json && typeof obj === 'string') { - try { - obj = JSON.parse(obj); - } catch (e) { - // Probably a malformed JSON from server - return cb(e); - } - } - if (Array.isArray(obj)) { - obj = obj.map(function (v) { - var obj; - if (v.ok) { - return v; - } else if (v.error && v.error === 'conflict') { - obj = errors.REV_CONFLICT; - obj.id = v.id; - return obj; - } else if (v.error && v.error === 'forbidden') { - obj = errors.FORBIDDEN; - obj.id = v.id; - obj.reason = v.reason; - return obj; - } else if (v.missing) { - obj = errors.MISSING_DOC; - obj.missing = v.missing; - return obj; - } else { - return v; - } - }); - } - cb(null, obj, resp); - } - - function onError(err, cb) { - var errParsed, errObj, errType, key; - try { - errParsed = JSON.parse(err.responseText); - //would prefer not to have a try/catch clause - for (key in errors) { - if (errors.hasOwnProperty(key) && - errors[key].name === errParsed.error) { - errType = errors[key]; - break; - } - } - if (!errType) { - errType = errors.UNKNOWN_ERROR; - if (err.status) { - errType.status = err.status; - } - if (err.statusText) { - err.name = err.statusText; - } - } - errObj = errors.error(errType, errParsed.reason); - } catch (e) { - for (var key in errors) { - if (errors.hasOwnProperty(key) && errors[key].status === err.status) { - errType = errors[key]; - break; - } - } - if (!errType) { - errType = errors.UNKNOWN_ERROR; - if (err.status) { - errType.status = err.status; - } - if (err.statusText) { - err.name = err.statusText; - } - } - errObj = errors.error(errType); - } - cb(errObj); - } - - var timer; - var xhr; - if (options.xhr) { - xhr = new options.xhr(); - } else { - xhr = new XMLHttpRequest(); - } - xhr.open(options.method, options.url); - xhr.withCredentials = true; - - if (options.json) { - options.headers.Accept = 'application/json'; - options.headers['Content-Type'] = options.headers['Content-Type'] || - 'application/json'; - if (options.body && - options.processData && - typeof options.body !== "string") { - options.body = JSON.stringify(options.body); - } - } - - if (options.binary) { - xhr.responseType = 'arraybuffer'; - } - - var createCookie = function (name, value, days) { - var expires = ""; - if (days) { - var date = new Date(); - date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000)); - expires = "; expires=" + date.toGMTString(); - } - document.cookie = name + "=" + value + expires + "; path=/"; - }; - - for (var key in options.headers) { - if (key === 'Cookie') { - var cookie = options.headers[key].split('='); - createCookie(cookie[0], cookie[1], 10); - } else { - xhr.setRequestHeader(key, options.headers[key]); - } - } - - if (!("body" in options)) { - options.body = null; - } - - var abortReq = function () { - if (requestCompleted) { - return; - } - xhr.abort(); - onError(xhr, callback); - }; - - xhr.onreadystatechange = function () { - if (xhr.readyState !== 4 || requestCompleted) { - return; - } - clearTimeout(timer); - if (xhr.status >= 200 && xhr.status < 300) { - var data; - if (options.binary) { - data = createBlob([xhr.response || ''], { - type: xhr.getResponseHeader('Content-Type') - }); - } else { - data = xhr.responseText; - } - onSuccess(data, xhr, callback); - } else { - onError(xhr, callback); - } - }; - - if (options.timeout > 0) { - timer = setTimeout(abortReq, options.timeout); - xhr.onprogress = function () { - clearTimeout(timer); - timer = setTimeout(abortReq, options.timeout); - }; - if (typeof hasUpload === 'undefined') { - // IE throws an error if you try to access it directly - hasUpload = Object.keys(xhr).indexOf('upload') !== -1; - } - if (hasUpload) { // does not exist in ie9 - xhr.upload.onprogress = xhr.onprogress; - } - } - if (options.body && (options.body instanceof Blob)) { - var reader = new FileReader(); - reader.onloadend = function (e) { - - var binary = ""; - var bytes = new Uint8Array(this.result); - var length = bytes.byteLength; - - for (var i = 0; i < length; i++) { - binary += String.fromCharCode(bytes[i]); - } - - binary = utils.fixBinary(binary); - xhr.send(binary); - }; - reader.readAsArrayBuffer(options.body); - } else { - xhr.send(options.body); - } - return {abort: abortReq}; -} - -module.exports = ajax; diff --git a/lib/ajax.js b/lib/ajax.js deleted file mode 100644 index 0f6e62f..0000000 --- a/lib/ajax.js +++ /dev/null @@ -1,183 +0,0 @@ -"use strict"; - -var request = require('request'); -var errors = require('./errors'); -var utils = require("./utils"); - -/* istanbul ignore next */ -function ajax(options, adapterCallback) { - - var requestCompleted = false; - var callback = utils.getArguments(function (args) { - if (requestCompleted) { - return; - } - adapterCallback.apply(this, args); - requestCompleted = true; - }); - - if (typeof options === "function") { - callback = options; - options = {}; - } - - options = utils.clone(options); - - var defaultOptions = { - method : "GET", - headers: {}, - json: true, - processData: true, - timeout: 10000, - cache: false - }; - - options = utils.extend(true, defaultOptions, options); - - - function onSuccess(obj, resp, cb) { - if (!options.binary && !options.json && options.processData && - typeof obj !== 'string') { - obj = JSON.stringify(obj); - } else if (!options.binary && options.json && typeof obj === 'string') { - try { - obj = JSON.parse(obj); - } catch (e) { - // Probably a malformed JSON from server - return cb(e); - } - } - if (Array.isArray(obj)) { - obj = obj.map(function (v) { - var obj; - if (v.ok) { - return v; - } else if (v.error && v.error === 'conflict') { - obj = errors.REV_CONFLICT; - obj.id = v.id; - return obj; - } else if (v.error && v.error === 'forbidden') { - obj = errors.FORBIDDEN; - obj.id = v.id; - obj.reason = v.reason; - return obj; - } else if (v.missing) { - obj = errors.MISSING_DOC; - obj.missing = v.missing; - return obj; - } else { - return v; - } - }); - } - cb(null, obj, resp); - } - - function onError(err, cb) { - var errParsed, errObj, errType, key; - if (err.code && err.status) { - var err2 = new Error(err.message || err.code); - err2.status = err.status; - return cb(err2); - } - try { - errParsed = JSON.parse(err.responseText); - //would prefer not to have a try/catch clause - for (key in errors) { - if (errors.hasOwnProperty(key) && - errors[key].name === errParsed.error) { - errType = errors[key]; - break; - } - } - if (!errType) { - errType = errors.UNKNOWN_ERROR; - if (err.status) { - errType.status = err.status; - } - if (err.statusText) { - err.name = err.statusText; - } - } - errObj = errors.error(errType, errParsed.reason); - } catch (e) { - for (var key in errors) { - if (errors.hasOwnProperty(key) && errors[key].status === err.status) { - errType = errors[key]; - break; - } - } - if (!errType) { - errType = errors.UNKNOWN_ERROR; - if (err.status) { - errType.status = err.status; - } - if (err.statusText) { - err.name = err.statusText; - } - } - errObj = errors.error(errType); - } - cb(errObj); - } - - - if (options.json) { - if (!options.binary) { - options.headers.Accept = 'application/json'; - } - options.headers['Content-Type'] = options.headers['Content-Type'] || - 'application/json'; - } - - if (options.binary) { - options.encoding = null; - options.json = false; - } - - if (!options.processData) { - options.json = false; - } - - return request(options, function (err, response, body) { - if (err) { - err.status = response ? response.statusCode : 400; - return onError(err, callback); - } - var error; - var content_type = response.headers['content-type']; - var data = (body || new Buffer('')); - - // CouchDB doesn't always return the right content-type for JSON data, so - // we check for ^{ and }$ (ignoring leading/trailing whitespace) - if (!options.binary && (options.json || !options.processData) && - typeof data !== 'object' && - (/json/.test(content_type) || - (/^[\s]*\{/.test(data) && /\}[\s]*$/.test(data)))) { - data = JSON.parse(data); - } - - if (response.statusCode >= 200 && response.statusCode < 300) { - onSuccess(data, response, callback); - } - else { - if (options.binary) { - data = JSON.parse(data.toString()); - } - if (data.reason === 'missing') { - error = errors.MISSING_DOC; - } else if (data.reason === 'no_db_file') { - error = errors.error(errors.DB_MISSING, data.reason); - } else if (data.error === 'conflict') { - error = errors.REV_CONFLICT; - } else { - error = errors.error(errors.UNKNOWN_ERROR, data.reason, data.error); - } - error.status = response.statusCode; - callback(error); - } - }); -} - -/* istanbul ignore next */ -module.exports = ajax; diff --git a/lib/blob.js b/lib/blob.js deleted file mode 100644 index e963c57..0000000 --- a/lib/blob.js +++ /dev/null @@ -1,28 +0,0 @@ -"use strict"; - -//Abstracts constructing a Blob object, so it also works in older -//browsers that don't support the native Blob constructor. (i.e. -//old QtWebKit versions, at least). -function createBlob(parts, properties) { - parts = parts || []; - properties = properties || {}; - try { - return new Blob(parts, properties); - } catch (e) { - if (e.name !== "TypeError") { - throw e; - } - var BlobBuilder = global.BlobBuilder || - global.MSBlobBuilder || - global.MozBlobBuilder || - global.WebKitBlobBuilder; - var builder = new BlobBuilder(); - for (var i = 0; i < parts.length; i += 1) { - builder.append(parts[i]); - } - return builder.getBlob(properties.type); - } -} - -module.exports = createBlob; - diff --git a/lib/errors.js b/lib/errors.js deleted file mode 100644 index 3453c7e..0000000 --- a/lib/errors.js +++ /dev/null @@ -1,130 +0,0 @@ -"use strict"; - -function PouchError(opts) { - this.status = opts.status; - this.name = opts.error; - this.message = opts.reason; - this.error = true; -} - -PouchError.prototype__proto__ = Error.prototype; -/* istanbul ignore next */ -PouchError.prototype.toString = function () { - return JSON.stringify({ - status: this.status, - name: this.name, - message: this.message - }); -}; - -exports.UNAUTHORIZED = new PouchError({ - status: 401, - error: 'unauthorized', - reason: "Name or password is incorrect." -}); -exports.MISSING_BULK_DOCS = new PouchError({ - status: 400, - error: 'bad_request', - reason: "Missing JSON list of 'docs'" -}); -exports.MISSING_DOC = new PouchError({ - status: 404, - error: 'not_found', - reason: 'missing' -}); -exports.REV_CONFLICT = new PouchError({ - status: 409, - error: 'conflict', - reason: 'Document update conflict' -}); -exports.INVALID_ID = new PouchError({ - status: 400, - error: 'invalid_id', - reason: '_id field must contain a string' -}); -exports.MISSING_ID = new PouchError({ - status: 412, - error: 'missing_id', - reason: '_id is required for puts' -}); -exports.RESERVED_ID = new PouchError({ - status: 400, - error: 'bad_request', - reason: 'Only reserved document ids may start with underscore.' -}); -exports.NOT_OPEN = new PouchError({ - status: 412, - error: 'precondition_failed', - reason: 'Database not open' -}); -exports.UNKNOWN_ERROR = new PouchError({ - status: 500, - error: 'unknown_error', - reason: 'Database encountered an unknown error' -}); -exports.BAD_ARG = new PouchError({ - status: 500, - error: 'badarg', - reason: 'Some query argument is invalid' -}); -exports.INVALID_REQUEST = new PouchError({ - status: 400, - error: 'invalid_request', - reason: 'Request was invalid' -}); -exports.QUERY_PARSE_ERROR = new PouchError({ - status: 400, - error: 'query_parse_error', - reason: 'Some query parameter is invalid' -}); -exports.DOC_VALIDATION = new PouchError({ - status: 500, - error: 'doc_validation', - reason: 'Bad special document member' -}); -exports.BAD_REQUEST = new PouchError({ - status: 400, - error: 'bad_request', - reason: 'Something wrong with the request' -}); -exports.NOT_AN_OBJECT = new PouchError({ - status: 400, - error: 'bad_request', - reason: 'Document must be a JSON object' -}); -exports.DB_MISSING = new PouchError({ - status: 404, - error: 'not_found', - reason: 'Database not found' -}); -exports.IDB_ERROR = new PouchError({ - status: 500, - error: 'indexed_db_went_bad', - reason: 'unknown' -}); -exports.WSQ_ERROR = new PouchError({ - status: 500, - error: 'web_sql_went_bad', - reason: 'unknown' -}); -exports.LDB_ERROR = new PouchError({ - status: 500, - error: 'levelDB_went_went_bad', - reason: 'unknown' -}); -exports.FORBIDDEN = new PouchError({ - status: 403, - error: 'forbidden', - reason: 'Forbidden by design doc validate_doc_update function' -}); -/* istanbul ignore next */ -exports.error = function (error, reason, name) { - function CustomPouchError(msg) { - this.message = reason; - if (name) { - this.name = name; - } - } - CustomPouchError.prototype = error; - return new CustomPouchError(reason); -}; diff --git a/lib/index.js b/lib/index.js index 58e7b3e..2598712 100644 --- a/lib/index.js +++ b/lib/index.js @@ -1,7 +1,7 @@ 'use strict'; var utils = require('./utils'); -var ajax = require('./ajax'); +var ajax = require('pouchdb-ajax'); var Checkpointer = require('./checkpointer'); exports.load = utils.toPromise(function (url, opts, callback) { diff --git a/lib/utils.js b/lib/utils.js index 22864de..330e2bb 100644 --- a/lib/utils.js +++ b/lib/utils.js @@ -8,10 +8,9 @@ if (typeof window !== 'undefined' && window.PouchDB) { Promise = typeof global.Promise === 'function' ? global.Promise : require('lie'); } exports.uuid = require('./uuid'); + exports.extend = require('pouchdb-extend'); -exports.clone = function (obj) { - return exports.extend(true, {}, obj); -}; + /* istanbul ignore next */ exports.once = function (fun) { var called = false; @@ -25,18 +24,8 @@ exports.once = function (fun) { } }); }; -/* istanbul ignore next */ -exports.getArguments = function (fun) { - return function () { - var len = arguments.length; - var args = new Array(len); - var i = -1; - while (++i < len) { - args[i] = arguments[i]; - } - return fun.call(this, args); - }; -}; +exports.getArguments = require('argsarray'); + /* istanbul ignore next */ exports.toPromise = function (func) { //create the function we will be returning diff --git a/package.json b/package.json index 4db29b3..ab0d839 100644 --- a/package.json +++ b/package.json @@ -36,6 +36,7 @@ "es3ify": "^0.1.3", "inherits": "~2.0.1", "lie": "^2.6.0", + "pouchdb-ajax": "^1.0.0", "pouchdb-extend": "^0.1.2", "request": "^2.47.0", "spark-md5": "0.0.5" @@ -51,7 +52,6 @@ "mocha": "~1.18", "phantomjs": "^1.9.7-5", "pouchdb": "pouchdb/pouchdb", - "request": "^2.36.0", "sauce-connect-launcher": "^0.4.2", "uglify-js": "^2.4.13", "watchify": "~0.4.1",