@eclipse-docks/extension-sqleditor 0.7.89 → 0.7.90

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
@@ -8,7 +8,7 @@ extensionRegistry.registerExtension({
8
8
  id: pkg.name,
9
9
  name: "SQL Editor",
10
10
  description: "Generic SQL editor with pluggable backends",
11
- loader: () => import("./sqleditor-extension-K5TQp9rX.js"),
11
+ loader: () => import("./sqleditor-extension-bxzEDMXN.js"),
12
12
  icon: "database"
13
13
  });
14
14
  //#endregion
@@ -12,6 +12,7 @@ export declare class DocksSqlEditor extends DocksPart implements EditorContentPr
12
12
  private selectedConnectionId;
13
13
  private sqlEngineLoading;
14
14
  private dbVersion;
15
+ private sqlVersionLoading;
15
16
  private widgetRef;
16
17
  private databases;
17
18
  private unsubscribeContributionsToken?;
@@ -1 +1 @@
1
- {"version":3,"file":"sql-editor.d.ts","sourceRoot":"","sources":["../src/sql-editor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,KAAK,WAAW,EAAE,KAAK,qBAAqB,EAA0I,MAAM,qBAAqB,CAAC;AAuBtO,qBACa,cAAe,SAAQ,SAAU,YAAW,qBAAqB;IAErE,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;IAEvD,wEAAwE;IAExE,OAAO,CAAC,oBAAoB,CAAwC;IAGpE,OAAO,CAAC,gBAAgB,CAAS;IAGjC,OAAO,CAAC,SAAS,CAAiC;IAElD,OAAO,CAAC,SAAS,CAAkC;IACnD,OAAO,CAAC,SAAS,CAAkC;IACnD,OAAO,CAAC,6BAA6B,CAAC,CAAS;cAE/B,QAAQ;YAsBV,eAAe;YAoBf,iBAAiB;YAmBjB,kBAAkB;YAoClB,eAAe;YAcf,cAAc;YAWd,kBAAkB;YAelB,sBAAsB;YAYtB,0BAA0B;YAgB1B,oBAAoB;IAqBlC,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;IAmDtB,OAAO,CAAC,iBAAiB;YAMX,gBAAgB;YAehB,gBAAgB;IAqB9B,OAAO,CAAC,yBAAyB;YAQnB,oBAAoB;IAyBlC,SAAS,CAAC,aAAa;IAgOvB,SAAS,CAAC,aAAa;IAmBvB,MAAM,CAAC,MAAM,0BA+BX;CACH;AAED,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,qBAAqB;QAC7B,kBAAkB,EAAE,cAAc,CAAC;KACpC;CACF"}
1
+ {"version":3,"file":"sql-editor.d.ts","sourceRoot":"","sources":["../src/sql-editor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,KAAK,WAAW,EAAE,KAAK,qBAAqB,EAA0I,MAAM,qBAAqB,CAAC;AAuBtO,qBACa,cAAe,SAAQ,SAAU,YAAW,qBAAqB;IAErE,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;IAEvD,wEAAwE;IAExE,OAAO,CAAC,oBAAoB,CAAwC;IAGpE,OAAO,CAAC,gBAAgB,CAAS;IAGjC,OAAO,CAAC,SAAS,CAAiC;IAGlD,OAAO,CAAC,iBAAiB,CAAS;IAElC,OAAO,CAAC,SAAS,CAAkC;IACnD,OAAO,CAAC,SAAS,CAAkC;IACnD,OAAO,CAAC,6BAA6B,CAAC,CAAS;cAE/B,QAAQ;YAsBV,eAAe;YAqBf,iBAAiB;YAmBjB,kBAAkB;YAqClB,eAAe;YAkBf,cAAc;YAYd,kBAAkB;YAiBlB,sBAAsB;YAatB,0BAA0B;YAkB1B,oBAAoB;IAqBlC,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;IAmDtB,OAAO,CAAC,iBAAiB;YAMX,gBAAgB;YAehB,gBAAgB;IAqB9B,OAAO,CAAC,yBAAyB;YAQnB,oBAAoB;IAyBlC,SAAS,CAAC,aAAa;IAuOvB,SAAS,CAAC,aAAa;IAmBvB,MAAM,CAAC,MAAM,0BA+BX;CACH;AAED,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,qBAAqB;QAC7B,kBAAkB,EAAE,cAAc,CAAC;KACpC;CACF"}
@@ -359,6 +359,7 @@ var DocksSqlEditor = class DocksSqlEditor extends DocksPart {
359
359
  this.selectedConnectionId = void 0;
360
360
  this.sqlEngineLoading = false;
361
361
  this.dbVersion = void 0;
362
+ this.sqlVersionLoading = false;
362
363
  this.widgetRef = createRef();
363
364
  this.databases = /* @__PURE__ */ new Map();
364
365
  this._onContentChange = () => {
@@ -386,6 +387,7 @@ var DocksSqlEditor = class DocksSqlEditor extends DocksPart {
386
387
  this.availableConnections = [];
387
388
  this.selectedConnectionId = void 0;
388
389
  this.dbVersion = void 0;
390
+ this.sqlVersionLoading = false;
389
391
  await this.updateComplete;
390
392
  return;
391
393
  }
@@ -419,6 +421,7 @@ var DocksSqlEditor = class DocksSqlEditor extends DocksPart {
419
421
  this.selectedConnectionId = void 0;
420
422
  this.dbVersion = void 0;
421
423
  this.sqlEngineLoading = false;
424
+ this.sqlVersionLoading = false;
422
425
  await this.updateComplete;
423
426
  return;
424
427
  }
@@ -446,14 +449,18 @@ var DocksSqlEditor = class DocksSqlEditor extends DocksPart {
446
449
  }
447
450
  async updateDbVersion() {
448
451
  this.dbVersion = void 0;
452
+ this.sqlVersionLoading = false;
449
453
  const engineId = this.selectedEngineId;
450
454
  if (!engineId || this.selectedConnectionId === void 0) return;
451
455
  const db = this.databases.get(engineId);
452
456
  if (!db?.readVersion) return;
457
+ this.sqlVersionLoading = true;
453
458
  try {
454
459
  this.dbVersion = await db.readVersion();
455
460
  } catch {
456
461
  this.dbVersion = void 0;
462
+ } finally {
463
+ this.sqlVersionLoading = false;
457
464
  }
458
465
  this.requestUpdate();
459
466
  }
@@ -463,6 +470,7 @@ var DocksSqlEditor = class DocksSqlEditor extends DocksPart {
463
470
  this.selectedEngineId = value || null;
464
471
  this.selectedConnectionId = void 0;
465
472
  this.dbVersion = void 0;
473
+ this.sqlVersionLoading = false;
466
474
  await this.refreshConnections();
467
475
  this.requestUpdate();
468
476
  }
@@ -471,6 +479,8 @@ var DocksSqlEditor = class DocksSqlEditor extends DocksPart {
471
479
  const next = value === "" ? null : value;
472
480
  if (this.selectedConnectionId === next) return;
473
481
  this.selectedConnectionId = next;
482
+ this.dbVersion = void 0;
483
+ this.sqlVersionLoading = false;
474
484
  const engineId = this.selectedEngineId;
475
485
  if (!engineId) return;
476
486
  const db = await this.getOrLoadDatabase(engineId);
@@ -485,6 +495,7 @@ var DocksSqlEditor = class DocksSqlEditor extends DocksPart {
485
495
  this.selectedEngineId = value || null;
486
496
  this.selectedConnectionId = void 0;
487
497
  this.dbVersion = void 0;
498
+ this.sqlVersionLoading = false;
488
499
  await this.refreshConnections();
489
500
  this.requestUpdate();
490
501
  }
@@ -493,6 +504,8 @@ var DocksSqlEditor = class DocksSqlEditor extends DocksPart {
493
504
  const next = value === "" ? null : value;
494
505
  if (this.selectedConnectionId === next) return;
495
506
  this.selectedConnectionId = next;
507
+ this.dbVersion = void 0;
508
+ this.sqlVersionLoading = false;
496
509
  const engineId = this.selectedEngineId;
497
510
  if (!engineId) return;
498
511
  const db = await this.getOrLoadDatabase(engineId);
@@ -658,11 +671,14 @@ var DocksSqlEditor = class DocksSqlEditor extends DocksPart {
658
671
  const dbForEngine = engineId ? this.databases.get(engineId) : null;
659
672
  const supportsExtensions = Boolean(dbForEngine?.listDbExtensions);
660
673
  const connectionButtonLabel = this.sqlEngineLoading ? "Loading…" : this.selectedConnectionId === void 0 ? "Select connection" : this.selectedConnectionId === null ? "In-memory" : this.availableConnections.find((c) => c.id === this.selectedConnectionId)?.label ?? "Connection";
661
- const runDisabled = this.running || this.sqlEngineLoading || this.selectedConnectionId === void 0;
662
- const sqlConnected = this.selectedConnectionId !== void 0 && !this.sqlEngineLoading;
663
- const statusTitle = this.sqlEngineLoading ? "Connecting…" : sqlConnected ? "SQL engine connected" : "No connection selected";
664
- const statusIconColor = this.sqlEngineLoading ? "var(--wa-color-warning-500)" : sqlConnected ? "var(--wa-color-green-40)" : "var(--wa-color-red-40)";
665
- const statusText = this.sqlEngineLoading ? "" : this.dbVersion ? this.dbVersion : sqlConnected ? "Connected" : "Not connected";
674
+ const runDisabled = this.running || this.sqlEngineLoading || this.sqlVersionLoading || this.selectedConnectionId === void 0;
675
+ const dbSupportsVersion = Boolean(dbForEngine?.readVersion);
676
+ const awaitingVersion = this.selectedConnectionId !== void 0 && dbSupportsVersion && (this.sqlEngineLoading || this.sqlVersionLoading || !this.dbVersion);
677
+ const isConnecting = this.sqlEngineLoading || awaitingVersion;
678
+ const sqlConnected = this.selectedConnectionId !== void 0 && !isConnecting;
679
+ const statusTitle = isConnecting ? "Connecting…" : sqlConnected ? "SQL engine connected" : "No connection selected";
680
+ const statusIconColor = isConnecting ? "var(--wa-color-warning-500)" : sqlConnected ? "var(--wa-color-green-40)" : "var(--wa-color-red-40)";
681
+ const statusText = isConnecting ? "" : this.dbVersion ? this.dbVersion : sqlConnected ? "Connected" : "Not connected";
666
682
  return html`
667
683
  <div class="sql-toolbar-part" style=${styleMap({
668
684
  display: "flex",
@@ -806,7 +822,7 @@ var DocksSqlEditor = class DocksSqlEditor extends DocksPart {
806
822
  label="SQL engine status"
807
823
  style=${styleMap({ color: statusIconColor })}
808
824
  ></wa-icon>
809
- ${this.sqlEngineLoading ? html`<wa-spinner style="font-size: 0.9rem"></wa-spinner>` : html`<span
825
+ ${isConnecting ? html`<wa-spinner style="font-size: 0.9rem"></wa-spinner>` : html`<span
810
826
  class="sql-toolbar-version"
811
827
  style=${styleMap({
812
828
  fontSize: "0.8rem",
@@ -883,6 +899,7 @@ _decorate([state()], DocksSqlEditor.prototype, "availableConnections", void 0);
883
899
  _decorate([state()], DocksSqlEditor.prototype, "selectedConnectionId", void 0);
884
900
  _decorate([state()], DocksSqlEditor.prototype, "sqlEngineLoading", void 0);
885
901
  _decorate([state()], DocksSqlEditor.prototype, "dbVersion", void 0);
902
+ _decorate([state()], DocksSqlEditor.prototype, "sqlVersionLoading", void 0);
886
903
  DocksSqlEditor = _decorate([customElement("docks-sql-editor")], DocksSqlEditor);
887
904
  //#endregion
888
905
  //#region src/sqleditor-extension.ts
@@ -910,4 +927,4 @@ function activate() {
910
927
  //#endregion
911
928
  export { activate as default };
912
929
 
913
- //# sourceMappingURL=sqleditor-extension-K5TQp9rX.js.map
930
+ //# sourceMappingURL=sqleditor-extension-bxzEDMXN.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sqleditor-extension-bxzEDMXN.js","names":[],"sources":["../src/sql-extension-manager.ts","../src/sql-editor.ts","../src/sqleditor-extension.ts"],"sourcesContent":["import { rootContext, taskService, toastError } from '@eclipse-docks/core';\nimport {\n css,\n customElement,\n html,\n LitElement,\n property,\n repeat,\n state,\n} from '@eclipse-docks/core/externals/lit';\nimport type { SqlDatabase, SqlDatabaseExtensionInfo } from './sql-api';\n\nexport interface SqlExtensionManagerOptions {\n db: SqlDatabase | null;\n databaseLabel: string;\n}\n\n@customElement('docks-sql-extension-manager')\nexport class DocksSqlExtensionManager extends LitElement {\n @property({ type: Boolean })\n open = false;\n\n @property({ attribute: false })\n db: SqlDatabase | null = null;\n\n @property()\n databaseLabel = '';\n\n @state()\n private extensions: SqlDatabaseExtensionInfo[] = [];\n\n @state()\n private loading = false;\n\n @state()\n private updatingId: string | null = null;\n\n @state()\n private error: string | null = null;\n\n @state()\n private filterText = '';\n\n public configure(options: SqlExtensionManagerOptions): void {\n this.db = options.db;\n this.databaseLabel = options.databaseLabel;\n this.extensions = [];\n this.error = null;\n void this.refreshExtensions();\n }\n\n public show(): void {\n if (!this.db || !this.db.listDbExtensions) return;\n this.open = true;\n }\n\n public hide(): void {\n this.open = false;\n }\n\n private async refreshExtensions(): Promise<void> {\n if (!this.db || !this.db.listDbExtensions) {\n this.extensions = [];\n return;\n }\n this.loading = true;\n this.error = null;\n try {\n const result = await taskService.runAsync(\n 'Loading database extensions',\n async () => this.db!.listDbExtensions!(),\n );\n this.extensions = Array.isArray(result) ? result : [];\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n this.error = msg;\n toastError(msg);\n } finally {\n this.loading = false;\n }\n }\n\n private async enableExtension(ext: SqlDatabaseExtensionInfo): Promise<void> {\n if (!this.db || !this.db.enableDbExtension) return;\n this.updatingId = ext.id;\n this.error = null;\n try {\n await taskService.runAsync(\n `Enabling extension ${ext.label || ext.id}`,\n async () => this.db!.enableDbExtension!(ext.id),\n );\n await this.refreshExtensions();\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n this.error = msg;\n toastError(msg);\n } finally {\n this.updatingId = null;\n }\n }\n\n private async disableExtension(ext: SqlDatabaseExtensionInfo): Promise<void> {\n if (!this.db || !this.db.disableDbExtension) return;\n this.updatingId = ext.id;\n this.error = null;\n try {\n await taskService.runAsync(\n `Disabling extension ${ext.label || ext.id}`,\n async () => this.db!.disableDbExtension!(ext.id),\n );\n await this.refreshExtensions();\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n this.error = msg;\n toastError(msg);\n } finally {\n this.updatingId = null;\n }\n }\n\n private renderExtensionRow(ext: SqlDatabaseExtensionInfo) {\n const installed = Boolean(ext.installed);\n const canDisable = installed && !!this.db?.disableDbExtension;\n const isUpdating = this.updatingId === ext.id;\n\n return html`\n <div class=\"extension-item\">\n <div class=\"extension-main\">\n <div class=\"extension-name\">${ext.label || ext.id}</div>\n ${ext.description\n ? html`<div class=\"extension-desc\">${ext.description}</div>`\n : null}\n </div>\n <div class=\"extension-meta\">\n <span\n class=${installed ? 'badge badge-installed' : 'badge badge-available'}\n >\n ${installed ? 'Installed' : 'Available'}\n </span>\n <div class=\"extension-actions\">\n ${installed\n ? html`\n <wa-button\n size=\"small\"\n appearance=\"plain\"\n ?disabled=${!canDisable || isUpdating}\n @click=${() => void this.disableExtension(ext)}\n >\n <wa-icon\n name=\"circle-minus\"\n label=\"Disable\"\n ></wa-icon>\n </wa-button>\n `\n : html`\n <wa-button\n size=\"small\"\n appearance=\"plain\"\n ?disabled=${isUpdating}\n @click=${() => void this.enableExtension(ext)}\n >\n <wa-icon\n name=\"plug-circle-plus\"\n label=\"Enable\"\n ></wa-icon>\n </wa-button>\n `}\n </div>\n </div>\n </div>\n `;\n }\n\n render() {\n const hasDb = Boolean(this.db && this.db.listDbExtensions);\n const filter = this.filterText.trim().toLowerCase();\n const filteredExtensions = !filter\n ? this.extensions\n : this.extensions.filter((ext) => {\n const text = `${ext.label ?? ''} ${ext.id} ${\n ext.description ?? ''\n }`.toLowerCase();\n return text.includes(filter);\n });\n const hasItems = filteredExtensions.length > 0;\n\n return html`\n <wa-dialog\n label=\"Database extensions\"\n ?open=${this.open}\n @wa-after-hide=${() => {\n this.open = false;\n this.dispatchEvent(\n new CustomEvent('hide', { bubbles: true, composed: true }),\n );\n }}\n >\n <div class=\"extension-manager\">\n <p class=\"extension-manager-description\">\n Database:\n <strong>${this.databaseLabel || 'Current connection'}</strong>\n </p>\n\n ${!hasDb\n ? html`\n <wa-alert variant=\"warning\" open>\n <wa-icon slot=\"icon\" name=\"triangle-exclamation\"></wa-icon>\n The current SQL engine does not expose any extension information.\n </wa-alert>\n `\n : null}\n\n ${this.error\n ? html`\n <wa-alert\n variant=\"danger\"\n open\n closable\n @wa-after-hide=${() => {\n this.error = null;\n }}\n >\n <wa-icon slot=\"icon\" name=\"circle-exclamation\"></wa-icon>\n ${this.error}\n </wa-alert>\n `\n : null}\n\n <wa-input\n size=\"small\"\n placeholder=\"Filter extensions…\"\n .value=${this.filterText}\n @input=${(event: Event) => {\n const target = event.target as HTMLInputElement | null;\n this.filterText = target?.value ?? '';\n }}\n @wa-clear=${() => {\n this.filterText = '';\n }}\n with-clear\n >\n <wa-icon slot=\"prefix\" name=\"magnifying-glass\"></wa-icon>\n </wa-input>\n\n <div class=\"extension-list\">\n ${this.loading\n ? html`<div class=\"extension-list-empty\">Loading extensions…</div>`\n : !hasItems\n ? html`\n <div class=\"extension-list-empty\">\n No extensions available for this connection.\n </div>\n `\n : repeat(\n filteredExtensions,\n (ext) => ext.id,\n (ext) => this.renderExtensionRow(ext),\n )}\n </div>\n </div>\n <div slot=\"footer\" class=\"extension-manager-footer\">\n <wa-button variant=\"default\" @click=${() => this.hide()}>\n Close\n </wa-button>\n </div>\n </wa-dialog>\n `;\n }\n\n static styles = css`\n :host {\n display: contents;\n }\n\n .extension-manager {\n display: flex;\n flex-direction: column;\n gap: 1rem;\n padding: 1rem;\n height: 420px;\n box-sizing: border-box;\n }\n\n .extension-toolbar {\n display: flex;\n justify-content: flex-end;\n }\n\n .extension-manager-description {\n margin: 0;\n font-size: 0.95rem;\n opacity: 0.9;\n }\n\n .extension-list {\n display: flex;\n flex-direction: column;\n gap: 0.5rem;\n flex: 1;\n min-height: 0;\n max-height: 100%;\n overflow-y: auto;\n }\n\n .extension-list-empty {\n font-size: 0.9rem;\n opacity: 0.8;\n padding: 0.5rem 0;\n }\n\n .extension-item {\n display: flex;\n align-items: flex-start;\n justify-content: space-between;\n gap: 0.75rem;\n padding: 0.5rem 0;\n border-bottom: 1px solid var(--wa-color-neutral-200, #e5e7eb);\n }\n\n .extension-main {\n display: flex;\n flex-direction: column;\n gap: 0.15rem;\n min-width: 0;\n }\n\n .extension-name {\n font-weight: 500;\n font-size: 0.95rem;\n }\n\n .extension-desc {\n font-size: 0.85rem;\n opacity: 0.8;\n }\n\n .extension-meta {\n display: flex;\n flex-direction: column;\n align-items: flex-end;\n gap: 0.35rem;\n }\n\n .extension-actions {\n display: flex;\n gap: 0.25rem;\n }\n\n .badge {\n display: inline-flex;\n align-items: center;\n padding: 0.15rem 0.4rem;\n border-radius: 999px;\n font-size: 0.75rem;\n border: 1px solid var(--wa-color-neutral-200, #e5e7eb);\n }\n\n .badge-installed {\n background-color: var(--wa-color-success-50, #ecfdf3);\n }\n\n .badge-available {\n background-color: var(--wa-color-neutral-50, #f9fafb);\n }\n\n .extension-manager-footer {\n display: flex;\n justify-content: flex-end;\n padding-top: 1rem;\n border-top: 1px solid var(--wa-color-neutral-200, #e5e7eb);\n }\n `;\n}\n\nclass SqlExtensionManagerService {\n private managerInstance: DocksSqlExtensionManager | null = null;\n\n public showExtensionManager(\n options: SqlExtensionManagerOptions,\n ): DocksSqlExtensionManager | null {\n if (!options.db || !options.db.listDbExtensions) {\n toastError('The current SQL engine does not support extensions.');\n return null;\n }\n if (!this.managerInstance) {\n this.managerInstance = document.createElement(\n 'docks-sql-extension-manager',\n ) as DocksSqlExtensionManager;\n document.body.appendChild(this.managerInstance);\n }\n this.managerInstance.configure(options);\n this.managerInstance.show();\n return this.managerInstance;\n }\n\n public getManager(): DocksSqlExtensionManager | null {\n return this.managerInstance;\n }\n}\n\nexport const sqlExtensionManagerService = new SqlExtensionManagerService();\nrootContext.put('sqlExtensionManagerService', sqlExtensionManagerService);\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'docks-sql-extension-manager': DocksSqlExtensionManager;\n }\n}\n\n","import { DocksPart, type EditorInput, type EditorContentProvider, toastError, toastInfo, confirmDialog, publish, contributionRegistry, subscribe, unsubscribe, TOPIC_CONTRIBUTEIONS_CHANGED, taskService } from '@eclipse-docks/core';\nimport {\n createRef,\n css,\n customElement,\n html,\n property,\n ref,\n state,\n styleMap,\n} from '@eclipse-docks/core/externals/lit';\nimport type { SqlAdapterContribution, SqlConnectionInfo, SqlDatabase } from './sql-api';\nimport { sqlExtensionManagerService } from './sql-extension-manager';\nimport { DocksMonacoWidget } from '@eclipse-docks/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('docks-sql-editor')\nexport class DocksSqlEditor extends DocksPart 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 /** `undefined` = user has not chosen a connection yet (placeholder). */\n @state()\n private selectedConnectionId: string | null | undefined = undefined;\n\n @state()\n private sqlEngineLoading = false;\n\n @state()\n private dbVersion: string | undefined = undefined;\n\n @state()\n private sqlVersionLoading = false;\n\n private widgetRef = createRef<DocksMonacoWidget>();\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 =\n typeof textContents === 'string'\n ? textContents\n : textContents == null\n ? ''\n : String(textContents);\n this.initialUri = file.getWorkspacePath();\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.updateComplete;\n void this.refreshAdapters().catch((err) => {\n toastError(err instanceof Error ? err.message : String(err));\n });\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 = undefined;\n this.dbVersion = undefined;\n this.sqlVersionLoading = false;\n await this.updateComplete;\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 }\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 = undefined;\n this.dbVersion = undefined;\n this.sqlEngineLoading = false;\n this.sqlVersionLoading = false;\n await this.updateComplete;\n return;\n }\n this.sqlEngineLoading = true;\n this.dbVersion = undefined;\n this.requestUpdate();\n try {\n const db = await this.getOrLoadDatabase(engineId);\n if (!db) {\n this.availableConnections = [];\n this.selectedConnectionId = undefined;\n return;\n }\n const infos = await db.listConnections();\n this.availableConnections = infos;\n const currentId = db.currentConnectionId;\n if (currentId !== null && currentId !== undefined) {\n this.selectedConnectionId = currentId;\n await this.updateDbVersion();\n } else {\n this.selectedConnectionId = undefined;\n }\n } finally {\n this.sqlEngineLoading = false;\n await this.updateComplete;\n this.requestUpdate();\n }\n }\n\n private async updateDbVersion(): Promise<void> {\n this.dbVersion = undefined;\n this.sqlVersionLoading = false;\n const engineId = this.selectedEngineId;\n if (!engineId || this.selectedConnectionId === undefined) return;\n const db = this.databases.get(engineId);\n if (!db?.readVersion) return;\n this.sqlVersionLoading = true;\n try {\n this.dbVersion = await db.readVersion();\n } catch {\n this.dbVersion = undefined;\n } finally {\n this.sqlVersionLoading = false;\n }\n this.requestUpdate();\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 this.selectedConnectionId = undefined;\n this.dbVersion = undefined;\n this.sqlVersionLoading = false;\n await this.refreshConnections();\n this.requestUpdate();\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 this.dbVersion = undefined;\n this.sqlVersionLoading = false;\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 await this.updateDbVersion();\n this.requestUpdate();\n }\n\n private async onEngineDropdownSelect(\n e: CustomEvent<{ item?: { value?: string } }>,\n ): Promise<void> {\n const value = e.detail?.item?.value ?? '';\n if (this.selectedEngineId === value) return;\n this.selectedEngineId = value || null;\n this.selectedConnectionId = undefined;\n this.dbVersion = undefined;\n this.sqlVersionLoading = false;\n await this.refreshConnections();\n this.requestUpdate();\n }\n\n private async onConnectionDropdownSelect(\n e: CustomEvent<{ item?: { value?: string } }>,\n ): Promise<void> {\n const value = e.detail?.item?.value ?? '';\n const next = value === '' ? null : value;\n if (this.selectedConnectionId === next) return;\n this.selectedConnectionId = next;\n this.dbVersion = undefined;\n this.sqlVersionLoading = false;\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 await this.updateDbVersion();\n this.requestUpdate();\n }\n\n private async deleteConnectionById(e: Event, id: string | null): Promise<void> {\n e.stopPropagation();\n e.preventDefault();\n const engineId = this.selectedEngineId;\n if (!engineId) return;\n const db = await this.getOrLoadDatabase(engineId);\n if (!db || !db.deleteConnection) return;\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 }\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 selection = this.getSelection()?.trim();\n const content = this.getContent()?.trim();\n const sql = useSelectionOnly ? selection : content;\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 === undefined) {\n toastError('Select a connection');\n return;\n }\n\n this.running = true;\n const label = truncateLabel(sql);\n this.requestUpdate();\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 }\n }\n\n private clearRunningState(): void {\n if (!this.running) return;\n this.running = false;\n this.requestUpdate();\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 await this.updateDbVersion();\n toastInfo(`Connection \"${info.label}\" created`);\n this.requestUpdate();\n }\n\n private async deleteConnection(): Promise<void> {\n const engineId = this.selectedEngineId;\n if (!engineId) return;\n if (this.selectedConnectionId === undefined) 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 }\n\n private getCurrentConnectionLabel(): string | null {\n const id = this.selectedConnectionId;\n if (id === undefined) return null;\n if (id === null) return 'In-memory';\n const info = this.availableConnections.find((c) => c.id === id);\n return info?.label ?? id;\n }\n\n private async openExtensionManager(): Promise<void> {\n const engineId = this.selectedEngineId;\n if (!engineId) return;\n if (this.selectedConnectionId === undefined) {\n toastError('Select a connection');\n return;\n }\n const db = await this.getOrLoadDatabase(engineId);\n if (!db || !db.listDbExtensions) {\n toastInfo('Extensions are not available for the selected SQL engine.');\n return;\n }\n const adapter =\n this.availableAdapters.find((c) => c.id === engineId) ?? null;\n const engineLabel = adapter?.label ?? engineId;\n const connectionLabel = this.getCurrentConnectionLabel();\n const databaseLabel = connectionLabel\n ? `${engineLabel} – ${connectionLabel}`\n : engineLabel;\n sqlExtensionManagerService.showExtensionManager({\n db,\n databaseLabel,\n });\n }\n\n protected renderToolbar() {\n const adapters = this.availableAdapters;\n const hasEngines = adapters.length > 0;\n const hasConnections = this.availableConnections.length > 0;\n const engineId = this.selectedEngineId;\n const dbForEngine = engineId ? this.databases.get(engineId) : null;\n const supportsExtensions = Boolean(dbForEngine?.listDbExtensions);\n const connectionButtonLabel = this.sqlEngineLoading\n ? 'Loading…'\n : this.selectedConnectionId === undefined\n ? 'Select connection'\n : this.selectedConnectionId === null\n ? 'In-memory'\n : this.availableConnections.find(\n (c) => c.id === this.selectedConnectionId,\n )?.label ?? 'Connection';\n const runDisabled =\n this.running ||\n this.sqlEngineLoading ||\n this.sqlVersionLoading ||\n this.selectedConnectionId === undefined;\n\n const dbSupportsVersion = Boolean(dbForEngine?.readVersion);\n const awaitingVersion =\n this.selectedConnectionId !== undefined &&\n dbSupportsVersion &&\n (this.sqlEngineLoading || this.sqlVersionLoading || !this.dbVersion);\n const isConnecting = this.sqlEngineLoading || awaitingVersion;\n const sqlConnected =\n this.selectedConnectionId !== undefined && !isConnecting;\n const statusTitle = isConnecting\n ? 'Connecting…'\n : sqlConnected\n ? 'SQL engine connected'\n : 'No connection selected';\n const statusIconColor = isConnecting\n ? 'var(--wa-color-warning-500)'\n : sqlConnected\n ? 'var(--wa-color-green-40)'\n : 'var(--wa-color-red-40)';\n const statusText = isConnecting\n ? ''\n : this.dbVersion\n ? this.dbVersion\n : sqlConnected\n ? 'Connected'\n : 'Not connected';\n\n // Toolbar markup renders under docks-toolbar; host static styles do not apply there.\n const sqlToolbarPartStyle = {\n display: 'flex',\n flex: '1',\n minWidth: '0',\n alignItems: 'center',\n gap: 'var(--wa-space-2xs)',\n flexWrap: 'nowrap',\n } as const;\n const sqlToolbarLeadStyle = {\n display: 'flex',\n flex: '1',\n minWidth: '0',\n flexWrap: 'nowrap',\n alignItems: 'center',\n gap: 'var(--wa-space-2xs)',\n overflowX: 'auto',\n } as const;\n const sqlToolbarStatusStyle = {\n flexShrink: '0',\n display: 'inline-flex',\n alignItems: 'center',\n gap: '0.5rem',\n minHeight: '1.25rem',\n whiteSpace: 'nowrap',\n } as const;\n const sqlToolbarVersionStyle = {\n fontSize: '0.8rem',\n opacity: '0.85',\n whiteSpace: 'nowrap',\n maxWidth: '14rem',\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n } as const;\n\n return html`\n <div class=\"sql-toolbar-part\" style=${styleMap(sqlToolbarPartStyle)}>\n <div class=\"sql-toolbar-lead\" style=${styleMap(sqlToolbarLeadStyle)}>\n <wa-dropdown\n class=\"engine-select\"\n placement=\"bottom-start\"\n distance=\"4\"\n size=\"small\"\n @wa-select=${(e: CustomEvent) => void this.onEngineDropdownSelect(e)}\n >\n <wa-button\n slot=\"trigger\"\n appearance=\"plain\"\n size=\"small\"\n with-caret\n title=\"SQL engine\"\n >\n ${this.selectedEngineId\n ? adapters.find((a) => a.id === this.selectedEngineId)?.label ??\n this.selectedEngineId\n : 'Select engine'}\n </wa-button>\n ${adapters.map(\n (adapter) => html`\n <wa-dropdown-item\n value=${adapter.id}\n type=\"checkbox\"\n ?checked=${adapter.id === this.selectedEngineId}\n >\n ${adapter.label}\n </wa-dropdown-item>\n `,\n )}\n </wa-dropdown>\n <wa-dropdown\n class=\"connection-select\"\n placement=\"bottom-start\"\n distance=\"4\"\n size=\"small\"\n @wa-select=${(e: CustomEvent) =>\n void this.onConnectionDropdownSelect(e)}\n >\n <wa-button\n slot=\"trigger\"\n appearance=\"plain\"\n size=\"small\"\n with-caret\n title=\"Connection\"\n ?disabled=${!hasEngines || !hasConnections || this.sqlEngineLoading}\n >\n ${connectionButtonLabel}\n </wa-button>\n ${this.availableConnections.map(\n (info) => html`\n <wa-dropdown-item\n value=${info.id ?? ''}\n type=\"checkbox\"\n ?checked=${info.id === this.selectedConnectionId}\n >\n ${info.label}\n <wa-button\n slot=\"details\"\n appearance=\"plain\"\n size=\"small\"\n title=${info.id === null\n ? 'Reset in-memory connection'\n : 'Delete connection'}\n @click=${(e: Event) => this.deleteConnectionById(e, info.id)}\n >\n <wa-icon\n name=${info.id === null ? 'rotate-right' : 'trash'}\n label=${info.id === null ? 'Reset' : 'Delete'}\n ></wa-icon>\n </wa-button>\n </wa-dropdown-item>\n `,\n )}\n </wa-dropdown>\n <wa-button\n size=\"small\"\n appearance=\"plain\"\n title=\"New connection\"\n ?disabled=${this.sqlEngineLoading}\n @click=${() => void this.createConnection()}\n >\n <wa-icon name=\"plus\" label=\"New\"></wa-icon>\n </wa-button>\n ${supportsExtensions\n ? html`\n <wa-button\n size=\"small\"\n appearance=\"plain\"\n title=\"Manage extensions\"\n ?disabled=${!hasEngines ||\n !hasConnections ||\n this.selectedConnectionId === undefined ||\n this.sqlEngineLoading}\n @click=${() => void this.openExtensionManager()}\n >\n <wa-icon name=\"puzzle-piece\" label=\"Extensions\"></wa-icon>\n Extensions\n </wa-button>\n `\n : null}\n <wa-button\n size=\"small\"\n appearance=\"plain\"\n ?disabled=${runDisabled}\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=${runDisabled}\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 </div>\n <span\n class=\"sql-toolbar-status\"\n aria-live=\"polite\"\n title=${statusTitle}\n style=${styleMap(sqlToolbarStatusStyle)}\n >\n <wa-icon\n name=\"circle\"\n label=\"SQL engine status\"\n style=${styleMap({ color: statusIconColor })}\n ></wa-icon>\n ${isConnecting\n ? html`<wa-spinner style=\"font-size: 0.9rem\"></wa-spinner>`\n : html`<span\n class=\"sql-toolbar-version\"\n style=${styleMap(sqlToolbarVersionStyle)}\n >${statusText}</span\n >`}\n </span>\n </div>\n `;\n }\n\n protected renderContent() {\n if (this.initialContent === undefined) {\n return html`<div class=\"editor-placeholder\"></div>`;\n }\n\n return html`\n <div class=\"editor-area\">\n <docks-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 ></docks-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 docks-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 'docks-sql-editor': DocksSqlEditor;\n }\n}\n\n","import { editorRegistry, File, type EditorInput } from '@eclipse-docks/core';\nimport { html } from '@eclipse-docks/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.getWorkspacePath(),\n data: input,\n key: input.getWorkspacePath(),\n icon: 'database',\n state: {},\n component: () => null as any,\n };\n editorInput.component = (id: string) =>\n html`<docks-sql-editor id=\"${id}\" .input=${editorInput}></docks-sql-editor>`;\n return editorInput;\n },\n });\n}\n\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@eclipse-docks/extension-sqleditor",
3
- "version": "0.7.89",
3
+ "version": "0.7.90",
4
4
  "type": "module",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.js",
@@ -1 +0,0 @@
1
- {"version":3,"file":"sqleditor-extension-K5TQp9rX.js","names":[],"sources":["../src/sql-extension-manager.ts","../src/sql-editor.ts","../src/sqleditor-extension.ts"],"sourcesContent":["import { rootContext, taskService, toastError } from '@eclipse-docks/core';\nimport {\n css,\n customElement,\n html,\n LitElement,\n property,\n repeat,\n state,\n} from '@eclipse-docks/core/externals/lit';\nimport type { SqlDatabase, SqlDatabaseExtensionInfo } from './sql-api';\n\nexport interface SqlExtensionManagerOptions {\n db: SqlDatabase | null;\n databaseLabel: string;\n}\n\n@customElement('docks-sql-extension-manager')\nexport class DocksSqlExtensionManager extends LitElement {\n @property({ type: Boolean })\n open = false;\n\n @property({ attribute: false })\n db: SqlDatabase | null = null;\n\n @property()\n databaseLabel = '';\n\n @state()\n private extensions: SqlDatabaseExtensionInfo[] = [];\n\n @state()\n private loading = false;\n\n @state()\n private updatingId: string | null = null;\n\n @state()\n private error: string | null = null;\n\n @state()\n private filterText = '';\n\n public configure(options: SqlExtensionManagerOptions): void {\n this.db = options.db;\n this.databaseLabel = options.databaseLabel;\n this.extensions = [];\n this.error = null;\n void this.refreshExtensions();\n }\n\n public show(): void {\n if (!this.db || !this.db.listDbExtensions) return;\n this.open = true;\n }\n\n public hide(): void {\n this.open = false;\n }\n\n private async refreshExtensions(): Promise<void> {\n if (!this.db || !this.db.listDbExtensions) {\n this.extensions = [];\n return;\n }\n this.loading = true;\n this.error = null;\n try {\n const result = await taskService.runAsync(\n 'Loading database extensions',\n async () => this.db!.listDbExtensions!(),\n );\n this.extensions = Array.isArray(result) ? result : [];\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n this.error = msg;\n toastError(msg);\n } finally {\n this.loading = false;\n }\n }\n\n private async enableExtension(ext: SqlDatabaseExtensionInfo): Promise<void> {\n if (!this.db || !this.db.enableDbExtension) return;\n this.updatingId = ext.id;\n this.error = null;\n try {\n await taskService.runAsync(\n `Enabling extension ${ext.label || ext.id}`,\n async () => this.db!.enableDbExtension!(ext.id),\n );\n await this.refreshExtensions();\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n this.error = msg;\n toastError(msg);\n } finally {\n this.updatingId = null;\n }\n }\n\n private async disableExtension(ext: SqlDatabaseExtensionInfo): Promise<void> {\n if (!this.db || !this.db.disableDbExtension) return;\n this.updatingId = ext.id;\n this.error = null;\n try {\n await taskService.runAsync(\n `Disabling extension ${ext.label || ext.id}`,\n async () => this.db!.disableDbExtension!(ext.id),\n );\n await this.refreshExtensions();\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n this.error = msg;\n toastError(msg);\n } finally {\n this.updatingId = null;\n }\n }\n\n private renderExtensionRow(ext: SqlDatabaseExtensionInfo) {\n const installed = Boolean(ext.installed);\n const canDisable = installed && !!this.db?.disableDbExtension;\n const isUpdating = this.updatingId === ext.id;\n\n return html`\n <div class=\"extension-item\">\n <div class=\"extension-main\">\n <div class=\"extension-name\">${ext.label || ext.id}</div>\n ${ext.description\n ? html`<div class=\"extension-desc\">${ext.description}</div>`\n : null}\n </div>\n <div class=\"extension-meta\">\n <span\n class=${installed ? 'badge badge-installed' : 'badge badge-available'}\n >\n ${installed ? 'Installed' : 'Available'}\n </span>\n <div class=\"extension-actions\">\n ${installed\n ? html`\n <wa-button\n size=\"small\"\n appearance=\"plain\"\n ?disabled=${!canDisable || isUpdating}\n @click=${() => void this.disableExtension(ext)}\n >\n <wa-icon\n name=\"circle-minus\"\n label=\"Disable\"\n ></wa-icon>\n </wa-button>\n `\n : html`\n <wa-button\n size=\"small\"\n appearance=\"plain\"\n ?disabled=${isUpdating}\n @click=${() => void this.enableExtension(ext)}\n >\n <wa-icon\n name=\"plug-circle-plus\"\n label=\"Enable\"\n ></wa-icon>\n </wa-button>\n `}\n </div>\n </div>\n </div>\n `;\n }\n\n render() {\n const hasDb = Boolean(this.db && this.db.listDbExtensions);\n const filter = this.filterText.trim().toLowerCase();\n const filteredExtensions = !filter\n ? this.extensions\n : this.extensions.filter((ext) => {\n const text = `${ext.label ?? ''} ${ext.id} ${\n ext.description ?? ''\n }`.toLowerCase();\n return text.includes(filter);\n });\n const hasItems = filteredExtensions.length > 0;\n\n return html`\n <wa-dialog\n label=\"Database extensions\"\n ?open=${this.open}\n @wa-after-hide=${() => {\n this.open = false;\n this.dispatchEvent(\n new CustomEvent('hide', { bubbles: true, composed: true }),\n );\n }}\n >\n <div class=\"extension-manager\">\n <p class=\"extension-manager-description\">\n Database:\n <strong>${this.databaseLabel || 'Current connection'}</strong>\n </p>\n\n ${!hasDb\n ? html`\n <wa-alert variant=\"warning\" open>\n <wa-icon slot=\"icon\" name=\"triangle-exclamation\"></wa-icon>\n The current SQL engine does not expose any extension information.\n </wa-alert>\n `\n : null}\n\n ${this.error\n ? html`\n <wa-alert\n variant=\"danger\"\n open\n closable\n @wa-after-hide=${() => {\n this.error = null;\n }}\n >\n <wa-icon slot=\"icon\" name=\"circle-exclamation\"></wa-icon>\n ${this.error}\n </wa-alert>\n `\n : null}\n\n <wa-input\n size=\"small\"\n placeholder=\"Filter extensions…\"\n .value=${this.filterText}\n @input=${(event: Event) => {\n const target = event.target as HTMLInputElement | null;\n this.filterText = target?.value ?? '';\n }}\n @wa-clear=${() => {\n this.filterText = '';\n }}\n with-clear\n >\n <wa-icon slot=\"prefix\" name=\"magnifying-glass\"></wa-icon>\n </wa-input>\n\n <div class=\"extension-list\">\n ${this.loading\n ? html`<div class=\"extension-list-empty\">Loading extensions…</div>`\n : !hasItems\n ? html`\n <div class=\"extension-list-empty\">\n No extensions available for this connection.\n </div>\n `\n : repeat(\n filteredExtensions,\n (ext) => ext.id,\n (ext) => this.renderExtensionRow(ext),\n )}\n </div>\n </div>\n <div slot=\"footer\" class=\"extension-manager-footer\">\n <wa-button variant=\"default\" @click=${() => this.hide()}>\n Close\n </wa-button>\n </div>\n </wa-dialog>\n `;\n }\n\n static styles = css`\n :host {\n display: contents;\n }\n\n .extension-manager {\n display: flex;\n flex-direction: column;\n gap: 1rem;\n padding: 1rem;\n height: 420px;\n box-sizing: border-box;\n }\n\n .extension-toolbar {\n display: flex;\n justify-content: flex-end;\n }\n\n .extension-manager-description {\n margin: 0;\n font-size: 0.95rem;\n opacity: 0.9;\n }\n\n .extension-list {\n display: flex;\n flex-direction: column;\n gap: 0.5rem;\n flex: 1;\n min-height: 0;\n max-height: 100%;\n overflow-y: auto;\n }\n\n .extension-list-empty {\n font-size: 0.9rem;\n opacity: 0.8;\n padding: 0.5rem 0;\n }\n\n .extension-item {\n display: flex;\n align-items: flex-start;\n justify-content: space-between;\n gap: 0.75rem;\n padding: 0.5rem 0;\n border-bottom: 1px solid var(--wa-color-neutral-200, #e5e7eb);\n }\n\n .extension-main {\n display: flex;\n flex-direction: column;\n gap: 0.15rem;\n min-width: 0;\n }\n\n .extension-name {\n font-weight: 500;\n font-size: 0.95rem;\n }\n\n .extension-desc {\n font-size: 0.85rem;\n opacity: 0.8;\n }\n\n .extension-meta {\n display: flex;\n flex-direction: column;\n align-items: flex-end;\n gap: 0.35rem;\n }\n\n .extension-actions {\n display: flex;\n gap: 0.25rem;\n }\n\n .badge {\n display: inline-flex;\n align-items: center;\n padding: 0.15rem 0.4rem;\n border-radius: 999px;\n font-size: 0.75rem;\n border: 1px solid var(--wa-color-neutral-200, #e5e7eb);\n }\n\n .badge-installed {\n background-color: var(--wa-color-success-50, #ecfdf3);\n }\n\n .badge-available {\n background-color: var(--wa-color-neutral-50, #f9fafb);\n }\n\n .extension-manager-footer {\n display: flex;\n justify-content: flex-end;\n padding-top: 1rem;\n border-top: 1px solid var(--wa-color-neutral-200, #e5e7eb);\n }\n `;\n}\n\nclass SqlExtensionManagerService {\n private managerInstance: DocksSqlExtensionManager | null = null;\n\n public showExtensionManager(\n options: SqlExtensionManagerOptions,\n ): DocksSqlExtensionManager | null {\n if (!options.db || !options.db.listDbExtensions) {\n toastError('The current SQL engine does not support extensions.');\n return null;\n }\n if (!this.managerInstance) {\n this.managerInstance = document.createElement(\n 'docks-sql-extension-manager',\n ) as DocksSqlExtensionManager;\n document.body.appendChild(this.managerInstance);\n }\n this.managerInstance.configure(options);\n this.managerInstance.show();\n return this.managerInstance;\n }\n\n public getManager(): DocksSqlExtensionManager | null {\n return this.managerInstance;\n }\n}\n\nexport const sqlExtensionManagerService = new SqlExtensionManagerService();\nrootContext.put('sqlExtensionManagerService', sqlExtensionManagerService);\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'docks-sql-extension-manager': DocksSqlExtensionManager;\n }\n}\n\n","import { DocksPart, type EditorInput, type EditorContentProvider, toastError, toastInfo, confirmDialog, publish, contributionRegistry, subscribe, unsubscribe, TOPIC_CONTRIBUTEIONS_CHANGED, taskService } from '@eclipse-docks/core';\nimport {\n createRef,\n css,\n customElement,\n html,\n property,\n ref,\n state,\n styleMap,\n} from '@eclipse-docks/core/externals/lit';\nimport type { SqlAdapterContribution, SqlConnectionInfo, SqlDatabase } from './sql-api';\nimport { sqlExtensionManagerService } from './sql-extension-manager';\nimport { DocksMonacoWidget } from '@eclipse-docks/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('docks-sql-editor')\nexport class DocksSqlEditor extends DocksPart 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 /** `undefined` = user has not chosen a connection yet (placeholder). */\n @state()\n private selectedConnectionId: string | null | undefined = undefined;\n\n @state()\n private sqlEngineLoading = false;\n\n @state()\n private dbVersion: string | undefined = undefined;\n\n private widgetRef = createRef<DocksMonacoWidget>();\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 =\n typeof textContents === 'string'\n ? textContents\n : textContents == null\n ? ''\n : String(textContents);\n this.initialUri = file.getWorkspacePath();\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.updateComplete;\n void this.refreshAdapters().catch((err) => {\n toastError(err instanceof Error ? err.message : String(err));\n });\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 = undefined;\n this.dbVersion = undefined;\n await this.updateComplete;\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 }\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 = undefined;\n this.dbVersion = undefined;\n this.sqlEngineLoading = false;\n await this.updateComplete;\n return;\n }\n this.sqlEngineLoading = true;\n this.dbVersion = undefined;\n this.requestUpdate();\n try {\n const db = await this.getOrLoadDatabase(engineId);\n if (!db) {\n this.availableConnections = [];\n this.selectedConnectionId = undefined;\n return;\n }\n const infos = await db.listConnections();\n this.availableConnections = infos;\n const currentId = db.currentConnectionId;\n if (currentId !== null && currentId !== undefined) {\n this.selectedConnectionId = currentId;\n await this.updateDbVersion();\n } else {\n this.selectedConnectionId = undefined;\n }\n } finally {\n this.sqlEngineLoading = false;\n await this.updateComplete;\n this.requestUpdate();\n }\n }\n\n private async updateDbVersion(): Promise<void> {\n this.dbVersion = undefined;\n const engineId = this.selectedEngineId;\n if (!engineId || this.selectedConnectionId === undefined) return;\n const db = this.databases.get(engineId);\n if (!db?.readVersion) return;\n try {\n this.dbVersion = await db.readVersion();\n } catch {\n this.dbVersion = undefined;\n }\n this.requestUpdate();\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 this.selectedConnectionId = undefined;\n this.dbVersion = undefined;\n await this.refreshConnections();\n this.requestUpdate();\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 await this.updateDbVersion();\n this.requestUpdate();\n }\n\n private async onEngineDropdownSelect(\n e: CustomEvent<{ item?: { value?: string } }>,\n ): Promise<void> {\n const value = e.detail?.item?.value ?? '';\n if (this.selectedEngineId === value) return;\n this.selectedEngineId = value || null;\n this.selectedConnectionId = undefined;\n this.dbVersion = undefined;\n await this.refreshConnections();\n this.requestUpdate();\n }\n\n private async onConnectionDropdownSelect(\n e: CustomEvent<{ item?: { value?: string } }>,\n ): Promise<void> {\n const value = e.detail?.item?.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 await this.updateDbVersion();\n this.requestUpdate();\n }\n\n private async deleteConnectionById(e: Event, id: string | null): Promise<void> {\n e.stopPropagation();\n e.preventDefault();\n const engineId = this.selectedEngineId;\n if (!engineId) return;\n const db = await this.getOrLoadDatabase(engineId);\n if (!db || !db.deleteConnection) return;\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 }\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 selection = this.getSelection()?.trim();\n const content = this.getContent()?.trim();\n const sql = useSelectionOnly ? selection : content;\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 === undefined) {\n toastError('Select a connection');\n return;\n }\n\n this.running = true;\n const label = truncateLabel(sql);\n this.requestUpdate();\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 }\n }\n\n private clearRunningState(): void {\n if (!this.running) return;\n this.running = false;\n this.requestUpdate();\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 await this.updateDbVersion();\n toastInfo(`Connection \"${info.label}\" created`);\n this.requestUpdate();\n }\n\n private async deleteConnection(): Promise<void> {\n const engineId = this.selectedEngineId;\n if (!engineId) return;\n if (this.selectedConnectionId === undefined) 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 }\n\n private getCurrentConnectionLabel(): string | null {\n const id = this.selectedConnectionId;\n if (id === undefined) return null;\n if (id === null) return 'In-memory';\n const info = this.availableConnections.find((c) => c.id === id);\n return info?.label ?? id;\n }\n\n private async openExtensionManager(): Promise<void> {\n const engineId = this.selectedEngineId;\n if (!engineId) return;\n if (this.selectedConnectionId === undefined) {\n toastError('Select a connection');\n return;\n }\n const db = await this.getOrLoadDatabase(engineId);\n if (!db || !db.listDbExtensions) {\n toastInfo('Extensions are not available for the selected SQL engine.');\n return;\n }\n const adapter =\n this.availableAdapters.find((c) => c.id === engineId) ?? null;\n const engineLabel = adapter?.label ?? engineId;\n const connectionLabel = this.getCurrentConnectionLabel();\n const databaseLabel = connectionLabel\n ? `${engineLabel} – ${connectionLabel}`\n : engineLabel;\n sqlExtensionManagerService.showExtensionManager({\n db,\n databaseLabel,\n });\n }\n\n protected renderToolbar() {\n const adapters = this.availableAdapters;\n const hasEngines = adapters.length > 0;\n const hasConnections = this.availableConnections.length > 0;\n const engineId = this.selectedEngineId;\n const dbForEngine = engineId ? this.databases.get(engineId) : null;\n const supportsExtensions = Boolean(dbForEngine?.listDbExtensions);\n const connectionButtonLabel = this.sqlEngineLoading\n ? 'Loading…'\n : this.selectedConnectionId === undefined\n ? 'Select connection'\n : this.selectedConnectionId === null\n ? 'In-memory'\n : this.availableConnections.find(\n (c) => c.id === this.selectedConnectionId,\n )?.label ?? 'Connection';\n const runDisabled =\n this.running ||\n this.sqlEngineLoading ||\n this.selectedConnectionId === undefined;\n\n const sqlConnected =\n this.selectedConnectionId !== undefined && !this.sqlEngineLoading;\n const statusTitle = this.sqlEngineLoading\n ? 'Connecting…'\n : sqlConnected\n ? 'SQL engine connected'\n : 'No connection selected';\n const statusIconColor = this.sqlEngineLoading\n ? 'var(--wa-color-warning-500)'\n : sqlConnected\n ? 'var(--wa-color-green-40)'\n : 'var(--wa-color-red-40)';\n const statusText = this.sqlEngineLoading\n ? ''\n : this.dbVersion\n ? this.dbVersion\n : sqlConnected\n ? 'Connected'\n : 'Not connected';\n\n // Toolbar markup renders under docks-toolbar; host static styles do not apply there.\n const sqlToolbarPartStyle = {\n display: 'flex',\n flex: '1',\n minWidth: '0',\n alignItems: 'center',\n gap: 'var(--wa-space-2xs)',\n flexWrap: 'nowrap',\n } as const;\n const sqlToolbarLeadStyle = {\n display: 'flex',\n flex: '1',\n minWidth: '0',\n flexWrap: 'nowrap',\n alignItems: 'center',\n gap: 'var(--wa-space-2xs)',\n overflowX: 'auto',\n } as const;\n const sqlToolbarStatusStyle = {\n flexShrink: '0',\n display: 'inline-flex',\n alignItems: 'center',\n gap: '0.5rem',\n minHeight: '1.25rem',\n whiteSpace: 'nowrap',\n } as const;\n const sqlToolbarVersionStyle = {\n fontSize: '0.8rem',\n opacity: '0.85',\n whiteSpace: 'nowrap',\n maxWidth: '14rem',\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n } as const;\n\n return html`\n <div class=\"sql-toolbar-part\" style=${styleMap(sqlToolbarPartStyle)}>\n <div class=\"sql-toolbar-lead\" style=${styleMap(sqlToolbarLeadStyle)}>\n <wa-dropdown\n class=\"engine-select\"\n placement=\"bottom-start\"\n distance=\"4\"\n size=\"small\"\n @wa-select=${(e: CustomEvent) => void this.onEngineDropdownSelect(e)}\n >\n <wa-button\n slot=\"trigger\"\n appearance=\"plain\"\n size=\"small\"\n with-caret\n title=\"SQL engine\"\n >\n ${this.selectedEngineId\n ? adapters.find((a) => a.id === this.selectedEngineId)?.label ??\n this.selectedEngineId\n : 'Select engine'}\n </wa-button>\n ${adapters.map(\n (adapter) => html`\n <wa-dropdown-item\n value=${adapter.id}\n type=\"checkbox\"\n ?checked=${adapter.id === this.selectedEngineId}\n >\n ${adapter.label}\n </wa-dropdown-item>\n `,\n )}\n </wa-dropdown>\n <wa-dropdown\n class=\"connection-select\"\n placement=\"bottom-start\"\n distance=\"4\"\n size=\"small\"\n @wa-select=${(e: CustomEvent) =>\n void this.onConnectionDropdownSelect(e)}\n >\n <wa-button\n slot=\"trigger\"\n appearance=\"plain\"\n size=\"small\"\n with-caret\n title=\"Connection\"\n ?disabled=${!hasEngines || !hasConnections || this.sqlEngineLoading}\n >\n ${connectionButtonLabel}\n </wa-button>\n ${this.availableConnections.map(\n (info) => html`\n <wa-dropdown-item\n value=${info.id ?? ''}\n type=\"checkbox\"\n ?checked=${info.id === this.selectedConnectionId}\n >\n ${info.label}\n <wa-button\n slot=\"details\"\n appearance=\"plain\"\n size=\"small\"\n title=${info.id === null\n ? 'Reset in-memory connection'\n : 'Delete connection'}\n @click=${(e: Event) => this.deleteConnectionById(e, info.id)}\n >\n <wa-icon\n name=${info.id === null ? 'rotate-right' : 'trash'}\n label=${info.id === null ? 'Reset' : 'Delete'}\n ></wa-icon>\n </wa-button>\n </wa-dropdown-item>\n `,\n )}\n </wa-dropdown>\n <wa-button\n size=\"small\"\n appearance=\"plain\"\n title=\"New connection\"\n ?disabled=${this.sqlEngineLoading}\n @click=${() => void this.createConnection()}\n >\n <wa-icon name=\"plus\" label=\"New\"></wa-icon>\n </wa-button>\n ${supportsExtensions\n ? html`\n <wa-button\n size=\"small\"\n appearance=\"plain\"\n title=\"Manage extensions\"\n ?disabled=${!hasEngines ||\n !hasConnections ||\n this.selectedConnectionId === undefined ||\n this.sqlEngineLoading}\n @click=${() => void this.openExtensionManager()}\n >\n <wa-icon name=\"puzzle-piece\" label=\"Extensions\"></wa-icon>\n Extensions\n </wa-button>\n `\n : null}\n <wa-button\n size=\"small\"\n appearance=\"plain\"\n ?disabled=${runDisabled}\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=${runDisabled}\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 </div>\n <span\n class=\"sql-toolbar-status\"\n aria-live=\"polite\"\n title=${statusTitle}\n style=${styleMap(sqlToolbarStatusStyle)}\n >\n <wa-icon\n name=\"circle\"\n label=\"SQL engine status\"\n style=${styleMap({ color: statusIconColor })}\n ></wa-icon>\n ${this.sqlEngineLoading\n ? html`<wa-spinner style=\"font-size: 0.9rem\"></wa-spinner>`\n : html`<span\n class=\"sql-toolbar-version\"\n style=${styleMap(sqlToolbarVersionStyle)}\n >${statusText}</span\n >`}\n </span>\n </div>\n `;\n }\n\n protected renderContent() {\n if (this.initialContent === undefined) {\n return html`<div class=\"editor-placeholder\"></div>`;\n }\n\n return html`\n <div class=\"editor-area\">\n <docks-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 ></docks-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 docks-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 'docks-sql-editor': DocksSqlEditor;\n }\n}\n\n","import { editorRegistry, File, type EditorInput } from '@eclipse-docks/core';\nimport { html } from '@eclipse-docks/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.getWorkspacePath(),\n data: input,\n key: input.getWorkspacePath(),\n icon: 'database',\n state: {},\n component: () => null as any,\n };\n editorInput.component = (id: string) =>\n html`<docks-sql-editor id=\"${id}\" .input=${editorInput}></docks-sql-editor>`;\n return editorInput;\n },\n });\n}\n\n"],"mappings":"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"}