Skip to content

Commit 5c7c560

Browse files
authored
Merge pull request #327 from line-o/next
Update to node-exist v7
2 parents d56340e + bf8d7e2 commit 5c7c560

File tree

21 files changed

+648
-579
lines changed

21 files changed

+648
-579
lines changed

commands/edit.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import * as readline from 'node:readline'
99
import chalk from 'chalk'
1010
import { execa } from 'execa'
1111
import { getEditor } from 'env-editor'
12-
import { connect } from '@existdb/node-exist'
12+
import { getXmlRpcClient } from '@existdb/node-exist'
1313

1414
/**
1515
* @typedef { import("@existdb/node-exist").NodeExist } NodeExist
@@ -148,5 +148,5 @@ export async function handler (argv) {
148148
return 0
149149
}
150150
const { resource, connectionOptions, editor } = argv
151-
return await edit(connect(connectionOptions), resource, editor)
151+
return await edit(getXmlRpcClient(connectionOptions), resource, editor)
152152
}

commands/exec.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { connect } from '@existdb/node-exist'
1+
import { getXmlRpcClient } from '@existdb/node-exist'
22
import { readFileSync } from 'node:fs'
33

44
/**
@@ -68,7 +68,7 @@ function getQuery (file, query) {
6868
* @param {NodeExist.BoundModules} db bound NodeExist modules
6969
* @param {string|Buffer} query the query to execute
7070
* @param {object} variables the bound variables
71-
* @returns {Number}
71+
* @returns {Promise<Number>} exit code
7272
*/
7373
async function execute (db, query, variables) {
7474
const result = await db.queries.readAll(query, { variables })
@@ -106,7 +106,7 @@ export async function handler (argv) {
106106
}
107107
const { file, bind, query } = argv
108108
const _query = getQuery(file, query)
109-
const db = connect(argv.connectionOptions)
109+
const db = getXmlRpcClient(argv.connectionOptions)
110110

111111
return await execute(db, _query, bind)
112112
}

commands/get.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { resolve, join, posix, dirname, basename } from 'node:path'
22
import { statSync, existsSync, mkdirSync } from 'node:fs'
33
import { writeFile } from 'node:fs/promises'
4-
import { connect } from '@existdb/node-exist'
4+
import { getXmlRpcClient } from '@existdb/node-exist'
55
import Bottleneck from 'bottleneck'
66
import { getGlobMatcher } from '../utility/glob.js'
77

@@ -379,7 +379,7 @@ export async function handler (argv) {
379379

380380
const target = argv.target ? argv.target : '.'
381381

382-
const db = connect(argv.connectionOptions)
382+
const db = getXmlRpcClient(argv.connectionOptions)
383383
const version = await db.server.version()
384384
argv.version = version
385385

commands/info.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { connect } from '@existdb/node-exist'
1+
import { getXmlRpcClient } from '@existdb/node-exist'
22
import { readXquery } from '../utility/xq.js'
33

44
/**
@@ -59,5 +59,5 @@ export async function handler (argv) {
5959
return 0
6060
}
6161
const { connectionOptions } = argv
62-
return info(connect(connectionOptions), argv)
62+
return info(getXmlRpcClient(connectionOptions), argv)
6363
}

commands/list.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import chalk from 'chalk'
2-
import { connect, getMimeType } from '@existdb/node-exist'
2+
import { getXmlRpcClient, getMimeType } from '@existdb/node-exist'
33
import { readXquery } from '../utility/xq.js'
44
import { getDateFormatter } from '../utility/colored-date.js'
55
import { multiSort } from '../utility/sorter.js'
@@ -592,7 +592,7 @@ export async function handler (argv) {
592592
return 1
593593
}
594594

595-
const db = connect(argv.connectionOptions)
595+
const db = getXmlRpcClient(argv.connectionOptions)
596596

597597
return ls(db, collection, argv)
598598
}

commands/package/install/github.js

Lines changed: 50 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
import { got } from 'got'
1+
import { Client, interceptors, fetch } from 'undici'
22
import { valid, gt, lt, eq } from 'semver'
33
import chalk from 'chalk'
44

5-
import { connect, getRestClient } from '@existdb/node-exist'
5+
import { getXmlRpcClient, getRestClient } from '@existdb/node-exist'
66

77
import { isDBAdmin, getUserInfo } from '../../../utility/connection.js'
88
import {
@@ -12,9 +12,24 @@ import {
1212
} from '../../../utility/package.js'
1313
import { logFailure, logSuccess, logSkipped } from '../../../utility/message.js'
1414

15-
async function getRelease (api, owner, repo, release, assetFilter, verbose) {
15+
/**
16+
* @typedef { import("undici").Dispatcher.ComposedDispatcher } Dispatcher.ComposedDispatcher
17+
*/
18+
19+
/**
20+
* get the release information from Github API
21+
* @param {Dispatcher.ComposedDispatcher} api
22+
* @param {String} address the api address
23+
* @param {String} owner the owner of the repo
24+
* @param {String} repo the name of the repo
25+
* @param {String} [release] the specific release naem (optional)
26+
* @param {String} assetFilter the pattern to find the XAR
27+
* @param {boolean} verbose display more information
28+
* @returns {Promise<{ xarName: string, packageContents: string, releaseName: string, tagName:string }>} release info
29+
*/
30+
async function getRelease (api, origin, owner, repo, release, assetFilter, verbose) {
1631
const tag = release === 'latest' ? release : 'tags/' + release
17-
const path = `repos/${owner}/${repo}/releases/${tag}`
32+
const path = `/repos/${owner}/${repo}/releases/${tag}`
1833
/**
1934
* @type {unknown[]}
2035
*/
@@ -28,14 +43,15 @@ async function getRelease (api, owner, repo, release, assetFilter, verbose) {
2843
*/
2944
let tagName
3045
try {
31-
const result = await got.get(path, { prefixUrl: api }).json()
46+
const { body } = await api.request({ method: 'GET', path })
47+
const result = await body.json()
3248
// The name is not always filled in. Fall back to the tag_name if it is absent
3349
releaseName = result.name || result.tag_name
3450
assets = result.assets
3551
tagName = result.tag_name
3652
} catch (e) {
3753
throw Error(
38-
`Could not get release from: ${e.options.url} ${e.response.statusCode}: ${e.response.statusMessage}`
54+
`Could not get release from: ${origin}${path} ${e.statusCode}: ${e.body.message}`
3955
)
4056
}
4157
const filteredAssets = assets.filter(assetFilter)
@@ -59,6 +75,15 @@ async function getRelease (api, owner, repo, release, assetFilter, verbose) {
5975
}
6076
}
6177

78+
/**
79+
* Install a package after it was uploaded
80+
* @param {import('@existdb/node-exist').NodeExistXmlRpcClient} db the XML-RPC client connected to an exist-db
81+
* @param {Function} upload a function uploading the XAR package
82+
* @param {string} xarName the name of the XAR package
83+
* @param {Readable} contents the ReadableStream that will be put to the database
84+
* @param {string} registry the URL to the registry that will be used ot resolve dependencies
85+
* @returns {Promise<{ success: boolean, error?: Error }>} the result of the installation
86+
*/
6287
async function install (db, upload, xarName, contents, registry) {
6388
const xarDisplay = chalk.dim(xarName)
6489
const uploadResult = await upload(contents, xarName)
@@ -128,6 +153,14 @@ export const builder = (yargs) => {
128153
.options(options)
129154
}
130155

156+
const requestHeaderInterceptor = (baseheaders) => dispatch => {
157+
return (opts, handler) => {
158+
const { headers } = opts
159+
opts.headers = { ...headers, ...baseheaders }
160+
return dispatch(opts, handler)
161+
}
162+
}
163+
131164
export async function handler (argv) {
132165
if (argv.help) {
133166
return 0
@@ -148,7 +181,7 @@ export async function handler (argv) {
148181
} = argv
149182

150183
const repo = argv.repo && argv.repo !== '' ? argv.repo : abbrev
151-
const db = connect(connectionOptions)
184+
const db = getXmlRpcClient(connectionOptions)
152185

153186
// check permissions (and therefore implicitly the connection)
154187
const user = await getUserInfo(db)
@@ -158,7 +191,7 @@ export async function handler (argv) {
158191
)
159192
}
160193

161-
const restClient = await getRestClient(connectionOptions)
194+
const restClient = getRestClient(connectionOptions)
162195
// check rest connection
163196
await restClient.get('db')
164197
const upload = putPackage.bind(null, db, restClient)
@@ -170,11 +203,16 @@ export async function handler (argv) {
170203
}
171204

172205
const installedVersion = (await getInstalledPackageMeta(db, abbrev)).version
206+
const apiClient = new Client(api).compose([
207+
requestHeaderInterceptor({ 'User-Agent': 'xst/undici.Client' }),
208+
interceptors.responseError({ throwOnError: true })
209+
])
173210

174211
if (verbose) {
175212
console.log(`Preparing to install ${owner}/${repo} at version ${release}`)
176213
}
177214
const { xarName, packageContents, releaseName, tagName } = await getRelease(
215+
apiClient,
178216
api,
179217
owner,
180218
repo,
@@ -219,8 +257,10 @@ export async function handler (argv) {
219257
}
220258

221259
try {
222-
const contentStream = got.stream.get(packageContents)
223-
const result = await install(db, upload, xarName, contentStream, registry)
260+
// using fetch here as the packageContents could be anywhere on the internet
261+
// and the contents might be gzipped, so we benefit from automatic decompression
262+
const { body } = await fetch(packageContents, { method: 'GET' })
263+
const result = await install(db, upload, xarName, body, registry)
224264
let action
225265
if (isDowngrade) {
226266
action = `${chalk.yellow('downgraded')} to`

commands/package/install/local.js

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { basename } from 'node:path'
33
import { valid, gt, lt, eq } from 'semver'
44
import chalk from 'chalk'
55

6-
import { connect } from '@existdb/node-exist'
6+
import { getXmlRpcClient } from '@existdb/node-exist'
77

88
import { isDBAdmin, getUserInfo } from '../../../utility/connection.js'
99
import {
@@ -15,12 +15,12 @@ import {
1515
import { logFailure, logSuccess, logSkipped } from '../../../utility/message.js'
1616

1717
/**
18-
* @typedef { import("@existdb/node-exist").NodeExist } NodeExist
18+
* @typedef { import("@existdb/node-exist").NodeExistXmlRpcClient } NodeExistXmlRpcClient
1919
*/
2020

2121
/**
22-
*
23-
* @param {NodeExist} db
22+
* Upload and install a xar package from the local filesystem
23+
* @param {NodeExistXmlRpcClient} db
2424
* @param {Function} upload
2525
* @param {String} localFilePath
2626
* @param {Boolean} force
@@ -84,7 +84,9 @@ async function install (db, upload, localFilePath, force, verbose) {
8484
logSuccess(message)
8585
return installResult
8686
} catch (e) {
87-
logFailure(`${xarDisplay} ${e.message}`)
87+
// catch request errors
88+
const message = e.statusCode ? `Request failed with status code ${e.statusCode}` : e.message
89+
logFailure(`${xarDisplay} ${message}`)
8890
return { success: false, error: e }
8991
}
9092
}
@@ -133,7 +135,7 @@ export async function handler (argv) {
133135
}
134136
})
135137

136-
const db = connect(connectionOptions)
138+
const db = getXmlRpcClient(connectionOptions)
137139

138140
// check permissions (and therefore implicitly the connection)
139141
const user = await getUserInfo(db)

commands/package/install/registry.js

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import chalk from 'chalk'
22

3-
import { connect } from '@existdb/node-exist'
3+
import { getXmlRpcClient } from '@existdb/node-exist'
44

55
import { isDBAdmin, getUserInfo } from '../../../utility/connection.js'
66
import {
@@ -34,10 +34,9 @@ export async function handler (argv) {
3434
if (argv.help) {
3535
return 0
3636
}
37-
3837
// main
3938
const { connectionOptions, registry, force, verbose } = argv
40-
const db = connect(connectionOptions)
39+
const db = getXmlRpcClient(connectionOptions)
4140

4241
// check permissions (and therefore implicitly the connection)
4342
const user = await getUserInfo(db)
@@ -51,7 +50,7 @@ export async function handler (argv) {
5150

5251
if (verbose) {
5352
const installedOrNot = info.version ? `already installed in version ${info.version}` : 'not installed yet'
54-
console.error(`Package ${info.name} is ${installedOrNot}.`)
53+
console.error(`Package ${info.name || argv.package} is ${installedOrNot}.`)
5554
}
5655

5756
let pkgInfo

commands/package/list.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import chalk from 'chalk'
2-
import { connect } from '@existdb/node-exist'
2+
import { getXmlRpcClient } from '@existdb/node-exist'
33
import { multiSort } from '../../utility/sorter.js'
44
import { padReducer } from '../../utility/padding.js'
55
import { getDateFormatter } from '../../utility/colored-date.js'
@@ -598,6 +598,6 @@ export async function handler (argv) {
598598
return 0
599599
}
600600

601-
const db = connect(argv.connectionOptions)
601+
const db = getXmlRpcClient(argv.connectionOptions)
602602
return await listPackages(db, argv)
603603
}

commands/package/uninstall.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
import chalk from 'chalk'
2-
import { connect } from '@existdb/node-exist'
2+
import { getXmlRpcClient } from '@existdb/node-exist'
33
import { readXquery } from '../../utility/xq.js'
44

55
const query = readXquery('uninstall.xq')
66

77
async function getUserInfo (db) {
8-
const { user } = db.client.options.basic_auth
8+
const { user } = db.connection
99
return await db.users.getUserInfo(user)
1010
}
1111

@@ -58,7 +58,7 @@ export async function handler (argv) {
5858
}
5959

6060
// check permissions (and therefore implicitly the connection)
61-
const db = connect(argv.connectionOptions)
61+
const db = getXmlRpcClient(argv.connectionOptions)
6262
const accountInfo = await getUserInfo(db)
6363
const isAdmin = accountInfo.groups.includes('dba')
6464
if (!isAdmin) {

0 commit comments

Comments
 (0)