node-exist

Mostly a shallow wrapper for eXist's XML-RPC API.
Attempts to translate terminologies into node world. Uses promises.
Install
npm install @existdb/node-exist
Use
Creating, reading and removing a collection:
const exist = require('@existdb/node-exist')
const db = exist.connect()
db.collections.create('/db/apps/test')
.then(result => db.collections.describe('/db/apps/test'))
.then(result => console.log('collection description:', result))
.catch(e => console.error('fail', e))
Uploading an XML file into the database
const exist = require('@existdb/node-exist')
const db = exist.connect()
db.documents.upload(Buffer.from('<root/>'))
.then(fileHandle => db.documents.parseLocal(fileHandle, '/db/apps/test/file.xml', {}))
.then(result => db.documents.read('/db/apps/test/file.xml'))
.then(result => console.log('test file contents', result))
.catch(error => console.error('fail', error))
Since all interactions with the database are promises you can also use async functions
const exist = require('@existdb/node-exist')
const db = exist.connect()
async function uploadAndParse (filePath, contents) {
const fileHandle = await db.documents.upload(contents)
await db.documents.parseLocal(fileHandle, filePath, {})
return filePath
}
uploadAndParse('/db/apps/test-file.xml', Buffer.from('<root/>'))
.then(filePath => console.log("uploaded", filePath))
.catch(error => console.error(error))
You can also have a look at the
examples for more use-cases.
Configuration
Connect as someone else than guest
exist.connect({
basic_auth: {
user: 'me',
pass: '1 troubadour artisanal #compost'
}
})
Connect to a local development server using HTTP
exist.connect({ secure: false, port: 8080 })
Connect to a server with an invalid or expired certificate
exist.connect({ rejectUnauthorized: false })
Defaults
{
host: 'localhost',
port: '8443',
path: '/exist/xmlrpc',
basic_auth: {
user: 'guest',
pass: 'guest'
},
secure: true
}
Components
The methods are grouped into components by what they operate on.
Every method returns a promise.
Queries
Status: working
execute
db.queries.execute(query, options)
read
db.queries.read(query, options)
readAll
This convenience function calls queries.count then retrieves all result pages and returns them in an array.
db.queries.readAll(query, options)
Example:
const query = `xquery version "3.1";
xmldb:get-child-collections($collection)
=> string-join(",\n")
`
const options = { variables: collection: "/db/apps" }
db.queries.readAll(query, options)
.then(result => {
const response = Buffer.concat(result.pages).toString()
console.log(response)
})
.catch(error => console.error(error))
count
db.queries.count(resultHandle)
retrieve
db.queries.retrieveResult(resultHandle, page)
retrieveAll
db.queries.retrieveAll(resultHandle)
releaseResult
free result on server
db.queries.releaseResult(resultHandle)
Documents
A document can be seen as a file. It might be indexed if it's type is not binary.
upload
Resolves into a file handle which can then be used by db.documents.parseLocal.
db.documents.upload(Buffer.from('test'))
parseLocal
db.documents.parseLocal(fileHandle, 'foo/test.txt', {})
read
db.documents.read('foo.xml')
remove
db.documents.remove('foo.xml')
Resources
Status: working
A resource is identified by its path in the database.
Documents and collections are resources.
describe
db.resources.describe(resourcePath)
setPermissions
db.resources.setPermissions(resourcePath, 400)
getPermissions
db.resources.getPermissions(resourcePath)
Collections
Status: working
create
db.collections.create(collectionPath)
remove
db.collections.remove(collectionPath)
describe
db.collections.describe(collectionPath)
read
db.collections.read(collectionPath)
App
Status: working
upload
After uploading a XAR you can install it
db.app.upload(xarBuffer, xarName)
Example:
const xarContents = fs.readFileSync('spec/files/test-app.xar')
db.app.upload(xarContents, 'test-app.xar')
.then(result => console.log(result))
.catch(error => console.error(error))
install
Install an uploaded XAR (this will call repo:install-and-deploy-from-db).
For extra safety a previously installed version will be removed before
installing the new version.
Dependencies will be resolved from http://exist-db.org/exist/apps/public-repo
by default.
If you want to use a different repository provide the optional customPackageRepoUrl.
db.app.install(xarName, packageUri[, customPackageRepoUrl])
Example:
db.app.install('test-app.xar', 'http://exist-db.org/apps/test-app')
.then(result => console.log(result))
.catch(error => console.error(error))
Returns
{
"success": true,
"result": {
"update": false,
"target": "/db/apps/test-app"
}
}
Error
{
"success": false,
"error": {
"code": "err:EXPATH00",
"value": "Missing descriptor from package: /db/system/repo/test-app.xar"
}
}
remove
Uninstall and remove the application identified by its namespace URL.
If no app with packageUri could be found then this counts as success.
db.app.remove(packageUri)
Example:
db.app.remove('http://exist-db.org/apps/test-app')
.then(result => console.log(result))
.catch(error => console.error(error))
Returns
{ success: true }
Error
{
success: false,
error: Object | Error
}
Indices
Status: TODO
Users
Status: failing
byName
db.users.byName(username)
list
db.users.list()
server
Status: working
syncToDisk
db.server.syncToDisk()
shutdown
db.server.shutdown()
Note: There is no way to bring it up again.
Test
All tests are in spec/tests and written for tape
npm test
Roadmap
Compatibility
node-exist is tested to be compatible with eXist-db 4 and 5.
It should be compatible with version 3, except XAR installation.
Disclaimer
Use at your own risk.
This software is safe for development.
It may be used to work with a production instance, but think twice before your data is lost.