Mostly a shallow wrapper for eXist's XML-RPC API. Attempts to translate terminologies into node world. Uses promises.
npm install @existdb/node-exist
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
}
// top-level await is not available everywhere, yet
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.
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 })
{
host: 'localhost',
port: '8443',
path: '/exist/xmlrpc', // you most likely do not need to change that
basic_auth: {
user: 'guest',
pass: 'guest'
},
secure: true
}
The methods are grouped into components by what they operate on. Every method returns a promise.
Status: working
db.queries.execute(query, options)
db.queries.read(query, options)
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))
db.queries.count(resultHandle)
db.queries.retrieveResult(resultHandle, page)
db.queries.retrieveAll(resultHandle)
free result on server
db.queries.releaseResult(resultHandle)
A document can be seen as a file. It might be indexed if it's type is not binary.
Resolves into a file handle which can then be used by db.documents.parseLocal
.
db.documents.upload(Buffer.from('test'))
db.documents.parseLocal(fileHandle, 'foo/test.txt', {})
db.documents.read('foo.xml')
db.documents.remove('foo.xml')
Status: working
A resource is identified by its path in the database. Documents and collections are resources.
db.resources.describe(resourcePath)
db.resources.setPermissions(resourcePath, 400)
db.resources.getPermissions(resourcePath)
Status: working
db.collections.create(collectionPath)
db.collections.remove(collectionPath)
db.collections.describe(collectionPath)
db.collections.read(collectionPath)
Status: working
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 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[, customPackageRepoUrl])
Example:
db.app.install('test-app.xar')
.then(result => console.log(result))
.catch(error => console.error(error))
Returns
{
"success": true,
"result": {
"update": false, // true if a previous version was found
"target": "/db/apps/test-app"
}
}
Error
{
success: false,
error: Error
}
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
}
Status: TODO
Status: failing
db.users.byName(username)
db.users.list()
Status: working
db.server.syncToDisk()
db.server.shutdown()
Note: There is no way to bring it up again.
You can use this library to interact with local or remote existdb instances on the command line. You can find a few basic examples in this repository.
All tests are in spec/tests and written for tape
npm test
- switch to use eXist-db's REST-API.
- refactor to ES6 modules
node-exist is tested to be compatible with eXist-db 4 and 5. It should be compatible with version 3, except XAR installation.
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.