@eclipse-lyra/extension-sqleditor 0.0.0 → 0.7.21
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js
CHANGED
|
@@ -5,7 +5,7 @@ extensionRegistry.registerExtension({
|
|
|
5
5
|
id: pkg.name,
|
|
6
6
|
name: "SQL Editor",
|
|
7
7
|
description: "Generic SQL editor with pluggable backends",
|
|
8
|
-
loader: () => import("./sqleditor-extension-
|
|
8
|
+
loader: () => import("./sqleditor-extension-BgrK4zpJ.js"),
|
|
9
9
|
icon: "database"
|
|
10
10
|
});
|
|
11
11
|
export {
|
package/dist/sql-editor.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sql-editor.d.ts","sourceRoot":"","sources":["../src/sql-editor.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,KAAK,WAAW,EAAE,KAAK,qBAAqB,
|
|
1
|
+
{"version":3,"file":"sql-editor.d.ts","sourceRoot":"","sources":["../src/sql-editor.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,KAAK,WAAW,EAAE,KAAK,qBAAqB,EAA0I,MAAM,oBAAoB,CAAC;AAkBpO,qBACa,aAAc,SAAQ,QAAS,YAAW,qBAAqB;IAEnE,KAAK,CAAC,EAAE,WAAW,CAAC;IAGpB,QAAQ,UAAS;IAGxB,OAAO,CAAC,cAAc,CAAiC;IAGvD,OAAO,CAAC,UAAU,CAAiC;IAGnD,OAAO,CAAC,OAAO,CAAS;IAGxB,OAAO,CAAC,iBAAiB,CAAgC;IAGzD,OAAO,CAAC,gBAAgB,CAAuB;IAG/C,OAAO,CAAC,oBAAoB,CAA2B;IAGvD,OAAO,CAAC,oBAAoB,CAAuB;IAEnD,OAAO,CAAC,SAAS,CAAiC;IAClD,OAAO,CAAC,SAAS,CAAkC;IACnD,OAAO,CAAC,6BAA6B,CAAC,CAAS;cAE/B,QAAQ;YAeV,eAAe;YAqBf,iBAAiB;YAmBjB,kBAAkB;YAmClB,cAAc;YAUd,kBAAkB;IAehC,OAAO,CAAC,gBAAgB,CAEtB;IAEF,IAAI,IAAI,IAAI;cAMI,OAAO;IAYhB,WAAW,IAAI,MAAM,GAAG,IAAI;IAI5B,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAIjC,UAAU,IAAI,MAAM,GAAG,IAAI;IAI3B,YAAY,IAAI,MAAM,GAAG,IAAI;IAI7B,UAAU,CAAC,KAAK,GAAE,MAAU,GAAG;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI;IAI7E,WAAW,IAAI,MAAM,GAAG,IAAI;YAIrB,QAAQ;IAwDtB,OAAO,CAAC,iBAAiB;YAOX,gBAAgB;YAehB,gBAAgB;IAqB9B,SAAS,CAAC,aAAa;IAwEvB,MAAM;IAmBN,MAAM,CAAC,MAAM,0BA+BX;CACH;AAED,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,qBAAqB;QAC7B,iBAAiB,EAAE,aAAa,CAAC;KAClC;CACF"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { LyraPart, subscribe, TOPIC_CONTRIBUTEIONS_CHANGED, contributionRegistry, toastError, unsubscribe, publish, toastInfo, confirmDialog, editorRegistry, File } from "@eclipse-lyra/core";
|
|
1
|
+
import { LyraPart, subscribe, TOPIC_CONTRIBUTEIONS_CHANGED, contributionRegistry, taskService, toastError, unsubscribe, publish, toastInfo, confirmDialog, editorRegistry, File } from "@eclipse-lyra/core";
|
|
2
2
|
import { html as html$1 } from "@eclipse-lyra/core/externals/lit";
|
|
3
3
|
import { property, state, customElement } from "lit/decorators.js";
|
|
4
4
|
import { css, html } from "lit";
|
|
@@ -56,6 +56,7 @@ let LyraSqlEditor = class extends LyraPart {
|
|
|
56
56
|
this.selectedEngineId = null;
|
|
57
57
|
this.availableConnections = [];
|
|
58
58
|
this.selectedConnectionId = null;
|
|
59
|
+
await this.updateComplete;
|
|
59
60
|
this.updateToolbar();
|
|
60
61
|
return;
|
|
61
62
|
}
|
|
@@ -63,7 +64,9 @@ let LyraSqlEditor = class extends LyraPart {
|
|
|
63
64
|
const duckdbAdapter = contributions.find((c) => c.id === "duckdb");
|
|
64
65
|
this.selectedEngineId = (duckdbAdapter ?? contributions[0]).id;
|
|
65
66
|
}
|
|
67
|
+
this.requestUpdate();
|
|
66
68
|
await this.refreshConnections();
|
|
69
|
+
await this.updateComplete;
|
|
67
70
|
this.updateToolbar();
|
|
68
71
|
}
|
|
69
72
|
async getOrLoadDatabase(engineId) {
|
|
@@ -72,7 +75,11 @@ let LyraSqlEditor = class extends LyraPart {
|
|
|
72
75
|
const adapter = this.availableAdapters.find((c) => c.id === engineId);
|
|
73
76
|
if (!adapter) return null;
|
|
74
77
|
try {
|
|
75
|
-
const
|
|
78
|
+
const label = adapter.label || adapter.id;
|
|
79
|
+
const database = await taskService.runAsync(`Opening ${label} database`, async (progress) => {
|
|
80
|
+
progress.message = `Connecting to ${label}…`;
|
|
81
|
+
return adapter.loader();
|
|
82
|
+
});
|
|
76
83
|
this.databases.set(engineId, database);
|
|
77
84
|
return database;
|
|
78
85
|
} catch (err) {
|
|
@@ -85,6 +92,7 @@ let LyraSqlEditor = class extends LyraPart {
|
|
|
85
92
|
if (!engineId) {
|
|
86
93
|
this.availableConnections = [];
|
|
87
94
|
this.selectedConnectionId = null;
|
|
95
|
+
await this.updateComplete;
|
|
88
96
|
this.updateToolbar();
|
|
89
97
|
return;
|
|
90
98
|
}
|
|
@@ -92,6 +100,7 @@ let LyraSqlEditor = class extends LyraPart {
|
|
|
92
100
|
if (!db) {
|
|
93
101
|
this.availableConnections = [];
|
|
94
102
|
this.selectedConnectionId = null;
|
|
103
|
+
await this.updateComplete;
|
|
95
104
|
this.updateToolbar();
|
|
96
105
|
return;
|
|
97
106
|
}
|
|
@@ -100,6 +109,7 @@ let LyraSqlEditor = class extends LyraPart {
|
|
|
100
109
|
const currentId = db.currentConnectionId;
|
|
101
110
|
if (currentId !== null) {
|
|
102
111
|
this.selectedConnectionId = currentId;
|
|
112
|
+
await this.updateComplete;
|
|
103
113
|
this.updateToolbar();
|
|
104
114
|
return;
|
|
105
115
|
}
|
|
@@ -108,6 +118,7 @@ let LyraSqlEditor = class extends LyraPart {
|
|
|
108
118
|
if (preferred) {
|
|
109
119
|
await db.selectConnection(preferred.id ?? null);
|
|
110
120
|
}
|
|
121
|
+
await this.updateComplete;
|
|
111
122
|
this.updateToolbar();
|
|
112
123
|
}
|
|
113
124
|
async onEngineChange(e) {
|
|
@@ -199,10 +210,11 @@ let LyraSqlEditor = class extends LyraPart {
|
|
|
199
210
|
const timeoutId = window.setTimeout(() => this.clearRunningState(), timeoutMs);
|
|
200
211
|
try {
|
|
201
212
|
const result = await db.runQuery(sql);
|
|
213
|
+
const adapter = this.availableAdapters.find((c) => c.id === engineId);
|
|
202
214
|
publish("dataview/publish", {
|
|
203
215
|
title: label,
|
|
204
216
|
data: { columns: result.columns, rows: result.rows },
|
|
205
|
-
source: engineId
|
|
217
|
+
source: adapter?.label ?? engineId
|
|
206
218
|
});
|
|
207
219
|
} catch (err) {
|
|
208
220
|
toastError(err instanceof Error ? err.message : String(err));
|
|
@@ -424,4 +436,4 @@ function activate() {
|
|
|
424
436
|
export {
|
|
425
437
|
activate as default
|
|
426
438
|
};
|
|
427
|
-
//# sourceMappingURL=sqleditor-extension-
|
|
439
|
+
//# sourceMappingURL=sqleditor-extension-BgrK4zpJ.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sqleditor-extension-BgrK4zpJ.js","sources":["../src/sql-editor.ts","../src/sqleditor-extension.ts"],"sourcesContent":["import { customElement, property, state } from 'lit/decorators.js';\nimport { LyraPart, type EditorInput, type EditorContentProvider, toastError, toastInfo, confirmDialog, publish, contributionRegistry, subscribe, unsubscribe, TOPIC_CONTRIBUTEIONS_CHANGED, taskService } from '@eclipse-lyra/core';\nimport type {\n SqlAdapterContribution,\n SqlConnectionInfo,\n SqlDatabase,\n} from '@eclipse-lyra/extension-sqleditor';\nimport { css, html } from 'lit';\nimport { createRef, ref } from 'lit/directives/ref.js';\nimport { LyraMonacoWidget } from '@eclipse-lyra/extension-monaco-editor';\n\nconst MAX_TAB_LABEL = 28;\n\nfunction truncateLabel(sql: string): string {\n const oneLine = sql.replace(/\\s+/g, ' ').trim();\n if (oneLine.length <= MAX_TAB_LABEL) return oneLine;\n return `${oneLine.slice(0, MAX_TAB_LABEL)}…`;\n}\n\n@customElement('lyra-sql-editor')\nexport class LyraSqlEditor extends LyraPart implements EditorContentProvider {\n @property({ attribute: false })\n public input?: EditorInput;\n\n @property({ type: Boolean })\n public readOnly = false;\n\n @state()\n private initialContent: string | undefined = undefined;\n\n @state()\n private initialUri: string | undefined = undefined;\n\n @state()\n private running = false;\n\n @state()\n private availableAdapters: SqlAdapterContribution[] = [];\n\n @state()\n private selectedEngineId: string | null = null;\n\n @state()\n private availableConnections: SqlConnectionInfo[] = [];\n\n @state()\n private selectedConnectionId: string | null = null;\n\n private widgetRef = createRef<LyraMonacoWidget>();\n private databases = new Map<string, SqlDatabase>();\n private unsubscribeContributionsToken?: string;\n\n protected async doInitUI() {\n const file = this.input!.data;\n const textContents = await file.getContents();\n this.initialContent = textContents;\n this.initialUri = file.getName();\n this.unsubscribeContributionsToken = subscribe(TOPIC_CONTRIBUTEIONS_CHANGED, (event: { target?: string } | undefined) => {\n if (event?.target === 'system.sqladapters') {\n void this.refreshAdapters();\n }\n });\n\n await this.refreshAdapters();\n this.requestUpdate();\n }\n\n private async refreshAdapters(): Promise<void> {\n const contributions = contributionRegistry.getContributions<SqlAdapterContribution>('system.sqladapters');\n this.availableAdapters = contributions;\n if (!contributions.length) {\n this.selectedEngineId = null;\n this.availableConnections = [];\n this.selectedConnectionId = null;\n await this.updateComplete;\n this.updateToolbar();\n return;\n }\n if (!this.selectedEngineId) {\n const duckdbAdapter = contributions.find((c) => c.id === 'duckdb');\n this.selectedEngineId = (duckdbAdapter ?? contributions[0]).id;\n }\n this.requestUpdate();\n await this.refreshConnections();\n await this.updateComplete;\n this.updateToolbar();\n }\n\n private async getOrLoadDatabase(engineId: string): Promise<SqlDatabase | null> {\n const cached = this.databases.get(engineId);\n if (cached) return cached;\n const adapter = this.availableAdapters.find((c) => c.id === engineId);\n if (!adapter) return null;\n try {\n const label = adapter.label || adapter.id;\n const database = await taskService.runAsync(`Opening ${label} database`, async (progress) => {\n progress.message = `Connecting to ${label}…`;\n return adapter.loader();\n });\n this.databases.set(engineId, database);\n return database;\n } catch (err) {\n toastError(err instanceof Error ? err.message : String(err));\n return null;\n }\n }\n\n private async refreshConnections(): Promise<void> {\n const engineId = this.selectedEngineId;\n if (!engineId) {\n this.availableConnections = [];\n this.selectedConnectionId = null;\n await this.updateComplete;\n this.updateToolbar();\n return;\n }\n const db = await this.getOrLoadDatabase(engineId);\n if (!db) {\n this.availableConnections = [];\n this.selectedConnectionId = null;\n await this.updateComplete;\n this.updateToolbar();\n return;\n }\n const infos = await db.listConnections();\n this.availableConnections = infos;\n const currentId = db.currentConnectionId;\n if (currentId !== null) {\n this.selectedConnectionId = currentId;\n await this.updateComplete;\n this.updateToolbar();\n return;\n }\n const preferred = infos.find((info: SqlConnectionInfo) => info.isDefault) ?? infos[0];\n this.selectedConnectionId = preferred ? preferred.id : null;\n if (preferred) {\n await db.selectConnection(preferred.id ?? null);\n }\n await this.updateComplete;\n this.updateToolbar();\n }\n\n private async onEngineChange(e: Event): Promise<void> {\n const select = e.target as { value?: string };\n const value = select?.value ?? '';\n if (this.selectedEngineId === value) return;\n this.selectedEngineId = value || null;\n await this.refreshConnections();\n this.requestUpdate();\n this.updateToolbar();\n }\n\n private async onConnectionChange(e: Event): Promise<void> {\n const select = e.target as { value?: string };\n const value = select?.value ?? '';\n const next = value === '' ? null : value;\n if (this.selectedConnectionId === next) return;\n this.selectedConnectionId = next;\n const engineId = this.selectedEngineId;\n if (!engineId) return;\n const db = await this.getOrLoadDatabase(engineId);\n if (!db) return;\n await db.selectConnection(next);\n this.requestUpdate();\n this.updateToolbar();\n }\n\n private _onContentChange = () => {\n this.markDirty(true);\n };\n\n save(): void {\n const value = this.widgetRef.value?.getContent() ?? '';\n this.input?.data.saveContents(value);\n this.markDirty(false);\n }\n\n protected async doClose() {\n if (this.unsubscribeContributionsToken) {\n unsubscribe(this.unsubscribeContributionsToken);\n this.unsubscribeContributionsToken = undefined;\n }\n this.widgetRef.value?.dispose();\n for (const db of this.databases.values()) {\n await db.close();\n }\n this.databases.clear();\n }\n\n public getLanguage(): string | null {\n return 'sql';\n }\n\n public isLanguage(lang: string): boolean {\n return lang.toLowerCase() === 'sql';\n }\n\n public getContent(): string | null {\n return this.widgetRef.value?.getContent() ?? null;\n }\n\n public getSelection(): string | null {\n return this.widgetRef.value?.getSelection() ?? null;\n }\n\n public getSnippet(lines: number = 5): { snippet: string; cursorLine: number } | null {\n return this.widgetRef.value?.getSnippet(lines) ?? null;\n }\n\n public getFilePath(): string | null {\n return this.input?.data?.getWorkspacePath() ?? null;\n }\n\n private async runQuery(useSelectionOnly = false): Promise<void> {\n const sql = useSelectionOnly\n ? this.getSelection()?.trim()\n : (this.getSelection()?.trim() || this.getContent()?.trim());\n if (!sql) {\n toastError(useSelectionOnly ? 'No selection to run' : 'No SQL to run');\n return;\n }\n if (this.running) return;\n\n const engineId = this.selectedEngineId;\n if (!engineId) {\n toastError('No SQL engine available');\n return;\n }\n\n const db = await this.getOrLoadDatabase(engineId);\n if (!db) {\n toastError('Could not initialize SQL engine');\n return;\n }\n\n if (!this.selectedConnectionId && this.availableConnections.length) {\n const preferred = this.availableConnections.find(\n (info: SqlConnectionInfo) => info.isDefault,\n ) ?? this.availableConnections[0];\n this.selectedConnectionId = preferred.id;\n await db.selectConnection(preferred.id ?? null);\n }\n\n this.running = true;\n const label = truncateLabel(sql);\n this.requestUpdate();\n this.updateToolbar();\n\n const timeoutMs = 60_000;\n const timeoutId = window.setTimeout(() => this.clearRunningState(), timeoutMs);\n\n try {\n const result = await db.runQuery(sql);\n const adapter = this.availableAdapters.find((c) => c.id === engineId);\n publish('dataview/publish', {\n title: label,\n data: { columns: result.columns, rows: result.rows },\n source: adapter?.label ?? engineId,\n });\n } catch (err) {\n toastError(err instanceof Error ? err.message : String(err));\n } finally {\n window.clearTimeout(timeoutId);\n this.running = false;\n this.requestUpdate();\n this.updateToolbar();\n }\n }\n\n private clearRunningState(): void {\n if (!this.running) return;\n this.running = false;\n this.requestUpdate();\n this.updateToolbar();\n }\n\n private async createConnection(): Promise<void> {\n const engineId = this.selectedEngineId;\n if (!engineId) return;\n const db = await this.getOrLoadDatabase(engineId);\n if (!db || !db.createConnection) return;\n const info = await db.createConnection();\n if (!info) return;\n await this.refreshConnections();\n this.selectedConnectionId = info.id;\n await db.selectConnection(info.id ?? null);\n toastInfo(`Connection \"${info.label}\" created`);\n this.requestUpdate();\n this.updateToolbar();\n }\n\n private async deleteConnection(): Promise<void> {\n const engineId = this.selectedEngineId;\n if (!engineId) return;\n const db = await this.getOrLoadDatabase(engineId);\n if (!db || !db.deleteConnection) return;\n const id = this.selectedConnectionId;\n const connectionLabel =\n this.availableConnections.find((info) => info.id === id)?.label ??\n (id === null ? 'In-memory' : id ?? 'Current connection');\n const ok = await confirmDialog(`Delete connection \"${connectionLabel}\"?`);\n if (!ok) return;\n if (id !== null) {\n await db.deleteConnection(id);\n } else {\n await db.selectConnection(null);\n }\n await this.refreshConnections();\n this.requestUpdate();\n this.updateToolbar();\n }\n\n protected renderToolbar() {\n const engineValue = this.selectedEngineId ?? '';\n const connectionValue = this.selectedConnectionId ?? '';\n const adapters = this.availableAdapters;\n const hasEngines = adapters.length > 0;\n const hasConnections = this.availableConnections.length > 0;\n\n return html`\n <wa-select\n class=\"engine-select\"\n size=\"small\"\n .value=${engineValue}\n title=\"SQL engine\"\n @change=${(e: Event) => void this.onEngineChange(e)}\n >\n ${adapters.map(\n (adapter) =>\n html`<wa-option value=${adapter.id}>${adapter.label}</wa-option>`,\n )}\n </wa-select>\n <wa-select\n class=\"connection-select\"\n size=\"small\"\n .value=${connectionValue}\n title=\"Connection\"\n ?disabled=${!hasEngines || !hasConnections}\n @change=${(e: Event) => void this.onConnectionChange(e)}\n >\n ${this.availableConnections.map(\n (info) =>\n html`<wa-option value=${info.id ?? ''}>${info.label}</wa-option>`,\n )}\n </wa-select>\n <wa-button\n size=\"small\"\n appearance=\"plain\"\n title=\"New connection\"\n @click=${() => void this.createConnection()}\n >\n <wa-icon name=\"plus\" label=\"New\"></wa-icon>\n </wa-button>\n <wa-button\n size=\"small\"\n appearance=\"plain\"\n title=\"Delete connection\"\n @click=${() => void this.deleteConnection()}\n >\n <wa-icon name=\"trash\" label=\"Delete\"></wa-icon>\n </wa-button>\n <wa-button\n size=\"small\"\n appearance=\"plain\"\n ?disabled=${this.running}\n @click=${() => void this.runQuery(true)}\n title=\"Run selection only\"\n >\n <wa-icon name=\"i-cursor\" label=\"Run selection\"></wa-icon>\n ${this.running ? 'Running…' : 'Run selection'}\n </wa-button>\n <wa-button\n size=\"small\"\n appearance=\"plain\"\n ?disabled=${this.running}\n @click=${() => void this.runQuery(false)}\n title=\"Run all SQL\"\n >\n <wa-icon name=\"play\" label=\"Run\"></wa-icon>\n ${this.running ? 'Running…' : 'Run all'}\n </wa-button>\n `;\n }\n\n render() {\n if (this.initialContent === undefined) {\n return html`<div class=\"editor-placeholder\"></div>`;\n }\n\n return html`\n <div class=\"editor-area\">\n <lyra-monaco-widget\n .value=${this.initialContent}\n .uri=${this.initialUri}\n .language=${'sql'}\n .readOnly=${this.readOnly}\n @content-change=${this._onContentChange}\n ${ref(this.widgetRef)}\n ></lyra-monaco-widget>\n </div>\n `;\n }\n\n static styles = css`\n :host {\n display: flex;\n flex-direction: column;\n position: relative;\n width: 100%;\n height: 100%;\n }\n .engine-select {\n max-width: 10rem;\n }\n .connection-select {\n max-width: 12rem;\n }\n .editor-area {\n flex: 1;\n min-height: 0;\n height: 100%;\n display: flex;\n flex-direction: column;\n overflow: hidden;\n }\n .editor-area lyra-monaco-widget,\n .editor-area monaco-widget {\n flex: 1;\n min-height: 0;\n }\n .editor-placeholder {\n flex: 1;\n min-height: 0;\n }\n `;\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'lyra-sql-editor': LyraSqlEditor;\n }\n}\n\n","import { editorRegistry, File, type EditorInput } from '@eclipse-lyra/core';\nimport { html } from '@eclipse-lyra/core/externals/lit';\nimport './sql-editor';\n\nexport default function activate() {\n editorRegistry.registerEditorInputHandler({\n editorId: 'system.sqleditor',\n label: 'SQL Editor',\n icon: 'database',\n canHandle: (input: unknown) =>\n input instanceof File && input.getName().toLowerCase().endsWith('.sql'),\n ranking: 900,\n handle: async (input: File) => {\n const editorInput: EditorInput = {\n title: input.getName(),\n data: input,\n key: input.getName(),\n icon: 'database',\n noOverflow: false,\n state: {},\n component: () => null as any,\n };\n editorInput.component = () =>\n html`<lyra-sql-editor .input=${editorInput}></lyra-sql-editor>`;\n return editorInput;\n },\n });\n}\n\n"],"names":["html"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"sqleditor-extension-DQrJIYDT.js","sources":["../src/sql-editor.ts","../src/sqleditor-extension.ts"],"sourcesContent":["import { customElement, property, state } from 'lit/decorators.js';\nimport { LyraPart, type EditorInput, type EditorContentProvider, toastError, toastInfo, confirmDialog, publish, contributionRegistry, subscribe, unsubscribe, TOPIC_CONTRIBUTEIONS_CHANGED } from '@eclipse-lyra/core';\nimport type {\n SqlAdapterContribution,\n SqlConnectionInfo,\n SqlDatabase,\n} from '@eclipse-lyra/extension-sqleditor';\nimport { css, html } from 'lit';\nimport { createRef, ref } from 'lit/directives/ref.js';\nimport { LyraMonacoWidget } from '@eclipse-lyra/extension-monaco-editor';\n\nconst MAX_TAB_LABEL = 28;\n\nfunction truncateLabel(sql: string): string {\n const oneLine = sql.replace(/\\s+/g, ' ').trim();\n if (oneLine.length <= MAX_TAB_LABEL) return oneLine;\n return `${oneLine.slice(0, MAX_TAB_LABEL)}…`;\n}\n\n@customElement('lyra-sql-editor')\nexport class LyraSqlEditor extends LyraPart implements EditorContentProvider {\n @property({ attribute: false })\n public input?: EditorInput;\n\n @property({ type: Boolean })\n public readOnly = false;\n\n @state()\n private initialContent: string | undefined = undefined;\n\n @state()\n private initialUri: string | undefined = undefined;\n\n @state()\n private running = false;\n\n @state()\n private availableAdapters: SqlAdapterContribution[] = [];\n\n @state()\n private selectedEngineId: string | null = null;\n\n @state()\n private availableConnections: SqlConnectionInfo[] = [];\n\n @state()\n private selectedConnectionId: string | null = null;\n\n private widgetRef = createRef<LyraMonacoWidget>();\n private databases = new Map<string, SqlDatabase>();\n private unsubscribeContributionsToken?: string;\n\n protected async doInitUI() {\n const file = this.input!.data;\n const textContents = await file.getContents();\n this.initialContent = textContents;\n this.initialUri = file.getName();\n this.unsubscribeContributionsToken = subscribe(TOPIC_CONTRIBUTEIONS_CHANGED, (event: { target?: string } | undefined) => {\n if (event?.target === 'system.sqladapters') {\n void this.refreshAdapters();\n }\n });\n\n await this.refreshAdapters();\n this.requestUpdate();\n }\n\n private async refreshAdapters(): Promise<void> {\n const contributions = contributionRegistry.getContributions<SqlAdapterContribution>('system.sqladapters');\n this.availableAdapters = contributions;\n if (!contributions.length) {\n this.selectedEngineId = null;\n this.availableConnections = [];\n this.selectedConnectionId = null;\n this.updateToolbar();\n return;\n }\n if (!this.selectedEngineId) {\n const duckdbAdapter = contributions.find((c) => c.id === 'duckdb');\n this.selectedEngineId = (duckdbAdapter ?? contributions[0]).id;\n }\n await this.refreshConnections();\n this.updateToolbar();\n }\n\n private async getOrLoadDatabase(engineId: string): Promise<SqlDatabase | null> {\n const cached = this.databases.get(engineId);\n if (cached) return cached;\n const adapter = this.availableAdapters.find((c) => c.id === engineId);\n if (!adapter) return null;\n try {\n const database = await adapter.loader();\n this.databases.set(engineId, database);\n return database;\n } catch (err) {\n toastError(err instanceof Error ? err.message : String(err));\n return null;\n }\n }\n\n private async refreshConnections(): Promise<void> {\n const engineId = this.selectedEngineId;\n if (!engineId) {\n this.availableConnections = [];\n this.selectedConnectionId = null;\n this.updateToolbar();\n return;\n }\n const db = await this.getOrLoadDatabase(engineId);\n if (!db) {\n this.availableConnections = [];\n this.selectedConnectionId = null;\n this.updateToolbar();\n return;\n }\n const infos = await db.listConnections();\n this.availableConnections = infos;\n const currentId = db.currentConnectionId;\n if (currentId !== null) {\n this.selectedConnectionId = currentId;\n this.updateToolbar();\n return;\n }\n const preferred = infos.find((info: SqlConnectionInfo) => info.isDefault) ?? infos[0];\n this.selectedConnectionId = preferred ? preferred.id : null;\n if (preferred) {\n await db.selectConnection(preferred.id ?? null);\n }\n this.updateToolbar();\n }\n\n private async onEngineChange(e: Event): Promise<void> {\n const select = e.target as { value?: string };\n const value = select?.value ?? '';\n if (this.selectedEngineId === value) return;\n this.selectedEngineId = value || null;\n await this.refreshConnections();\n this.requestUpdate();\n this.updateToolbar();\n }\n\n private async onConnectionChange(e: Event): Promise<void> {\n const select = e.target as { value?: string };\n const value = select?.value ?? '';\n const next = value === '' ? null : value;\n if (this.selectedConnectionId === next) return;\n this.selectedConnectionId = next;\n const engineId = this.selectedEngineId;\n if (!engineId) return;\n const db = await this.getOrLoadDatabase(engineId);\n if (!db) return;\n await db.selectConnection(next);\n this.requestUpdate();\n this.updateToolbar();\n }\n\n private _onContentChange = () => {\n this.markDirty(true);\n };\n\n save(): void {\n const value = this.widgetRef.value?.getContent() ?? '';\n this.input?.data.saveContents(value);\n this.markDirty(false);\n }\n\n protected async doClose() {\n if (this.unsubscribeContributionsToken) {\n unsubscribe(this.unsubscribeContributionsToken);\n this.unsubscribeContributionsToken = undefined;\n }\n this.widgetRef.value?.dispose();\n for (const db of this.databases.values()) {\n await db.close();\n }\n this.databases.clear();\n }\n\n public getLanguage(): string | null {\n return 'sql';\n }\n\n public isLanguage(lang: string): boolean {\n return lang.toLowerCase() === 'sql';\n }\n\n public getContent(): string | null {\n return this.widgetRef.value?.getContent() ?? null;\n }\n\n public getSelection(): string | null {\n return this.widgetRef.value?.getSelection() ?? null;\n }\n\n public getSnippet(lines: number = 5): { snippet: string; cursorLine: number } | null {\n return this.widgetRef.value?.getSnippet(lines) ?? null;\n }\n\n public getFilePath(): string | null {\n return this.input?.data?.getWorkspacePath() ?? null;\n }\n\n private async runQuery(useSelectionOnly = false): Promise<void> {\n const sql = useSelectionOnly\n ? this.getSelection()?.trim()\n : (this.getSelection()?.trim() || this.getContent()?.trim());\n if (!sql) {\n toastError(useSelectionOnly ? 'No selection to run' : 'No SQL to run');\n return;\n }\n if (this.running) return;\n\n const engineId = this.selectedEngineId;\n if (!engineId) {\n toastError('No SQL engine available');\n return;\n }\n\n const db = await this.getOrLoadDatabase(engineId);\n if (!db) {\n toastError('Could not initialize SQL engine');\n return;\n }\n\n if (!this.selectedConnectionId && this.availableConnections.length) {\n const preferred = this.availableConnections.find(\n (info: SqlConnectionInfo) => info.isDefault,\n ) ?? this.availableConnections[0];\n this.selectedConnectionId = preferred.id;\n await db.selectConnection(preferred.id ?? null);\n }\n\n this.running = true;\n const label = truncateLabel(sql);\n this.requestUpdate();\n this.updateToolbar();\n\n const timeoutMs = 60_000;\n const timeoutId = window.setTimeout(() => this.clearRunningState(), timeoutMs);\n\n try {\n const result = await db.runQuery(sql);\n publish('dataview/publish', {\n title: label,\n data: { columns: result.columns, rows: result.rows },\n source: engineId,\n });\n } catch (err) {\n toastError(err instanceof Error ? err.message : String(err));\n } finally {\n window.clearTimeout(timeoutId);\n this.running = false;\n this.requestUpdate();\n this.updateToolbar();\n }\n }\n\n private clearRunningState(): void {\n if (!this.running) return;\n this.running = false;\n this.requestUpdate();\n this.updateToolbar();\n }\n\n private async createConnection(): Promise<void> {\n const engineId = this.selectedEngineId;\n if (!engineId) return;\n const db = await this.getOrLoadDatabase(engineId);\n if (!db || !db.createConnection) return;\n const info = await db.createConnection();\n if (!info) return;\n await this.refreshConnections();\n this.selectedConnectionId = info.id;\n await db.selectConnection(info.id ?? null);\n toastInfo(`Connection \"${info.label}\" created`);\n this.requestUpdate();\n this.updateToolbar();\n }\n\n private async deleteConnection(): Promise<void> {\n const engineId = this.selectedEngineId;\n if (!engineId) return;\n const db = await this.getOrLoadDatabase(engineId);\n if (!db || !db.deleteConnection) return;\n const id = this.selectedConnectionId;\n const connectionLabel =\n this.availableConnections.find((info) => info.id === id)?.label ??\n (id === null ? 'In-memory' : id ?? 'Current connection');\n const ok = await confirmDialog(`Delete connection \"${connectionLabel}\"?`);\n if (!ok) return;\n if (id !== null) {\n await db.deleteConnection(id);\n } else {\n await db.selectConnection(null);\n }\n await this.refreshConnections();\n this.requestUpdate();\n this.updateToolbar();\n }\n\n protected renderToolbar() {\n const engineValue = this.selectedEngineId ?? '';\n const connectionValue = this.selectedConnectionId ?? '';\n const adapters = this.availableAdapters;\n const hasEngines = adapters.length > 0;\n const hasConnections = this.availableConnections.length > 0;\n\n return html`\n <wa-select\n class=\"engine-select\"\n size=\"small\"\n .value=${engineValue}\n title=\"SQL engine\"\n @change=${(e: Event) => void this.onEngineChange(e)}\n >\n ${adapters.map(\n (adapter) =>\n html`<wa-option value=${adapter.id}>${adapter.label}</wa-option>`,\n )}\n </wa-select>\n <wa-select\n class=\"connection-select\"\n size=\"small\"\n .value=${connectionValue}\n title=\"Connection\"\n ?disabled=${!hasEngines || !hasConnections}\n @change=${(e: Event) => void this.onConnectionChange(e)}\n >\n ${this.availableConnections.map(\n (info) =>\n html`<wa-option value=${info.id ?? ''}>${info.label}</wa-option>`,\n )}\n </wa-select>\n <wa-button\n size=\"small\"\n appearance=\"plain\"\n title=\"New connection\"\n @click=${() => void this.createConnection()}\n >\n <wa-icon name=\"plus\" label=\"New\"></wa-icon>\n </wa-button>\n <wa-button\n size=\"small\"\n appearance=\"plain\"\n title=\"Delete connection\"\n @click=${() => void this.deleteConnection()}\n >\n <wa-icon name=\"trash\" label=\"Delete\"></wa-icon>\n </wa-button>\n <wa-button\n size=\"small\"\n appearance=\"plain\"\n ?disabled=${this.running}\n @click=${() => void this.runQuery(true)}\n title=\"Run selection only\"\n >\n <wa-icon name=\"i-cursor\" label=\"Run selection\"></wa-icon>\n ${this.running ? 'Running…' : 'Run selection'}\n </wa-button>\n <wa-button\n size=\"small\"\n appearance=\"plain\"\n ?disabled=${this.running}\n @click=${() => void this.runQuery(false)}\n title=\"Run all SQL\"\n >\n <wa-icon name=\"play\" label=\"Run\"></wa-icon>\n ${this.running ? 'Running…' : 'Run all'}\n </wa-button>\n `;\n }\n\n render() {\n if (this.initialContent === undefined) {\n return html`<div class=\"editor-placeholder\"></div>`;\n }\n\n return html`\n <div class=\"editor-area\">\n <lyra-monaco-widget\n .value=${this.initialContent}\n .uri=${this.initialUri}\n .language=${'sql'}\n .readOnly=${this.readOnly}\n @content-change=${this._onContentChange}\n ${ref(this.widgetRef)}\n ></lyra-monaco-widget>\n </div>\n `;\n }\n\n static styles = css`\n :host {\n display: flex;\n flex-direction: column;\n position: relative;\n width: 100%;\n height: 100%;\n }\n .engine-select {\n max-width: 10rem;\n }\n .connection-select {\n max-width: 12rem;\n }\n .editor-area {\n flex: 1;\n min-height: 0;\n height: 100%;\n display: flex;\n flex-direction: column;\n overflow: hidden;\n }\n .editor-area lyra-monaco-widget,\n .editor-area monaco-widget {\n flex: 1;\n min-height: 0;\n }\n .editor-placeholder {\n flex: 1;\n min-height: 0;\n }\n `;\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'lyra-sql-editor': LyraSqlEditor;\n }\n}\n\n","import { editorRegistry, File, type EditorInput } from '@eclipse-lyra/core';\nimport { html } from '@eclipse-lyra/core/externals/lit';\nimport './sql-editor';\n\nexport default function activate() {\n editorRegistry.registerEditorInputHandler({\n editorId: 'system.sqleditor',\n label: 'SQL Editor',\n icon: 'database',\n canHandle: (input: unknown) =>\n input instanceof File && input.getName().toLowerCase().endsWith('.sql'),\n ranking: 900,\n handle: async (input: File) => {\n const editorInput: EditorInput = {\n title: input.getName(),\n data: input,\n key: input.getName(),\n icon: 'database',\n noOverflow: false,\n state: {},\n component: () => null as any,\n };\n editorInput.component = () =>\n html`<lyra-sql-editor .input=${editorInput}></lyra-sql-editor>`;\n return editorInput;\n },\n });\n}\n\n"],"names":["html"],"mappings":"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"}
|