@eclipse-docks/extension-sqleditor 0.7.88 → 0.7.89
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 +1 -1
- package/dist/index.js.map +1 -1
- package/dist/sql-api.d.ts +2 -0
- package/dist/sql-api.d.ts.map +1 -1
- package/dist/sql-editor.d.ts +4 -0
- package/dist/sql-editor.d.ts.map +1 -1
- package/dist/sql-extension-manager.d.ts +1 -1
- package/dist/sql-extension-manager.d.ts.map +1 -1
- package/dist/{sqleditor-extension-CFNQ6Cj0.js → sqleditor-extension-K5TQp9rX.js} +141 -52
- package/dist/sqleditor-extension-K5TQp9rX.js.map +1 -0
- package/package.json +1 -1
- package/dist/sqleditor-extension-CFNQ6Cj0.js.map +0 -1
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-
|
|
11
|
+
loader: () => import("./sqleditor-extension-K5TQp9rX.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[];
|
package/dist/sql-api.d.ts.map
CHANGED
|
@@ -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"}
|
package/dist/sql-editor.d.ts
CHANGED
|
@@ -8,7 +8,10 @@ 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;
|
|
12
15
|
private widgetRef;
|
|
13
16
|
private databases;
|
|
14
17
|
private unsubscribeContributionsToken?;
|
|
@@ -16,6 +19,7 @@ export declare class DocksSqlEditor extends DocksPart implements EditorContentPr
|
|
|
16
19
|
private refreshAdapters;
|
|
17
20
|
private getOrLoadDatabase;
|
|
18
21
|
private refreshConnections;
|
|
22
|
+
private updateDbVersion;
|
|
19
23
|
private onEngineChange;
|
|
20
24
|
private onConnectionChange;
|
|
21
25
|
private onEngineDropdownSelect;
|
package/dist/sql-editor.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sql-editor.d.ts","sourceRoot":"","sources":["../src/sql-editor.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"sql-editor.d.ts","sourceRoot":"","sources":["../src/sql-editor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,KAAK,WAAW,EAAE,KAAK,qBAAqB,EAA0I,MAAM,qBAAqB,CAAC;AAuBtO,qBACa,cAAe,SAAQ,SAAU,YAAW,qBAAqB;IAErE,KAAK,CAAC,EAAE,WAAW,CAAC;IAGpB,QAAQ,UAAS;IAGxB,OAAO,CAAC,cAAc,CAAiC;IAGvD,OAAO,CAAC,UAAU,CAAiC;IAGnD,OAAO,CAAC,OAAO,CAAS;IAGxB,OAAO,CAAC,iBAAiB,CAAgC;IAGzD,OAAO,CAAC,gBAAgB,CAAuB;IAG/C,OAAO,CAAC,oBAAoB,CAA2B;IAEvD,wEAAwE;IAExE,OAAO,CAAC,oBAAoB,CAAwC;IAGpE,OAAO,CAAC,gBAAgB,CAAS;IAGjC,OAAO,CAAC,SAAS,CAAiC;IAElD,OAAO,CAAC,SAAS,CAAkC;IACnD,OAAO,CAAC,SAAS,CAAkC;IACnD,OAAO,CAAC,6BAA6B,CAAC,CAAS;cAE/B,QAAQ;YAsBV,eAAe;YAoBf,iBAAiB;YAmBjB,kBAAkB;YAoClB,eAAe;YAcf,cAAc;YAWd,kBAAkB;YAelB,sBAAsB;YAYtB,0BAA0B;YAgB1B,oBAAoB;IAqBlC,OAAO,CAAC,gBAAgB,CAEtB;IAEF,IAAI,IAAI,IAAI;cAMI,OAAO;IAYhB,WAAW,IAAI,MAAM,GAAG,IAAI;IAI5B,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAIjC,UAAU,IAAI,MAAM,GAAG,IAAI;IAI3B,YAAY,IAAI,MAAM,GAAG,IAAI;IAI7B,UAAU,CAAC,KAAK,GAAE,MAAU,GAAG;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI;IAI7E,WAAW,IAAI,MAAM,GAAG,IAAI;YAIrB,QAAQ;IAmDtB,OAAO,CAAC,iBAAiB;YAMX,gBAAgB;YAehB,gBAAgB;IAqB9B,OAAO,CAAC,yBAAyB;YAQnB,oBAAoB;IAyBlC,SAAS,CAAC,aAAa;IAgOvB,SAAS,CAAC,aAAa;IAmBvB,MAAM,CAAC,MAAM,0BA+BX;CACH;AAED,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,qBAAqB;QAC7B,kBAAkB,EAAE,cAAc,CAAC;KACpC;CACF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sql-extension-manager.d.ts","sourceRoot":"","sources":["../src/sql-extension-manager.ts"],"names":[],"mappings":"
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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,9 @@ var DocksSqlEditor = class DocksSqlEditor extends DocksPart {
|
|
|
360
356
|
this.availableAdapters = [];
|
|
361
357
|
this.selectedEngineId = null;
|
|
362
358
|
this.availableConnections = [];
|
|
363
|
-
this.selectedConnectionId =
|
|
359
|
+
this.selectedConnectionId = void 0;
|
|
360
|
+
this.sqlEngineLoading = false;
|
|
361
|
+
this.dbVersion = void 0;
|
|
364
362
|
this.widgetRef = createRef();
|
|
365
363
|
this.databases = /* @__PURE__ */ new Map();
|
|
366
364
|
this._onContentChange = () => {
|
|
@@ -369,13 +367,16 @@ var DocksSqlEditor = class DocksSqlEditor extends DocksPart {
|
|
|
369
367
|
}
|
|
370
368
|
async doInitUI() {
|
|
371
369
|
const file = this.input.data;
|
|
372
|
-
|
|
370
|
+
const textContents = await file.getContents();
|
|
371
|
+
this.initialContent = typeof textContents === "string" ? textContents : textContents == null ? "" : String(textContents);
|
|
373
372
|
this.initialUri = file.getWorkspacePath();
|
|
374
373
|
this.unsubscribeContributionsToken = subscribe(TOPIC_CONTRIBUTEIONS_CHANGED, (event) => {
|
|
375
374
|
if (event?.target === "system.sqladapters") this.refreshAdapters();
|
|
376
375
|
});
|
|
377
|
-
await this.
|
|
378
|
-
this.
|
|
376
|
+
await this.updateComplete;
|
|
377
|
+
this.refreshAdapters().catch((err) => {
|
|
378
|
+
toastError(err instanceof Error ? err.message : String(err));
|
|
379
|
+
});
|
|
379
380
|
}
|
|
380
381
|
async refreshAdapters() {
|
|
381
382
|
const contributions = contributionRegistry.getContributions("system.sqladapters");
|
|
@@ -383,7 +384,8 @@ var DocksSqlEditor = class DocksSqlEditor extends DocksPart {
|
|
|
383
384
|
if (!contributions.length) {
|
|
384
385
|
this.selectedEngineId = null;
|
|
385
386
|
this.availableConnections = [];
|
|
386
|
-
this.selectedConnectionId =
|
|
387
|
+
this.selectedConnectionId = void 0;
|
|
388
|
+
this.dbVersion = void 0;
|
|
387
389
|
await this.updateComplete;
|
|
388
390
|
return;
|
|
389
391
|
}
|
|
@@ -414,34 +416,53 @@ var DocksSqlEditor = class DocksSqlEditor extends DocksPart {
|
|
|
414
416
|
const engineId = this.selectedEngineId;
|
|
415
417
|
if (!engineId) {
|
|
416
418
|
this.availableConnections = [];
|
|
417
|
-
this.selectedConnectionId =
|
|
419
|
+
this.selectedConnectionId = void 0;
|
|
420
|
+
this.dbVersion = void 0;
|
|
421
|
+
this.sqlEngineLoading = false;
|
|
418
422
|
await this.updateComplete;
|
|
419
423
|
return;
|
|
420
424
|
}
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
+
this.sqlEngineLoading = true;
|
|
426
|
+
this.dbVersion = void 0;
|
|
427
|
+
this.requestUpdate();
|
|
428
|
+
try {
|
|
429
|
+
const db = await this.getOrLoadDatabase(engineId);
|
|
430
|
+
if (!db) {
|
|
431
|
+
this.availableConnections = [];
|
|
432
|
+
this.selectedConnectionId = void 0;
|
|
433
|
+
return;
|
|
434
|
+
}
|
|
435
|
+
this.availableConnections = await db.listConnections();
|
|
436
|
+
const currentId = db.currentConnectionId;
|
|
437
|
+
if (currentId !== null && currentId !== void 0) {
|
|
438
|
+
this.selectedConnectionId = currentId;
|
|
439
|
+
await this.updateDbVersion();
|
|
440
|
+
} else this.selectedConnectionId = void 0;
|
|
441
|
+
} finally {
|
|
442
|
+
this.sqlEngineLoading = false;
|
|
425
443
|
await this.updateComplete;
|
|
426
|
-
|
|
444
|
+
this.requestUpdate();
|
|
427
445
|
}
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
446
|
+
}
|
|
447
|
+
async updateDbVersion() {
|
|
448
|
+
this.dbVersion = void 0;
|
|
449
|
+
const engineId = this.selectedEngineId;
|
|
450
|
+
if (!engineId || this.selectedConnectionId === void 0) return;
|
|
451
|
+
const db = this.databases.get(engineId);
|
|
452
|
+
if (!db?.readVersion) return;
|
|
453
|
+
try {
|
|
454
|
+
this.dbVersion = await db.readVersion();
|
|
455
|
+
} catch {
|
|
456
|
+
this.dbVersion = void 0;
|
|
435
457
|
}
|
|
436
|
-
|
|
437
|
-
this.selectedConnectionId = preferred ? preferred.id : null;
|
|
438
|
-
if (preferred) await db.selectConnection(preferred.id ?? null);
|
|
439
|
-
await this.updateComplete;
|
|
458
|
+
this.requestUpdate();
|
|
440
459
|
}
|
|
441
460
|
async onEngineChange(e) {
|
|
442
461
|
const value = e.target?.value ?? "";
|
|
443
462
|
if (this.selectedEngineId === value) return;
|
|
444
463
|
this.selectedEngineId = value || null;
|
|
464
|
+
this.selectedConnectionId = void 0;
|
|
465
|
+
this.dbVersion = void 0;
|
|
445
466
|
await this.refreshConnections();
|
|
446
467
|
this.requestUpdate();
|
|
447
468
|
}
|
|
@@ -455,12 +476,15 @@ var DocksSqlEditor = class DocksSqlEditor extends DocksPart {
|
|
|
455
476
|
const db = await this.getOrLoadDatabase(engineId);
|
|
456
477
|
if (!db) return;
|
|
457
478
|
await db.selectConnection(next);
|
|
479
|
+
await this.updateDbVersion();
|
|
458
480
|
this.requestUpdate();
|
|
459
481
|
}
|
|
460
482
|
async onEngineDropdownSelect(e) {
|
|
461
483
|
const value = e.detail?.item?.value ?? "";
|
|
462
484
|
if (this.selectedEngineId === value) return;
|
|
463
485
|
this.selectedEngineId = value || null;
|
|
486
|
+
this.selectedConnectionId = void 0;
|
|
487
|
+
this.dbVersion = void 0;
|
|
464
488
|
await this.refreshConnections();
|
|
465
489
|
this.requestUpdate();
|
|
466
490
|
}
|
|
@@ -474,6 +498,7 @@ var DocksSqlEditor = class DocksSqlEditor extends DocksPart {
|
|
|
474
498
|
const db = await this.getOrLoadDatabase(engineId);
|
|
475
499
|
if (!db) return;
|
|
476
500
|
await db.selectConnection(next);
|
|
501
|
+
await this.updateDbVersion();
|
|
477
502
|
this.requestUpdate();
|
|
478
503
|
}
|
|
479
504
|
async deleteConnectionById(e, id) {
|
|
@@ -540,10 +565,9 @@ var DocksSqlEditor = class DocksSqlEditor extends DocksPart {
|
|
|
540
565
|
toastError("Could not initialize SQL engine");
|
|
541
566
|
return;
|
|
542
567
|
}
|
|
543
|
-
if (
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
await db.selectConnection(preferred.id ?? null);
|
|
568
|
+
if (this.selectedConnectionId === void 0) {
|
|
569
|
+
toastError("Select a connection");
|
|
570
|
+
return;
|
|
547
571
|
}
|
|
548
572
|
this.running = true;
|
|
549
573
|
const label = truncateLabel(sql);
|
|
@@ -583,12 +607,14 @@ var DocksSqlEditor = class DocksSqlEditor extends DocksPart {
|
|
|
583
607
|
await this.refreshConnections();
|
|
584
608
|
this.selectedConnectionId = info.id;
|
|
585
609
|
await db.selectConnection(info.id ?? null);
|
|
610
|
+
await this.updateDbVersion();
|
|
586
611
|
toastInfo(`Connection "${info.label}" created`);
|
|
587
612
|
this.requestUpdate();
|
|
588
613
|
}
|
|
589
614
|
async deleteConnection() {
|
|
590
615
|
const engineId = this.selectedEngineId;
|
|
591
616
|
if (!engineId) return;
|
|
617
|
+
if (this.selectedConnectionId === void 0) return;
|
|
592
618
|
const db = await this.getOrLoadDatabase(engineId);
|
|
593
619
|
if (!db || !db.deleteConnection) return;
|
|
594
620
|
const id = this.selectedConnectionId;
|
|
@@ -600,13 +626,17 @@ var DocksSqlEditor = class DocksSqlEditor extends DocksPart {
|
|
|
600
626
|
}
|
|
601
627
|
getCurrentConnectionLabel() {
|
|
602
628
|
const id = this.selectedConnectionId;
|
|
629
|
+
if (id === void 0) return null;
|
|
603
630
|
if (id === null) return "In-memory";
|
|
604
|
-
if (!id) return null;
|
|
605
631
|
return this.availableConnections.find((c) => c.id === id)?.label ?? id;
|
|
606
632
|
}
|
|
607
633
|
async openExtensionManager() {
|
|
608
634
|
const engineId = this.selectedEngineId;
|
|
609
635
|
if (!engineId) return;
|
|
636
|
+
if (this.selectedConnectionId === void 0) {
|
|
637
|
+
toastError("Select a connection");
|
|
638
|
+
return;
|
|
639
|
+
}
|
|
610
640
|
const db = await this.getOrLoadDatabase(engineId);
|
|
611
641
|
if (!db || !db.listDbExtensions) {
|
|
612
642
|
toastInfo("Extensions are not available for the selected SQL engine.");
|
|
@@ -627,7 +657,30 @@ var DocksSqlEditor = class DocksSqlEditor extends DocksPart {
|
|
|
627
657
|
const engineId = this.selectedEngineId;
|
|
628
658
|
const dbForEngine = engineId ? this.databases.get(engineId) : null;
|
|
629
659
|
const supportsExtensions = Boolean(dbForEngine?.listDbExtensions);
|
|
630
|
-
|
|
660
|
+
const connectionButtonLabel = this.sqlEngineLoading ? "Loading…" : this.selectedConnectionId === void 0 ? "Select connection" : this.selectedConnectionId === null ? "In-memory" : this.availableConnections.find((c) => c.id === this.selectedConnectionId)?.label ?? "Connection";
|
|
661
|
+
const runDisabled = this.running || this.sqlEngineLoading || this.selectedConnectionId === void 0;
|
|
662
|
+
const sqlConnected = this.selectedConnectionId !== void 0 && !this.sqlEngineLoading;
|
|
663
|
+
const statusTitle = this.sqlEngineLoading ? "Connecting…" : sqlConnected ? "SQL engine connected" : "No connection selected";
|
|
664
|
+
const statusIconColor = this.sqlEngineLoading ? "var(--wa-color-warning-500)" : sqlConnected ? "var(--wa-color-green-40)" : "var(--wa-color-red-40)";
|
|
665
|
+
const statusText = this.sqlEngineLoading ? "" : this.dbVersion ? this.dbVersion : sqlConnected ? "Connected" : "Not connected";
|
|
666
|
+
return html`
|
|
667
|
+
<div class="sql-toolbar-part" style=${styleMap({
|
|
668
|
+
display: "flex",
|
|
669
|
+
flex: "1",
|
|
670
|
+
minWidth: "0",
|
|
671
|
+
alignItems: "center",
|
|
672
|
+
gap: "var(--wa-space-2xs)",
|
|
673
|
+
flexWrap: "nowrap"
|
|
674
|
+
})}>
|
|
675
|
+
<div class="sql-toolbar-lead" style=${styleMap({
|
|
676
|
+
display: "flex",
|
|
677
|
+
flex: "1",
|
|
678
|
+
minWidth: "0",
|
|
679
|
+
flexWrap: "nowrap",
|
|
680
|
+
alignItems: "center",
|
|
681
|
+
gap: "var(--wa-space-2xs)",
|
|
682
|
+
overflowX: "auto"
|
|
683
|
+
})}>
|
|
631
684
|
<wa-dropdown
|
|
632
685
|
class="engine-select"
|
|
633
686
|
placement="bottom-start"
|
|
@@ -644,7 +697,7 @@ var DocksSqlEditor = class DocksSqlEditor extends DocksPart {
|
|
|
644
697
|
>
|
|
645
698
|
${this.selectedEngineId ? adapters.find((a) => a.id === this.selectedEngineId)?.label ?? this.selectedEngineId : "Select engine"}
|
|
646
699
|
</wa-button>
|
|
647
|
-
${adapters.map((adapter) => html
|
|
700
|
+
${adapters.map((adapter) => html`
|
|
648
701
|
<wa-dropdown-item
|
|
649
702
|
value=${adapter.id}
|
|
650
703
|
type="checkbox"
|
|
@@ -667,11 +720,11 @@ var DocksSqlEditor = class DocksSqlEditor extends DocksPart {
|
|
|
667
720
|
size="small"
|
|
668
721
|
with-caret
|
|
669
722
|
title="Connection"
|
|
670
|
-
?disabled=${!hasEngines || !hasConnections}
|
|
723
|
+
?disabled=${!hasEngines || !hasConnections || this.sqlEngineLoading}
|
|
671
724
|
>
|
|
672
|
-
${
|
|
725
|
+
${connectionButtonLabel}
|
|
673
726
|
</wa-button>
|
|
674
|
-
${this.availableConnections.map((info) => html
|
|
727
|
+
${this.availableConnections.map((info) => html`
|
|
675
728
|
<wa-dropdown-item
|
|
676
729
|
value=${info.id ?? ""}
|
|
677
730
|
type="checkbox"
|
|
@@ -697,16 +750,17 @@ var DocksSqlEditor = class DocksSqlEditor extends DocksPart {
|
|
|
697
750
|
size="small"
|
|
698
751
|
appearance="plain"
|
|
699
752
|
title="New connection"
|
|
753
|
+
?disabled=${this.sqlEngineLoading}
|
|
700
754
|
@click=${() => void this.createConnection()}
|
|
701
755
|
>
|
|
702
756
|
<wa-icon name="plus" label="New"></wa-icon>
|
|
703
757
|
</wa-button>
|
|
704
|
-
${supportsExtensions ? html
|
|
758
|
+
${supportsExtensions ? html`
|
|
705
759
|
<wa-button
|
|
706
760
|
size="small"
|
|
707
761
|
appearance="plain"
|
|
708
762
|
title="Manage extensions"
|
|
709
|
-
?disabled=${!hasEngines || !hasConnections}
|
|
763
|
+
?disabled=${!hasEngines || !hasConnections || this.selectedConnectionId === void 0 || this.sqlEngineLoading}
|
|
710
764
|
@click=${() => void this.openExtensionManager()}
|
|
711
765
|
>
|
|
712
766
|
<wa-icon name="puzzle-piece" label="Extensions"></wa-icon>
|
|
@@ -716,7 +770,7 @@ var DocksSqlEditor = class DocksSqlEditor extends DocksPart {
|
|
|
716
770
|
<wa-button
|
|
717
771
|
size="small"
|
|
718
772
|
appearance="plain"
|
|
719
|
-
?disabled=${
|
|
773
|
+
?disabled=${runDisabled}
|
|
720
774
|
@click=${() => void this.runQuery(true)}
|
|
721
775
|
title="Run selection only"
|
|
722
776
|
>
|
|
@@ -726,18 +780,51 @@ var DocksSqlEditor = class DocksSqlEditor extends DocksPart {
|
|
|
726
780
|
<wa-button
|
|
727
781
|
size="small"
|
|
728
782
|
appearance="plain"
|
|
729
|
-
?disabled=${
|
|
783
|
+
?disabled=${runDisabled}
|
|
730
784
|
@click=${() => void this.runQuery(false)}
|
|
731
785
|
title="Run all SQL"
|
|
732
786
|
>
|
|
733
787
|
<wa-icon name="play" label="Run"></wa-icon>
|
|
734
788
|
${this.running ? "Running…" : "Run all"}
|
|
735
789
|
</wa-button>
|
|
790
|
+
</div>
|
|
791
|
+
<span
|
|
792
|
+
class="sql-toolbar-status"
|
|
793
|
+
aria-live="polite"
|
|
794
|
+
title=${statusTitle}
|
|
795
|
+
style=${styleMap({
|
|
796
|
+
flexShrink: "0",
|
|
797
|
+
display: "inline-flex",
|
|
798
|
+
alignItems: "center",
|
|
799
|
+
gap: "0.5rem",
|
|
800
|
+
minHeight: "1.25rem",
|
|
801
|
+
whiteSpace: "nowrap"
|
|
802
|
+
})}
|
|
803
|
+
>
|
|
804
|
+
<wa-icon
|
|
805
|
+
name="circle"
|
|
806
|
+
label="SQL engine status"
|
|
807
|
+
style=${styleMap({ color: statusIconColor })}
|
|
808
|
+
></wa-icon>
|
|
809
|
+
${this.sqlEngineLoading ? html`<wa-spinner style="font-size: 0.9rem"></wa-spinner>` : html`<span
|
|
810
|
+
class="sql-toolbar-version"
|
|
811
|
+
style=${styleMap({
|
|
812
|
+
fontSize: "0.8rem",
|
|
813
|
+
opacity: "0.85",
|
|
814
|
+
whiteSpace: "nowrap",
|
|
815
|
+
maxWidth: "14rem",
|
|
816
|
+
overflow: "hidden",
|
|
817
|
+
textOverflow: "ellipsis"
|
|
818
|
+
})}
|
|
819
|
+
>${statusText}</span
|
|
820
|
+
>`}
|
|
821
|
+
</span>
|
|
822
|
+
</div>
|
|
736
823
|
`;
|
|
737
824
|
}
|
|
738
825
|
renderContent() {
|
|
739
|
-
if (this.initialContent === void 0) return html
|
|
740
|
-
return html
|
|
826
|
+
if (this.initialContent === void 0) return html`<div class="editor-placeholder"></div>`;
|
|
827
|
+
return html`
|
|
741
828
|
<div class="editor-area">
|
|
742
829
|
<docks-monaco-widget
|
|
743
830
|
.value=${this.initialContent}
|
|
@@ -794,6 +881,8 @@ _decorate([state()], DocksSqlEditor.prototype, "availableAdapters", void 0);
|
|
|
794
881
|
_decorate([state()], DocksSqlEditor.prototype, "selectedEngineId", void 0);
|
|
795
882
|
_decorate([state()], DocksSqlEditor.prototype, "availableConnections", void 0);
|
|
796
883
|
_decorate([state()], DocksSqlEditor.prototype, "selectedConnectionId", void 0);
|
|
884
|
+
_decorate([state()], DocksSqlEditor.prototype, "sqlEngineLoading", void 0);
|
|
885
|
+
_decorate([state()], DocksSqlEditor.prototype, "dbVersion", void 0);
|
|
797
886
|
DocksSqlEditor = _decorate([customElement("docks-sql-editor")], DocksSqlEditor);
|
|
798
887
|
//#endregion
|
|
799
888
|
//#region src/sqleditor-extension.ts
|
|
@@ -821,4 +910,4 @@ function activate() {
|
|
|
821
910
|
//#endregion
|
|
822
911
|
export { activate as default };
|
|
823
912
|
|
|
824
|
-
//# sourceMappingURL=sqleditor-extension-
|
|
913
|
+
//# sourceMappingURL=sqleditor-extension-K5TQp9rX.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sqleditor-extension-K5TQp9rX.js","names":[],"sources":["../src/sql-extension-manager.ts","../src/sql-editor.ts","../src/sqleditor-extension.ts"],"sourcesContent":["import { rootContext, taskService, toastError } from '@eclipse-docks/core';\nimport {\n css,\n customElement,\n html,\n LitElement,\n property,\n repeat,\n state,\n} from '@eclipse-docks/core/externals/lit';\nimport type { SqlDatabase, SqlDatabaseExtensionInfo } from './sql-api';\n\nexport interface SqlExtensionManagerOptions {\n db: SqlDatabase | null;\n databaseLabel: string;\n}\n\n@customElement('docks-sql-extension-manager')\nexport class DocksSqlExtensionManager extends LitElement {\n @property({ type: Boolean })\n open = false;\n\n @property({ attribute: false })\n db: SqlDatabase | null = null;\n\n @property()\n databaseLabel = '';\n\n @state()\n private extensions: SqlDatabaseExtensionInfo[] = [];\n\n @state()\n private loading = false;\n\n @state()\n private updatingId: string | null = null;\n\n @state()\n private error: string | null = null;\n\n @state()\n private filterText = '';\n\n public configure(options: SqlExtensionManagerOptions): void {\n this.db = options.db;\n this.databaseLabel = options.databaseLabel;\n this.extensions = [];\n this.error = null;\n void this.refreshExtensions();\n }\n\n public show(): void {\n if (!this.db || !this.db.listDbExtensions) return;\n this.open = true;\n }\n\n public hide(): void {\n this.open = false;\n }\n\n private async refreshExtensions(): Promise<void> {\n if (!this.db || !this.db.listDbExtensions) {\n this.extensions = [];\n return;\n }\n this.loading = true;\n this.error = null;\n try {\n const result = await taskService.runAsync(\n 'Loading database extensions',\n async () => this.db!.listDbExtensions!(),\n );\n this.extensions = Array.isArray(result) ? result : [];\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n this.error = msg;\n toastError(msg);\n } finally {\n this.loading = false;\n }\n }\n\n private async enableExtension(ext: SqlDatabaseExtensionInfo): Promise<void> {\n if (!this.db || !this.db.enableDbExtension) return;\n this.updatingId = ext.id;\n this.error = null;\n try {\n await taskService.runAsync(\n `Enabling extension ${ext.label || ext.id}`,\n async () => this.db!.enableDbExtension!(ext.id),\n );\n await this.refreshExtensions();\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n this.error = msg;\n toastError(msg);\n } finally {\n this.updatingId = null;\n }\n }\n\n private async disableExtension(ext: SqlDatabaseExtensionInfo): Promise<void> {\n if (!this.db || !this.db.disableDbExtension) return;\n this.updatingId = ext.id;\n this.error = null;\n try {\n await taskService.runAsync(\n `Disabling extension ${ext.label || ext.id}`,\n async () => this.db!.disableDbExtension!(ext.id),\n );\n await this.refreshExtensions();\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n this.error = msg;\n toastError(msg);\n } finally {\n this.updatingId = null;\n }\n }\n\n private renderExtensionRow(ext: SqlDatabaseExtensionInfo) {\n const installed = Boolean(ext.installed);\n const canDisable = installed && !!this.db?.disableDbExtension;\n const isUpdating = this.updatingId === ext.id;\n\n return html`\n <div class=\"extension-item\">\n <div class=\"extension-main\">\n <div class=\"extension-name\">${ext.label || ext.id}</div>\n ${ext.description\n ? html`<div class=\"extension-desc\">${ext.description}</div>`\n : null}\n </div>\n <div class=\"extension-meta\">\n <span\n class=${installed ? 'badge badge-installed' : 'badge badge-available'}\n >\n ${installed ? 'Installed' : 'Available'}\n </span>\n <div class=\"extension-actions\">\n ${installed\n ? html`\n <wa-button\n size=\"small\"\n appearance=\"plain\"\n ?disabled=${!canDisable || isUpdating}\n @click=${() => void this.disableExtension(ext)}\n >\n <wa-icon\n name=\"circle-minus\"\n label=\"Disable\"\n ></wa-icon>\n </wa-button>\n `\n : html`\n <wa-button\n size=\"small\"\n appearance=\"plain\"\n ?disabled=${isUpdating}\n @click=${() => void this.enableExtension(ext)}\n >\n <wa-icon\n name=\"plug-circle-plus\"\n label=\"Enable\"\n ></wa-icon>\n </wa-button>\n `}\n </div>\n </div>\n </div>\n `;\n }\n\n render() {\n const hasDb = Boolean(this.db && this.db.listDbExtensions);\n const filter = this.filterText.trim().toLowerCase();\n const filteredExtensions = !filter\n ? this.extensions\n : this.extensions.filter((ext) => {\n const text = `${ext.label ?? ''} ${ext.id} ${\n ext.description ?? ''\n }`.toLowerCase();\n return text.includes(filter);\n });\n const hasItems = filteredExtensions.length > 0;\n\n return html`\n <wa-dialog\n label=\"Database extensions\"\n ?open=${this.open}\n @wa-after-hide=${() => {\n this.open = false;\n this.dispatchEvent(\n new CustomEvent('hide', { bubbles: true, composed: true }),\n );\n }}\n >\n <div class=\"extension-manager\">\n <p class=\"extension-manager-description\">\n Database:\n <strong>${this.databaseLabel || 'Current connection'}</strong>\n </p>\n\n ${!hasDb\n ? html`\n <wa-alert variant=\"warning\" open>\n <wa-icon slot=\"icon\" name=\"triangle-exclamation\"></wa-icon>\n The current SQL engine does not expose any extension information.\n </wa-alert>\n `\n : null}\n\n ${this.error\n ? html`\n <wa-alert\n variant=\"danger\"\n open\n closable\n @wa-after-hide=${() => {\n this.error = null;\n }}\n >\n <wa-icon slot=\"icon\" name=\"circle-exclamation\"></wa-icon>\n ${this.error}\n </wa-alert>\n `\n : null}\n\n <wa-input\n size=\"small\"\n placeholder=\"Filter extensions…\"\n .value=${this.filterText}\n @input=${(event: Event) => {\n const target = event.target as HTMLInputElement | null;\n this.filterText = target?.value ?? '';\n }}\n @wa-clear=${() => {\n this.filterText = '';\n }}\n with-clear\n >\n <wa-icon slot=\"prefix\" name=\"magnifying-glass\"></wa-icon>\n </wa-input>\n\n <div class=\"extension-list\">\n ${this.loading\n ? html`<div class=\"extension-list-empty\">Loading extensions…</div>`\n : !hasItems\n ? html`\n <div class=\"extension-list-empty\">\n No extensions available for this connection.\n </div>\n `\n : repeat(\n filteredExtensions,\n (ext) => ext.id,\n (ext) => this.renderExtensionRow(ext),\n )}\n </div>\n </div>\n <div slot=\"footer\" class=\"extension-manager-footer\">\n <wa-button variant=\"default\" @click=${() => this.hide()}>\n Close\n </wa-button>\n </div>\n </wa-dialog>\n `;\n }\n\n static styles = css`\n :host {\n display: contents;\n }\n\n .extension-manager {\n display: flex;\n flex-direction: column;\n gap: 1rem;\n padding: 1rem;\n height: 420px;\n box-sizing: border-box;\n }\n\n .extension-toolbar {\n display: flex;\n justify-content: flex-end;\n }\n\n .extension-manager-description {\n margin: 0;\n font-size: 0.95rem;\n opacity: 0.9;\n }\n\n .extension-list {\n display: flex;\n flex-direction: column;\n gap: 0.5rem;\n flex: 1;\n min-height: 0;\n max-height: 100%;\n overflow-y: auto;\n }\n\n .extension-list-empty {\n font-size: 0.9rem;\n opacity: 0.8;\n padding: 0.5rem 0;\n }\n\n .extension-item {\n display: flex;\n align-items: flex-start;\n justify-content: space-between;\n gap: 0.75rem;\n padding: 0.5rem 0;\n border-bottom: 1px solid var(--wa-color-neutral-200, #e5e7eb);\n }\n\n .extension-main {\n display: flex;\n flex-direction: column;\n gap: 0.15rem;\n min-width: 0;\n }\n\n .extension-name {\n font-weight: 500;\n font-size: 0.95rem;\n }\n\n .extension-desc {\n font-size: 0.85rem;\n opacity: 0.8;\n }\n\n .extension-meta {\n display: flex;\n flex-direction: column;\n align-items: flex-end;\n gap: 0.35rem;\n }\n\n .extension-actions {\n display: flex;\n gap: 0.25rem;\n }\n\n .badge {\n display: inline-flex;\n align-items: center;\n padding: 0.15rem 0.4rem;\n border-radius: 999px;\n font-size: 0.75rem;\n border: 1px solid var(--wa-color-neutral-200, #e5e7eb);\n }\n\n .badge-installed {\n background-color: var(--wa-color-success-50, #ecfdf3);\n }\n\n .badge-available {\n background-color: var(--wa-color-neutral-50, #f9fafb);\n }\n\n .extension-manager-footer {\n display: flex;\n justify-content: flex-end;\n padding-top: 1rem;\n border-top: 1px solid var(--wa-color-neutral-200, #e5e7eb);\n }\n `;\n}\n\nclass SqlExtensionManagerService {\n private managerInstance: DocksSqlExtensionManager | null = null;\n\n public showExtensionManager(\n options: SqlExtensionManagerOptions,\n ): DocksSqlExtensionManager | null {\n if (!options.db || !options.db.listDbExtensions) {\n toastError('The current SQL engine does not support extensions.');\n return null;\n }\n if (!this.managerInstance) {\n this.managerInstance = document.createElement(\n 'docks-sql-extension-manager',\n ) as DocksSqlExtensionManager;\n document.body.appendChild(this.managerInstance);\n }\n this.managerInstance.configure(options);\n this.managerInstance.show();\n return this.managerInstance;\n }\n\n public getManager(): DocksSqlExtensionManager | null {\n return this.managerInstance;\n }\n}\n\nexport const sqlExtensionManagerService = new SqlExtensionManagerService();\nrootContext.put('sqlExtensionManagerService', sqlExtensionManagerService);\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'docks-sql-extension-manager': DocksSqlExtensionManager;\n }\n}\n\n","import { DocksPart, type EditorInput, type EditorContentProvider, toastError, toastInfo, confirmDialog, publish, contributionRegistry, subscribe, unsubscribe, TOPIC_CONTRIBUTEIONS_CHANGED, taskService } from '@eclipse-docks/core';\nimport {\n createRef,\n css,\n customElement,\n html,\n property,\n ref,\n state,\n styleMap,\n} from '@eclipse-docks/core/externals/lit';\nimport type { SqlAdapterContribution, SqlConnectionInfo, SqlDatabase } from './sql-api';\nimport { sqlExtensionManagerService } from './sql-extension-manager';\nimport { DocksMonacoWidget } from '@eclipse-docks/extension-monaco-editor/widget';\n\nconst MAX_TAB_LABEL = 28;\n\nfunction truncateLabel(sql: string): string {\n const oneLine = sql.replace(/\\s+/g, ' ').trim();\n if (oneLine.length <= MAX_TAB_LABEL) return oneLine;\n return `${oneLine.slice(0, MAX_TAB_LABEL)}…`;\n}\n\n@customElement('docks-sql-editor')\nexport class DocksSqlEditor extends DocksPart implements EditorContentProvider {\n @property({ attribute: false })\n public input?: EditorInput;\n\n @property({ type: Boolean })\n public readOnly = false;\n\n @state()\n private initialContent: string | undefined = undefined;\n\n @state()\n private initialUri: string | undefined = undefined;\n\n @state()\n private running = false;\n\n @state()\n private availableAdapters: SqlAdapterContribution[] = [];\n\n @state()\n private selectedEngineId: string | null = null;\n\n @state()\n private availableConnections: SqlConnectionInfo[] = [];\n\n /** `undefined` = user has not chosen a connection yet (placeholder). */\n @state()\n private selectedConnectionId: string | null | undefined = undefined;\n\n @state()\n private sqlEngineLoading = false;\n\n @state()\n private dbVersion: string | undefined = undefined;\n\n private widgetRef = createRef<DocksMonacoWidget>();\n private databases = new Map<string, SqlDatabase>();\n private unsubscribeContributionsToken?: string;\n\n protected async doInitUI() {\n const file = this.input!.data;\n const textContents = await file.getContents();\n this.initialContent =\n typeof textContents === 'string'\n ? textContents\n : textContents == null\n ? ''\n : String(textContents);\n this.initialUri = file.getWorkspacePath();\n this.unsubscribeContributionsToken = subscribe(TOPIC_CONTRIBUTEIONS_CHANGED, (event: { target?: string } | undefined) => {\n if (event?.target === 'system.sqladapters') {\n void this.refreshAdapters();\n }\n });\n\n await this.updateComplete;\n void this.refreshAdapters().catch((err) => {\n toastError(err instanceof Error ? err.message : String(err));\n });\n }\n\n private async refreshAdapters(): Promise<void> {\n const contributions = contributionRegistry.getContributions<SqlAdapterContribution>('system.sqladapters');\n this.availableAdapters = contributions;\n if (!contributions.length) {\n this.selectedEngineId = null;\n this.availableConnections = [];\n this.selectedConnectionId = undefined;\n this.dbVersion = undefined;\n await this.updateComplete;\n return;\n }\n if (!this.selectedEngineId) {\n const duckdbAdapter = contributions.find((c) => c.id === 'duckdb');\n this.selectedEngineId = (duckdbAdapter ?? contributions[0]).id;\n }\n this.requestUpdate();\n await this.refreshConnections();\n await this.updateComplete;\n }\n\n private async getOrLoadDatabase(engineId: string): Promise<SqlDatabase | null> {\n const cached = this.databases.get(engineId);\n if (cached) return cached;\n const adapter = this.availableAdapters.find((c) => c.id === engineId);\n if (!adapter) return null;\n try {\n const label = adapter.label || adapter.id;\n const database = await taskService.runAsync(`Opening ${label} database`, async (progress) => {\n progress.message = `Connecting to ${label}…`;\n return adapter.loader();\n });\n this.databases.set(engineId, database);\n return database;\n } catch (err) {\n toastError(err instanceof Error ? err.message : String(err));\n return null;\n }\n }\n\n private async refreshConnections(): Promise<void> {\n const engineId = this.selectedEngineId;\n if (!engineId) {\n this.availableConnections = [];\n this.selectedConnectionId = undefined;\n this.dbVersion = undefined;\n this.sqlEngineLoading = false;\n await this.updateComplete;\n return;\n }\n this.sqlEngineLoading = true;\n this.dbVersion = undefined;\n this.requestUpdate();\n try {\n const db = await this.getOrLoadDatabase(engineId);\n if (!db) {\n this.availableConnections = [];\n this.selectedConnectionId = undefined;\n return;\n }\n const infos = await db.listConnections();\n this.availableConnections = infos;\n const currentId = db.currentConnectionId;\n if (currentId !== null && currentId !== undefined) {\n this.selectedConnectionId = currentId;\n await this.updateDbVersion();\n } else {\n this.selectedConnectionId = undefined;\n }\n } finally {\n this.sqlEngineLoading = false;\n await this.updateComplete;\n this.requestUpdate();\n }\n }\n\n private async updateDbVersion(): Promise<void> {\n this.dbVersion = undefined;\n const engineId = this.selectedEngineId;\n if (!engineId || this.selectedConnectionId === undefined) return;\n const db = this.databases.get(engineId);\n if (!db?.readVersion) return;\n try {\n this.dbVersion = await db.readVersion();\n } catch {\n this.dbVersion = undefined;\n }\n this.requestUpdate();\n }\n\n private async onEngineChange(e: Event): Promise<void> {\n const select = e.target as { value?: string };\n const value = select?.value ?? '';\n if (this.selectedEngineId === value) return;\n this.selectedEngineId = value || null;\n this.selectedConnectionId = undefined;\n this.dbVersion = undefined;\n await this.refreshConnections();\n this.requestUpdate();\n }\n\n private async onConnectionChange(e: Event): Promise<void> {\n const select = e.target as { value?: string };\n const value = select?.value ?? '';\n const next = value === '' ? null : value;\n if (this.selectedConnectionId === next) return;\n this.selectedConnectionId = next;\n const engineId = this.selectedEngineId;\n if (!engineId) return;\n const db = await this.getOrLoadDatabase(engineId);\n if (!db) return;\n await db.selectConnection(next);\n await this.updateDbVersion();\n this.requestUpdate();\n }\n\n private async onEngineDropdownSelect(\n e: CustomEvent<{ item?: { value?: string } }>,\n ): Promise<void> {\n const value = e.detail?.item?.value ?? '';\n if (this.selectedEngineId === value) return;\n this.selectedEngineId = value || null;\n this.selectedConnectionId = undefined;\n this.dbVersion = undefined;\n await this.refreshConnections();\n this.requestUpdate();\n }\n\n private async onConnectionDropdownSelect(\n e: CustomEvent<{ item?: { value?: string } }>,\n ): Promise<void> {\n const value = e.detail?.item?.value ?? '';\n const next = value === '' ? null : value;\n if (this.selectedConnectionId === next) return;\n this.selectedConnectionId = next;\n const engineId = this.selectedEngineId;\n if (!engineId) return;\n const db = await this.getOrLoadDatabase(engineId);\n if (!db) return;\n await db.selectConnection(next);\n await this.updateDbVersion();\n this.requestUpdate();\n }\n\n private async deleteConnectionById(e: Event, id: string | null): Promise<void> {\n e.stopPropagation();\n e.preventDefault();\n const engineId = this.selectedEngineId;\n if (!engineId) return;\n const db = await this.getOrLoadDatabase(engineId);\n if (!db || !db.deleteConnection) return;\n const connectionLabel =\n this.availableConnections.find((info) => info.id === id)?.label ??\n (id === null ? 'In-memory' : id ?? 'Current connection');\n const ok = await confirmDialog(`Delete connection \"${connectionLabel}\"?`);\n if (!ok) return;\n if (id !== null) {\n await db.deleteConnection(id);\n } else {\n await db.selectConnection(null);\n }\n await this.refreshConnections();\n this.requestUpdate();\n }\n\n private _onContentChange = () => {\n this.markDirty(true);\n };\n\n save(): void {\n const value = this.widgetRef.value?.getContent() ?? '';\n this.input?.data.saveContents(value);\n this.markDirty(false);\n }\n\n protected async doClose() {\n if (this.unsubscribeContributionsToken) {\n unsubscribe(this.unsubscribeContributionsToken);\n this.unsubscribeContributionsToken = undefined;\n }\n this.widgetRef.value?.dispose();\n for (const db of this.databases.values()) {\n await db.close();\n }\n this.databases.clear();\n }\n\n public getLanguage(): string | null {\n return 'sql';\n }\n\n public isLanguage(lang: string): boolean {\n return lang.toLowerCase() === 'sql';\n }\n\n public getContent(): string | null {\n return this.widgetRef.value?.getContent() ?? null;\n }\n\n public getSelection(): string | null {\n return this.widgetRef.value?.getSelection() ?? null;\n }\n\n public getSnippet(lines: number = 5): { snippet: string; cursorLine: number } | null {\n return this.widgetRef.value?.getSnippet(lines) ?? null;\n }\n\n public getFilePath(): string | null {\n return this.input?.data?.getWorkspacePath() ?? null;\n }\n\n private async runQuery(useSelectionOnly = false): Promise<void> {\n const selection = this.getSelection()?.trim();\n const content = this.getContent()?.trim();\n const sql = useSelectionOnly ? selection : content;\n if (!sql) {\n toastError(useSelectionOnly ? 'No selection to run' : 'No SQL to run');\n return;\n }\n if (this.running) return;\n\n const engineId = this.selectedEngineId;\n if (!engineId) {\n toastError('No SQL engine available');\n return;\n }\n\n const db = await this.getOrLoadDatabase(engineId);\n if (!db) {\n toastError('Could not initialize SQL engine');\n return;\n }\n\n if (this.selectedConnectionId === undefined) {\n toastError('Select a connection');\n return;\n }\n\n this.running = true;\n const label = truncateLabel(sql);\n this.requestUpdate();\n\n const timeoutMs = 60_000;\n const timeoutId = window.setTimeout(() => this.clearRunningState(), timeoutMs);\n\n try {\n const result = await db.runQuery(sql);\n const adapter = this.availableAdapters.find((c) => c.id === engineId);\n publish('dataview/publish', {\n title: label,\n data: { columns: result.columns, rows: result.rows },\n source: adapter?.label ?? engineId,\n });\n } catch (err) {\n toastError(err instanceof Error ? err.message : String(err));\n } finally {\n window.clearTimeout(timeoutId);\n this.running = false;\n this.requestUpdate();\n }\n }\n\n private clearRunningState(): void {\n if (!this.running) return;\n this.running = false;\n this.requestUpdate();\n }\n\n private async createConnection(): Promise<void> {\n const engineId = this.selectedEngineId;\n if (!engineId) return;\n const db = await this.getOrLoadDatabase(engineId);\n if (!db || !db.createConnection) return;\n const info = await db.createConnection();\n if (!info) return;\n await this.refreshConnections();\n this.selectedConnectionId = info.id;\n await db.selectConnection(info.id ?? null);\n await this.updateDbVersion();\n toastInfo(`Connection \"${info.label}\" created`);\n this.requestUpdate();\n }\n\n private async deleteConnection(): Promise<void> {\n const engineId = this.selectedEngineId;\n if (!engineId) return;\n if (this.selectedConnectionId === undefined) return;\n const db = await this.getOrLoadDatabase(engineId);\n if (!db || !db.deleteConnection) return;\n const id = this.selectedConnectionId;\n const connectionLabel =\n this.availableConnections.find((info) => info.id === id)?.label ??\n (id === null ? 'In-memory' : id ?? 'Current connection');\n const ok = await confirmDialog(`Delete connection \"${connectionLabel}\"?`);\n if (!ok) return;\n if (id !== null) {\n await db.deleteConnection(id);\n } else {\n await db.selectConnection(null);\n }\n await this.refreshConnections();\n this.requestUpdate();\n }\n\n private getCurrentConnectionLabel(): string | null {\n const id = this.selectedConnectionId;\n if (id === undefined) return null;\n if (id === null) return 'In-memory';\n const info = this.availableConnections.find((c) => c.id === id);\n return info?.label ?? id;\n }\n\n private async openExtensionManager(): Promise<void> {\n const engineId = this.selectedEngineId;\n if (!engineId) return;\n if (this.selectedConnectionId === undefined) {\n toastError('Select a connection');\n return;\n }\n const db = await this.getOrLoadDatabase(engineId);\n if (!db || !db.listDbExtensions) {\n toastInfo('Extensions are not available for the selected SQL engine.');\n return;\n }\n const adapter =\n this.availableAdapters.find((c) => c.id === engineId) ?? null;\n const engineLabel = adapter?.label ?? engineId;\n const connectionLabel = this.getCurrentConnectionLabel();\n const databaseLabel = connectionLabel\n ? `${engineLabel} – ${connectionLabel}`\n : engineLabel;\n sqlExtensionManagerService.showExtensionManager({\n db,\n databaseLabel,\n });\n }\n\n protected renderToolbar() {\n const adapters = this.availableAdapters;\n const hasEngines = adapters.length > 0;\n const hasConnections = this.availableConnections.length > 0;\n const engineId = this.selectedEngineId;\n const dbForEngine = engineId ? this.databases.get(engineId) : null;\n const supportsExtensions = Boolean(dbForEngine?.listDbExtensions);\n const connectionButtonLabel = this.sqlEngineLoading\n ? 'Loading…'\n : this.selectedConnectionId === undefined\n ? 'Select connection'\n : this.selectedConnectionId === null\n ? 'In-memory'\n : this.availableConnections.find(\n (c) => c.id === this.selectedConnectionId,\n )?.label ?? 'Connection';\n const runDisabled =\n this.running ||\n this.sqlEngineLoading ||\n this.selectedConnectionId === undefined;\n\n const sqlConnected =\n this.selectedConnectionId !== undefined && !this.sqlEngineLoading;\n const statusTitle = this.sqlEngineLoading\n ? 'Connecting…'\n : sqlConnected\n ? 'SQL engine connected'\n : 'No connection selected';\n const statusIconColor = this.sqlEngineLoading\n ? 'var(--wa-color-warning-500)'\n : sqlConnected\n ? 'var(--wa-color-green-40)'\n : 'var(--wa-color-red-40)';\n const statusText = this.sqlEngineLoading\n ? ''\n : this.dbVersion\n ? this.dbVersion\n : sqlConnected\n ? 'Connected'\n : 'Not connected';\n\n // Toolbar markup renders under docks-toolbar; host static styles do not apply there.\n const sqlToolbarPartStyle = {\n display: 'flex',\n flex: '1',\n minWidth: '0',\n alignItems: 'center',\n gap: 'var(--wa-space-2xs)',\n flexWrap: 'nowrap',\n } as const;\n const sqlToolbarLeadStyle = {\n display: 'flex',\n flex: '1',\n minWidth: '0',\n flexWrap: 'nowrap',\n alignItems: 'center',\n gap: 'var(--wa-space-2xs)',\n overflowX: 'auto',\n } as const;\n const sqlToolbarStatusStyle = {\n flexShrink: '0',\n display: 'inline-flex',\n alignItems: 'center',\n gap: '0.5rem',\n minHeight: '1.25rem',\n whiteSpace: 'nowrap',\n } as const;\n const sqlToolbarVersionStyle = {\n fontSize: '0.8rem',\n opacity: '0.85',\n whiteSpace: 'nowrap',\n maxWidth: '14rem',\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n } as const;\n\n return html`\n <div class=\"sql-toolbar-part\" style=${styleMap(sqlToolbarPartStyle)}>\n <div class=\"sql-toolbar-lead\" style=${styleMap(sqlToolbarLeadStyle)}>\n <wa-dropdown\n class=\"engine-select\"\n placement=\"bottom-start\"\n distance=\"4\"\n size=\"small\"\n @wa-select=${(e: CustomEvent) => void this.onEngineDropdownSelect(e)}\n >\n <wa-button\n slot=\"trigger\"\n appearance=\"plain\"\n size=\"small\"\n with-caret\n title=\"SQL engine\"\n >\n ${this.selectedEngineId\n ? adapters.find((a) => a.id === this.selectedEngineId)?.label ??\n this.selectedEngineId\n : 'Select engine'}\n </wa-button>\n ${adapters.map(\n (adapter) => html`\n <wa-dropdown-item\n value=${adapter.id}\n type=\"checkbox\"\n ?checked=${adapter.id === this.selectedEngineId}\n >\n ${adapter.label}\n </wa-dropdown-item>\n `,\n )}\n </wa-dropdown>\n <wa-dropdown\n class=\"connection-select\"\n placement=\"bottom-start\"\n distance=\"4\"\n size=\"small\"\n @wa-select=${(e: CustomEvent) =>\n void this.onConnectionDropdownSelect(e)}\n >\n <wa-button\n slot=\"trigger\"\n appearance=\"plain\"\n size=\"small\"\n with-caret\n title=\"Connection\"\n ?disabled=${!hasEngines || !hasConnections || this.sqlEngineLoading}\n >\n ${connectionButtonLabel}\n </wa-button>\n ${this.availableConnections.map(\n (info) => html`\n <wa-dropdown-item\n value=${info.id ?? ''}\n type=\"checkbox\"\n ?checked=${info.id === this.selectedConnectionId}\n >\n ${info.label}\n <wa-button\n slot=\"details\"\n appearance=\"plain\"\n size=\"small\"\n title=${info.id === null\n ? 'Reset in-memory connection'\n : 'Delete connection'}\n @click=${(e: Event) => this.deleteConnectionById(e, info.id)}\n >\n <wa-icon\n name=${info.id === null ? 'rotate-right' : 'trash'}\n label=${info.id === null ? 'Reset' : 'Delete'}\n ></wa-icon>\n </wa-button>\n </wa-dropdown-item>\n `,\n )}\n </wa-dropdown>\n <wa-button\n size=\"small\"\n appearance=\"plain\"\n title=\"New connection\"\n ?disabled=${this.sqlEngineLoading}\n @click=${() => void this.createConnection()}\n >\n <wa-icon name=\"plus\" label=\"New\"></wa-icon>\n </wa-button>\n ${supportsExtensions\n ? html`\n <wa-button\n size=\"small\"\n appearance=\"plain\"\n title=\"Manage extensions\"\n ?disabled=${!hasEngines ||\n !hasConnections ||\n this.selectedConnectionId === undefined ||\n this.sqlEngineLoading}\n @click=${() => void this.openExtensionManager()}\n >\n <wa-icon name=\"puzzle-piece\" label=\"Extensions\"></wa-icon>\n Extensions\n </wa-button>\n `\n : null}\n <wa-button\n size=\"small\"\n appearance=\"plain\"\n ?disabled=${runDisabled}\n @click=${() => void this.runQuery(true)}\n title=\"Run selection only\"\n >\n <wa-icon name=\"i-cursor\" label=\"Run selection\"></wa-icon>\n ${this.running ? 'Running…' : 'Run selection'}\n </wa-button>\n <wa-button\n size=\"small\"\n appearance=\"plain\"\n ?disabled=${runDisabled}\n @click=${() => void this.runQuery(false)}\n title=\"Run all SQL\"\n >\n <wa-icon name=\"play\" label=\"Run\"></wa-icon>\n ${this.running ? 'Running…' : 'Run all'}\n </wa-button>\n </div>\n <span\n class=\"sql-toolbar-status\"\n aria-live=\"polite\"\n title=${statusTitle}\n style=${styleMap(sqlToolbarStatusStyle)}\n >\n <wa-icon\n name=\"circle\"\n label=\"SQL engine status\"\n style=${styleMap({ color: statusIconColor })}\n ></wa-icon>\n ${this.sqlEngineLoading\n ? html`<wa-spinner style=\"font-size: 0.9rem\"></wa-spinner>`\n : html`<span\n class=\"sql-toolbar-version\"\n style=${styleMap(sqlToolbarVersionStyle)}\n >${statusText}</span\n >`}\n </span>\n </div>\n `;\n }\n\n protected renderContent() {\n if (this.initialContent === undefined) {\n return html`<div class=\"editor-placeholder\"></div>`;\n }\n\n return html`\n <div class=\"editor-area\">\n <docks-monaco-widget\n .value=${this.initialContent}\n .uri=${this.initialUri}\n .language=${'sql'}\n .readOnly=${this.readOnly}\n @content-change=${this._onContentChange}\n ${ref(this.widgetRef)}\n ></docks-monaco-widget>\n </div>\n `;\n }\n\n static styles = css`\n :host {\n display: flex;\n flex-direction: column;\n position: relative;\n width: 100%;\n height: 100%;\n }\n .engine-select {\n max-width: 10rem;\n }\n .connection-select {\n max-width: 12rem;\n }\n .editor-area {\n flex: 1;\n min-height: 0;\n height: 100%;\n display: flex;\n flex-direction: column;\n overflow: hidden;\n }\n .editor-area docks-monaco-widget,\n .editor-area monaco-widget {\n flex: 1;\n min-height: 0;\n }\n .editor-placeholder {\n flex: 1;\n min-height: 0;\n }\n `;\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'docks-sql-editor': DocksSqlEditor;\n }\n}\n\n","import { editorRegistry, File, type EditorInput } from '@eclipse-docks/core';\nimport { html } from '@eclipse-docks/core/externals/lit';\nimport './sql-editor';\n\nexport default function activate() {\n editorRegistry.registerEditorInputHandler({\n editorId: 'system.sqleditor',\n label: 'SQL Editor',\n icon: 'database',\n canHandle: (input: unknown) =>\n input instanceof File && input.getName().toLowerCase().endsWith('.sql'),\n ranking: 900,\n handle: async (input: File) => {\n const editorInput: EditorInput = {\n title: input.getWorkspacePath(),\n data: input,\n key: input.getWorkspacePath(),\n icon: 'database',\n state: {},\n component: () => null as any,\n };\n editorInput.component = (id: string) =>\n html`<docks-sql-editor id=\"${id}\" .input=${editorInput}></docks-sql-editor>`;\n return editorInput;\n },\n });\n}\n\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -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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"}
|