{"id":15493360,"url":"https://github.com/exist-db/gulp-exist","last_synced_at":"2026-04-01T17:55:08.874Z","repository":{"id":1631963,"uuid":"43557948","full_name":"eXist-db/gulp-exist","owner":"eXist-db","description":"A gulp plugin to deploy to eXist-db ","archived":false,"fork":false,"pushed_at":"2025-04-07T03:19:26.000Z","size":1451,"stargazers_count":16,"open_issues_count":3,"forks_count":3,"subscribers_count":10,"default_branch":"main","last_synced_at":"2025-04-15T11:12:58.723Z","etag":null,"topics":["build-tool","devops","exist-db","gulp","nodejs"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/eXist-db.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"open_collective":"existdb"}},"created_at":"2015-10-02T14:38:34.000Z","updated_at":"2025-04-09T10:10:38.000Z","dependencies_parsed_at":"2024-11-07T14:25:46.525Z","dependency_job_id":null,"html_url":"https://github.com/eXist-db/gulp-exist","commit_stats":{"total_commits":317,"total_committers":8,"mean_commits":39.625,"dds":0.6435331230283912,"last_synced_commit":"47a15756a28a55b7092f320c33be375af4d14ad6"},"previous_names":[],"tags_count":21,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eXist-db%2Fgulp-exist","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eXist-db%2Fgulp-exist/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eXist-db%2Fgulp-exist/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eXist-db%2Fgulp-exist/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/eXist-db","download_url":"https://codeload.github.com/eXist-db/gulp-exist/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":249058384,"owners_count":21205911,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["build-tool","devops","exist-db","gulp","nodejs"],"created_at":"2024-10-02T08:05:52.436Z","updated_at":"2026-04-01T17:55:08.771Z","avatar_url":"https://github.com/eXist-db.png","language":"JavaScript","readme":"# gulp-exist\n\n[![version](https://img.shields.io/npm/v/@existdb/gulp-exist.svg)](https://www.npmjs.com/package/@existdb/gulp-exist)\n![semantic release status](https://github.com/exist-db/gulp-exist/actions/workflows/semantic-release.yml/badge.svg)\n[![windows ci](https://ci.appveyor.com/api/projects/status/wcbi1e0yx47prhl6?svg=true)](https://ci.appveyor.com/project/olvidalo/gulp-exist)\n\n\n\u003e A gulp plugin to deploy to and query an eXist-db using eXist's XML-RPC API.\n\n## Prerequisites\n\nIn order to make use of `gulp-exist` you will need to have \n[gulp](https://gulpjs.com/docs/en/getting-started/quick-start) installed (in version 5 or later).\n\nAnd a running [existdb](https://exist-db.org) instance, of course (version 4.11.1 or higher recommended).\n\n## Installation\n\nIn your project folder run\n\n```sh\nnpm install --save-dev gulp @existdb/gulp-exist\n```\n\n## Usage\n\nThen create a file with the name `gulpfile.js` in the root of your project with the following contents\n\n```js\nconst { src } = require('gulp'),\n    { createClient } = require('@existdb/gulp-exist')\n\n// authenticate against local eXist instance for development \nconst connectionOptions = {\n    basic_auth: {\n        user: \"admin\",\n        pass: \"\"\n    }\n}\n\nconst exClient = createClient(connectionOptions)\n\n// deploy all\nfunction deploy () {\n    return src('**/*', { cwd: 'build', encoding: false })\n        .pipe(exClient.dest({ target: '/db/apps/myapp/' }))\n}\n\nexports.default = deploy\n```\n\nNow, `gulp deploy` will store all files in the `build` directory to\n**/db/apps/myapp** collection in eXist.\n\nAlso note, that non-existing collections and sub-folders will be created\nautomatically for you.\n\nHave a look at the [example gulpfile](https://github.com/eXist-db/gulp-exist/tree/master/spec/examples/gulpfile.js)\nfor a more complete gulpfile offering more advanced tasks.\n\n## API\n\n### exist.readOptionsFromEnv()\n\nRead connection options from environment variables.\nCurrently supported variables are listed in the table below.\n\n| variable name | default | description\n|----|----|----\n| `EXISTDB_USER` | _none_ | the user used to connect to the database and to execute queries with\n| `EXISTDB_PASS` | _none_ | the password to authenticate the user against the database\n| `EXISTDB_SERVER` | `https://localhost:8443` | the URL of the database instance to connect to (only http and https protocol allowed)\n\n#### Example\n\nWith the below setup the connection is then controlled by the variables\nin the environment.  \n\n```js\nconst { src } = require('gulp')\nconst { createClient, readOptionsFromEnv } = require('@existdb/gulp-exist')\nconst exClient = createClient(readOptionsFromEnv())\n\n// deploy all\nfunction deploy () {\n    return src('**/*', { cwd: 'build', encoding: false })\n        .pipe(exClient.dest({ target: '/db/apps/myapp/' }))\n}\n\nexports.default = deploy\n```\n\n```sh\nEXISTDB_SERVER=http://localhost:8080 \\\nEXISTDB_USER=admin \\\nEXISTDB_PASS= \\\ngulp deploy\n```\n\nThe npm package [dotenv-cli](https://www.npmjs.com/package/dotenv-cli) offers a great way to read and set environment\nvariables from files.\n\n```sh\nnpm install -g dotenv-cli\n```\n\nCreate a `.env` in your project root.\n\n```sh\nEXISTDB_SERVER=http://localhost:8080\nEXISTDB_USER=admin\nEXISTDB_PASS=\n```\nAnd then \n\n```sh\ndotenv gulp deploy\n```\n\n### exist.createClient(options)\n\nReturns a set of functions to interact with an eXist-db instance.\nWhat you can do is dependent on the permissions of the user specified\nin the connection options.\n\nNOTE: The connection options are passed through to the XMLRPC client\nlibrary.\nSo it might be possible to use different authentication methods or\nto pass in more options than mentioned below as long as your eXist-db\ninstallation understands them.\n\n#### Options\n\n##### host\n\nType: `string`\nDefault: `'localhost'`\n\n##### port\n\nType: `number`\nDefault: `8443`\n\n##### path\n\nPath to eXist's XML-RPC endpoint\n\nType: `string`\nDefault: `'/exist/xmlrpc'`\n\n##### basic_auth\n\nThe credentials used to authenticate requests.\nWhat you can and cannot do depends on the permissions\nthis user has.\n\nType: `Object`\nDefault: \n```js\n{ user: 'guest', pass: 'guest' }\n```\n\n##### secure\n\nUse HTTPS (or HTTP) to connect to the database instance.\n\n**NOTE:** You need a valid certificate installed in the keystore of\nexist for connections to remote servers.\n\nType: `Boolean`\nDefault: `true`\n\n#### Example\n\nConnecting to a remote server using a secure connection.\n\n```js\nconst { createClient } = require('@existdb/gulp-exist')\nconst exClient = createClient({\n    host: \"my-server.tld\",\n    secure: true,\n    port: 443,\n    basic_auth: {\n        user: \"app\",\n        pass: \"1 handmade eclectic eclaire\"\n    }\n})\n```\n\nConnecting to localhost server using a insecure connection.\n\n```js\nconst { createClient } = require('@existdb/gulp-exist')\nconst exClient = createClient({\n    host: \"localhost\",\n    secure: false,\n    port: 8080\n})\n```\n\n### existClient.dest(options)\n\nUploads input files to a target collection in eXist.\n\n#### Options\n\n##### target\n\nRemote deployment target collection. Non-existent collections will be created.\n\nType: `string`\nDefault `'/db'`\n\n##### html5AsBinary\n\nWhen set to true, any HTML file that cannot be\nparsed as valid XML, will be uploaded as a binary file instead.\nHTML5 documents tend to be non well-formed XML.\n\nFormerly `binary_fallback`.\nNOTE: Binary documents can not be indexed and therefore are also not\nsearchable by the eXist-db. This option is only useful for template files.\n\nType: `boolean`\nDefault: `false`\n\n##### permissions\n\nSpecify remote permissions for files as path-permission pairs.\n\nType: `Object{path: permissions}`\nDefault: `{}`\n\n```js\n{\n    '.secrets/key':   'rwx------',\n    'controller.xql': 'rwxr-xr-x'\n}\n```\n\n#### Example\n\n```js\nconst { src } = require('gulp')\nconst { createClient } = require('@existdb/gulp-exist')\n\n// override defaults\nconst exist = createClient({\n    basic_auth: {\n        user: 'admin',\n        pass: ''\n    }\n})\n\nfunction deployWithPermissions () {\n    return src('**/*', { cwd: '.', encoding: false })\n        .pipe(exist.dest({\n            target: '/db/apps/myapp/',\n            permissions: { 'controller.xql': 'rwxr-xr-x' }\n        }))\n}\n\nexports.default = deployWithPermissions\n```\n### existClient.install(options)\n\n#### Options\n\n##### packageUri (deprecated)\n\nThe unique package descriptor of the application to be installed.\n\n**NOTE:** For versions after v4.0.2 this option is ignored and will be read \nfrom the XAR itself.\n\n##### customPackageRepoUrl\n\nThe application repository that will be used to resolve dependencies.\nOnly needs to be set if the default repository cannot be used.\n\n#### Example\n\n```js\nconst { src } = require('gulp')\nconst { createClient } = require('@existdb/gulp-exist')\n\n// override defaults\nconst exist = createClient({\n    basic_auth: {\n        user: 'admin',\n        pass: ''\n    }\n})\n\nfunction install () {\n    return src('spec/files/test-app.xar', { encoding: false })\n        .pipe(exist.install())\n}\n```\n\n### existClient.newer(options)\n\nFilters the input stream for files that are newer than their remote counterpart.\n\n#### Options\n\n##### target\n\nWhich collection to compare the local files to.\n\n#### Example\n\nOnly upload modified files.\n\n```js\nconst { src } = require('gulp')\nconst { createClient } = require('@existdb/gulp-exist')\n\n// override some default connection options\nconst exist = createClient({\n    basic_auth: {\n        user: 'admin',\n        pass: ''\n    }\n})\n\nconst target = '/db/apps/myapp/'  // the collection to write to\nconst html5AsBinary = true        // upload HTML5 templates as binary\n\n\nfunction deployNewer () {\n\treturn src('**/*', { cwd: '.', encoding: false })\n\t\t.pipe(exist.newer({ target }))\n\t\t.pipe(exist.dest({ target, html5AsBinary }));\n}\n\nexports.default = deployNewer\n```\n\n### existClient.query(options)\n\nExecute input files as XQuery on the server.\n\nThe input files will not be stored in eXist but read locally and executed \ndirectly. The query results will be logged in the console (can be disabled by\nsetting `printXqlResults` to `false`). For each input file, the result\nof the query will also be emitted as an output file that can optionally be\ncopied into a local directory for logging. Timestamps will be appended to the\nfilename. The filename extension of the output files can be controlled with\n`xqlOutputExt` (default is `xml`).\n\n#### Query options\n\n##### printXqlResults\n\nWhether to print the results of executed XQuerys to console.\n\nType: `boolean`\nDefault: `true`\n\n##### xqlOutputExt\n\nThe filename extension that will be used for XQuery result files emitted by\n`exist.query()`. Possible values are 'xml' or 'json'.\n\nType: `string`\nDefault: `'xml'`\n\n##### queryParams\n\nQuery params passed to the eXist-db XMLRPC API\n(https://exist-db.org/exist/apps/doc/devguide_xmlrpc). Can be used to pass\nquery variables (see Example 2).\n\nType: `Object`\nDefault: `{}`\n\n#### Example 1\n\nUpload a collection index configuration file and re-index the collection\n\n*scripts/reindex.xq*\n\n```xquery\nxquery version \"3.1\";\ndeclare option exist:serialize \"method=json media-type=text/javascript\";\n\nmap { \"success\": xmldb:reindex('/db/apps/myapp/data') }\n```\n\n*gulpfile.js*\n\n```js\nconst { src, dest } = require('gulp')\nconst { createClient } = require('@existdb/gulp-exist')\n\n// override some default connection options\nconst exist = createClient({\n    basic_auth: {\n        user: \"admin\",\n        pass: \"\"\n    }\n})\n\nconst queryConfig = {\n\ttarget: '/db/apps/myapp',\n\txqlOutputExt: 'json'\n}\n\nfunction deployCollectionXConf () {\n\treturn src('collection.xconf', { cwd: '.' })\n\t\t.pipe(exist.dest({\n            target: `/db/system/config${queryConfig.target}`\n        }))\n}\n\nfunction reindex () {\n\treturn src('scripts/reindex.xq', { cwd: '.' })\n\t\t.pipe(exist.query(queryConfig))\n        .pipe(dest('logs'))\n}\n\nexports.default = series(deployCollectionXConf, reindex)\n```\n\n#### Example 2\n\nPass a variable to the XQuery script.\n\n*scripts/var.xq*\n\n```xquery\n(: optionally declare the variable as external :)\ndeclare variable $someVariable external;\n\n\u003cresult\u003e{ $someVariable }\u003c/result\u003e\n```\n\n*gulpfile.js*\n\n```js\nconst { src, dest } = require('gulp')\nconst { createClient } = require('@existdb/gulp-exist')\n\n// override some default connection options\nconst exist = createClient({\n    basic_auth: {\n        user: \"admin\",\n        pass: \"\"\n    }\n})\n\n// set `variables` query parameter\nconst queryConfig = {\n\tqueryParams: {\n\t    variables: {\n\t        someVariable: \"some value\"\n\t    }\n\t}\n}\n\nfunction runQueryWithVariable () {\n\treturn src('scripts/var.xq', { cwd: '.' })\n\t\t.pipe(exist.query(queryConfig))\n        .pipe(dest('logs'))\n}\n\nexports.default = runQueryWithVarible\n```\n\n## Define Custom Mime Types\n\nOverride the mime type used to store files in exist based on their extension.\n`defineMimeTypes` just exposes `mime.define()`.\n*NOTE:* attempt to redefine a registered **extension** will throw an error.\n\nExtended by default:\n```js\n{\n    'application/xquery': ['xq', 'xquery', 'xqs', 'xql', 'xqm'],\n    'application/xml': ['xconf', 'odd']\n}\n```\n\nType: `Object {mimetype: [extensions]}`\n\n##### Example\n\n```js\nexist.defineMimeTypes({ 'text/foo': ['bar'] })\n```\n\n## More examples\n\nHave a look at the [example gulpfile](https://github.com/eXist-db/gulp-exist/tree/master/spec/examples/gulpfile.js).\n\n### Watch File Changes\n\n`watch` will report when a file has changed. `deployBuild` will run\neach time that happens uploading all files that have changed since its\nlast execution.\n\n```js\nconst { watch, src, dest, lastRun } = require('gulp')\nconst { createClient } = require('@existdb/gulp-exist')\n\n// override defaults\nconst connectionOptions = {\n    basic_auth: {\n        user: \"admin\",\n        pass: \"\"\n    }\n}\n\nconst exist = createClient(connectionOptions)\n\nfunction deployBuild () {\n    return src('build/**/*', {\n            base: 'build',\n            since: lastRun(deployBuild),\n            encoding: false\n        })\n        .pipe(exist.dest({target}))\n}\n\nexports.deploy = deployBuild\n\nfunction watchBuild () {\n    watch('build/**/*', series(deployBuild));\n}\nexports.watch = watchBuild\n\nexports.default = series(deployBuild, watchDeploy)\n```\n\n### Create and Install XAR Archive\n\n```js\nconst { src, dest } = require('gulp'),\n    zip = require('gulp-zip'),\n    pkg = require('./package.json'),\n    { createClient } = require('@existdb/gulp-exist')\n\n// override some default connection options\nconst exist = createClient({\n    basic_auth: {\n        user: \"admin\",\n        pass: \"\"\n    }\n})\n\nfunction build {\n    // compile everything into the 'build' directory\n}\n\nfunction xar () {\n    return src('build/**/*', { base: 'build', encoding: false })\n            .pipe(zip(`${pkg.abbrev}-${pkg.version}.xar`))\n            .pipe(dest(\".\"));\n}\n\nfunction install () {\n    return src(`${pkg.abbrev}-${pkg.version}.xar`, { encoding: false })\n      .pipe(exist.install({ packageUri: \"http://myapp\" }))\n}\n\nexports.default = series(build, xar, install)\n```\n\n## Test\n\n### Prerequisites\n\nA running instance of eXist-db v2.2+ at localhost port 8443 with an\nadmin user that has a blank password.\n\nYou can override the above settings with environment variables (see [dbconnection.js](https://github.com/eXist-db/gulp-exist/tree/master/spec/dbconnection.js) for details).\n\n### Run the Tests\n\n```sh\nnpm test\n```\n\n[dotenv-cli](https://www.npmjs.com/package/dotenv-cli) can be used here, too:\n\n```sh\ndotenv npm test\n```\n","funding_links":["https://opencollective.com/existdb"],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fexist-db%2Fgulp-exist","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fexist-db%2Fgulp-exist","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fexist-db%2Fgulp-exist/lists"}