diff --git a/.mocharc.json b/.mocharc.json index 2fc56a1..03cfbd0 100644 --- a/.mocharc.json +++ b/.mocharc.json @@ -2,4 +2,4 @@ "extension": ["ts"], "spec": "test/**/*.spec.ts", "require": "ts-node/register" - } \ No newline at end of file +} diff --git a/client/package-lock.json b/client/package-lock.json index 60eb994..86400b8 100644 --- a/client/package-lock.json +++ b/client/package-lock.json @@ -379,7 +379,6 @@ "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", "dev": true, "license": "MIT", - "peer": true, "bin": { "acorn": "bin/acorn" }, @@ -416,7 +415,6 @@ "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "fast-deep-equal": "^3.1.3", "fast-uri": "^3.0.1", @@ -541,7 +539,6 @@ } ], "license": "MIT", - "peer": true, "dependencies": { "baseline-browser-mapping": "^2.9.0", "caniuse-lite": "^1.0.30001759", @@ -2020,7 +2017,6 @@ "integrity": "sha512-Qphch25abbMNtekmEGJmeRUhLDbe+QfiWTiqpKYkpCOWY64v9eyl+KRRLmqOFA2AvKPpc9DC6+u2n76tQLBoaA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@types/eslint-scope": "^3.7.7", "@types/estree": "^1.0.8", @@ -2070,7 +2066,6 @@ "integrity": "sha512-pIDJHIEI9LR0yxHXQ+Qh95k2EvXpWzZ5l+d+jIo+RdSm9MiHfzazIxwwni/p7+x4eJZuvG1AJwgC4TNQ7NRgsg==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@discoveryjs/json-ext": "^0.5.0", "@webpack-cli/configtest": "^2.1.1", @@ -2458,8 +2453,7 @@ "version": "8.15.0", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", - "dev": true, - "peer": true + "dev": true }, "acorn-import-phases": { "version": "1.0.4", @@ -2479,7 +2473,6 @@ "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", "dev": true, - "peer": true, "requires": { "fast-deep-equal": "^3.1.3", "fast-uri": "^3.0.1", @@ -2553,7 +2546,6 @@ "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.1.tgz", "integrity": "sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA==", "dev": true, - "peer": true, "requires": { "baseline-browser-mapping": "^2.9.0", "caniuse-lite": "^1.0.30001759", @@ -3541,7 +3533,6 @@ "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.104.1.tgz", "integrity": "sha512-Qphch25abbMNtekmEGJmeRUhLDbe+QfiWTiqpKYkpCOWY64v9eyl+KRRLmqOFA2AvKPpc9DC6+u2n76tQLBoaA==", "dev": true, - "peer": true, "requires": { "@types/eslint-scope": "^3.7.7", "@types/estree": "^1.0.8", @@ -3575,7 +3566,6 @@ "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-5.1.4.tgz", "integrity": "sha512-pIDJHIEI9LR0yxHXQ+Qh95k2EvXpWzZ5l+d+jIo+RdSm9MiHfzazIxwwni/p7+x4eJZuvG1AJwgC4TNQ7NRgsg==", "dev": true, - "peer": true, "requires": { "@discoveryjs/json-ext": "^0.5.0", "@webpack-cli/configtest": "^2.1.1", diff --git a/client/src/extension.ts b/client/src/extension.ts index 7cfe3e3..bbd724d 100644 --- a/client/src/extension.ts +++ b/client/src/extension.ts @@ -12,7 +12,7 @@ import { Task, TaskExecution, QuickPickItem } from 'vscode'; import { LanguageClient, LanguageClientOptions, TransportKind, GenericNotificationHandler, RevealOutputChannelOn } from "vscode-languageclient/node"; -import QueryResultsProvider from './query-results-provider'; +import QueryResultsProvider, { CursorState } from './query-results-provider'; class TaskPickItem implements QuickPickItem { label: string = ''; @@ -230,6 +230,24 @@ export function activate(extensionContext: ExtensionContext) { taskStatusbar.tooltip = "eXist-db: click to configure automatic synchronization"; taskStatusbar.command = "existdb.control-sync"; + // Output format status bar + const formatStatusbar = Window.createStatusBarItem(StatusBarAlignment.Right, 0); + function updateFormatStatusbar() { + const config = Workspace.getConfiguration('existdb'); + const method = config.get('query.serializationMethod', 'adaptive'); + const label = method.charAt(0).toUpperCase() + method.slice(1); + formatStatusbar.text = `$(symbol-string) ${label}`; + formatStatusbar.tooltip = 'eXist-db: click to change output format'; + formatStatusbar.command = 'existdb.setOutputFormat'; + formatStatusbar.show(); + } + updateFormatStatusbar(); + Workspace.onDidChangeConfiguration(e => { + if (e.affectsConfiguration('existdb.query')) { + updateFormatStatusbar(); + } + }); + async function updateTaskStatusbarVisibility() { if (!Workspace.workspaceFolders || Workspace.workspaceFolders.length === 0) { taskStatusbar.hide(); @@ -395,94 +413,160 @@ export function activate(extensionContext: ExtensionContext) { }); context.subscriptions.push(command); + function getClientForUri(uri: Uri): LanguageClient | undefined { + let folder = Workspace.getWorkspaceFolder(uri); + if (!folder || uri.scheme === 'untitled') { + return defaultClient; + } + folder = getOuterMostWorkspaceFolder(folder); + return clients.get(folder.uri.toString()); + } + + function getSerializationOptions(queryText: string): Record { + const config = Workspace.getConfiguration('existdb'); + const options: Record = { + method: config.get('query.serializationMethod', 'adaptive'), + indent: config.get('query.indent', true) ? 'yes' : 'no' + }; + // Auto-enable highlight-matches for Lucene full-text queries + if (/\bft:(query|search)\b/.test(queryText)) { + options['highlight-matches'] = 'both'; + } + return options; + } + + function formatResultItems(items: any[], output: string): string { + if (!Array.isArray(items) || items.length === 0) { + return ''; + } + return items.map((item: any) => { + if (typeof item === 'string') { + return item; + } + return item.value != null ? String(item.value) : ''; + }).join('\n'); + } + + function buildHeader(hits: number, elapsed: string | number, output: string, showing: number): string { + let message = `Query returned ${hits} in ${elapsed}ms.`; + if (hits > showing) { + message += ` Showing ${showing} of ${hits} items.`; + } + switch (output) { + case 'xml': + case 'html': + case 'html5': + return `\n`; + case 'json': + return ''; + default: + return `(: ${message} :)\n`; + } + } + + function getLangForOutput(output: string): string { + switch (output) { + case 'adaptive': + return 'xquery'; + case 'html': + case 'html5': + return 'html'; + case 'json': + return 'json'; + default: + return 'xml'; + } + } + + function displayResults(queryResult: any, resultsProvider: QueryResultsProvider) { + const hits = typeof queryResult.hits === 'string' ? parseInt(queryResult.hits) : (queryResult.hits || 0); + const elapsed = queryResult.elapsed || '0'; + const output = queryResult.output || 'adaptive'; + + // Cursor-based results: items come as array from cursor:fetch + let content: string; + let showing: number; + if (queryResult.cursor && Array.isArray(queryResult.results)) { + const formatted = formatResultItems(queryResult.results, output); + showing = queryResult.results.length; + content = buildHeader(hits, elapsed, output, showing) + formatted; + + // Track cursor state for paging + resultsProvider.cursorState = { + cursor: queryResult.cursor, + hits, + fetched: showing, + output, + pageSize: 100 + }; + } else { + // Legacy string results + content = queryResult.results || ''; + showing = Math.min(hits, 100); + if (hits) { + content = buildHeader(hits, elapsed, output, showing) + content; + } + resultsProvider.clearCursor(); + } + + if (output === 'html' || output === 'html5' || output === 'xhtml') { + const panel = Window.createWebviewPanel( + 'existdb-query', + 'eXistdb Query Result', + ViewColumn.Beside + ); + panel.webview.html = content; + resultsProvider.clearCursor(); + } else { + const lang = getLangForOutput(output); + resultsProvider.update(content); + Workspace.openTextDocument(resultsProvider.queryResultsUri).then((document) => { + Languages.setTextDocumentLanguage(document, lang); + Window.showTextDocument(document, { viewColumn: ViewColumn.Beside, preview: true, preserveFocus: true }); + }); + } + } + command = commands.registerCommand('existdb.execute', () => { + // Close any previous cursor before starting a new query + if (resultsProvider.cursorState) { + const prevCursor = resultsProvider.cursorState.cursor; + resultsProvider.clearCursor(); + const editor = Window.activeTextEditor; + if (editor) { + const client = getClientForUri(editor.document.uri); + if (client) { + client.sendRequest('workspace/executeCommand', { + command: 'closeCursor', + arguments: [prevCursor] + }).catch(() => {}); + } + } + } + Window.withProgress({ location: ProgressLocation.Notification, title: "Executing query!", cancellable: false }, (progress) => { - return new Promise((resolve, reject) => { + return new Promise((resolve, reject) => { const editor = Window.activeTextEditor; if (editor) { const text = editor.document.getText(); const uri = editor.document.uri; - let folder = Workspace.getWorkspaceFolder(uri); - let result; - if ((!folder || uri.scheme === 'untitled')) { - result = defaultClient.sendRequest('workspace/executeCommand', { + const client = getClientForUri(uri); + if (client) { + const serializationOptions = getSerializationOptions(text); + client.sendRequest('workspace/executeCommand', { command: 'execute', - arguments: [uri.toString(), text] - }); - } else { - folder = getOuterMostWorkspaceFolder(folder); - const client = clients.get(folder.uri.toString()); - if (client) { - result = client.sendRequest('workspace/executeCommand', { - command: 'execute', - arguments: [uri.toString(), text] - }); - } - } - if (result) { - result.then((queryResult: any) => { + arguments: [uri.toString(), text, serializationOptions] + }).then((queryResult: any) => { if (!queryResult || typeof queryResult !== 'object') { reject(); return; } - let content: string = queryResult.results || ''; - if (queryResult.hits) { - const hits = typeof queryResult.hits === 'string' ? parseInt(queryResult.hits) : queryResult.hits; - const elapsed = queryResult.elapsed || '0'; - let message = `Query returned ${hits} in ${elapsed}ms.`; - if (hits > 100) { - message += ' Showing first 100 results.'; - } - switch (queryResult.output) { - case 'xml': - case 'html': - case 'html5': - content = `\n${queryResult.results || ''}`; - break; - case 'json': - content = queryResult.results || ''; - break; - default: - content = `(: ${message} :)\n${queryResult.results || ''}`; - break; - } - } - if (queryResult.output === 'html' || queryResult.output === 'html5' || - queryResult.output === 'xhtml') { - const panel = Window.createWebviewPanel( - 'existdb-query', - 'eXistdb Query Result', - ViewColumn.Beside - ); - - panel.webview.html = content; - } else { - let lang: string; - switch (queryResult.output) { - case 'adaptive': - lang = 'xquery'; - break; - case 'html': - case 'html5': - lang = 'html'; - break; - case 'json': - lang = 'json'; - break; - default: - lang = 'xml'; - } - resultsProvider.update(content); - Workspace.openTextDocument(resultsProvider.queryResultsUri).then((document) => { - Languages.setTextDocumentLanguage(document, lang); - Window.showTextDocument(document, { viewColumn: ViewColumn.Beside, preview: true, preserveFocus: true }); - }); - } - resolve(null); + displayResults(queryResult, resultsProvider); + resolve(); }).catch((error) => { Window.showWarningMessage(`Could not query server: ${error}`); reject(); @@ -494,6 +578,81 @@ export function activate(extensionContext: ExtensionContext) { }); context.subscriptions.push(command); + command = commands.registerCommand('existdb.loadMoreResults', () => { + const state = resultsProvider.cursorState; + if (!state) { + Window.showInformationMessage('No more results to load.'); + return; + } + if (state.fetched >= state.hits) { + Window.showInformationMessage('All results have been loaded.'); + return; + } + const editor = Window.activeTextEditor; + if (!editor) { + return; + } + const client = getClientForUri(editor.document.uri); + if (!client) { + return; + } + + Window.withProgress({ + location: ProgressLocation.Notification, + title: "Loading more results...", + cancellable: false + }, () => { + const start = state.fetched + 1; + const count = state.pageSize; + const queryText = editor.document.getText(); + const serializationOptions = getSerializationOptions(queryText); + return client.sendRequest('workspace/executeCommand', { + command: 'fetch', + arguments: [state.cursor, start, count, serializationOptions] + }).then((items: any) => { + if (Array.isArray(items) && items.length > 0) { + const page = '\n' + formatResultItems(items, state.output); + state.fetched += items.length; + resultsProvider.appendResults(page); + } + if (state.fetched >= state.hits) { + // All results fetched — close cursor + client.sendRequest('workspace/executeCommand', { + command: 'closeCursor', + arguments: [state.cursor] + }).catch(() => {}); + resultsProvider.clearCursor(); + Window.showInformationMessage('All results loaded.'); + } + }).catch((error) => { + Window.showWarningMessage(`Failed to fetch results: ${error}`); + }); + }); + }); + context.subscriptions.push(command); + + command = commands.registerCommand('existdb.setOutputFormat', () => { + const config = Workspace.getConfiguration('existdb'); + const current = config.get('query.serializationMethod', 'adaptive'); + const formats = [ + { label: 'Adaptive', value: 'adaptive', description: 'XQuery default output' }, + { label: 'XML', value: 'xml', description: 'XML serialization' }, + { label: 'JSON', value: 'json', description: 'JSON serialization' }, + { label: 'Text', value: 'text', description: 'Plain text' } + ]; + const items = formats.map(f => ({ + label: f.value === current ? `$(check) ${f.label}` : f.label, + description: f.description, + value: f.value + })); + Window.showQuickPick(items, { placeHolder: 'Select output format' }).then(pick => { + if (pick) { + config.update('query.serializationMethod', (pick as any).value, false); + } + }); + }); + context.subscriptions.push(command); + command = commands.registerCommand('existdb.deploy', (ev) => { if (ev && ev.path) { deploy({ path: ev.path }); diff --git a/client/src/query-results-provider.ts b/client/src/query-results-provider.ts index ac0d64d..a206220 100644 --- a/client/src/query-results-provider.ts +++ b/client/src/query-results-provider.ts @@ -1,7 +1,19 @@ import * as vscode from 'vscode'; /** - * Content provider for XQuery execution results + * Tracks an active cursor-based query result set + */ +export interface CursorState { + cursor: string; + hits: number; + fetched: number; + output: string; + pageSize: number; +} + +/** + * Content provider for XQuery execution results. + * Supports cursor-based paging: results can be appended as new pages are fetched. */ export default class QueryResultsProvider implements vscode.TextDocumentContentProvider { public results: string = ''; @@ -9,6 +21,9 @@ export default class QueryResultsProvider implements vscode.TextDocumentContentP public queryResultsUri = vscode.Uri.parse("xmldb-query://results"); private changeEvent = new vscode.EventEmitter(); + /** Active cursor state for paged results; null when using legacy execution */ + public cursorState: CursorState | null = null; + public provideTextDocumentContent(uri: vscode.Uri, token: vscode.CancellationToken): string | Promise { return this.results; } @@ -21,4 +36,16 @@ export default class QueryResultsProvider implements vscode.TextDocumentContentP this.results = results; this.changeEvent.fire(this.queryResultsUri); } -} \ No newline at end of file + + /** + * Append a new page of results to existing content. + */ + public appendResults(page: string) { + this.results += page; + this.changeEvent.fire(this.queryResultsUri); + } + + public clearCursor() { + this.cursorState = null; + } +} diff --git a/package-lock.json b/package-lock.json index 77d211a..ebeed33 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12,10 +12,13 @@ "devDependencies": { "@types/mocha": "^9.1.1", "@types/node": "^18.7.9", + "@types/sinon": "^21.0.0", "assert": "^2.0.0", + "axios": "^1.13.6", "copy-webpack-plugin": "^11.0.0", "mocha": "^10.0.0", "rimraf": "^3.0.2", + "sinon": "^21.0.3", "ts-loader": "^9.3.1", "ts-node": "^10.9.1", "tslint": "^6.1.3", @@ -178,6 +181,47 @@ "node": ">= 8" } }, + "node_modules/@sinonjs/commons": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.1.tgz", + "integrity": "sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "type-detect": "4.0.8" + } + }, + "node_modules/@sinonjs/fake-timers": { + "version": "15.1.1", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-15.1.1.tgz", + "integrity": "sha512-cO5W33JgAPbOh07tvZjUOJ7oWhtaqGHiZw+11DPbyqh2kHTBc3eF/CjJDeQ4205RLQsX6rxCuYOroFQwl7JDRw==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "@sinonjs/commons": "^3.0.1" + } + }, + "node_modules/@sinonjs/samsam": { + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-9.0.3.tgz", + "integrity": "sha512-ZgYY7Dc2RW+OUdnZ1DEHg00lhRt+9BjymPKHog4PRFzr1U3MbK57+djmscWyKxzO1qfunHqs4N45WWyKIFKpiQ==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "@sinonjs/commons": "^3.0.1", + "type-detect": "^4.1.0" + } + }, + "node_modules/@sinonjs/samsam/node_modules/type-detect": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.1.0.tgz", + "integrity": "sha512-Acylog8/luQ8L7il+geoSxhEkazvkslg7PSNKOX59mbB9cOveP5aq9h74Y7YU8yDpJwetzQQrfIwtf4Wp4LKcw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, "node_modules/@tsconfig/node10": { "version": "1.0.9", "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz", @@ -251,11 +295,27 @@ "integrity": "sha512-GRaXQx6jGfL8sKfaIDD6OupbIHBr9jv7Jnaml9tB7l4v068PAOXqfcujMMo5PhbIs6ggR1XODELqahT2R8v0fg==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "undici-types": "~5.26.4" } }, + "node_modules/@types/sinon": { + "version": "21.0.0", + "resolved": "https://registry.npmjs.org/@types/sinon/-/sinon-21.0.0.tgz", + "integrity": "sha512-+oHKZ0lTI+WVLxx1IbJDNmReQaIsQJjN2e7UUrJHEeByG7bFeKJYsv1E75JxTQ9QKJDp21bAa/0W2Xo4srsDnw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/sinonjs__fake-timers": "*" + } + }, + "node_modules/@types/sinonjs__fake-timers": { + "version": "15.0.1", + "resolved": "https://registry.npmjs.org/@types/sinonjs__fake-timers/-/sinonjs__fake-timers-15.0.1.tgz", + "integrity": "sha512-Ko2tjWJq8oozHzHV+reuvS5KYIRAokHnGbDwGh/J64LntgpbuylF74ipEL24HCyRjf9FOlBiBHWBR1RlVKsI1w==", + "dev": true, + "license": "MIT" + }, "node_modules/@ungap/promise-all-settled": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz", @@ -482,7 +542,6 @@ "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", "dev": true, "license": "MIT", - "peer": true, "bin": { "acorn": "bin/acorn" }, @@ -626,6 +685,25 @@ "util": "^0.12.0" } }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/axios": { + "version": "1.13.6", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.13.6.tgz", + "integrity": "sha512-ChTCHMouEe2kn713WHbQGcuYrr6fXTBiu460OTwWrWob16g1bXn4vtz07Ope7ewMozJAnEquLk5lWQWtBig9DQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "follow-redirects": "^1.15.11", + "form-data": "^4.0.5", + "proxy-from-env": "^1.1.0" + } + }, "node_modules/balanced-match": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", @@ -700,7 +778,6 @@ } ], "license": "MIT", - "peer": true, "dependencies": { "baseline-browser-mapping": "^2.9.0", "caniuse-lite": "^1.0.30001759", @@ -732,6 +809,20 @@ "node": ">=0.10.0" } }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/camelcase": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", @@ -876,6 +967,19 @@ "integrity": "sha512-3tlv/dIP7FWvj3BsbHrGLJ6l/oKh1O3TcgBqMn+yyCagOxc23fyzDS6HypQbgxWbkpDnf52p1LuR4eWDQ/K9WQ==", "dev": true }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dev": true, + "license": "MIT", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, "node_modules/commander": { "version": "2.20.1", "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.1.tgz", @@ -988,6 +1092,16 @@ "object-keys": "^1.0.12" } }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.4.0" + } + }, "node_modules/diff": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.1.tgz", @@ -1007,6 +1121,21 @@ "node": ">=8" } }, + "node_modules/dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/electron-to-chromium": { "version": "1.5.267", "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.267.tgz", @@ -1065,6 +1194,26 @@ "string.prototype.trimright": "^2.1.0" } }, + "node_modules/es-define-property": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, "node_modules/es-module-lexer": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-2.0.0.tgz", @@ -1072,6 +1221,35 @@ "dev": true, "license": "MIT" }, + "node_modules/es-object-atoms": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", + "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-set-tostringtag": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", + "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/es-to-primitive": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.0.tgz", @@ -1284,6 +1462,44 @@ "flat": "cli.js" } }, + "node_modules/follow-redirects": { + "version": "1.15.11", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.11.tgz", + "integrity": "sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "license": "MIT", + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "node_modules/form-data": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.5.tgz", + "integrity": "sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==", + "dev": true, + "license": "MIT", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "es-set-tostringtag": "^2.1.0", + "hasown": "^2.0.2", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", @@ -1323,6 +1539,45 @@ "node": "6.* || 8.* || >= 10.*" } }, + "node_modules/get-intrinsic": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "function-bind": "^1.1.2", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "dev": true, + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/glob": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", @@ -1382,6 +1637,19 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/gopd": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/graceful-fs": { "version": "4.2.11", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", @@ -1409,10 +1677,33 @@ } }, "node_modules/has-symbols": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.0.tgz", - "integrity": "sha1-uhqPGvKg/DllD1yFA2dwQSIGO0Q=", - "dev": true + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-symbols": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, "node_modules/hasown": { "version": "2.0.2", @@ -1865,6 +2156,16 @@ "integrity": "sha512-c3sIjNUow0+8swNwVpqoH4YCShKNFkMaw6oH1mNS2haDZQqkeZFlHS3dhoeEbKKmJB4vXpJucU6oH75aDYeE9g==", "dev": true }, + "node_modules/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, "node_modules/merge-stream": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", @@ -2320,6 +2621,13 @@ "node": ">=8" } }, + "node_modules/proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", + "dev": true, + "license": "MIT" + }, "node_modules/queue-microtask": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", @@ -2517,7 +2825,6 @@ "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "fast-deep-equal": "^3.1.3", "fast-uri": "^3.0.1", @@ -2601,6 +2908,57 @@ "node": ">=8" } }, + "node_modules/sinon": { + "version": "21.0.3", + "resolved": "https://registry.npmjs.org/sinon/-/sinon-21.0.3.tgz", + "integrity": "sha512-0x8TQFr8EjADhSME01u1ZK31yv2+bd6Z5NrBCHVM+n4qL1wFqbxftmeyi3bwlr49FbbzRfrqSFOpyHCOh/YmYA==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "@sinonjs/commons": "^3.0.1", + "@sinonjs/fake-timers": "^15.1.1", + "@sinonjs/samsam": "^9.0.3", + "diff": "^8.0.3", + "supports-color": "^7.2.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/sinon" + } + }, + "node_modules/sinon/node_modules/diff": { + "version": "8.0.3", + "resolved": "https://registry.npmjs.org/diff/-/diff-8.0.3.tgz", + "integrity": "sha512-qejHi7bcSD4hQAZE0tNAawRK1ZtafHDmMTMkrrIGgSLl7hTnQHmKCeB45xAcbfTqK2zowkM3j3bHt/4b/ARbYQ==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/sinon/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/sinon/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/slash": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-4.0.0.tgz", @@ -3039,13 +3397,22 @@ "typescript": ">=2.1.0 || >=2.1.0-dev || >=2.2.0-dev || >=2.3.0-dev || >=2.4.0-dev || >=2.5.0-dev || >=2.6.0-dev || >=2.7.0-dev || >=2.8.0-dev || >=2.9.0-dev || >= 3.0.0-dev || >= 3.1.0-dev" } }, + "node_modules/type-detect": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, "node_modules/typescript": { "version": "4.9.5", "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", "dev": true, "license": "Apache-2.0", - "peer": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -3131,7 +3498,6 @@ "integrity": "sha512-Qphch25abbMNtekmEGJmeRUhLDbe+QfiWTiqpKYkpCOWY64v9eyl+KRRLmqOFA2AvKPpc9DC6+u2n76tQLBoaA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@types/eslint-scope": "^3.7.7", "@types/estree": "^1.0.8", @@ -3181,7 +3547,6 @@ "integrity": "sha512-NLhDfH/h4O6UOy+0LSso42xvYypClINuMNBVVzX4vX98TmTaTUxwRbXdhucbFMd2qLaCTcLq/PdYrvi8onw90w==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@discoveryjs/json-ext": "^0.5.0", "@webpack-cli/configtest": "^1.2.0", diff --git a/package.json b/package.json index 3b9a911..c9c67de 100644 --- a/package.json +++ b/package.json @@ -10,7 +10,7 @@ "vscode:prepublish": "npm run clean && npm run webpack", "test-compile": "tsc -p ./", "watch": "tsc -b -w", - "test": "npm run test-compile && mocha", + "test": "TS_NODE_PROJECT=test/tsconfig.json mocha", "postinstall": "cd client && npm install && cd ../server && npm install && cd ../sync && npm install && cd ..", "webpack": "cd server && npm run webpack && cd ../client && npm run webpack && cd ../sync && npm run webpack", "webpack-dev": "cd server && npm run webpack-dev && cd ../client && npm run webpack-dev && cd ../sync && npm run webpack-dev", @@ -63,6 +63,16 @@ "command": "existdb.deploy", "title": "Deploy package to the database", "category": "eXist-db" + }, + { + "command": "existdb.loadMoreResults", + "title": "Load more query results", + "category": "eXist-db" + }, + { + "command": "existdb.setOutputFormat", + "title": "Set Output Format", + "category": "eXist-db" } ], "menus": { @@ -151,6 +161,25 @@ "type": "string", "default": null, "description": "Path to the app collection within eXist" + }, + "existdb.query.serializationMethod": { + "scope": "resource", + "type": "string", + "default": "adaptive", + "enum": ["adaptive", "xml", "json", "text"], + "enumDescriptions": [ + "Adaptive output (XQuery default)", + "XML serialization", + "JSON serialization", + "Plain text" + ], + "description": "Default serialization method for query results" + }, + "existdb.query.indent": { + "scope": "resource", + "type": "boolean", + "default": true, + "description": "Indent query results for readability" } } }, @@ -187,10 +216,13 @@ "devDependencies": { "@types/mocha": "^9.1.1", "@types/node": "^18.7.9", + "@types/sinon": "^21.0.0", "assert": "^2.0.0", + "axios": "^1.13.6", "copy-webpack-plugin": "^11.0.0", "mocha": "^10.0.0", "rimraf": "^3.0.2", + "sinon": "^21.0.3", "ts-loader": "^9.3.1", "ts-node": "^10.9.1", "tslint": "^6.1.3", diff --git a/server/package-lock.json b/server/package-lock.json index 6678b15..16884f5 100644 --- a/server/package-lock.json +++ b/server/package-lock.json @@ -10,40 +10,16 @@ "license": "GPL-3.0-or-later", "dependencies": { "axios": "^1.7.0", + "prettier": "^3.8.1", + "prettier-plugin-xquery": "^1.5.0", "vscode-languageserver": "^9.0.0", "vscode-languageserver-textdocument": "^1.0.12", - "vscode-uri": "^3.0.8", - "xqlint": "github:eXistSolutions/xqlint#exist-syntax" + "vscode-uri": "^3.0.8" }, - "devDependencies": {}, "engines": { "node": "^18.0.0" } }, - "node_modules/ansi-regex": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-0.2.1.tgz", - "integrity": "sha1-DY6UaWej2BQ/k+JOKYUl/BsiNfk=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ansi-styles": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-1.1.0.tgz", - "integrity": "sha1-6uy/Zs1waIJ2Cy9GkVgrj1XXp94=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dependencies": { - "sprintf-js": "~1.0.2" - } - }, "node_modules/asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", @@ -89,29 +65,6 @@ "node": ">= 0.4" } }, - "node_modules/chalk": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-0.5.1.tgz", - "integrity": "sha1-Zjs6ZItotV0EaQ1JFnqoN4WPIXQ=", - "dependencies": { - "ansi-styles": "^1.1.0", - "escape-string-regexp": "^1.0.0", - "has-ansi": "^0.1.0", - "strip-ansi": "^0.3.0", - "supports-color": "^0.2.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/colors": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/colors/-/colors-0.6.2.tgz", - "integrity": "sha1-JCP+ZnisDF2uiFLl0OW+CMmXq8w=", - "engines": { - "node": ">=0.1.90" - } - }, "node_modules/combined-stream": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", @@ -123,45 +76,6 @@ "node": ">= 0.8" } }, - "node_modules/commander": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.3.0.tgz", - "integrity": "sha1-/UMOiJgy7DU7ms0d4hfBHLPu+HM=", - "engines": { - "node": ">= 0.6.x" - } - }, - "node_modules/configstore": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/configstore/-/configstore-0.3.2.tgz", - "integrity": "sha1-JeTBbDdoq/dcWmW8YXYfSVBVtFk=", - "dependencies": { - "graceful-fs": "^3.0.1", - "js-yaml": "^3.1.0", - "mkdirp": "^0.5.0", - "object-assign": "^2.0.0", - "osenv": "^0.1.0", - "user-home": "^1.0.0", - "uuid": "^2.0.1", - "xdg-basedir": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" - }, - "node_modules/deep-extend": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", - "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", - "engines": { - "node": ">=4.0.0" - } - }, "node_modules/delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", @@ -184,25 +98,6 @@ "node": ">= 0.4" } }, - "node_modules/duplexify": { - "version": "3.7.1", - "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.7.1.tgz", - "integrity": "sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g==", - "dependencies": { - "end-of-stream": "^1.0.0", - "inherits": "^2.0.1", - "readable-stream": "^2.0.0", - "stream-shift": "^1.0.0" - } - }, - "node_modules/end-of-stream": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", - "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", - "dependencies": { - "once": "^1.4.0" - } - }, "node_modules/es-define-property": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", @@ -248,35 +143,6 @@ "node": ">= 0.4" } }, - "node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", - "bin": { - "esparse": "bin/esparse.js", - "esvalidate": "bin/esvalidate.js" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/final-fs": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/final-fs/-/final-fs-1.6.1.tgz", - "integrity": "sha1-1tzZLvb+T+jAer1WjHE1YQ7eMjY=", - "dependencies": { - "node-fs": "~0.1.5", - "when": "~2.0.1" - } - }, "node_modules/follow-redirects": { "version": "1.15.11", "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.11.tgz", @@ -355,59 +221,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/got": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/got/-/got-3.3.1.tgz", - "integrity": "sha1-5dDtSvVfw+701WAHdp2YGSvLLso=", - "dependencies": { - "duplexify": "^3.2.0", - "infinity-agent": "^2.0.0", - "is-redirect": "^1.0.0", - "is-stream": "^1.0.0", - "lowercase-keys": "^1.0.0", - "nested-error-stacks": "^1.0.0", - "object-assign": "^3.0.0", - "prepend-http": "^1.0.0", - "read-all-stream": "^3.0.0", - "timed-out": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/got/node_modules/object-assign": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-3.0.0.tgz", - "integrity": "sha1-m+3VygiXlJvKR+f/QIBi1Un1h/I=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/graceful-fs": { - "version": "3.0.12", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-3.0.12.tgz", - "integrity": "sha512-J55gaCS4iTTJfTXIxSVw3EMQckcqkpdRv3IR7gu6sq0+tbC363Zx6KH/SEwXASK9JRbhyZmVjJEVJIOxYsB3Qg==", - "dependencies": { - "natives": "^1.1.3" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/has-ansi": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-0.1.0.tgz", - "integrity": "sha1-hPJlqujA5qiKEtcCKJS3VoiUxi4=", - "dependencies": { - "ansi-regex": "^0.2.0" - }, - "bin": { - "has-ansi": "cli.js" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/has-symbols": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", @@ -447,93 +260,6 @@ "node": ">= 0.4" } }, - "node_modules/infinity-agent": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/infinity-agent/-/infinity-agent-2.0.3.tgz", - "integrity": "sha1-ReDi/3qesDCyfWK3SzdEt6esQhY=" - }, - "node_modules/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - }, - "node_modules/ini": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz", - "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==", - "deprecated": "Please update to ini >=1.3.6 to avoid a prototype pollution issue", - "engines": { - "node": "*" - } - }, - "node_modules/is-npm": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-npm/-/is-npm-1.0.0.tgz", - "integrity": "sha1-8vtjpl5JBbQGyGBydloaTceTufQ=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-redirect": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-redirect/-/is-redirect-1.0.0.tgz", - "integrity": "sha1-HQPd7VO9jbDzDCbk+V02/HyH3CQ=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" - }, - "node_modules/js-yaml": { - "version": "3.13.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", - "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", - "dependencies": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/latest-version": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/latest-version/-/latest-version-1.0.1.tgz", - "integrity": "sha1-cs/Ebj6NG+ZR4eu1Tqn26pbzdLs=", - "dependencies": { - "package-json": "^1.0.0" - }, - "bin": { - "latest-version": "cli.js" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/lodash": { - "version": "3.10.1", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-3.10.1.tgz", - "integrity": "sha1-W/Rejkm6QYnhfUgnid/RW9FAt7Y=" - }, - "node_modules/lowercase-keys": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz", - "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/math-intrinsics": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", @@ -562,360 +288,37 @@ "node": ">= 0.6" } }, - "node_modules/minimist": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=" - }, - "node_modules/mkdirp": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", - "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", - "deprecated": "Legacy versions of mkdirp are no longer supported. Please update to mkdirp 1.x. (Note that the API surface has changed to use Promises in 1.x.)", - "dependencies": { - "minimist": "0.0.8" - }, + "node_modules/prettier": { + "version": "3.8.1", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.8.1.tgz", + "integrity": "sha512-UOnG6LftzbdaHZcKoPFtOcCKztrQ57WkHDeRD9t/PTQtmT0NHSeWWepj6pS0z/N7+08BHFDQVUrfmfMRcZwbMg==", + "license": "MIT", "bin": { - "mkdirp": "bin/cmd.js" - } - }, - "node_modules/natives": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/natives/-/natives-1.1.6.tgz", - "integrity": "sha512-6+TDFewD4yxY14ptjKaS63GVdtKiES1pTPyxn9Jb0rBqPMZ7VcCiooEhPNsr+mqHtMGxa/5c/HhcC4uPEUw/nA==", - "deprecated": "This module relies on Node.js's internals and will break at some point. Do not use it, and update to graceful-fs@4.x." - }, - "node_modules/nested-error-stacks": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/nested-error-stacks/-/nested-error-stacks-1.0.2.tgz", - "integrity": "sha1-GfYZWRUZ8JZ2mlupqG5u7sgjw88=", - "dependencies": { - "inherits": "~2.0.1" - } - }, - "node_modules/node-fs": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/node-fs/-/node-fs-0.1.7.tgz", - "integrity": "sha1-MjI8zLRsn78PwRgS1FAhzDHTJbs=", - "os": [ - "linux", - "darwin", - "freebsd", - "win32", - "smartos", - "sunos" - ], - "engines": { - "node": ">=0.1.97" - } - }, - "node_modules/object-assign": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-2.1.1.tgz", - "integrity": "sha1-Q8NuXVaf+OSBbE76i+AtJpZ8GKo=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "dependencies": { - "wrappy": "1" - } - }, - "node_modules/os-homedir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", - "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/os-tmpdir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", - "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/osenv": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.5.tgz", - "integrity": "sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==", - "dependencies": { - "os-homedir": "^1.0.0", - "os-tmpdir": "^1.0.0" - } - }, - "node_modules/package-json": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/package-json/-/package-json-1.2.0.tgz", - "integrity": "sha1-yOysCUInzfdqMWh07QXifMk5oOA=", - "dependencies": { - "got": "^3.2.0", - "registry-url": "^3.0.0" + "prettier": "bin/prettier.cjs" }, "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/pinkie": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", - "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/pinkie-promise": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", - "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", - "dependencies": { - "pinkie": "^2.0.0" + "node": ">=14" }, - "engines": { - "node": ">=0.10.0" + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" } }, - "node_modules/prepend-http": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-1.0.4.tgz", - "integrity": "sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw=", - "engines": { - "node": ">=0.10.0" + "node_modules/prettier-plugin-xquery": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/prettier-plugin-xquery/-/prettier-plugin-xquery-1.5.0.tgz", + "integrity": "sha512-W3MOTMaxuieU3RaZ7FvV0aySRUulygh1Zz7MNf1ozFMA3SZHAkX/osNcJWD+g44E37CPCQVtIUUTbMvH159JDg==", + "license": "MIT", + "dependencies": { + "prettier": "^3.6.2", + "xq-parser": "^0.3.2" } }, - "node_modules/process-nextick-args": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" - }, "node_modules/proxy-from-env": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", "license": "MIT" }, - "node_modules/q": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/q/-/q-1.0.1.tgz", - "integrity": "sha1-EYcq7t7okmgRCxCnGESP+xARKhQ=", - "engines": { - "node": ">=0.6.0", - "teleport": ">=0.2.0" - } - }, - "node_modules/rc": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", - "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", - "dependencies": { - "deep-extend": "^0.6.0", - "ini": "~1.3.0", - "minimist": "^1.2.0", - "strip-json-comments": "~2.0.1" - }, - "bin": { - "rc": "cli.js" - } - }, - "node_modules/rc/node_modules/minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=" - }, - "node_modules/read-all-stream": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/read-all-stream/-/read-all-stream-3.1.0.tgz", - "integrity": "sha1-NcPhd/IHjveJ7kv6+kNzB06u9Po=", - "dependencies": { - "pinkie-promise": "^2.0.0", - "readable-stream": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/readable-stream": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "node_modules/registry-url": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/registry-url/-/registry-url-3.1.0.tgz", - "integrity": "sha1-PU74cPc93h138M+aOBQyRE4XSUI=", - "dependencies": { - "rc": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" - }, - "node_modules/semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "bin": { - "semver": "bin/semver" - } - }, - "node_modules/semver-diff": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/semver-diff/-/semver-diff-2.1.0.tgz", - "integrity": "sha1-S7uEN8jTfksM8aaP1ybsbWRdbTY=", - "dependencies": { - "semver": "^5.0.3" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" - }, - "node_modules/stream-shift": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.0.tgz", - "integrity": "sha1-1cdSgl5TZ+eG944Y5EXqIjoVWVI=" - }, - "node_modules/string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dependencies": { - "safe-buffer": "~5.1.0" - } - }, - "node_modules/string-length": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/string-length/-/string-length-1.0.1.tgz", - "integrity": "sha1-VpcPscOFWOnnC3KL894mmsRa36w=", - "dependencies": { - "strip-ansi": "^3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/string-length/node_modules/ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/string-length/node_modules/strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dependencies": { - "ansi-regex": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/strip-ansi": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-0.3.0.tgz", - "integrity": "sha1-JfSOoiynkYfzF0pNuHWTR7sSYiA=", - "dependencies": { - "ansi-regex": "^0.2.1" - }, - "bin": { - "strip-ansi": "cli.js" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/strip-json-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/supports-color": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-0.2.0.tgz", - "integrity": "sha1-2S3iaU6z9nMjlz1649i1W0wiGQo=", - "bin": { - "supports-color": "cli.js" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/timed-out": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/timed-out/-/timed-out-2.0.0.tgz", - "integrity": "sha1-84sK6B03R9YoAB9B2vxlKs5nHAo=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/update-notifier": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-0.2.2.tgz", - "integrity": "sha1-5ps6eEtOaGoqzZj15mlEWRmW4Yc=", - "dependencies": { - "chalk": "^0.5.1", - "configstore": "^0.3.1", - "is-npm": "^1.0.0", - "latest-version": "^1.0.0", - "semver-diff": "^2.0.0", - "string-length": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/user-home": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/user-home/-/user-home-1.1.1.tgz", - "integrity": "sha1-K1viOjK2Onyd640PKNSFcko98ZA=", - "bin": { - "user-home": "cli.js" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" - }, - "node_modules/uuid": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-2.0.3.tgz", - "integrity": "sha1-Z+LoY3lyFVMN/zGOW/nc6/1Hsho=", - "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details." - }, "node_modules/vscode-jsonrpc": { "version": "8.2.0", "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-8.2.0.tgz", @@ -965,67 +368,14 @@ "integrity": "sha512-/BpdSx+yCQGnCvecbyXdxHDkuk55/G3xwnC0GqY4gmQ3j+A+g8kzzgB4Nk/SINjqn6+waqw3EgbVF2QKExkRxQ==", "license": "MIT" }, - "node_modules/when": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/when/-/when-2.0.1.tgz", - "integrity": "sha1-jYcv4V5oQkyRtLck6EjggH2rZkI=" - }, - "node_modules/wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" - }, - "node_modules/xdg-basedir": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-1.0.1.tgz", - "integrity": "sha1-FP+PY6T9vLBdW27qIrNvMDO58E4=", - "dependencies": { - "user-home": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/xqlint": { - "version": "0.3.1", - "resolved": "git+ssh://git@github.com/eXistSolutions/xqlint.git#1a98bca0649c14bad8cdc15701d9ef8779dc4d1e", - "integrity": "sha512-L069Yct51LiLLMe441N+M+BYoZnhQuNTBfjBAYnfXqa5HByHpyCvzLtNvH9mei6BS06Z0MLRg06yAizHnzTMQQ==", - "dependencies": { - "colors": "~0.6.2", - "commander": "~2.3.0", - "final-fs": "~1.6.0", - "lodash": "^3.2.0", - "q": "~1.0.0", - "update-notifier": "~0.2.0" - }, - "bin": { - "xqlint": "bin/xqlint" - }, - "engines": { - "node": ">=0.1.0", - "npm": ">=1.1.0" - } + "node_modules/xq-parser": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/xq-parser/-/xq-parser-0.3.2.tgz", + "integrity": "sha512-Xu6PBGgMyBN4rKDmOk/ik7MrPUrEfsQ7RipDfBTw+EZ/uTwvVb/DkCiXvIvay2ycLe1dlDo33xyVPThGtPFRkg==", + "license": "MIT" } }, "dependencies": { - "ansi-regex": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-0.2.1.tgz", - "integrity": "sha1-DY6UaWej2BQ/k+JOKYUl/BsiNfk=" - }, - "ansi-styles": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-1.1.0.tgz", - "integrity": "sha1-6uy/Zs1waIJ2Cy9GkVgrj1XXp94=" - }, - "argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "requires": { - "sprintf-js": "~1.0.2" - } - }, "asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", @@ -1064,23 +414,6 @@ "function-bind": "^1.1.2" } }, - "chalk": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-0.5.1.tgz", - "integrity": "sha1-Zjs6ZItotV0EaQ1JFnqoN4WPIXQ=", - "requires": { - "ansi-styles": "^1.1.0", - "escape-string-regexp": "^1.0.0", - "has-ansi": "^0.1.0", - "strip-ansi": "^0.3.0", - "supports-color": "^0.2.0" - } - }, - "colors": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/colors/-/colors-0.6.2.tgz", - "integrity": "sha1-JCP+ZnisDF2uiFLl0OW+CMmXq8w=" - }, "combined-stream": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", @@ -1089,36 +422,6 @@ "delayed-stream": "~1.0.0" } }, - "commander": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.3.0.tgz", - "integrity": "sha1-/UMOiJgy7DU7ms0d4hfBHLPu+HM=" - }, - "configstore": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/configstore/-/configstore-0.3.2.tgz", - "integrity": "sha1-JeTBbDdoq/dcWmW8YXYfSVBVtFk=", - "requires": { - "graceful-fs": "^3.0.1", - "js-yaml": "^3.1.0", - "mkdirp": "^0.5.0", - "object-assign": "^2.0.0", - "osenv": "^0.1.0", - "user-home": "^1.0.0", - "uuid": "^2.0.1", - "xdg-basedir": "^1.0.0" - } - }, - "core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" - }, - "deep-extend": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", - "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==" - }, "delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", @@ -1134,25 +437,6 @@ "gopd": "^1.2.0" } }, - "duplexify": { - "version": "3.7.1", - "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.7.1.tgz", - "integrity": "sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g==", - "requires": { - "end-of-stream": "^1.0.0", - "inherits": "^2.0.1", - "readable-stream": "^2.0.0", - "stream-shift": "^1.0.0" - } - }, - "end-of-stream": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", - "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", - "requires": { - "once": "^1.4.0" - } - }, "es-define-property": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", @@ -1182,25 +466,6 @@ "hasown": "^2.0.2" } }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" - }, - "esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==" - }, - "final-fs": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/final-fs/-/final-fs-1.6.1.tgz", - "integrity": "sha1-1tzZLvb+T+jAer1WjHE1YQ7eMjY=", - "requires": { - "node-fs": "~0.1.5", - "when": "~2.0.1" - } - }, "follow-redirects": { "version": "1.15.11", "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.11.tgz", @@ -1242,46 +507,6 @@ "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==" }, - "got": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/got/-/got-3.3.1.tgz", - "integrity": "sha1-5dDtSvVfw+701WAHdp2YGSvLLso=", - "requires": { - "duplexify": "^3.2.0", - "infinity-agent": "^2.0.0", - "is-redirect": "^1.0.0", - "is-stream": "^1.0.0", - "lowercase-keys": "^1.0.0", - "nested-error-stacks": "^1.0.0", - "object-assign": "^3.0.0", - "prepend-http": "^1.0.0", - "read-all-stream": "^3.0.0", - "timed-out": "^2.0.0" - }, - "dependencies": { - "object-assign": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-3.0.0.tgz", - "integrity": "sha1-m+3VygiXlJvKR+f/QIBi1Un1h/I=" - } - } - }, - "graceful-fs": { - "version": "3.0.12", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-3.0.12.tgz", - "integrity": "sha512-J55gaCS4iTTJfTXIxSVw3EMQckcqkpdRv3IR7gu6sq0+tbC363Zx6KH/SEwXASK9JRbhyZmVjJEVJIOxYsB3Qg==", - "requires": { - "natives": "^1.1.3" - } - }, - "has-ansi": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-0.1.0.tgz", - "integrity": "sha1-hPJlqujA5qiKEtcCKJS3VoiUxi4=", - "requires": { - "ansi-regex": "^0.2.0" - } - }, "has-symbols": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", @@ -1303,68 +528,6 @@ "function-bind": "^1.1.2" } }, - "infinity-agent": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/infinity-agent/-/infinity-agent-2.0.3.tgz", - "integrity": "sha1-ReDi/3qesDCyfWK3SzdEt6esQhY=" - }, - "inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - }, - "ini": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz", - "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==" - }, - "is-npm": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-npm/-/is-npm-1.0.0.tgz", - "integrity": "sha1-8vtjpl5JBbQGyGBydloaTceTufQ=" - }, - "is-redirect": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-redirect/-/is-redirect-1.0.0.tgz", - "integrity": "sha1-HQPd7VO9jbDzDCbk+V02/HyH3CQ=" - }, - "is-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=" - }, - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" - }, - "js-yaml": { - "version": "3.13.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", - "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", - "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - } - }, - "latest-version": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/latest-version/-/latest-version-1.0.1.tgz", - "integrity": "sha1-cs/Ebj6NG+ZR4eu1Tqn26pbzdLs=", - "requires": { - "package-json": "^1.0.0" - } - }, - "lodash": { - "version": "3.10.1", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-3.10.1.tgz", - "integrity": "sha1-W/Rejkm6QYnhfUgnid/RW9FAt7Y=" - }, - "lowercase-keys": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz", - "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==" - }, "math-intrinsics": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", @@ -1383,270 +546,25 @@ "mime-db": "1.40.0" } }, - "minimist": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=" - }, - "mkdirp": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", - "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", - "requires": { - "minimist": "0.0.8" - } - }, - "natives": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/natives/-/natives-1.1.6.tgz", - "integrity": "sha512-6+TDFewD4yxY14ptjKaS63GVdtKiES1pTPyxn9Jb0rBqPMZ7VcCiooEhPNsr+mqHtMGxa/5c/HhcC4uPEUw/nA==" - }, - "nested-error-stacks": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/nested-error-stacks/-/nested-error-stacks-1.0.2.tgz", - "integrity": "sha1-GfYZWRUZ8JZ2mlupqG5u7sgjw88=", - "requires": { - "inherits": "~2.0.1" - } - }, - "node-fs": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/node-fs/-/node-fs-0.1.7.tgz", - "integrity": "sha1-MjI8zLRsn78PwRgS1FAhzDHTJbs=" - }, - "object-assign": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-2.1.1.tgz", - "integrity": "sha1-Q8NuXVaf+OSBbE76i+AtJpZ8GKo=" - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "requires": { - "wrappy": "1" - } - }, - "os-homedir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", - "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=" - }, - "os-tmpdir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", - "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=" - }, - "osenv": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.5.tgz", - "integrity": "sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==", - "requires": { - "os-homedir": "^1.0.0", - "os-tmpdir": "^1.0.0" - } - }, - "package-json": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/package-json/-/package-json-1.2.0.tgz", - "integrity": "sha1-yOysCUInzfdqMWh07QXifMk5oOA=", - "requires": { - "got": "^3.2.0", - "registry-url": "^3.0.0" - } - }, - "pinkie": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", - "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=" + "prettier": { + "version": "3.8.1", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.8.1.tgz", + "integrity": "sha512-UOnG6LftzbdaHZcKoPFtOcCKztrQ57WkHDeRD9t/PTQtmT0NHSeWWepj6pS0z/N7+08BHFDQVUrfmfMRcZwbMg==" }, - "pinkie-promise": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", - "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", + "prettier-plugin-xquery": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/prettier-plugin-xquery/-/prettier-plugin-xquery-1.5.0.tgz", + "integrity": "sha512-W3MOTMaxuieU3RaZ7FvV0aySRUulygh1Zz7MNf1ozFMA3SZHAkX/osNcJWD+g44E37CPCQVtIUUTbMvH159JDg==", "requires": { - "pinkie": "^2.0.0" + "prettier": "^3.6.2", + "xq-parser": "^0.3.2" } }, - "prepend-http": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-1.0.4.tgz", - "integrity": "sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw=" - }, - "process-nextick-args": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" - }, "proxy-from-env": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" }, - "q": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/q/-/q-1.0.1.tgz", - "integrity": "sha1-EYcq7t7okmgRCxCnGESP+xARKhQ=" - }, - "rc": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", - "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", - "requires": { - "deep-extend": "^0.6.0", - "ini": "~1.3.0", - "minimist": "^1.2.0", - "strip-json-comments": "~2.0.1" - }, - "dependencies": { - "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=" - } - } - }, - "read-all-stream": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/read-all-stream/-/read-all-stream-3.1.0.tgz", - "integrity": "sha1-NcPhd/IHjveJ7kv6+kNzB06u9Po=", - "requires": { - "pinkie-promise": "^2.0.0", - "readable-stream": "^2.0.0" - } - }, - "readable-stream": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "registry-url": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/registry-url/-/registry-url-3.1.0.tgz", - "integrity": "sha1-PU74cPc93h138M+aOBQyRE4XSUI=", - "requires": { - "rc": "^1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - }, - "semver-diff": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/semver-diff/-/semver-diff-2.1.0.tgz", - "integrity": "sha1-S7uEN8jTfksM8aaP1ybsbWRdbTY=", - "requires": { - "semver": "^5.0.3" - } - }, - "sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" - }, - "stream-shift": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.0.tgz", - "integrity": "sha1-1cdSgl5TZ+eG944Y5EXqIjoVWVI=" - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "requires": { - "safe-buffer": "~5.1.0" - } - }, - "string-length": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/string-length/-/string-length-1.0.1.tgz", - "integrity": "sha1-VpcPscOFWOnnC3KL894mmsRa36w=", - "requires": { - "strip-ansi": "^3.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "requires": { - "ansi-regex": "^2.0.0" - } - } - } - }, - "strip-ansi": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-0.3.0.tgz", - "integrity": "sha1-JfSOoiynkYfzF0pNuHWTR7sSYiA=", - "requires": { - "ansi-regex": "^0.2.1" - } - }, - "strip-json-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=" - }, - "supports-color": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-0.2.0.tgz", - "integrity": "sha1-2S3iaU6z9nMjlz1649i1W0wiGQo=" - }, - "timed-out": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/timed-out/-/timed-out-2.0.0.tgz", - "integrity": "sha1-84sK6B03R9YoAB9B2vxlKs5nHAo=" - }, - "update-notifier": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-0.2.2.tgz", - "integrity": "sha1-5ps6eEtOaGoqzZj15mlEWRmW4Yc=", - "requires": { - "chalk": "^0.5.1", - "configstore": "^0.3.1", - "is-npm": "^1.0.0", - "latest-version": "^1.0.0", - "semver-diff": "^2.0.0", - "string-length": "^1.0.0" - } - }, - "user-home": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/user-home/-/user-home-1.1.1.tgz", - "integrity": "sha1-K1viOjK2Onyd640PKNSFcko98ZA=" - }, - "util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" - }, - "uuid": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-2.0.3.tgz", - "integrity": "sha1-Z+LoY3lyFVMN/zGOW/nc6/1Hsho=" - }, "vscode-jsonrpc": { "version": "8.2.0", "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-8.2.0.tgz", @@ -1684,36 +602,10 @@ "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-3.1.0.tgz", "integrity": "sha512-/BpdSx+yCQGnCvecbyXdxHDkuk55/G3xwnC0GqY4gmQ3j+A+g8kzzgB4Nk/SINjqn6+waqw3EgbVF2QKExkRxQ==" }, - "when": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/when/-/when-2.0.1.tgz", - "integrity": "sha1-jYcv4V5oQkyRtLck6EjggH2rZkI=" - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" - }, - "xdg-basedir": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-1.0.1.tgz", - "integrity": "sha1-FP+PY6T9vLBdW27qIrNvMDO58E4=", - "requires": { - "user-home": "^1.0.0" - } - }, - "xqlint": { - "version": "git+ssh://git@github.com/eXistSolutions/xqlint.git#1a98bca0649c14bad8cdc15701d9ef8779dc4d1e", - "integrity": "sha512-L069Yct51LiLLMe441N+M+BYoZnhQuNTBfjBAYnfXqa5HByHpyCvzLtNvH9mei6BS06Z0MLRg06yAizHnzTMQQ==", - "from": "xqlint@github:eXistSolutions/xqlint#exist-syntax", - "requires": { - "colors": "~0.6.2", - "commander": "~2.3.0", - "final-fs": "~1.6.0", - "lodash": "^3.2.0", - "q": "~1.0.0", - "update-notifier": "~0.2.0" - } + "xq-parser": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/xq-parser/-/xq-parser-0.3.2.tgz", + "integrity": "sha512-Xu6PBGgMyBN4rKDmOk/ik7MrPUrEfsQ7RipDfBTw+EZ/uTwvVb/DkCiXvIvay2ycLe1dlDo33xyVPThGtPFRkg==" } } } diff --git a/server/package.json b/server/package.json index fb767bd..3f65495 100644 --- a/server/package.json +++ b/server/package.json @@ -20,11 +20,10 @@ }, "dependencies": { "axios": "^1.7.0", + "prettier": "^3.8.1", + "prettier-plugin-xquery": "^1.5.0", "vscode-languageserver": "^9.0.0", "vscode-languageserver-textdocument": "^1.0.12", - "vscode-uri": "^3.0.8", - "xqlint": "github:eXistSolutions/xqlint#exist-syntax" - }, - "devDependencies": { + "vscode-uri": "^3.0.8" } -} +} \ No newline at end of file diff --git a/server/src/analyzed-document.ts b/server/src/analyzed-document.ts index 2848a33..9e882e4 100644 --- a/server/src/analyzed-document.ts +++ b/server/src/analyzed-document.ts @@ -3,21 +3,11 @@ import { ServerSettings } from './settings'; import { AST } from './ast'; import axios from 'axios'; import * as path from 'path'; -import * as fs from 'fs'; import { URI } from 'vscode-uri'; const funcDefRe = /(?:\(:~(.*?):\))?\s*declare\s+((?:%[\w\:\-]+(?:\([^\)]*\))?\s*)*function\s+([^\(]+)\()/gsm; const trimRe = /^[\x09\x0a\x0b\x0c\x0d\x20\xa0\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u2028\u2029\u202f\u205f\u3000]+|[\x09\x0a\x0b\x0c\x0d\x20\xa0\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u2028\u2029\u202f\u205f\u3000]+$/g; const paramRe = /\$[^\s]+/; -const importRe = /(import\s+module\s+namespace\s+[^=]+\s*=\s*["'][^"']+["']\s*(?:at\s+["'][^"']+["'])?\s*;)/g; -const moduleRe = /import\s+module\s+namespace\s+([^=\s]+)\s*=\s*["']([^"']+)["']\s*at\s+["']([^"']+)["']\s*;/; - -interface Import { - prefix: string; - uri: string; - source?: string; - isJava?: boolean; -} interface Symbol { signature: string; @@ -51,8 +41,6 @@ export class AnalyzedDocument { symbolsMap: Map = new Map(); - imports: Map = new Map(); - ast: any; logger: (message: string, prio?: string) => void; @@ -73,13 +61,13 @@ export class AnalyzedDocument { this.symbolsMap.clear(); AnalyzedDocument.getLocalSymbols(text, false, this.symbolsMap); this.localSymbols = Array.from(this.symbolsMap.values()); - this.parseImports(text); } async gotoDefinition(position: Position, relPath: string, textDocument: TextDocument, settings: ServerSettings): Promise { if (!this.ast) { return null; } + // Try local symbol lookup first (no roundtrip) const signature = this.getSignatureFromPosition(position); if (signature) { const symbol = this.symbolsMap.get(`${signature.name}#${signature.arity}`); @@ -88,82 +76,75 @@ export class AnalyzedDocument { uri: this.uri, range: this.computeLocation(textDocument, symbol.location) }; - } else { - return this.gotoDefinitionRemote(signature, relPath, textDocument, settings); } + // Fall back to server-side definition + return this.gotoDefinitionRemote(textDocument, position, relPath, settings); } return null; } - private async gotoDefinitionRemote(signature: any, relPath: string, textDocument: TextDocument, settings: ServerSettings): Promise { - const params = this.getParameters(signature, relPath, settings); + private async gotoDefinitionRemote(textDocument: TextDocument, position: Position, relPath: string, settings: ServerSettings): Promise { try { - const options = this.getOptions(params, settings); - const response = await axios.get(options.uri, { + // lang:* / cursor:* expects 1-indexed line/column + const response = await axios.post(`${settings.uri}/apps/existdb-openapi/api/langservice/definition`, { + query: textDocument.getText(), + line: position.line + 1, + column: position.character + 1, + "module-load-path": `${settings.path}/${relPath}` + }, { auth: { username: settings.user, password: settings.password }, - params: options.qs, - responseType: 'text' + headers: { "Content-Type": "application/json" }, + responseType: 'json' }); - + if (response.status !== 200) { this.status(false, settings); return null; } - - const json = JSON.parse(response.data); - if (json.length == 0) { - this.logger(`no description found for ${params.signature}`, 'info'); + + this.status(true, settings); + const def = response.data; + if (!def || !def.line && def.line !== 0) { return null; } - - this.status(true, settings); - const desc = json[0]; - const rp = path.relative(`${settings.path}/${relPath}`, desc.path); - const fp = URI.parse(this.uri).fsPath; - const absPath = path.resolve(path.dirname(fp), rp); - console.log(`reading ${absPath}`); - - return new Promise((resolve) => { - fs.readFile(absPath, { encoding: 'utf-8' }, (err: NodeJS.ErrnoException | null, content: string | Buffer) => { - if (err || !content) { - this.logger(`failed to parse ${absPath}`, 'error'); - resolve(null); - return; - } - const contentStr = typeof content === 'string' ? content : content.toString('utf-8'); - const symbol = AnalyzedDocument.getLocalSymbol(contentStr, signature.name, signature.arity); - if (symbol && symbol.location) { - resolve({ - uri: URI.file(absPath).toString(), - range: { - start: { - line: symbol.location.start, - character: 0 - }, - end: { - line: symbol.location.end + 1, - character: Number.MAX_VALUE - } - } - }); - } else { - resolve(null); - } - }); - }); + + // lang:* / cursor:* returns 1-indexed; convert to 0-indexed for LSP protocol + const defLine = Math.max(def.line - 1, 0); + const defCol = Math.max((def.column || 1) - 1, 0); + + // Cross-module: map database path to workspace file URI + let targetUri = this.uri; + if (def.uri && settings.path) { + const dbPath: string = def.uri; + const dbRoot: string = settings.path; + if (dbPath.startsWith(dbRoot)) { + const relModulePath = dbPath.substring(dbRoot.length); + const currentFilePath = URI.parse(this.uri).fsPath; + const workspaceRoot = currentFilePath.substring(0, + currentFilePath.length - relPath.length - path.basename(currentFilePath).length); + const targetPath = path.join(workspaceRoot, relModulePath); + targetUri = URI.file(targetPath).toString(); + } + } + + return { + uri: targetUri, + range: Range.create(defLine, defCol, defLine, defCol) + }; } catch (error) { this.status(false, settings); return null; } } - async getHover(position: Position, relPath: string, settings: ServerSettings): Promise { + async getHover(position: Position, relPath: string, textDocument: TextDocument, settings: ServerSettings): Promise { if (!this.ast) { return null; } + // Try local symbol lookup first (no roundtrip) const signature = this.getSignatureFromPosition(position); if (signature) { const symbol = this.symbolsMap.get(`${signature.name}#${signature.arity}`); @@ -178,52 +159,45 @@ export class AnalyzedDocument { value: md.join('\n\n') } }; - } else { - return this.getHoverRemote(signature, relPath, settings); } + // Fall back to server-side hover + return this.getHoverRemote(textDocument, position, relPath, settings); } return null; } - private async getHoverRemote(signature: any, relPath: string, settings: ServerSettings): Promise { - const params = this.getParameters(signature, relPath, settings); + private async getHoverRemote(textDocument: TextDocument, position: Position, relPath: string, settings: ServerSettings): Promise { try { - const options = this.getOptions(params, settings); - const response = await axios.get(options.uri, { + // lang:* / cursor:* expects 1-indexed line/column + const response = await axios.post(`${settings.uri}/apps/existdb-openapi/api/langservice/hover`, { + query: textDocument.getText(), + line: position.line + 1, + column: position.character + 1, + "module-load-path": `${settings.path}/${relPath}` + }, { auth: { username: settings.user, password: settings.password }, - params: options.qs, - responseType: 'text' + headers: { "Content-Type": "application/json" }, + responseType: 'json' }); - + if (response.status !== 200) { this.status(false, settings); return null; } - + this.status(true, settings); - const json = JSON.parse(response.data); - if (json.length == 0) { - this.logger(`hover: no description found for ${params.signature}`, 'info'); + const hover = response.data; + if (!hover || !hover.contents) { return null; } - - const desc = json[0]; - const md = [`**${desc.text}** as **${desc.leftLabel}**`]; - if (desc.description) { - md.push(desc.description); - } - if (desc.arguments && desc.arguments.length > 0) { - desc.arguments.forEach((arg: any) => { - md.push(`**\$${arg.name}** *${arg.type}* ${arg.description}`); - }); - } + return { contents: { kind: MarkupKind.Markdown, - value: md.join('\n\n') + value: hover.contents } }; } catch (error) { @@ -232,58 +206,40 @@ export class AnalyzedDocument { } } - private getParameters(signature: any, relPath: string, settings: ServerSettings) { - let imports: any; - const prefix = signature.name.split(':'); - if (prefix.length === 2) { - const imp = this.imports.get(prefix[0]); - if (imp) { - imports = [imp]; - } - } - if (!imports) { - imports = this.imports.values(); - } - const params = this.resolveImports(imports, false); - params.base = `${settings.path}/${relPath}`; - params.signature = `${signature.name}#${signature.arity}`; - return params; - } - - getCompletions(prefix: string | null, relPath: string, settings: ServerSettings): Promise> { - const params = this.resolveImports(this.imports.values(), false); - params.base = `${settings.path}/${relPath}`; + getCompletions(text: string, prefix: string | null, relPath: string, settings: ServerSettings): Promise> { + const body: any = { + query: text, + "module-load-path": `${settings.path}/${relPath}` + }; if (prefix) { - params.prefix = prefix; + body.prefix = prefix; } - const options = this.getOptions(params, settings); - return axios.get(options.uri, { + return axios.post(`${settings.uri}/apps/existdb-openapi/api/langservice/completions`, body, { auth: { username: settings.user, password: settings.password }, - params: options.qs, - responseType: 'text' + headers: { "Content-Type": "application/json" }, + responseType: 'json' }).then(response => { if (response.status !== 200) { this.status(false, settings); throw new Error(`Unexpected status code: ${response.status}`); } this.status(true, settings); - const json = JSON.parse(response.data); - const symbols: any[] = []; - json.forEach((item: { text: string; snippet: string; type: string; name: string; description: string; }) => { + const items: any[] = response.data; + const remoteCompletions = items.map((item: any) => { const symbol: Symbol = { - signature: item.text, - type: item.type, - snippet: item.snippet.replace(/\:\$/g, ':\\\$'), - name: item.name, - documentation: item.description + signature: item.detail || item.label, + type: item.kind === 'function' ? 'function' : 'variable', + snippet: item.insertText || item.label, + name: item.label, + documentation: item.documentation }; - symbols.push(symbol); this.symbolsMap.set(symbol.name, symbol); + return symbol; }); - return this.mapCompletions(this.localSymbols).concat(this.mapCompletions(symbols)); + return this.mapCompletions(this.localSymbols).concat(this.mapCompletions(remoteCompletions)); }).catch(error => { this.status(false, settings); return new ResponseError(ErrorCodes.InvalidRequest, error); @@ -294,6 +250,69 @@ export class AnalyzedDocument { return this.mapDocumentSymbols(this.localSymbols, textDocument); } + /** + * Cursor-based query execution via cursor:eval(). + * Returns a cursor handle, total item count, elapsed time, and the first page of results. + */ + async evalQuery(query: string, settings: ServerSettings, relPath: string, pageSize: number = 100, serializationOptions?: Record): Promise { + const output = this.getOutputMode(query); + const moduleLoadPath = `${settings.path}/${relPath}`; + this.logger(`Eval query with output mode: ${output}, path: ${moduleLoadPath}`); + // POST /api/query — server-side maps to cursor:eval and returns { cursor, items, elapsed } + const response = await axios.post(`${settings.uri}/apps/existdb-openapi/api/query`, { + query, + "module-load-path": moduleLoadPath + }, { + auth: { username: settings.user, password: settings.password }, + headers: { "Content-Type": "application/json" }, + responseType: 'json' + }); + const { cursor, items, elapsed } = response.data; + // Fetch first page immediately with serialization options + const results = await this.fetchResults(cursor, 1, pageSize, settings, serializationOptions); + return { + output, + cursor, + hits: items, + elapsed, + results + }; + } + + /** + * Fetch a page of results from an open cursor via cursor:fetch(). + * Serialization options (method, indent, highlight-matches) are forwarded to the server. + */ + async fetchResults(cursor: string, start: number, count: number, settings: ServerSettings, serializationOptions?: Record): Promise { + // GET /api/query/{id}/results — server-side maps to cursor:fetch + const params: Record = { start: String(start), count: String(count) }; + if (serializationOptions) { + Object.assign(params, serializationOptions); + } + const response = await axios.get(`${settings.uri}/apps/existdb-openapi/api/query/${encodeURIComponent(cursor)}/results`, { + params, + auth: { username: settings.user, password: settings.password }, + responseType: 'json' + }); + return response.data; + } + + /** + * Close a server-side cursor via cursor:close(). + */ + async closeCursor(cursor: string, settings: ServerSettings): Promise { + // DELETE /api/query/{id} — server-side maps to cursor:close + const response = await axios.delete(`${settings.uri}/apps/existdb-openapi/api/query/${encodeURIComponent(cursor)}`, { + auth: { username: settings.user, password: settings.password }, + responseType: 'json' + }); + return response.data?.closed === true; + } + + /** + * Legacy execution path via atom-editor endpoint. + * Used as fallback when cursor:eval is not available. + */ executeQuery(query: string, settings: ServerSettings, relPath: string): Promise { const params = { output: this.getOutputMode(query), @@ -301,7 +320,7 @@ export class AnalyzedDocument { count: '100', base: `${settings.path}/${relPath}` }; - this.logger(`Execute query with output mode: ${params.output}, path: ${params.base}`); + this.logger(`Execute query (legacy) with output mode: ${params.output}, path: ${params.base}`); return axios.post(`${settings.uri}/apps/atom-editor/execute`, new URLSearchParams(params).toString(), { auth: { username: settings.user, @@ -334,13 +353,6 @@ export class AnalyzedDocument { return 'adaptive'; } - private getOptions(params: any, settings: ServerSettings, target: string = 'atom-autocomplete.xql') { - return { - uri: `${settings.uri}/apps/atom-editor/${target}`, - qs: params - }; - } - private mapCompletions(symbols: any[]): CompletionItem[] { return symbols.map(symbol => { const completion: CompletionItem = { @@ -396,7 +408,6 @@ export class AnalyzedDocument { } const arity = args.length; const signature = name + "(" + args + ")"; - // const status = funcDef[2].indexOf("%private") == -1 ? "private" : 'public'; let location; if (lineCount) { const line = AnalyzedDocument.getLine(text, offset); @@ -506,53 +517,6 @@ export class AnalyzedDocument { return newlines; } - private parseImports(text: string) { - this.imports.clear(); - let match = importRe.exec(text); - - while (match != null) { - if (match[1]) { - const imp = match[1]; - match = moduleRe.exec(imp); - if (match && match.length === 4) { - const isJava = match[3].substring(0, 5) == "java:"; - const importData = { - prefix: match[1], - uri: match[2], - source: match[3], - isJava: isJava - }; - this.imports.set(importData.prefix, importData); - } - } - match = importRe.exec(text); - } - } - - private resolveImports(imports: IterableIterator, includeJava = true): { - mprefix: string[], uri: string[], source: string[], base: string, prefix?: string, - signature?: string - } { - const prefixes: string[] = []; - const uris: string[] = []; - const sources: string[] = []; - for (let imp of imports) { - if (!imp.isJava || includeJava) { - prefixes.push(imp.prefix); - uris.push(imp.uri); - if (imp.source) { - sources.push(imp.source); - } - } - } - return { - mprefix: prefixes, - uri: uris, - source: sources, - base: '' - }; - } - private getSignatureFromPosition(position: Position): any | undefined { const node = AST.findNode(this.ast, position); if (node) { @@ -562,4 +526,4 @@ export class AnalyzedDocument { } } } -} \ No newline at end of file +} diff --git a/server/src/linting.ts b/server/src/linting.ts index ca9d55d..ce5b52f 100644 --- a/server/src/linting.ts +++ b/server/src/linting.ts @@ -1,14 +1,24 @@ /** * Support for linting XQuery documents. - * + * * @author Wolfgang Meier */ import { Diagnostic, DiagnosticSeverity, Range, ResponseError, ErrorCodes } from 'vscode-languageserver'; -import { XQLint } from 'xqlint'; import { ServerSettings } from './settings'; import { AnalyzedDocument } from './analyzed-document'; import axios from 'axios'; +// eXide's REx-generated XQuery 3.1 parser + adapter that emits an AST shape +// compatible with what xqlint's JSONParseTreeHandler used to produce. The +// langserver only needs local symbol lookup (used by hover / go-to-definition +// when a server roundtrip isn't worth it); the adapter's normalized AST is +// what server/src/ast.ts traverses. +// +// eslint-disable-next-line @typescript-eslint/no-var-requires +const XQueryParser = require('./parser/XQueryParser'); +// eslint-disable-next-line @typescript-eslint/no-var-requires +const rexParserAdapter = require('./parser/adapter'); + export function lintDocument(text: string, relPath: string, document: AnalyzedDocument, settings: ServerSettings): Promise> { document.diagnostics = []; if (text.length == 0) { @@ -24,33 +34,35 @@ export function lintDocument(text: string, relPath: string, document: AnalyzedDo } function serverLint(text: String, settings: ServerSettings, relPath: string, document: AnalyzedDocument): Promise> { - return axios.put(`${settings.uri}/apps/atom-editor/compile.xql`, text, { + return axios.post(`${settings.uri}/apps/existdb-openapi/api/langservice/diagnostics`, { + query: text, + "module-load-path": `${settings.path}/${relPath}` + }, { auth: { username: settings.user, password: settings.password }, headers: { - "X-BasePath": `${settings.path}/${relPath}`, - "Content-Type": "application/octet-stream" + "Content-Type": "application/json" }, - responseType: 'text' + responseType: 'json' }).then(response => { if (response.status !== 200) { document.status(false, settings); return document; } document.status(true, settings); - const json = JSON.parse(response.data); - if (json.result !== 'pass') { - const error = parseErrorMessage(json.error); - if (!error.line) { - document.status(false, settings); - return document; - } else { - const diagnostic: Diagnostic = { - severity: DiagnosticSeverity.Error, - range: Range.create(error.line, error.column, error.line, error.column), - message: error.msg, + const diagnostics: any[] = response.data; + if (Array.isArray(diagnostics)) { + for (const d of diagnostics) { + // lang:diagnostics returns 1-indexed lines; LSP protocol uses 0-indexed + const line = Math.max(d.line - 1, 0); + const column = Math.max(d.column - 1, 0); + const diagnostic: Diagnostic = { + severity: mapSeverity(d.severity), + range: Range.create(line, column, line, column), + message: d.message, + code: d.code, source: 'xquery' }; document.diagnostics.push(diagnostic); @@ -63,48 +75,28 @@ function serverLint(text: String, settings: ServerSettings, relPath: string, doc }); } -function parseErrorMessage(error: any) { - let msg; - if (error.line) { - msg = error["#text"]; - } else { - msg = error; +function mapSeverity(severity: string | number): DiagnosticSeverity { + if (typeof severity === 'number') { + // LSP DiagnosticSeverity: 1=Error, 2=Warning, 3=Information, 4=Hint + if (severity >= 1 && severity <= 4) { + return severity as DiagnosticSeverity; + } + return DiagnosticSeverity.Error; } - - let str = /.*line:?\s*(\d+),\s*column:?\s*(\d+)/i.exec(msg); - let line = 0; - let column = 0; - if (str && str.length === 3) { - line = parseInt(str[1]) - 1; - column = parseInt(str[2]) - 1; - } else { - line = parseInt(error.line) - 1; - column = parseInt(error.column) - 1; + switch (severity) { + case 'error': return DiagnosticSeverity.Error; + case 'warning': return DiagnosticSeverity.Warning; + case 'info': return DiagnosticSeverity.Information; + case 'hint': return DiagnosticSeverity.Hint; + default: return DiagnosticSeverity.Error; } - - return { line: Math.max(line, 0), column: Math.max(column, 0), msg: msg }; } -function xqlint(uri: String, text: String, document: AnalyzedDocument): Diagnostic[] { - const xqlint = new XQLint(text, { - fileName: uri - }); - document.ast = xqlint.getAST(); - const warnings:any[] = xqlint.getWarnings(); - const diagnostics: Diagnostic[] = []; - warnings.forEach(warning => { - const diagnostic: Diagnostic = { - severity: DiagnosticSeverity.Warning, - range: Range.create( - warning.pos.sl, - warning.pos.sc, - warning.pos.el, - warning.pos.ec), - message: warning.message, - source: 'xquery' - }; - diagnostics.push(diagnostic); - }); - document.diagnostics = diagnostics; - return diagnostics; -} \ No newline at end of file +function xqlint(uri: String, text: String, document: AnalyzedDocument): void { + // Build an AST for local symbol lookup (hover, go-to-definition). + // Parse errors are intentionally ignored here — server-side + // lang:diagnostics handles error checking. We just need a best-effort + // AST whenever the source is parseable. + const result = rexParserAdapter.parseXQuery(text, XQueryParser); + document.ast = result.ast; +} diff --git a/server/src/parser/XQueryParser.js b/server/src/parser/XQueryParser.js new file mode 100644 index 0000000..005acd1 --- /dev/null +++ b/server/src/parser/XQueryParser.js @@ -0,0 +1,16105 @@ +// This file was generated on Sun Mar 8, 2026 10:09 (UTC-04) by REx v6.1 which is Copyright (c) 1979-2025 by Gunther Rademacher +// REx command line: XQuery-31-Family-XQUFEL.ebnf -ll 3 -backtrack -tree -javascript -name XQueryParser + +function XQueryParser(string, parsingEventHandler) +{ + init(string, parsingEventHandler); + + var thisParser = this; + + this.ParseException = function(b, e, s, o, x) + { + var begin = b; + var end = e; + var state = s; + var offending = o; + var expected = x; + + this.getBegin = function() {return begin;}; + this.getEnd = function() {return end;}; + this.getState = function() {return state;}; + this.getExpected = function() {return expected;}; + this.getOffending = function() {return offending;}; + this.isAmbiguousInput = function() {return false;}; + + this.getMessage = function() + { + return offending < 0 + ? "lexical analysis failed" + : "syntax error"; + }; + }; + + function init(source, parsingEventHandler) + { + eventHandler = parsingEventHandler; + input = source; + size = source.length; + reset(0, 0, 0); + } + + this.getInput = function() + { + return input; + }; + + this.getTokenOffset = function() + { + return b0; + }; + + this.getTokenEnd = function() + { + return e0; + }; + + function reset(l, b, e) + { + b0 = b; e0 = b; + l1 = l; b1 = b; e1 = e; + l2 = 0; b2 = 0; e2 = 0; + l3 = 0; b3 = 0; e3 = 0; + end = e; + eventHandler.reset(input); + } + + this.reset = function(l, b, e) + { + reset(l, b, e); + }; + + this.getOffendingToken = function(e) + { + var o = e.getOffending(); + return o >= 0 ? XQueryParser.TOKEN[o] : null; + }; + + this.getExpectedTokenSet = function(e) + { + var expected; + if (e.getExpected() < 0) + { + expected = XQueryParser.getTokenSet(- e.getState()); + } + else + { + expected = [XQueryParser.TOKEN[e.getExpected()]]; + } + return expected; + }; + + this.getErrorMessage = function(e) + { + var message = e.getMessage(); + var found = this.getOffendingToken(e); + var tokenSet = this.getExpectedTokenSet(e); + var size = e.getEnd() - e.getBegin(); + message += (found == null ? "" : ", found " + found) + + "\nwhile expecting " + + (tokenSet.length == 1 ? tokenSet[0] : ("[" + tokenSet.join(", ") + "]")) + + "\n" + + (size == 0 || found != null ? "" : "after successfully scanning " + size + " characters beginning "); + var prefix = input.substring(0, e.getBegin()); + var lines = prefix.split("\n"); + var line = lines.length; + var column = lines[line - 1].length + 1; + return message + + "at line " + line + ", column " + column + ":\n..." + + input.substring(e.getBegin(), Math.min(input.length, e.getBegin() + 64)) + + "..."; + }; + + this.parse_XQuery = function() + { + eventHandler.startNonterminal("XQuery", e0); + lookahead1W(251); // IntegerLiteral | DecimalLiteral | DoubleLiteral | StringLiteral | + // URIQualifiedName | QName^Token | S^WS | Wildcard | '$' | '%' | '(' | '(#' | + // '(:' | '+' | '-' | '.' | '..' | '/' | '//' | '<' | '' + consume(42); // '-->' + eventHandler.endNonterminal("DirCommentConstructor", e0); + } + + function parse_DirPIConstructor() + { + eventHandler.startNonterminal("DirPIConstructor", e0); + consume(59); // '' + if (l1 == 17) // S + { + consume(17); // S + lookahead1(4); // DirPIContents + consume(23); // DirPIContents + } + lookahead1(10); // '?>' + consume(66); // '?>' + eventHandler.endNonterminal("DirPIConstructor", e0); + } + + function parse_CDataSection() + { + eventHandler.startNonterminal("CDataSection", e0); + consume(55); // '' + consume(71); // ']]>' + eventHandler.endNonterminal("CDataSection", e0); + } + + function parse_ComputedConstructor() + { + eventHandler.startNonterminal("ComputedConstructor", e0); + switch (l1) + { + case 118: // 'document' + parse_CompDocConstructor(); + break; + case 120: // 'element' + parse_CompElemConstructor(); + break; + case 86: // 'attribute' + parse_CompAttrConstructor(); + break; + case 176: // 'namespace' + parse_CompNamespaceConstructor(); + break; + case 231: // 'text' + parse_CompTextConstructor(); + break; + case 97: // 'comment' + parse_CompCommentConstructor(); + break; + default: + parse_CompPIConstructor(); + } + eventHandler.endNonterminal("ComputedConstructor", e0); + } + + function parse_CompDocConstructor() + { + eventHandler.startNonterminal("CompDocConstructor", e0); + consume(118); // 'document' + lookahead1W(80); // S^WS | '(:' | '{' + whitespace(); + parse_EnclosedExpr(); + eventHandler.endNonterminal("CompDocConstructor", e0); + } + + function parse_CompElemConstructor() + { + eventHandler.startNonterminal("CompElemConstructor", e0); + consume(120); // 'element' + lookahead1W(240); // URIQualifiedName | QName^Token | S^WS | '(:' | 'after' | 'ancestor' | + // 'ancestor-or-self' | 'and' | 'array' | 'ascending' | 'attribute' | 'before' | + // 'case' | 'cast' | 'castable' | 'child' | 'collation' | 'comment' | 'contains' | + // 'content' | 'copy' | 'count' | 'declare' | 'default' | 'delete' | 'descendant' | + // 'descendant-or-self' | 'descending' | 'diacritics' | 'different' | 'distance' | + // 'div' | 'document' | 'document-node' | 'element' | 'else' | 'empty' | + // 'empty-sequence' | 'end' | 'entire' | 'eq' | 'every' | 'exactly' | 'except' | + // 'first' | 'following' | 'following-sibling' | 'for' | 'ft-option' | 'ftand' | + // 'ftnot' | 'ftor' | 'function' | 'ge' | 'group' | 'gt' | 'idiv' | 'if' | + // 'import' | 'insensitive' | 'insert' | 'instance' | 'intersect' | 'into' | 'is' | + // 'item' | 'language' | 'last' | 'le' | 'least' | 'let' | 'levels' | 'lowercase' | + // 'lt' | 'map' | 'mod' | 'modify' | 'module' | 'most' | 'namespace' | + // 'namespace-node' | 'ne' | 'no' | 'node' | 'nodes' | 'not' | 'occurs' | 'only' | + // 'or' | 'order' | 'ordered' | 'paragraph' | 'paragraphs' | 'parent' | 'phrase' | + // 'preceding' | 'preceding-sibling' | 'processing-instruction' | 'relationship' | + // 'rename' | 'replace' | 'return' | 'revalidation' | 'same' | 'satisfies' | + // 'schema-attribute' | 'schema-element' | 'score' | 'self' | 'sensitive' | + // 'sentence' | 'sentences' | 'skip' | 'some' | 'stable' | 'start' | 'stemming' | + // 'stop' | 'switch' | 'text' | 'thesaurus' | 'times' | 'to' | 'treat' | 'try' | + // 'typeswitch' | 'union' | 'unordered' | 'update' | 'uppercase' | 'using' | + // 'validate' | 'value' | 'weight' | 'where' | 'wildcards' | 'window' | 'with' | + // 'without' | 'word' | 'words' | 'xquery' | '{' + switch (l1) + { + case 261: // '{' + consume(261); // '{' + lookahead1W(251); // IntegerLiteral | DecimalLiteral | DoubleLiteral | StringLiteral | + // URIQualifiedName | QName^Token | S^WS | Wildcard | '$' | '%' | '(' | '(#' | + // '(:' | '+' | '-' | '.' | '..' | '/' | '//' | '<' | ''", + "'.'", + "'..'", + "'/'", + "'//'", + "'/>'", + "':'", + "':)'", + "'::'", + "':='", + "';'", + "'<'", + "'