@eclipse-docks/extension-sqleditor 0.7.88 → 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-CFNQ6Cj0.js"),
11
+ loader: () => import("./sqleditor-extension-bxzEDMXN.js"),
12
12
  icon: "database"
13
13
  });
14
14
  //#endregion
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../src/sql-api.ts","../src/index.ts"],"sourcesContent":["export const TARGET_SQL_ADAPTERS = 'system.sqladapters';\n\nexport interface SqlConnectionInfo {\n id: string | null;\n label: string;\n isDefault?: boolean;\n}\n\n/**\n * Describes a single database extension that can be managed through the SQL editor.\n *\n * Implementations should return the same identifiers from {@link SqlDatabase.listDbExtensions}\n * and accept them in {@link SqlDatabase.enableDbExtension} / {@link SqlDatabase.disableDbExtension}.\n */\nexport interface SqlDatabaseExtensionInfo {\n id: string;\n label: string;\n description?: string;\n /**\n * Indicates whether the extension is currently installed or enabled for the active database\n * connection. Omit or leave false when the adapter cannot determine the installed state.\n */\n installed?: boolean;\n}\n\n/**\n * Additional adapter-specific actions that can be surfaced by the SQL editor UI.\n *\n * These are optional and are not used by the generic extension manager, which relies instead\n * on the extension-related methods on {@link SqlDatabase}.\n */\nexport interface SqlAdapterAction {\n id: string;\n label: string;\n icon?: string;\n run(): Promise<void>;\n}\n\n/**\n * Abstraction for a concrete SQL engine that can be used from the SQL editor.\n *\n * All engines must implement connection management and query execution. Extension management\n * is optional but, when provided, follows the contract documented on the corresponding methods.\n */\nexport interface SqlDatabase {\n readonly engineId: string;\n readonly currentConnectionId: string | null;\n\n listConnections(): Promise<SqlConnectionInfo[]>;\n selectConnection(id: string | null): Promise<void>;\n runQuery(sql: string): Promise<{ columns: string[]; rows: unknown[][] }>;\n\n createConnection?(): Promise<SqlConnectionInfo | null>;\n deleteConnection?(id: string): Promise<void>;\n\n extraActions?: SqlAdapterAction[];\n\n /**\n * Return the list of extensions known to this engine for the currently selected connection.\n *\n * The list should be stable for the active connection and use {@link SqlDatabaseExtensionInfo.installed}\n * to mark which extensions are currently installed or enabled when that information is available.\n */\n listDbExtensions?(): Promise<SqlDatabaseExtensionInfo[]>;\n /**\n * Ensure that the extension identified by {@link SqlDatabaseExtensionInfo.id} is installed\n * and enabled for the current connection. It is safe for implementations to be idempotent.\n */\n enableDbExtension?(id: string): Promise<void>;\n /**\n * Disable or uninstall the given extension for the current connection, if the engine supports it.\n * Adapters that cannot disable extensions should omit this method entirely.\n */\n disableDbExtension?(id: string): Promise<void>;\n\n close(): Promise<void> | void;\n}\n\nexport interface SqlAdapterContribution {\n id: string;\n label: string;\n icon?: string;\n loader: () => Promise<SqlDatabase>;\n}\n\n","import { extensionRegistry } from '@eclipse-docks/core';\nimport pkg from '../package.json';\nexport type {\n SqlConnectionInfo,\n SqlDatabaseExtensionInfo,\n SqlAdapterAction,\n SqlDatabase,\n SqlAdapterContribution,\n} from './sql-api';\nexport { TARGET_SQL_ADAPTERS } from './sql-api';\n\nextensionRegistry.registerExtension({\n id: pkg.name,\n name: 'SQL Editor',\n description: 'Generic SQL editor with pluggable backends',\n loader: () => import('./sqleditor-extension'),\n icon: 'database',\n});\n\n"],"mappings":";;;AAAA,IAAa,sBAAsB;;;ACWnC,kBAAkB,kBAAkB;CAClC,IAAI,IAAI;CACR,MAAM;CACN,aAAa;CACb,cAAc,OAAO;CACrB,MAAM;CACP,CAAC"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../src/sql-api.ts","../src/index.ts"],"sourcesContent":["export const TARGET_SQL_ADAPTERS = 'system.sqladapters';\n\nexport interface SqlConnectionInfo {\n id: string | null;\n label: string;\n isDefault?: boolean;\n}\n\n/**\n * Describes a single database extension that can be managed through the SQL editor.\n *\n * Implementations should return the same identifiers from {@link SqlDatabase.listDbExtensions}\n * and accept them in {@link SqlDatabase.enableDbExtension} / {@link SqlDatabase.disableDbExtension}.\n */\nexport interface SqlDatabaseExtensionInfo {\n id: string;\n label: string;\n description?: string;\n /**\n * Indicates whether the extension is currently installed or enabled for the active database\n * connection. Omit or leave false when the adapter cannot determine the installed state.\n */\n installed?: boolean;\n}\n\n/**\n * Additional adapter-specific actions that can be surfaced by the SQL editor UI.\n *\n * These are optional and are not used by the generic extension manager, which relies instead\n * on the extension-related methods on {@link SqlDatabase}.\n */\nexport interface SqlAdapterAction {\n id: string;\n label: string;\n icon?: string;\n run(): Promise<void>;\n}\n\n/**\n * Abstraction for a concrete SQL engine that can be used from the SQL editor.\n *\n * All engines must implement connection management and query execution. Extension management\n * is optional but, when provided, follows the contract documented on the corresponding methods.\n */\nexport interface SqlDatabase {\n readonly engineId: string;\n readonly currentConnectionId: string | null;\n\n listConnections(): Promise<SqlConnectionInfo[]>;\n selectConnection(id: string | null): Promise<void>;\n runQuery(sql: string): Promise<{ columns: string[]; rows: unknown[][] }>;\n\n /** Optional engine/database version string for toolbar display after a connection is active. */\n readVersion?(): Promise<string>;\n\n createConnection?(): Promise<SqlConnectionInfo | null>;\n deleteConnection?(id: string): Promise<void>;\n\n extraActions?: SqlAdapterAction[];\n\n /**\n * Return the list of extensions known to this engine for the currently selected connection.\n *\n * The list should be stable for the active connection and use {@link SqlDatabaseExtensionInfo.installed}\n * to mark which extensions are currently installed or enabled when that information is available.\n */\n listDbExtensions?(): Promise<SqlDatabaseExtensionInfo[]>;\n /**\n * Ensure that the extension identified by {@link SqlDatabaseExtensionInfo.id} is installed\n * and enabled for the current connection. It is safe for implementations to be idempotent.\n */\n enableDbExtension?(id: string): Promise<void>;\n /**\n * Disable or uninstall the given extension for the current connection, if the engine supports it.\n * Adapters that cannot disable extensions should omit this method entirely.\n */\n disableDbExtension?(id: string): Promise<void>;\n\n close(): Promise<void> | void;\n}\n\nexport interface SqlAdapterContribution {\n id: string;\n label: string;\n icon?: string;\n loader: () => Promise<SqlDatabase>;\n}\n\n","import { extensionRegistry } from '@eclipse-docks/core';\nimport pkg from '../package.json';\nexport type {\n SqlConnectionInfo,\n SqlDatabaseExtensionInfo,\n SqlAdapterAction,\n SqlDatabase,\n SqlAdapterContribution,\n} from './sql-api';\nexport { TARGET_SQL_ADAPTERS } from './sql-api';\n\nextensionRegistry.registerExtension({\n id: pkg.name,\n name: 'SQL Editor',\n description: 'Generic SQL editor with pluggable backends',\n loader: () => import('./sqleditor-extension'),\n icon: 'database',\n});\n\n"],"mappings":";;;AAAA,IAAa,sBAAsB;;;ACWnC,kBAAkB,kBAAkB;CAClC,IAAI,IAAI;CACR,MAAM;CACN,aAAa;CACb,cAAc,OAAO;CACrB,MAAM;CACP,CAAC"}
package/dist/sql-api.d.ts CHANGED
@@ -47,6 +47,8 @@ export interface SqlDatabase {
47
47
  columns: string[];
48
48
  rows: unknown[][];
49
49
  }>;
50
+ /** Optional engine/database version string for toolbar display after a connection is active. */
51
+ readVersion?(): Promise<string>;
50
52
  createConnection?(): Promise<SqlConnectionInfo | null>;
51
53
  deleteConnection?(id: string): Promise<void>;
52
54
  extraActions?: SqlAdapterAction[];
@@ -1 +1 @@
1
- {"version":3,"file":"sql-api.d.ts","sourceRoot":"","sources":["../src/sql-api.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,mBAAmB,uBAAuB,CAAC;AAExD,MAAM,WAAW,iBAAiB;IAChC,EAAE,EAAE,MAAM,GAAG,IAAI,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAED;;;;;GAKG;AACH,MAAM,WAAW,wBAAwB;IACvC,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;OAGG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAED;;;;;GAKG;AACH,MAAM,WAAW,gBAAgB;IAC/B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACtB;AAED;;;;;GAKG;AACH,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,mBAAmB,EAAE,MAAM,GAAG,IAAI,CAAC;IAE5C,eAAe,IAAI,OAAO,CAAC,iBAAiB,EAAE,CAAC,CAAC;IAChD,gBAAgB,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACnD,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,OAAO,EAAE,MAAM,EAAE,CAAC;QAAC,IAAI,EAAE,OAAO,EAAE,EAAE,CAAA;KAAE,CAAC,CAAC;IAEzE,gBAAgB,CAAC,IAAI,OAAO,CAAC,iBAAiB,GAAG,IAAI,CAAC,CAAC;IACvD,gBAAgB,CAAC,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAE7C,YAAY,CAAC,EAAE,gBAAgB,EAAE,CAAC;IAElC;;;;;OAKG;IACH,gBAAgB,CAAC,IAAI,OAAO,CAAC,wBAAwB,EAAE,CAAC,CAAC;IACzD;;;OAGG;IACH,iBAAiB,CAAC,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC9C;;;OAGG;IACH,kBAAkB,CAAC,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAE/C,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;CAC/B;AAED,MAAM,WAAW,sBAAsB;IACrC,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,OAAO,CAAC,WAAW,CAAC,CAAC;CACpC"}
1
+ {"version":3,"file":"sql-api.d.ts","sourceRoot":"","sources":["../src/sql-api.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,mBAAmB,uBAAuB,CAAC;AAExD,MAAM,WAAW,iBAAiB;IAChC,EAAE,EAAE,MAAM,GAAG,IAAI,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAED;;;;;GAKG;AACH,MAAM,WAAW,wBAAwB;IACvC,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;OAGG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAED;;;;;GAKG;AACH,MAAM,WAAW,gBAAgB;IAC/B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACtB;AAED;;;;;GAKG;AACH,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,mBAAmB,EAAE,MAAM,GAAG,IAAI,CAAC;IAE5C,eAAe,IAAI,OAAO,CAAC,iBAAiB,EAAE,CAAC,CAAC;IAChD,gBAAgB,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACnD,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,OAAO,EAAE,MAAM,EAAE,CAAC;QAAC,IAAI,EAAE,OAAO,EAAE,EAAE,CAAA;KAAE,CAAC,CAAC;IAEzE,gGAAgG;IAChG,WAAW,CAAC,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC;IAEhC,gBAAgB,CAAC,IAAI,OAAO,CAAC,iBAAiB,GAAG,IAAI,CAAC,CAAC;IACvD,gBAAgB,CAAC,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAE7C,YAAY,CAAC,EAAE,gBAAgB,EAAE,CAAC;IAElC;;;;;OAKG;IACH,gBAAgB,CAAC,IAAI,OAAO,CAAC,wBAAwB,EAAE,CAAC,CAAC;IACzD;;;OAGG;IACH,iBAAiB,CAAC,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC9C;;;OAGG;IACH,kBAAkB,CAAC,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAE/C,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;CAC/B;AAED,MAAM,WAAW,sBAAsB;IACrC,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,OAAO,CAAC,WAAW,CAAC,CAAC;CACpC"}
@@ -8,7 +8,11 @@ export declare class DocksSqlEditor extends DocksPart implements EditorContentPr
8
8
  private availableAdapters;
9
9
  private selectedEngineId;
10
10
  private availableConnections;
11
+ /** `undefined` = user has not chosen a connection yet (placeholder). */
11
12
  private selectedConnectionId;
13
+ private sqlEngineLoading;
14
+ private dbVersion;
15
+ private sqlVersionLoading;
12
16
  private widgetRef;
13
17
  private databases;
14
18
  private unsubscribeContributionsToken?;
@@ -16,6 +20,7 @@ export declare class DocksSqlEditor extends DocksPart implements EditorContentPr
16
20
  private refreshAdapters;
17
21
  private getOrLoadDatabase;
18
22
  private refreshConnections;
23
+ private updateDbVersion;
19
24
  private onEngineChange;
20
25
  private onConnectionChange;
21
26
  private onEngineDropdownSelect;
@@ -1 +1 @@
1
- {"version":3,"file":"sql-editor.d.ts","sourceRoot":"","sources":["../src/sql-editor.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,KAAK,WAAW,EAAE,KAAK,qBAAqB,EAA0I,MAAM,qBAAqB,CAAC;AAetO,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;IAGvD,OAAO,CAAC,oBAAoB,CAAuB;IAEnD,OAAO,CAAC,SAAS,CAAkC;IACnD,OAAO,CAAC,SAAS,CAAkC;IACnD,OAAO,CAAC,6BAA6B,CAAC,CAAS;cAE/B,QAAQ;YAeV,eAAe;YAmBf,iBAAiB;YAmBjB,kBAAkB;YA+BlB,cAAc;YASd,kBAAkB;YAclB,sBAAsB;YAUtB,0BAA0B;YAe1B,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;IAsDtB,OAAO,CAAC,iBAAiB;YAMX,gBAAgB;YAchB,gBAAgB;IAoB9B,OAAO,CAAC,yBAAyB;YAQnB,oBAAoB;IAqBlC,SAAS,CAAC,aAAa;IAqIvB,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"}
@@ -1,4 +1,4 @@
1
- import { LitElement } from 'lit';
1
+ import { LitElement } from '@eclipse-docks/core/externals/lit';
2
2
  import { SqlDatabase } from './sql-api';
3
3
  export interface SqlExtensionManagerOptions {
4
4
  db: SqlDatabase | null;
@@ -1 +1 @@
1
- {"version":3,"file":"sql-extension-manager.d.ts","sourceRoot":"","sources":["../src/sql-extension-manager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAa,UAAU,EAAE,MAAM,KAAK,CAAC;AAI5C,OAAO,KAAK,EAAE,WAAW,EAA4B,MAAM,WAAW,CAAC;AAEvE,MAAM,WAAW,0BAA0B;IACzC,EAAE,EAAE,WAAW,GAAG,IAAI,CAAC;IACvB,aAAa,EAAE,MAAM,CAAC;CACvB;AAED,qBACa,wBAAyB,SAAQ,UAAU;IAEtD,IAAI,UAAS;IAGb,EAAE,EAAE,WAAW,GAAG,IAAI,CAAQ;IAG9B,aAAa,SAAM;IAGnB,OAAO,CAAC,UAAU,CAAkC;IAGpD,OAAO,CAAC,OAAO,CAAS;IAGxB,OAAO,CAAC,UAAU,CAAuB;IAGzC,OAAO,CAAC,KAAK,CAAuB;IAGpC,OAAO,CAAC,UAAU,CAAM;IAEjB,SAAS,CAAC,OAAO,EAAE,0BAA0B,GAAG,IAAI;IAQpD,IAAI,IAAI,IAAI;IAKZ,IAAI,IAAI,IAAI;YAIL,iBAAiB;YAsBjB,eAAe;YAmBf,gBAAgB;IAmB9B,OAAO,CAAC,kBAAkB;IAqD1B,MAAM;IAgGN,MAAM,CAAC,MAAM,0BAsGX;CACH;AAED,cAAM,0BAA0B;IAC9B,OAAO,CAAC,eAAe,CAAyC;IAEzD,oBAAoB,CACzB,OAAO,EAAE,0BAA0B,GAClC,wBAAwB,GAAG,IAAI;IAgB3B,UAAU,IAAI,wBAAwB,GAAG,IAAI;CAGrD;AAED,eAAO,MAAM,0BAA0B,4BAAmC,CAAC;AAG3E,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,qBAAqB;QAC7B,6BAA6B,EAAE,wBAAwB,CAAC;KACzD;CACF"}
1
+ {"version":3,"file":"sql-extension-manager.d.ts","sourceRoot":"","sources":["../src/sql-extension-manager.ts"],"names":[],"mappings":"AACA,OAAO,EAIL,UAAU,EAIX,MAAM,mCAAmC,CAAC;AAC3C,OAAO,KAAK,EAAE,WAAW,EAA4B,MAAM,WAAW,CAAC;AAEvE,MAAM,WAAW,0BAA0B;IACzC,EAAE,EAAE,WAAW,GAAG,IAAI,CAAC;IACvB,aAAa,EAAE,MAAM,CAAC;CACvB;AAED,qBACa,wBAAyB,SAAQ,UAAU;IAEtD,IAAI,UAAS;IAGb,EAAE,EAAE,WAAW,GAAG,IAAI,CAAQ;IAG9B,aAAa,SAAM;IAGnB,OAAO,CAAC,UAAU,CAAkC;IAGpD,OAAO,CAAC,OAAO,CAAS;IAGxB,OAAO,CAAC,UAAU,CAAuB;IAGzC,OAAO,CAAC,KAAK,CAAuB;IAGpC,OAAO,CAAC,UAAU,CAAM;IAEjB,SAAS,CAAC,OAAO,EAAE,0BAA0B,GAAG,IAAI;IAQpD,IAAI,IAAI,IAAI;IAKZ,IAAI,IAAI,IAAI;YAIL,iBAAiB;YAsBjB,eAAe;YAmBf,gBAAgB;IAmB9B,OAAO,CAAC,kBAAkB;IAqD1B,MAAM;IAgGN,MAAM,CAAC,MAAM,0BAsGX;CACH;AAED,cAAM,0BAA0B;IAC9B,OAAO,CAAC,eAAe,CAAyC;IAEzD,oBAAoB,CACzB,OAAO,EAAE,0BAA0B,GAClC,wBAAwB,GAAG,IAAI;IAgB3B,UAAU,IAAI,wBAAwB,GAAG,IAAI;CAGrD;AAED,eAAO,MAAM,0BAA0B,4BAAmC,CAAC;AAG3E,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,qBAAqB;QAC7B,6BAA6B,EAAE,wBAAwB,CAAC;KACzD;CACF"}
@@ -1,10 +1,6 @@
1
1
  import { DocksPart, File, TOPIC_CONTRIBUTEIONS_CHANGED, confirmDialog, contributionRegistry, editorRegistry, publish, rootContext, subscribe, taskService, toastError, toastInfo, unsubscribe } from "@eclipse-docks/core";
2
- import { html } from "@eclipse-docks/core/externals/lit";
3
- import { customElement, property, state } from "lit/decorators.js";
4
- import { LitElement, css, html as html$1 } from "lit";
5
- import { repeat } from "lit/directives/repeat.js";
2
+ import { LitElement, createRef, css, customElement, html, property, ref, repeat, state, styleMap } from "@eclipse-docks/core/externals/lit";
6
3
  import _decorate from "@oxc-project/runtime/helpers/decorate";
7
- import { createRef, ref } from "lit/directives/ref.js";
8
4
  //#region src/sql-extension-manager.ts
9
5
  var DocksSqlExtensionManager = class DocksSqlExtensionManager extends LitElement {
10
6
  constructor(..._args) {
@@ -84,11 +80,11 @@ var DocksSqlExtensionManager = class DocksSqlExtensionManager extends LitElement
84
80
  const installed = Boolean(ext.installed);
85
81
  const canDisable = installed && !!this.db?.disableDbExtension;
86
82
  const isUpdating = this.updatingId === ext.id;
87
- return html$1`
83
+ return html`
88
84
  <div class="extension-item">
89
85
  <div class="extension-main">
90
86
  <div class="extension-name">${ext.label || ext.id}</div>
91
- ${ext.description ? html$1`<div class="extension-desc">${ext.description}</div>` : null}
87
+ ${ext.description ? html`<div class="extension-desc">${ext.description}</div>` : null}
92
88
  </div>
93
89
  <div class="extension-meta">
94
90
  <span
@@ -97,7 +93,7 @@ var DocksSqlExtensionManager = class DocksSqlExtensionManager extends LitElement
97
93
  ${installed ? "Installed" : "Available"}
98
94
  </span>
99
95
  <div class="extension-actions">
100
- ${installed ? html$1`
96
+ ${installed ? html`
101
97
  <wa-button
102
98
  size="small"
103
99
  appearance="plain"
@@ -109,7 +105,7 @@ var DocksSqlExtensionManager = class DocksSqlExtensionManager extends LitElement
109
105
  label="Disable"
110
106
  ></wa-icon>
111
107
  </wa-button>
112
- ` : html$1`
108
+ ` : html`
113
109
  <wa-button
114
110
  size="small"
115
111
  appearance="plain"
@@ -134,7 +130,7 @@ var DocksSqlExtensionManager = class DocksSqlExtensionManager extends LitElement
134
130
  return `${ext.label ?? ""} ${ext.id} ${ext.description ?? ""}`.toLowerCase().includes(filter);
135
131
  });
136
132
  const hasItems = filteredExtensions.length > 0;
137
- return html$1`
133
+ return html`
138
134
  <wa-dialog
139
135
  label="Database extensions"
140
136
  ?open=${this.open}
@@ -152,14 +148,14 @@ var DocksSqlExtensionManager = class DocksSqlExtensionManager extends LitElement
152
148
  <strong>${this.databaseLabel || "Current connection"}</strong>
153
149
  </p>
154
150
 
155
- ${!hasDb ? html$1`
151
+ ${!hasDb ? html`
156
152
  <wa-alert variant="warning" open>
157
153
  <wa-icon slot="icon" name="triangle-exclamation"></wa-icon>
158
154
  The current SQL engine does not expose any extension information.
159
155
  </wa-alert>
160
156
  ` : null}
161
157
 
162
- ${this.error ? html$1`
158
+ ${this.error ? html`
163
159
  <wa-alert
164
160
  variant="danger"
165
161
  open
@@ -189,7 +185,7 @@ var DocksSqlExtensionManager = class DocksSqlExtensionManager extends LitElement
189
185
  </wa-input>
190
186
 
191
187
  <div class="extension-list">
192
- ${this.loading ? html$1`<div class="extension-list-empty">Loading extensions…</div>` : !hasItems ? html$1`
188
+ ${this.loading ? html`<div class="extension-list-empty">Loading extensions…</div>` : !hasItems ? html`
193
189
  <div class="extension-list-empty">
194
190
  No extensions available for this connection.
195
191
  </div>
@@ -360,7 +356,10 @@ var DocksSqlEditor = class DocksSqlEditor extends DocksPart {
360
356
  this.availableAdapters = [];
361
357
  this.selectedEngineId = null;
362
358
  this.availableConnections = [];
363
- this.selectedConnectionId = null;
359
+ this.selectedConnectionId = void 0;
360
+ this.sqlEngineLoading = false;
361
+ this.dbVersion = void 0;
362
+ this.sqlVersionLoading = false;
364
363
  this.widgetRef = createRef();
365
364
  this.databases = /* @__PURE__ */ new Map();
366
365
  this._onContentChange = () => {
@@ -369,13 +368,16 @@ var DocksSqlEditor = class DocksSqlEditor extends DocksPart {
369
368
  }
370
369
  async doInitUI() {
371
370
  const file = this.input.data;
372
- this.initialContent = await file.getContents();
371
+ const textContents = await file.getContents();
372
+ this.initialContent = typeof textContents === "string" ? textContents : textContents == null ? "" : String(textContents);
373
373
  this.initialUri = file.getWorkspacePath();
374
374
  this.unsubscribeContributionsToken = subscribe(TOPIC_CONTRIBUTEIONS_CHANGED, (event) => {
375
375
  if (event?.target === "system.sqladapters") this.refreshAdapters();
376
376
  });
377
- await this.refreshAdapters();
378
- this.requestUpdate();
377
+ await this.updateComplete;
378
+ this.refreshAdapters().catch((err) => {
379
+ toastError(err instanceof Error ? err.message : String(err));
380
+ });
379
381
  }
380
382
  async refreshAdapters() {
381
383
  const contributions = contributionRegistry.getContributions("system.sqladapters");
@@ -383,7 +385,9 @@ var DocksSqlEditor = class DocksSqlEditor extends DocksPart {
383
385
  if (!contributions.length) {
384
386
  this.selectedEngineId = null;
385
387
  this.availableConnections = [];
386
- this.selectedConnectionId = null;
388
+ this.selectedConnectionId = void 0;
389
+ this.dbVersion = void 0;
390
+ this.sqlVersionLoading = false;
387
391
  await this.updateComplete;
388
392
  return;
389
393
  }
@@ -414,34 +418,59 @@ var DocksSqlEditor = class DocksSqlEditor extends DocksPart {
414
418
  const engineId = this.selectedEngineId;
415
419
  if (!engineId) {
416
420
  this.availableConnections = [];
417
- this.selectedConnectionId = null;
421
+ this.selectedConnectionId = void 0;
422
+ this.dbVersion = void 0;
423
+ this.sqlEngineLoading = false;
424
+ this.sqlVersionLoading = false;
418
425
  await this.updateComplete;
419
426
  return;
420
427
  }
421
- const db = await this.getOrLoadDatabase(engineId);
422
- if (!db) {
423
- this.availableConnections = [];
424
- this.selectedConnectionId = null;
428
+ this.sqlEngineLoading = true;
429
+ this.dbVersion = void 0;
430
+ this.requestUpdate();
431
+ try {
432
+ const db = await this.getOrLoadDatabase(engineId);
433
+ if (!db) {
434
+ this.availableConnections = [];
435
+ this.selectedConnectionId = void 0;
436
+ return;
437
+ }
438
+ this.availableConnections = await db.listConnections();
439
+ const currentId = db.currentConnectionId;
440
+ if (currentId !== null && currentId !== void 0) {
441
+ this.selectedConnectionId = currentId;
442
+ await this.updateDbVersion();
443
+ } else this.selectedConnectionId = void 0;
444
+ } finally {
445
+ this.sqlEngineLoading = false;
425
446
  await this.updateComplete;
426
- return;
447
+ this.requestUpdate();
427
448
  }
428
- const infos = await db.listConnections();
429
- this.availableConnections = infos;
430
- const currentId = db.currentConnectionId;
431
- if (currentId !== null) {
432
- this.selectedConnectionId = currentId;
433
- await this.updateComplete;
434
- return;
449
+ }
450
+ async updateDbVersion() {
451
+ this.dbVersion = void 0;
452
+ this.sqlVersionLoading = false;
453
+ const engineId = this.selectedEngineId;
454
+ if (!engineId || this.selectedConnectionId === void 0) return;
455
+ const db = this.databases.get(engineId);
456
+ if (!db?.readVersion) return;
457
+ this.sqlVersionLoading = true;
458
+ try {
459
+ this.dbVersion = await db.readVersion();
460
+ } catch {
461
+ this.dbVersion = void 0;
462
+ } finally {
463
+ this.sqlVersionLoading = false;
435
464
  }
436
- const preferred = infos.find((info) => info.isDefault) ?? infos[0];
437
- this.selectedConnectionId = preferred ? preferred.id : null;
438
- if (preferred) await db.selectConnection(preferred.id ?? null);
439
- await this.updateComplete;
465
+ this.requestUpdate();
440
466
  }
441
467
  async onEngineChange(e) {
442
468
  const value = e.target?.value ?? "";
443
469
  if (this.selectedEngineId === value) return;
444
470
  this.selectedEngineId = value || null;
471
+ this.selectedConnectionId = void 0;
472
+ this.dbVersion = void 0;
473
+ this.sqlVersionLoading = false;
445
474
  await this.refreshConnections();
446
475
  this.requestUpdate();
447
476
  }
@@ -450,17 +479,23 @@ var DocksSqlEditor = class DocksSqlEditor extends DocksPart {
450
479
  const next = value === "" ? null : value;
451
480
  if (this.selectedConnectionId === next) return;
452
481
  this.selectedConnectionId = next;
482
+ this.dbVersion = void 0;
483
+ this.sqlVersionLoading = false;
453
484
  const engineId = this.selectedEngineId;
454
485
  if (!engineId) return;
455
486
  const db = await this.getOrLoadDatabase(engineId);
456
487
  if (!db) return;
457
488
  await db.selectConnection(next);
489
+ await this.updateDbVersion();
458
490
  this.requestUpdate();
459
491
  }
460
492
  async onEngineDropdownSelect(e) {
461
493
  const value = e.detail?.item?.value ?? "";
462
494
  if (this.selectedEngineId === value) return;
463
495
  this.selectedEngineId = value || null;
496
+ this.selectedConnectionId = void 0;
497
+ this.dbVersion = void 0;
498
+ this.sqlVersionLoading = false;
464
499
  await this.refreshConnections();
465
500
  this.requestUpdate();
466
501
  }
@@ -469,11 +504,14 @@ var DocksSqlEditor = class DocksSqlEditor extends DocksPart {
469
504
  const next = value === "" ? null : value;
470
505
  if (this.selectedConnectionId === next) return;
471
506
  this.selectedConnectionId = next;
507
+ this.dbVersion = void 0;
508
+ this.sqlVersionLoading = false;
472
509
  const engineId = this.selectedEngineId;
473
510
  if (!engineId) return;
474
511
  const db = await this.getOrLoadDatabase(engineId);
475
512
  if (!db) return;
476
513
  await db.selectConnection(next);
514
+ await this.updateDbVersion();
477
515
  this.requestUpdate();
478
516
  }
479
517
  async deleteConnectionById(e, id) {
@@ -540,10 +578,9 @@ var DocksSqlEditor = class DocksSqlEditor extends DocksPart {
540
578
  toastError("Could not initialize SQL engine");
541
579
  return;
542
580
  }
543
- if (!this.selectedConnectionId && this.availableConnections.length) {
544
- const preferred = this.availableConnections.find((info) => info.isDefault) ?? this.availableConnections[0];
545
- this.selectedConnectionId = preferred.id;
546
- await db.selectConnection(preferred.id ?? null);
581
+ if (this.selectedConnectionId === void 0) {
582
+ toastError("Select a connection");
583
+ return;
547
584
  }
548
585
  this.running = true;
549
586
  const label = truncateLabel(sql);
@@ -583,12 +620,14 @@ var DocksSqlEditor = class DocksSqlEditor extends DocksPart {
583
620
  await this.refreshConnections();
584
621
  this.selectedConnectionId = info.id;
585
622
  await db.selectConnection(info.id ?? null);
623
+ await this.updateDbVersion();
586
624
  toastInfo(`Connection "${info.label}" created`);
587
625
  this.requestUpdate();
588
626
  }
589
627
  async deleteConnection() {
590
628
  const engineId = this.selectedEngineId;
591
629
  if (!engineId) return;
630
+ if (this.selectedConnectionId === void 0) return;
592
631
  const db = await this.getOrLoadDatabase(engineId);
593
632
  if (!db || !db.deleteConnection) return;
594
633
  const id = this.selectedConnectionId;
@@ -600,13 +639,17 @@ var DocksSqlEditor = class DocksSqlEditor extends DocksPart {
600
639
  }
601
640
  getCurrentConnectionLabel() {
602
641
  const id = this.selectedConnectionId;
642
+ if (id === void 0) return null;
603
643
  if (id === null) return "In-memory";
604
- if (!id) return null;
605
644
  return this.availableConnections.find((c) => c.id === id)?.label ?? id;
606
645
  }
607
646
  async openExtensionManager() {
608
647
  const engineId = this.selectedEngineId;
609
648
  if (!engineId) return;
649
+ if (this.selectedConnectionId === void 0) {
650
+ toastError("Select a connection");
651
+ return;
652
+ }
610
653
  const db = await this.getOrLoadDatabase(engineId);
611
654
  if (!db || !db.listDbExtensions) {
612
655
  toastInfo("Extensions are not available for the selected SQL engine.");
@@ -627,7 +670,33 @@ var DocksSqlEditor = class DocksSqlEditor extends DocksPart {
627
670
  const engineId = this.selectedEngineId;
628
671
  const dbForEngine = engineId ? this.databases.get(engineId) : null;
629
672
  const supportsExtensions = Boolean(dbForEngine?.listDbExtensions);
630
- return html$1`
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";
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";
682
+ return html`
683
+ <div class="sql-toolbar-part" style=${styleMap({
684
+ display: "flex",
685
+ flex: "1",
686
+ minWidth: "0",
687
+ alignItems: "center",
688
+ gap: "var(--wa-space-2xs)",
689
+ flexWrap: "nowrap"
690
+ })}>
691
+ <div class="sql-toolbar-lead" style=${styleMap({
692
+ display: "flex",
693
+ flex: "1",
694
+ minWidth: "0",
695
+ flexWrap: "nowrap",
696
+ alignItems: "center",
697
+ gap: "var(--wa-space-2xs)",
698
+ overflowX: "auto"
699
+ })}>
631
700
  <wa-dropdown
632
701
  class="engine-select"
633
702
  placement="bottom-start"
@@ -644,7 +713,7 @@ var DocksSqlEditor = class DocksSqlEditor extends DocksPart {
644
713
  >
645
714
  ${this.selectedEngineId ? adapters.find((a) => a.id === this.selectedEngineId)?.label ?? this.selectedEngineId : "Select engine"}
646
715
  </wa-button>
647
- ${adapters.map((adapter) => html$1`
716
+ ${adapters.map((adapter) => html`
648
717
  <wa-dropdown-item
649
718
  value=${adapter.id}
650
719
  type="checkbox"
@@ -667,11 +736,11 @@ var DocksSqlEditor = class DocksSqlEditor extends DocksPart {
667
736
  size="small"
668
737
  with-caret
669
738
  title="Connection"
670
- ?disabled=${!hasEngines || !hasConnections}
739
+ ?disabled=${!hasEngines || !hasConnections || this.sqlEngineLoading}
671
740
  >
672
- ${this.selectedConnectionId === null ? "In-memory" : this.availableConnections.find((c) => c.id === this.selectedConnectionId)?.label ?? "Select connection"}
741
+ ${connectionButtonLabel}
673
742
  </wa-button>
674
- ${this.availableConnections.map((info) => html$1`
743
+ ${this.availableConnections.map((info) => html`
675
744
  <wa-dropdown-item
676
745
  value=${info.id ?? ""}
677
746
  type="checkbox"
@@ -697,16 +766,17 @@ var DocksSqlEditor = class DocksSqlEditor extends DocksPart {
697
766
  size="small"
698
767
  appearance="plain"
699
768
  title="New connection"
769
+ ?disabled=${this.sqlEngineLoading}
700
770
  @click=${() => void this.createConnection()}
701
771
  >
702
772
  <wa-icon name="plus" label="New"></wa-icon>
703
773
  </wa-button>
704
- ${supportsExtensions ? html$1`
774
+ ${supportsExtensions ? html`
705
775
  <wa-button
706
776
  size="small"
707
777
  appearance="plain"
708
778
  title="Manage extensions"
709
- ?disabled=${!hasEngines || !hasConnections}
779
+ ?disabled=${!hasEngines || !hasConnections || this.selectedConnectionId === void 0 || this.sqlEngineLoading}
710
780
  @click=${() => void this.openExtensionManager()}
711
781
  >
712
782
  <wa-icon name="puzzle-piece" label="Extensions"></wa-icon>
@@ -716,7 +786,7 @@ var DocksSqlEditor = class DocksSqlEditor extends DocksPart {
716
786
  <wa-button
717
787
  size="small"
718
788
  appearance="plain"
719
- ?disabled=${this.running}
789
+ ?disabled=${runDisabled}
720
790
  @click=${() => void this.runQuery(true)}
721
791
  title="Run selection only"
722
792
  >
@@ -726,18 +796,51 @@ var DocksSqlEditor = class DocksSqlEditor extends DocksPart {
726
796
  <wa-button
727
797
  size="small"
728
798
  appearance="plain"
729
- ?disabled=${this.running}
799
+ ?disabled=${runDisabled}
730
800
  @click=${() => void this.runQuery(false)}
731
801
  title="Run all SQL"
732
802
  >
733
803
  <wa-icon name="play" label="Run"></wa-icon>
734
804
  ${this.running ? "Running…" : "Run all"}
735
805
  </wa-button>
806
+ </div>
807
+ <span
808
+ class="sql-toolbar-status"
809
+ aria-live="polite"
810
+ title=${statusTitle}
811
+ style=${styleMap({
812
+ flexShrink: "0",
813
+ display: "inline-flex",
814
+ alignItems: "center",
815
+ gap: "0.5rem",
816
+ minHeight: "1.25rem",
817
+ whiteSpace: "nowrap"
818
+ })}
819
+ >
820
+ <wa-icon
821
+ name="circle"
822
+ label="SQL engine status"
823
+ style=${styleMap({ color: statusIconColor })}
824
+ ></wa-icon>
825
+ ${isConnecting ? html`<wa-spinner style="font-size: 0.9rem"></wa-spinner>` : html`<span
826
+ class="sql-toolbar-version"
827
+ style=${styleMap({
828
+ fontSize: "0.8rem",
829
+ opacity: "0.85",
830
+ whiteSpace: "nowrap",
831
+ maxWidth: "14rem",
832
+ overflow: "hidden",
833
+ textOverflow: "ellipsis"
834
+ })}
835
+ >${statusText}</span
836
+ >`}
837
+ </span>
838
+ </div>
736
839
  `;
737
840
  }
738
841
  renderContent() {
739
- if (this.initialContent === void 0) return html$1`<div class="editor-placeholder"></div>`;
740
- return html$1`
842
+ if (this.initialContent === void 0) return html`<div class="editor-placeholder"></div>`;
843
+ return html`
741
844
  <div class="editor-area">
742
845
  <docks-monaco-widget
743
846
  .value=${this.initialContent}
@@ -794,6 +897,9 @@ _decorate([state()], DocksSqlEditor.prototype, "availableAdapters", void 0);
794
897
  _decorate([state()], DocksSqlEditor.prototype, "selectedEngineId", void 0);
795
898
  _decorate([state()], DocksSqlEditor.prototype, "availableConnections", void 0);
796
899
  _decorate([state()], DocksSqlEditor.prototype, "selectedConnectionId", void 0);
900
+ _decorate([state()], DocksSqlEditor.prototype, "sqlEngineLoading", void 0);
901
+ _decorate([state()], DocksSqlEditor.prototype, "dbVersion", void 0);
902
+ _decorate([state()], DocksSqlEditor.prototype, "sqlVersionLoading", void 0);
797
903
  DocksSqlEditor = _decorate([customElement("docks-sql-editor")], DocksSqlEditor);
798
904
  //#endregion
799
905
  //#region src/sqleditor-extension.ts
@@ -821,4 +927,4 @@ function activate() {
821
927
  //#endregion
822
928
  export { activate as default };
823
929
 
824
- //# sourceMappingURL=sqleditor-extension-CFNQ6Cj0.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.88",
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-CFNQ6Cj0.js","names":[],"sources":["../src/sql-extension-manager.ts","../src/sql-editor.ts","../src/sqleditor-extension.ts"],"sourcesContent":["import { css, html, LitElement } from 'lit';\nimport { customElement, property, state } from 'lit/decorators.js';\nimport { repeat } from 'lit/directives/repeat.js';\nimport { rootContext, taskService, toastError } from '@eclipse-docks/core';\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 { customElement, property, state } from 'lit/decorators.js';\nimport { DocksPart, type EditorInput, type EditorContentProvider, toastError, toastInfo, confirmDialog, publish, contributionRegistry, subscribe, unsubscribe, TOPIC_CONTRIBUTEIONS_CHANGED, taskService } from '@eclipse-docks/core';\nimport type { SqlAdapterContribution, SqlConnectionInfo, SqlDatabase } from './sql-api';\nimport { sqlExtensionManagerService } from './sql-extension-manager';\nimport { css, html } from 'lit';\nimport { createRef, ref } from 'lit/directives/ref.js';\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 @state()\n private selectedConnectionId: string | null = null;\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 = 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.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 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 = null;\n await this.updateComplete;\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 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 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 }\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 }\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 }\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 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 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 && 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\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 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 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 === null) return 'In-memory';\n if (!id) return null;\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 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\n return html`\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}\n >\n ${this.selectedConnectionId === null\n ? 'In-memory'\n : this.availableConnections.find(\n (c) => c.id === this.selectedConnectionId,\n )?.label ?? 'Select connection'}\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 @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 || !hasConnections}\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=${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 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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"}