@eclipse-lyra/extension-sqleditor 0.7.24 → 0.7.25
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.
|
@@ -1 +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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"}
|
|
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/widget';\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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"}
|