Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

blue-cot

Package Overview
Dependencies
Maintainers
1
Versions
69
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

blue-cot - npm Package Compare versions

Comparing version 4.0.7 to 4.0.8

327

lib/db_handle.js

@@ -6,7 +6,7 @@ const querystring = require('querystring')

module.exports = (jsonRequest, dbName) => {
validateString(dbName, 'dbName')
const API = {
docUrl: docId => {
if (typeof docId !== 'string' || docId.length === 0) {
throw new TypeError('doc id must be a non-empty string')
}
validateString(docId, 'doc id')
if (docId.indexOf('_design/') === 0) {

@@ -18,121 +18,103 @@ return '/' + dbName + '/_design/' + encodeURIComponent(docId.substr(8))

},
info: () => {
return jsonRequest('GET', `/${dbName}`)
.then(res => res.data)
info: async () => {
const res = await jsonRequest('GET', `/${dbName}`)
return res.data
},
get: (docId, revId) => {
get: async (docId, revId) => {
var url = API.docUrl(docId)
if (typeof revId === 'string') url += `?rev=${revId}`
return jsonRequest('GET', url)
.then(res => {
if (res.statusCode === 200) return res.data
else throw errors_.buildFromRes(res, `error getting doc ${docId}`)
})
const res = await jsonRequest('GET', url)
if (res.statusCode === 200) return res.data
else throw errors_.buildFromRes(res, `error getting doc ${docId}`)
},
exists: docId => {
return jsonRequest('GET', API.docUrl(docId))
.then(res => {
exists: async docId => {
try {
const res = await jsonRequest('GET', API.docUrl(docId))
if (res.statusCode === 200) return true
else throw errors_.buildFromRes(res, `error getting doc ${docId}`)
})
.catch(err => {
} catch (err) {
if (err.statusCode === 404) return false
else throw err
})
}
},
put: (doc) => {
return jsonRequest('PUT', API.docUrl(doc._id), doc)
.then(res => {
if ([ 200, 201 ].includes(res.statusCode)) {
return res.data
} else {
throw errors_.buildFromRes(res, `error putting doc ${doc._id}`)
}
})
put: async doc => {
const res = await jsonRequest('PUT', API.docUrl(doc._id), doc)
if (res.statusCode === 200 || res.statusCode === 201) return res.data
else throw errors_.buildFromRes(res, `error putting doc ${doc._id}`)
},
post: (doc) => {
return jsonRequest('POST', `/${dbName}`, doc)
.then(res => {
if (res.statusCode === 201) {
return res.data
} else if (doc._id) {
throw errors_.buildFromRes(res, `error posting doc ${doc._id}`)
} else {
throw errors_.buildFromRes(res, `error posting new doc`)
}
})
post: async doc => {
const res = await jsonRequest('POST', `/${dbName}`, doc)
if (res.statusCode === 201) {
return res.data
} else if (doc._id) {
throw errors_.buildFromRes(res, `error posting doc ${doc._id}`)
} else {
throw errors_.buildFromRes(res, `error posting new doc`)
}
},
batch: (doc) => {
batch: async doc => {
const path = `/${dbName}?batch=ok`
return jsonRequest('POST', path, doc)
.then(res => {
if (res.statusCode === 202) {
return res.data
} else if (doc._id) {
throw errors_.buildFromRes(res, `error batch posting doc ${doc._id}`)
} else {
throw errors_.buildFromRes(res, `error batch posting new doc`)
}
})
const res = await jsonRequest('POST', path, doc)
if (res.statusCode === 202) {
return res.data
} else if (doc._id) {
throw errors_.buildFromRes(res, `error batch posting doc ${doc._id}`)
} else {
throw errors_.buildFromRes(res, `error batch posting new doc`)
}
},
update: (docId, fn) => {
update: async (docId, fn) => {
const db = API
const tryIt = () => {
return db.get(docId)
.catch(err => {
if (err.statusCode === 404) {
return { _id: docId }
} else {
throw err
}
})
.then(doc => db.put(fn(doc)))
.then(res => {
if (res.ok) {
return res
} else {
return tryIt()
}
})
const tryIt = async () => {
let doc
try {
doc = await db.get(docId)
} catch (err) {
if (err.statusCode === 404) doc = { _id: docId }
else throw err
}
const res = await db.put(fn(doc))
if (res.ok) return res
else return tryIt()
}
return tryIt()
},
delete: (docId, rev) => {
delete: async (docId, rev) => {
const url = API.docUrl(docId) + '?rev=' + encodeURIComponent(rev)
return jsonRequest('DELETE', url)
.then(res => {
if (res.statusCode === 200) {
return res.data
} else {
throw errors_.buildFromRes(res, `error deleting doc ${docId}`)
}
})
const res = await jsonRequest('DELETE', url)
if (res.statusCode === 200) return res.data
else throw errors_.buildFromRes(res, `error deleting doc ${docId}`)
},
// Based on http://stackoverflow.com/a/16827094/3324977
undelete: docId => {
// Verify that it's indeed a deleted document
return API.get(docId)
.then(res => {
undelete: async docId => {
try {
// Verify that it's indeed a deleted document: if get doesn't throw, there is nothing to undelete
await API.get(docId)
throw errors_.new("can't undelete an non-deleted document", 400, docId)
})
.catch(err => {
} catch (err) {
if (err.statusCode !== 404 || err.body.reason !== 'deleted') throw err
var url = API.docUrl(docId) + '?revs=true&open_revs=all'
return jsonRequest('GET', url)
.then(res => {
const data = res.data[0].ok
const currentRev = data._rev
const preDeleteRevNum = data._revisions.start - 1
const preDeleteRevId = data._revisions.ids[1]
const preDeleteRev = preDeleteRevNum + '-' + preDeleteRevId
return API.get(docId, preDeleteRev)
.then(preDeleteDoc => {
preDeleteDoc._rev = currentRev
return API.put(preDeleteDoc)
})
})
})
const res = await jsonRequest('GET', url)
const data = res.data[0].ok
const currentRev = data._rev
const preDeleteRevNum = data._revisions.start - 1
const preDeleteRevId = data._revisions.ids[1]
const preDeleteRev = preDeleteRevNum + '-' + preDeleteRevId
const preDeleteDoc = await API.get(docId, preDeleteRev)
preDeleteDoc._rev = currentRev
return API.put(preDeleteDoc)
}
},
bulk: docs => {
bulk: async docs => {
const url = `/${dbName}/_bulk_docs`

@@ -145,25 +127,19 @@

if (!isPlainObject(doc)) {
const err = errors_.new('invalid bulk doc', 400, { doc, index: i })
return Promise.reject(err)
throw errors_.new('invalid bulk doc', 400, { doc, index: i })
}
}
return jsonRequest('POST', url, { docs })
.then(res => {
if (res.statusCode === 201) {
for (let i = 0; i < res.data.length; i++) {
if (res.data[i].error != null) {
throw errors_.new('bulk response contains errors', 400, res.data)
}
}
return res.data
} else {
throw errors_.buildFromRes(res, `error posting to _bulk_docs`)
const res = await jsonRequest('POST', url, { docs })
if (res.statusCode !== 201) throw errors_.buildFromRes(res, `error posting to _bulk_docs`)
for (let i = 0; i < res.data.length; i++) {
if (res.data[i].error != null) {
throw errors_.new('bulk response contains errors', 400, res.data)
}
})
}
return res.data
},
buildQueryString: (query = {}) => {
if (!isPlainObject(query)) {
throw new Error(`query should be an object: ${JSON.stringify(query)}`)
}
validatePlainObject(query, 'query')

@@ -183,73 +159,74 @@ const q = {}

},
viewQuery: (path, query) => {
viewQuery: async (path, query) => {
const qs = API.buildQueryString(query)
const url = `/${dbName}/${path}?${qs}`
return jsonRequest('GET', url)
.then(res => {
if (res.statusCode === 200) return res.data
else throw errors_.buildFromRes(res, `error reading view ${path}`)
})
const res = await jsonRequest('GET', url)
if (res.statusCode === 200) return res.data
else throw errors_.buildFromRes(res, `error reading view ${path}`)
},
view: (designName, viewName, query) => {
view: async (designName, viewName, query) => {
return API.viewQuery(`_design/${designName}/_view/${viewName}`, query)
},
allDocs: query => {
allDocs: async query => {
return API.viewQuery('_all_docs', query)
},
viewKeysQuery: (path, keys, query) => {
viewKeysQuery: async (path, keys, query) => {
const qs = API.buildQueryString(query)
const url = `/${dbName}/${path}?${qs}`
return jsonRequest('POST', url, { keys })
.then(res => {
if (res.statusCode === 200) return res.data
else throw errors_.buildFromRes(res, `error reading view ${path}`)
})
const res = await jsonRequest('POST', url, { keys })
if (res.statusCode === 200) return res.data
else throw errors_.buildFromRes(res, `error reading view ${path}`)
},
viewKeys: (designName, viewName, keys, query) => {
viewKeys: async (designName, viewName, keys, query) => {
const path = `_design/${designName}/_view/${viewName}`
return API.viewKeysQuery(path, keys, query)
},
// http://docs.couchdb.org/en/latest/api/database/bulk-api.html#post--db-_all_docs
allDocsKeys: (keys, query) => {
allDocsKeys: async (keys, query) => {
return API.viewKeysQuery('_all_docs', keys, query)
},
fetch: keys => {
return API.viewKeysQuery('_all_docs', keys, { include_docs: true })
.then(({ rows }) => {
const docs = []
const errors = []
for (const row of rows) {
if (row.error) errors.push(row)
else if (row.value.deleted) errors.push({ key: row.key, error: 'deleted' })
else docs.push(row.doc)
}
if (errors.length > 0) {
throw errors_.new('docs fetch errors', 400, { keys, errors })
}
return docs
})
fetch: async keys => {
const { rows } = await API.viewKeysQuery('_all_docs', keys, { include_docs: true })
const docs = []
const errors = []
for (const row of rows) {
if (row.error) errors.push(row)
else if (row.value.deleted) errors.push({ key: row.key, error: 'deleted' })
else docs.push(row.doc)
}
if (errors.length > 0) {
throw errors_.new('docs fetch errors', 400, { keys, errors })
}
return docs
},
listRevs: docId => {
listRevs: async docId => {
const url = API.docUrl(docId) + '?revs_info=true'
return jsonRequest('GET', url)
.then(res => res.data._revs_info)
const res = await jsonRequest('GET', url)
return res.data._revs_info
},
revertLastChange: docId => {
return API.listRevs(docId)
.then((revsInfo) => {
const currentRevInfo = revsInfo[0]
// Select only the previous one
const candidatesRevsInfo = revsInfo.slice(1, 2)
return recover(API, docId, candidatesRevsInfo, currentRevInfo)
})
revertLastChange: async docId => {
const revsInfo = await API.listRevs(docId)
const currentRevInfo = revsInfo[0]
// Select only the previous one
const candidatesRevsInfo = revsInfo.slice(1, 2)
return recover(API, docId, candidatesRevsInfo, currentRevInfo)
},
revertToLastVersionWhere: (docId, testFn) => {
return API.listRevs(docId)
.then((revsInfo) => {
const currentRevInfo = revsInfo[0]
const candidatesRevsInfo = revsInfo.slice(1)
return recover(API, docId, candidatesRevsInfo, currentRevInfo, testFn)
})
revertToLastVersionWhere: async (docId, testFn) => {
const revsInfo = await API.listRevs(docId)
const currentRevInfo = revsInfo[0]
const candidatesRevsInfo = revsInfo.slice(1)
return recover(API, docId, candidatesRevsInfo, currentRevInfo, testFn)
},
changes: (query = {}) => {
changes: async (query = {}) => {
const q = {}

@@ -263,7 +240,5 @@ changesQueryKeys.forEach(key => {

return jsonRequest('GET', path)
.then(res => {
if (res.statusCode === 200) return res.data
else throw errors_.buildFromRes(res, `error reading _changes`)
})
const res = await jsonRequest('GET', path)
if (res.statusCode === 200) return res.data
else throw errors_.buildFromRes(res, `error reading _changes`)
}

@@ -310,1 +285,15 @@ }

}
const validateString = (str, label) => {
if (typeof str !== 'string' || str.length === 0) {
let errMessage = `invalid ${label}`
if (str != null) errMessage += ` ${str} (${typeof str})`
throw new TypeError(errMessage)
}
}
const validatePlainObject = (obj, label) => {
if (!isPlainObject(obj)) {
throw new TypeError(`invalid ${label} object: ${JSON.stringify(obj)} (${typeof obj})`)
}
}

@@ -23,3 +23,3 @@ {

],
"version": "4.0.7",
"version": "4.0.8",
"main": "lib/cot.js",

@@ -26,0 +26,0 @@ "dependencies": {

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc