@eclipse-docks/extension-sqleditor 0.7.68
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.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +17 -0
- package/dist/index.js.map +1 -0
- package/dist/sql-api.d.ts +78 -0
- package/dist/sql-api.d.ts.map +1 -0
- package/dist/sql-editor.d.ts +51 -0
- package/dist/sql-editor.d.ts.map +1 -0
- package/dist/sql-extension-manager.d.ts +38 -0
- package/dist/sql-extension-manager.d.ts.map +1 -0
- package/dist/sqleditor-extension-CFNQ6Cj0.js +824 -0
- package/dist/sqleditor-extension-CFNQ6Cj0.js.map +1 -0
- package/dist/sqleditor-extension.d.ts +2 -0
- package/dist/sqleditor-extension.d.ts.map +1 -0
- package/package.json +33 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,YAAY,EACV,iBAAiB,EACjB,wBAAwB,EACxB,gBAAgB,EAChB,WAAW,EACX,sBAAsB,GACvB,MAAM,WAAW,CAAC;AACnB,OAAO,EAAE,mBAAmB,EAAE,MAAM,WAAW,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { extensionRegistry } from "@eclipse-docks/core";
|
|
2
|
+
import pkg from "../package.json";
|
|
3
|
+
//#region src/sql-api.ts
|
|
4
|
+
var TARGET_SQL_ADAPTERS = "system.sqladapters";
|
|
5
|
+
//#endregion
|
|
6
|
+
//#region src/index.ts
|
|
7
|
+
extensionRegistry.registerExtension({
|
|
8
|
+
id: pkg.name,
|
|
9
|
+
name: "SQL Editor",
|
|
10
|
+
description: "Generic SQL editor with pluggable backends",
|
|
11
|
+
loader: () => import("./sqleditor-extension-CFNQ6Cj0.js"),
|
|
12
|
+
icon: "database"
|
|
13
|
+
});
|
|
14
|
+
//#endregion
|
|
15
|
+
export { TARGET_SQL_ADAPTERS };
|
|
16
|
+
|
|
17
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +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"}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
export declare const TARGET_SQL_ADAPTERS = "system.sqladapters";
|
|
2
|
+
export interface SqlConnectionInfo {
|
|
3
|
+
id: string | null;
|
|
4
|
+
label: string;
|
|
5
|
+
isDefault?: boolean;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Describes a single database extension that can be managed through the SQL editor.
|
|
9
|
+
*
|
|
10
|
+
* Implementations should return the same identifiers from {@link SqlDatabase.listDbExtensions}
|
|
11
|
+
* and accept them in {@link SqlDatabase.enableDbExtension} / {@link SqlDatabase.disableDbExtension}.
|
|
12
|
+
*/
|
|
13
|
+
export interface SqlDatabaseExtensionInfo {
|
|
14
|
+
id: string;
|
|
15
|
+
label: string;
|
|
16
|
+
description?: string;
|
|
17
|
+
/**
|
|
18
|
+
* Indicates whether the extension is currently installed or enabled for the active database
|
|
19
|
+
* connection. Omit or leave false when the adapter cannot determine the installed state.
|
|
20
|
+
*/
|
|
21
|
+
installed?: boolean;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Additional adapter-specific actions that can be surfaced by the SQL editor UI.
|
|
25
|
+
*
|
|
26
|
+
* These are optional and are not used by the generic extension manager, which relies instead
|
|
27
|
+
* on the extension-related methods on {@link SqlDatabase}.
|
|
28
|
+
*/
|
|
29
|
+
export interface SqlAdapterAction {
|
|
30
|
+
id: string;
|
|
31
|
+
label: string;
|
|
32
|
+
icon?: string;
|
|
33
|
+
run(): Promise<void>;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Abstraction for a concrete SQL engine that can be used from the SQL editor.
|
|
37
|
+
*
|
|
38
|
+
* All engines must implement connection management and query execution. Extension management
|
|
39
|
+
* is optional but, when provided, follows the contract documented on the corresponding methods.
|
|
40
|
+
*/
|
|
41
|
+
export interface SqlDatabase {
|
|
42
|
+
readonly engineId: string;
|
|
43
|
+
readonly currentConnectionId: string | null;
|
|
44
|
+
listConnections(): Promise<SqlConnectionInfo[]>;
|
|
45
|
+
selectConnection(id: string | null): Promise<void>;
|
|
46
|
+
runQuery(sql: string): Promise<{
|
|
47
|
+
columns: string[];
|
|
48
|
+
rows: unknown[][];
|
|
49
|
+
}>;
|
|
50
|
+
createConnection?(): Promise<SqlConnectionInfo | null>;
|
|
51
|
+
deleteConnection?(id: string): Promise<void>;
|
|
52
|
+
extraActions?: SqlAdapterAction[];
|
|
53
|
+
/**
|
|
54
|
+
* Return the list of extensions known to this engine for the currently selected connection.
|
|
55
|
+
*
|
|
56
|
+
* The list should be stable for the active connection and use {@link SqlDatabaseExtensionInfo.installed}
|
|
57
|
+
* to mark which extensions are currently installed or enabled when that information is available.
|
|
58
|
+
*/
|
|
59
|
+
listDbExtensions?(): Promise<SqlDatabaseExtensionInfo[]>;
|
|
60
|
+
/**
|
|
61
|
+
* Ensure that the extension identified by {@link SqlDatabaseExtensionInfo.id} is installed
|
|
62
|
+
* and enabled for the current connection. It is safe for implementations to be idempotent.
|
|
63
|
+
*/
|
|
64
|
+
enableDbExtension?(id: string): Promise<void>;
|
|
65
|
+
/**
|
|
66
|
+
* Disable or uninstall the given extension for the current connection, if the engine supports it.
|
|
67
|
+
* Adapters that cannot disable extensions should omit this method entirely.
|
|
68
|
+
*/
|
|
69
|
+
disableDbExtension?(id: string): Promise<void>;
|
|
70
|
+
close(): Promise<void> | void;
|
|
71
|
+
}
|
|
72
|
+
export interface SqlAdapterContribution {
|
|
73
|
+
id: string;
|
|
74
|
+
label: string;
|
|
75
|
+
icon?: string;
|
|
76
|
+
loader: () => Promise<SqlDatabase>;
|
|
77
|
+
}
|
|
78
|
+
//# sourceMappingURL=sql-api.d.ts.map
|
|
@@ -0,0 +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"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { DocksPart, EditorInput, EditorContentProvider } from '@eclipse-docks/core';
|
|
2
|
+
export declare class DocksSqlEditor extends DocksPart implements EditorContentProvider {
|
|
3
|
+
input?: EditorInput;
|
|
4
|
+
readOnly: boolean;
|
|
5
|
+
private initialContent;
|
|
6
|
+
private initialUri;
|
|
7
|
+
private running;
|
|
8
|
+
private availableAdapters;
|
|
9
|
+
private selectedEngineId;
|
|
10
|
+
private availableConnections;
|
|
11
|
+
private selectedConnectionId;
|
|
12
|
+
private widgetRef;
|
|
13
|
+
private databases;
|
|
14
|
+
private unsubscribeContributionsToken?;
|
|
15
|
+
protected doInitUI(): Promise<void>;
|
|
16
|
+
private refreshAdapters;
|
|
17
|
+
private getOrLoadDatabase;
|
|
18
|
+
private refreshConnections;
|
|
19
|
+
private onEngineChange;
|
|
20
|
+
private onConnectionChange;
|
|
21
|
+
private onEngineDropdownSelect;
|
|
22
|
+
private onConnectionDropdownSelect;
|
|
23
|
+
private deleteConnectionById;
|
|
24
|
+
private _onContentChange;
|
|
25
|
+
save(): void;
|
|
26
|
+
protected doClose(): Promise<void>;
|
|
27
|
+
getLanguage(): string | null;
|
|
28
|
+
isLanguage(lang: string): boolean;
|
|
29
|
+
getContent(): string | null;
|
|
30
|
+
getSelection(): string | null;
|
|
31
|
+
getSnippet(lines?: number): {
|
|
32
|
+
snippet: string;
|
|
33
|
+
cursorLine: number;
|
|
34
|
+
} | null;
|
|
35
|
+
getFilePath(): string | null;
|
|
36
|
+
private runQuery;
|
|
37
|
+
private clearRunningState;
|
|
38
|
+
private createConnection;
|
|
39
|
+
private deleteConnection;
|
|
40
|
+
private getCurrentConnectionLabel;
|
|
41
|
+
private openExtensionManager;
|
|
42
|
+
protected renderToolbar(): import('lit-html').TemplateResult<1>;
|
|
43
|
+
protected renderContent(): import('lit-html').TemplateResult<1>;
|
|
44
|
+
static styles: import('lit').CSSResult;
|
|
45
|
+
}
|
|
46
|
+
declare global {
|
|
47
|
+
interface HTMLElementTagNameMap {
|
|
48
|
+
'docks-sql-editor': DocksSqlEditor;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
//# sourceMappingURL=sql-editor.d.ts.map
|
|
@@ -0,0 +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;AAmBtO,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"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { LitElement } from 'lit';
|
|
2
|
+
import { SqlDatabase } from '@eclipse-docks/extension-sqleditor';
|
|
3
|
+
export interface SqlExtensionManagerOptions {
|
|
4
|
+
db: SqlDatabase | null;
|
|
5
|
+
databaseLabel: string;
|
|
6
|
+
}
|
|
7
|
+
export declare class DocksSqlExtensionManager extends LitElement {
|
|
8
|
+
open: boolean;
|
|
9
|
+
db: SqlDatabase | null;
|
|
10
|
+
databaseLabel: string;
|
|
11
|
+
private extensions;
|
|
12
|
+
private loading;
|
|
13
|
+
private updatingId;
|
|
14
|
+
private error;
|
|
15
|
+
private filterText;
|
|
16
|
+
configure(options: SqlExtensionManagerOptions): void;
|
|
17
|
+
show(): void;
|
|
18
|
+
hide(): void;
|
|
19
|
+
private refreshExtensions;
|
|
20
|
+
private enableExtension;
|
|
21
|
+
private disableExtension;
|
|
22
|
+
private renderExtensionRow;
|
|
23
|
+
render(): import('lit-html').TemplateResult<1>;
|
|
24
|
+
static styles: import('lit').CSSResult;
|
|
25
|
+
}
|
|
26
|
+
declare class SqlExtensionManagerService {
|
|
27
|
+
private managerInstance;
|
|
28
|
+
showExtensionManager(options: SqlExtensionManagerOptions): DocksSqlExtensionManager | null;
|
|
29
|
+
getManager(): DocksSqlExtensionManager | null;
|
|
30
|
+
}
|
|
31
|
+
export declare const sqlExtensionManagerService: SqlExtensionManagerService;
|
|
32
|
+
declare global {
|
|
33
|
+
interface HTMLElementTagNameMap {
|
|
34
|
+
'docks-sql-extension-manager': DocksSqlExtensionManager;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
export {};
|
|
38
|
+
//# sourceMappingURL=sql-extension-manager.d.ts.map
|
|
@@ -0,0 +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,EACV,WAAW,EAEZ,MAAM,oCAAoC,CAAC;AAE5C,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"}
|
|
@@ -0,0 +1,824 @@
|
|
|
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";
|
|
6
|
+
import _decorate from "@oxc-project/runtime/helpers/decorate";
|
|
7
|
+
import { createRef, ref } from "lit/directives/ref.js";
|
|
8
|
+
//#region src/sql-extension-manager.ts
|
|
9
|
+
var DocksSqlExtensionManager = class DocksSqlExtensionManager extends LitElement {
|
|
10
|
+
constructor(..._args) {
|
|
11
|
+
super(..._args);
|
|
12
|
+
this.open = false;
|
|
13
|
+
this.db = null;
|
|
14
|
+
this.databaseLabel = "";
|
|
15
|
+
this.extensions = [];
|
|
16
|
+
this.loading = false;
|
|
17
|
+
this.updatingId = null;
|
|
18
|
+
this.error = null;
|
|
19
|
+
this.filterText = "";
|
|
20
|
+
}
|
|
21
|
+
configure(options) {
|
|
22
|
+
this.db = options.db;
|
|
23
|
+
this.databaseLabel = options.databaseLabel;
|
|
24
|
+
this.extensions = [];
|
|
25
|
+
this.error = null;
|
|
26
|
+
this.refreshExtensions();
|
|
27
|
+
}
|
|
28
|
+
show() {
|
|
29
|
+
if (!this.db || !this.db.listDbExtensions) return;
|
|
30
|
+
this.open = true;
|
|
31
|
+
}
|
|
32
|
+
hide() {
|
|
33
|
+
this.open = false;
|
|
34
|
+
}
|
|
35
|
+
async refreshExtensions() {
|
|
36
|
+
if (!this.db || !this.db.listDbExtensions) {
|
|
37
|
+
this.extensions = [];
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
this.loading = true;
|
|
41
|
+
this.error = null;
|
|
42
|
+
try {
|
|
43
|
+
const result = await taskService.runAsync("Loading database extensions", async () => this.db.listDbExtensions());
|
|
44
|
+
this.extensions = Array.isArray(result) ? result : [];
|
|
45
|
+
} catch (err) {
|
|
46
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
47
|
+
this.error = msg;
|
|
48
|
+
toastError(msg);
|
|
49
|
+
} finally {
|
|
50
|
+
this.loading = false;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
async enableExtension(ext) {
|
|
54
|
+
if (!this.db || !this.db.enableDbExtension) return;
|
|
55
|
+
this.updatingId = ext.id;
|
|
56
|
+
this.error = null;
|
|
57
|
+
try {
|
|
58
|
+
await taskService.runAsync(`Enabling extension ${ext.label || ext.id}`, async () => this.db.enableDbExtension(ext.id));
|
|
59
|
+
await this.refreshExtensions();
|
|
60
|
+
} catch (err) {
|
|
61
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
62
|
+
this.error = msg;
|
|
63
|
+
toastError(msg);
|
|
64
|
+
} finally {
|
|
65
|
+
this.updatingId = null;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
async disableExtension(ext) {
|
|
69
|
+
if (!this.db || !this.db.disableDbExtension) return;
|
|
70
|
+
this.updatingId = ext.id;
|
|
71
|
+
this.error = null;
|
|
72
|
+
try {
|
|
73
|
+
await taskService.runAsync(`Disabling extension ${ext.label || ext.id}`, async () => this.db.disableDbExtension(ext.id));
|
|
74
|
+
await this.refreshExtensions();
|
|
75
|
+
} catch (err) {
|
|
76
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
77
|
+
this.error = msg;
|
|
78
|
+
toastError(msg);
|
|
79
|
+
} finally {
|
|
80
|
+
this.updatingId = null;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
renderExtensionRow(ext) {
|
|
84
|
+
const installed = Boolean(ext.installed);
|
|
85
|
+
const canDisable = installed && !!this.db?.disableDbExtension;
|
|
86
|
+
const isUpdating = this.updatingId === ext.id;
|
|
87
|
+
return html$1`
|
|
88
|
+
<div class="extension-item">
|
|
89
|
+
<div class="extension-main">
|
|
90
|
+
<div class="extension-name">${ext.label || ext.id}</div>
|
|
91
|
+
${ext.description ? html$1`<div class="extension-desc">${ext.description}</div>` : null}
|
|
92
|
+
</div>
|
|
93
|
+
<div class="extension-meta">
|
|
94
|
+
<span
|
|
95
|
+
class=${installed ? "badge badge-installed" : "badge badge-available"}
|
|
96
|
+
>
|
|
97
|
+
${installed ? "Installed" : "Available"}
|
|
98
|
+
</span>
|
|
99
|
+
<div class="extension-actions">
|
|
100
|
+
${installed ? html$1`
|
|
101
|
+
<wa-button
|
|
102
|
+
size="small"
|
|
103
|
+
appearance="plain"
|
|
104
|
+
?disabled=${!canDisable || isUpdating}
|
|
105
|
+
@click=${() => void this.disableExtension(ext)}
|
|
106
|
+
>
|
|
107
|
+
<wa-icon
|
|
108
|
+
name="circle-minus"
|
|
109
|
+
label="Disable"
|
|
110
|
+
></wa-icon>
|
|
111
|
+
</wa-button>
|
|
112
|
+
` : html$1`
|
|
113
|
+
<wa-button
|
|
114
|
+
size="small"
|
|
115
|
+
appearance="plain"
|
|
116
|
+
?disabled=${isUpdating}
|
|
117
|
+
@click=${() => void this.enableExtension(ext)}
|
|
118
|
+
>
|
|
119
|
+
<wa-icon
|
|
120
|
+
name="plug-circle-plus"
|
|
121
|
+
label="Enable"
|
|
122
|
+
></wa-icon>
|
|
123
|
+
</wa-button>
|
|
124
|
+
`}
|
|
125
|
+
</div>
|
|
126
|
+
</div>
|
|
127
|
+
</div>
|
|
128
|
+
`;
|
|
129
|
+
}
|
|
130
|
+
render() {
|
|
131
|
+
const hasDb = Boolean(this.db && this.db.listDbExtensions);
|
|
132
|
+
const filter = this.filterText.trim().toLowerCase();
|
|
133
|
+
const filteredExtensions = !filter ? this.extensions : this.extensions.filter((ext) => {
|
|
134
|
+
return `${ext.label ?? ""} ${ext.id} ${ext.description ?? ""}`.toLowerCase().includes(filter);
|
|
135
|
+
});
|
|
136
|
+
const hasItems = filteredExtensions.length > 0;
|
|
137
|
+
return html$1`
|
|
138
|
+
<wa-dialog
|
|
139
|
+
label="Database extensions"
|
|
140
|
+
?open=${this.open}
|
|
141
|
+
@wa-after-hide=${() => {
|
|
142
|
+
this.open = false;
|
|
143
|
+
this.dispatchEvent(new CustomEvent("hide", {
|
|
144
|
+
bubbles: true,
|
|
145
|
+
composed: true
|
|
146
|
+
}));
|
|
147
|
+
}}
|
|
148
|
+
>
|
|
149
|
+
<div class="extension-manager">
|
|
150
|
+
<p class="extension-manager-description">
|
|
151
|
+
Database:
|
|
152
|
+
<strong>${this.databaseLabel || "Current connection"}</strong>
|
|
153
|
+
</p>
|
|
154
|
+
|
|
155
|
+
${!hasDb ? html$1`
|
|
156
|
+
<wa-alert variant="warning" open>
|
|
157
|
+
<wa-icon slot="icon" name="triangle-exclamation"></wa-icon>
|
|
158
|
+
The current SQL engine does not expose any extension information.
|
|
159
|
+
</wa-alert>
|
|
160
|
+
` : null}
|
|
161
|
+
|
|
162
|
+
${this.error ? html$1`
|
|
163
|
+
<wa-alert
|
|
164
|
+
variant="danger"
|
|
165
|
+
open
|
|
166
|
+
closable
|
|
167
|
+
@wa-after-hide=${() => {
|
|
168
|
+
this.error = null;
|
|
169
|
+
}}
|
|
170
|
+
>
|
|
171
|
+
<wa-icon slot="icon" name="circle-exclamation"></wa-icon>
|
|
172
|
+
${this.error}
|
|
173
|
+
</wa-alert>
|
|
174
|
+
` : null}
|
|
175
|
+
|
|
176
|
+
<wa-input
|
|
177
|
+
size="small"
|
|
178
|
+
placeholder="Filter extensions…"
|
|
179
|
+
.value=${this.filterText}
|
|
180
|
+
@input=${(event) => {
|
|
181
|
+
this.filterText = event.target?.value ?? "";
|
|
182
|
+
}}
|
|
183
|
+
@wa-clear=${() => {
|
|
184
|
+
this.filterText = "";
|
|
185
|
+
}}
|
|
186
|
+
with-clear
|
|
187
|
+
>
|
|
188
|
+
<wa-icon slot="prefix" name="magnifying-glass"></wa-icon>
|
|
189
|
+
</wa-input>
|
|
190
|
+
|
|
191
|
+
<div class="extension-list">
|
|
192
|
+
${this.loading ? html$1`<div class="extension-list-empty">Loading extensions…</div>` : !hasItems ? html$1`
|
|
193
|
+
<div class="extension-list-empty">
|
|
194
|
+
No extensions available for this connection.
|
|
195
|
+
</div>
|
|
196
|
+
` : repeat(filteredExtensions, (ext) => ext.id, (ext) => this.renderExtensionRow(ext))}
|
|
197
|
+
</div>
|
|
198
|
+
</div>
|
|
199
|
+
<div slot="footer" class="extension-manager-footer">
|
|
200
|
+
<wa-button variant="default" @click=${() => this.hide()}>
|
|
201
|
+
Close
|
|
202
|
+
</wa-button>
|
|
203
|
+
</div>
|
|
204
|
+
</wa-dialog>
|
|
205
|
+
`;
|
|
206
|
+
}
|
|
207
|
+
static {
|
|
208
|
+
this.styles = css`
|
|
209
|
+
:host {
|
|
210
|
+
display: contents;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
.extension-manager {
|
|
214
|
+
display: flex;
|
|
215
|
+
flex-direction: column;
|
|
216
|
+
gap: 1rem;
|
|
217
|
+
padding: 1rem;
|
|
218
|
+
height: 420px;
|
|
219
|
+
box-sizing: border-box;
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
.extension-toolbar {
|
|
223
|
+
display: flex;
|
|
224
|
+
justify-content: flex-end;
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
.extension-manager-description {
|
|
228
|
+
margin: 0;
|
|
229
|
+
font-size: 0.95rem;
|
|
230
|
+
opacity: 0.9;
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
.extension-list {
|
|
234
|
+
display: flex;
|
|
235
|
+
flex-direction: column;
|
|
236
|
+
gap: 0.5rem;
|
|
237
|
+
flex: 1;
|
|
238
|
+
min-height: 0;
|
|
239
|
+
max-height: 100%;
|
|
240
|
+
overflow-y: auto;
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
.extension-list-empty {
|
|
244
|
+
font-size: 0.9rem;
|
|
245
|
+
opacity: 0.8;
|
|
246
|
+
padding: 0.5rem 0;
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
.extension-item {
|
|
250
|
+
display: flex;
|
|
251
|
+
align-items: flex-start;
|
|
252
|
+
justify-content: space-between;
|
|
253
|
+
gap: 0.75rem;
|
|
254
|
+
padding: 0.5rem 0;
|
|
255
|
+
border-bottom: 1px solid var(--wa-color-neutral-200, #e5e7eb);
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
.extension-main {
|
|
259
|
+
display: flex;
|
|
260
|
+
flex-direction: column;
|
|
261
|
+
gap: 0.15rem;
|
|
262
|
+
min-width: 0;
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
.extension-name {
|
|
266
|
+
font-weight: 500;
|
|
267
|
+
font-size: 0.95rem;
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
.extension-desc {
|
|
271
|
+
font-size: 0.85rem;
|
|
272
|
+
opacity: 0.8;
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
.extension-meta {
|
|
276
|
+
display: flex;
|
|
277
|
+
flex-direction: column;
|
|
278
|
+
align-items: flex-end;
|
|
279
|
+
gap: 0.35rem;
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
.extension-actions {
|
|
283
|
+
display: flex;
|
|
284
|
+
gap: 0.25rem;
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
.badge {
|
|
288
|
+
display: inline-flex;
|
|
289
|
+
align-items: center;
|
|
290
|
+
padding: 0.15rem 0.4rem;
|
|
291
|
+
border-radius: 999px;
|
|
292
|
+
font-size: 0.75rem;
|
|
293
|
+
border: 1px solid var(--wa-color-neutral-200, #e5e7eb);
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
.badge-installed {
|
|
297
|
+
background-color: var(--wa-color-success-50, #ecfdf3);
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
.badge-available {
|
|
301
|
+
background-color: var(--wa-color-neutral-50, #f9fafb);
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
.extension-manager-footer {
|
|
305
|
+
display: flex;
|
|
306
|
+
justify-content: flex-end;
|
|
307
|
+
padding-top: 1rem;
|
|
308
|
+
border-top: 1px solid var(--wa-color-neutral-200, #e5e7eb);
|
|
309
|
+
}
|
|
310
|
+
`;
|
|
311
|
+
}
|
|
312
|
+
};
|
|
313
|
+
_decorate([property({ type: Boolean })], DocksSqlExtensionManager.prototype, "open", void 0);
|
|
314
|
+
_decorate([property({ attribute: false })], DocksSqlExtensionManager.prototype, "db", void 0);
|
|
315
|
+
_decorate([property()], DocksSqlExtensionManager.prototype, "databaseLabel", void 0);
|
|
316
|
+
_decorate([state()], DocksSqlExtensionManager.prototype, "extensions", void 0);
|
|
317
|
+
_decorate([state()], DocksSqlExtensionManager.prototype, "loading", void 0);
|
|
318
|
+
_decorate([state()], DocksSqlExtensionManager.prototype, "updatingId", void 0);
|
|
319
|
+
_decorate([state()], DocksSqlExtensionManager.prototype, "error", void 0);
|
|
320
|
+
_decorate([state()], DocksSqlExtensionManager.prototype, "filterText", void 0);
|
|
321
|
+
DocksSqlExtensionManager = _decorate([customElement("docks-sql-extension-manager")], DocksSqlExtensionManager);
|
|
322
|
+
var SqlExtensionManagerService = class {
|
|
323
|
+
constructor() {
|
|
324
|
+
this.managerInstance = null;
|
|
325
|
+
}
|
|
326
|
+
showExtensionManager(options) {
|
|
327
|
+
if (!options.db || !options.db.listDbExtensions) {
|
|
328
|
+
toastError("The current SQL engine does not support extensions.");
|
|
329
|
+
return null;
|
|
330
|
+
}
|
|
331
|
+
if (!this.managerInstance) {
|
|
332
|
+
this.managerInstance = document.createElement("docks-sql-extension-manager");
|
|
333
|
+
document.body.appendChild(this.managerInstance);
|
|
334
|
+
}
|
|
335
|
+
this.managerInstance.configure(options);
|
|
336
|
+
this.managerInstance.show();
|
|
337
|
+
return this.managerInstance;
|
|
338
|
+
}
|
|
339
|
+
getManager() {
|
|
340
|
+
return this.managerInstance;
|
|
341
|
+
}
|
|
342
|
+
};
|
|
343
|
+
var sqlExtensionManagerService = new SqlExtensionManagerService();
|
|
344
|
+
rootContext.put("sqlExtensionManagerService", sqlExtensionManagerService);
|
|
345
|
+
//#endregion
|
|
346
|
+
//#region src/sql-editor.ts
|
|
347
|
+
var MAX_TAB_LABEL = 28;
|
|
348
|
+
function truncateLabel(sql) {
|
|
349
|
+
const oneLine = sql.replace(/\s+/g, " ").trim();
|
|
350
|
+
if (oneLine.length <= MAX_TAB_LABEL) return oneLine;
|
|
351
|
+
return `${oneLine.slice(0, MAX_TAB_LABEL)}…`;
|
|
352
|
+
}
|
|
353
|
+
var DocksSqlEditor = class DocksSqlEditor extends DocksPart {
|
|
354
|
+
constructor(..._args) {
|
|
355
|
+
super(..._args);
|
|
356
|
+
this.readOnly = false;
|
|
357
|
+
this.initialContent = void 0;
|
|
358
|
+
this.initialUri = void 0;
|
|
359
|
+
this.running = false;
|
|
360
|
+
this.availableAdapters = [];
|
|
361
|
+
this.selectedEngineId = null;
|
|
362
|
+
this.availableConnections = [];
|
|
363
|
+
this.selectedConnectionId = null;
|
|
364
|
+
this.widgetRef = createRef();
|
|
365
|
+
this.databases = /* @__PURE__ */ new Map();
|
|
366
|
+
this._onContentChange = () => {
|
|
367
|
+
this.markDirty(true);
|
|
368
|
+
};
|
|
369
|
+
}
|
|
370
|
+
async doInitUI() {
|
|
371
|
+
const file = this.input.data;
|
|
372
|
+
this.initialContent = await file.getContents();
|
|
373
|
+
this.initialUri = file.getWorkspacePath();
|
|
374
|
+
this.unsubscribeContributionsToken = subscribe(TOPIC_CONTRIBUTEIONS_CHANGED, (event) => {
|
|
375
|
+
if (event?.target === "system.sqladapters") this.refreshAdapters();
|
|
376
|
+
});
|
|
377
|
+
await this.refreshAdapters();
|
|
378
|
+
this.requestUpdate();
|
|
379
|
+
}
|
|
380
|
+
async refreshAdapters() {
|
|
381
|
+
const contributions = contributionRegistry.getContributions("system.sqladapters");
|
|
382
|
+
this.availableAdapters = contributions;
|
|
383
|
+
if (!contributions.length) {
|
|
384
|
+
this.selectedEngineId = null;
|
|
385
|
+
this.availableConnections = [];
|
|
386
|
+
this.selectedConnectionId = null;
|
|
387
|
+
await this.updateComplete;
|
|
388
|
+
return;
|
|
389
|
+
}
|
|
390
|
+
if (!this.selectedEngineId) this.selectedEngineId = (contributions.find((c) => c.id === "duckdb") ?? contributions[0]).id;
|
|
391
|
+
this.requestUpdate();
|
|
392
|
+
await this.refreshConnections();
|
|
393
|
+
await this.updateComplete;
|
|
394
|
+
}
|
|
395
|
+
async getOrLoadDatabase(engineId) {
|
|
396
|
+
const cached = this.databases.get(engineId);
|
|
397
|
+
if (cached) return cached;
|
|
398
|
+
const adapter = this.availableAdapters.find((c) => c.id === engineId);
|
|
399
|
+
if (!adapter) return null;
|
|
400
|
+
try {
|
|
401
|
+
const label = adapter.label || adapter.id;
|
|
402
|
+
const database = await taskService.runAsync(`Opening ${label} database`, async (progress) => {
|
|
403
|
+
progress.message = `Connecting to ${label}…`;
|
|
404
|
+
return adapter.loader();
|
|
405
|
+
});
|
|
406
|
+
this.databases.set(engineId, database);
|
|
407
|
+
return database;
|
|
408
|
+
} catch (err) {
|
|
409
|
+
toastError(err instanceof Error ? err.message : String(err));
|
|
410
|
+
return null;
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
async refreshConnections() {
|
|
414
|
+
const engineId = this.selectedEngineId;
|
|
415
|
+
if (!engineId) {
|
|
416
|
+
this.availableConnections = [];
|
|
417
|
+
this.selectedConnectionId = null;
|
|
418
|
+
await this.updateComplete;
|
|
419
|
+
return;
|
|
420
|
+
}
|
|
421
|
+
const db = await this.getOrLoadDatabase(engineId);
|
|
422
|
+
if (!db) {
|
|
423
|
+
this.availableConnections = [];
|
|
424
|
+
this.selectedConnectionId = null;
|
|
425
|
+
await this.updateComplete;
|
|
426
|
+
return;
|
|
427
|
+
}
|
|
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;
|
|
435
|
+
}
|
|
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;
|
|
440
|
+
}
|
|
441
|
+
async onEngineChange(e) {
|
|
442
|
+
const value = e.target?.value ?? "";
|
|
443
|
+
if (this.selectedEngineId === value) return;
|
|
444
|
+
this.selectedEngineId = value || null;
|
|
445
|
+
await this.refreshConnections();
|
|
446
|
+
this.requestUpdate();
|
|
447
|
+
}
|
|
448
|
+
async onConnectionChange(e) {
|
|
449
|
+
const value = e.target?.value ?? "";
|
|
450
|
+
const next = value === "" ? null : value;
|
|
451
|
+
if (this.selectedConnectionId === next) return;
|
|
452
|
+
this.selectedConnectionId = next;
|
|
453
|
+
const engineId = this.selectedEngineId;
|
|
454
|
+
if (!engineId) return;
|
|
455
|
+
const db = await this.getOrLoadDatabase(engineId);
|
|
456
|
+
if (!db) return;
|
|
457
|
+
await db.selectConnection(next);
|
|
458
|
+
this.requestUpdate();
|
|
459
|
+
}
|
|
460
|
+
async onEngineDropdownSelect(e) {
|
|
461
|
+
const value = e.detail?.item?.value ?? "";
|
|
462
|
+
if (this.selectedEngineId === value) return;
|
|
463
|
+
this.selectedEngineId = value || null;
|
|
464
|
+
await this.refreshConnections();
|
|
465
|
+
this.requestUpdate();
|
|
466
|
+
}
|
|
467
|
+
async onConnectionDropdownSelect(e) {
|
|
468
|
+
const value = e.detail?.item?.value ?? "";
|
|
469
|
+
const next = value === "" ? null : value;
|
|
470
|
+
if (this.selectedConnectionId === next) return;
|
|
471
|
+
this.selectedConnectionId = next;
|
|
472
|
+
const engineId = this.selectedEngineId;
|
|
473
|
+
if (!engineId) return;
|
|
474
|
+
const db = await this.getOrLoadDatabase(engineId);
|
|
475
|
+
if (!db) return;
|
|
476
|
+
await db.selectConnection(next);
|
|
477
|
+
this.requestUpdate();
|
|
478
|
+
}
|
|
479
|
+
async deleteConnectionById(e, id) {
|
|
480
|
+
e.stopPropagation();
|
|
481
|
+
e.preventDefault();
|
|
482
|
+
const engineId = this.selectedEngineId;
|
|
483
|
+
if (!engineId) return;
|
|
484
|
+
const db = await this.getOrLoadDatabase(engineId);
|
|
485
|
+
if (!db || !db.deleteConnection) return;
|
|
486
|
+
if (!await confirmDialog(`Delete connection "${this.availableConnections.find((info) => info.id === id)?.label ?? (id === null ? "In-memory" : id ?? "Current connection")}"?`)) return;
|
|
487
|
+
if (id !== null) await db.deleteConnection(id);
|
|
488
|
+
else await db.selectConnection(null);
|
|
489
|
+
await this.refreshConnections();
|
|
490
|
+
this.requestUpdate();
|
|
491
|
+
}
|
|
492
|
+
save() {
|
|
493
|
+
const value = this.widgetRef.value?.getContent() ?? "";
|
|
494
|
+
this.input?.data.saveContents(value);
|
|
495
|
+
this.markDirty(false);
|
|
496
|
+
}
|
|
497
|
+
async doClose() {
|
|
498
|
+
if (this.unsubscribeContributionsToken) {
|
|
499
|
+
unsubscribe(this.unsubscribeContributionsToken);
|
|
500
|
+
this.unsubscribeContributionsToken = void 0;
|
|
501
|
+
}
|
|
502
|
+
this.widgetRef.value?.dispose();
|
|
503
|
+
for (const db of this.databases.values()) await db.close();
|
|
504
|
+
this.databases.clear();
|
|
505
|
+
}
|
|
506
|
+
getLanguage() {
|
|
507
|
+
return "sql";
|
|
508
|
+
}
|
|
509
|
+
isLanguage(lang) {
|
|
510
|
+
return lang.toLowerCase() === "sql";
|
|
511
|
+
}
|
|
512
|
+
getContent() {
|
|
513
|
+
return this.widgetRef.value?.getContent() ?? null;
|
|
514
|
+
}
|
|
515
|
+
getSelection() {
|
|
516
|
+
return this.widgetRef.value?.getSelection() ?? null;
|
|
517
|
+
}
|
|
518
|
+
getSnippet(lines = 5) {
|
|
519
|
+
return this.widgetRef.value?.getSnippet(lines) ?? null;
|
|
520
|
+
}
|
|
521
|
+
getFilePath() {
|
|
522
|
+
return this.input?.data?.getWorkspacePath() ?? null;
|
|
523
|
+
}
|
|
524
|
+
async runQuery(useSelectionOnly = false) {
|
|
525
|
+
const selection = this.getSelection()?.trim();
|
|
526
|
+
const content = this.getContent()?.trim();
|
|
527
|
+
const sql = useSelectionOnly ? selection : content;
|
|
528
|
+
if (!sql) {
|
|
529
|
+
toastError(useSelectionOnly ? "No selection to run" : "No SQL to run");
|
|
530
|
+
return;
|
|
531
|
+
}
|
|
532
|
+
if (this.running) return;
|
|
533
|
+
const engineId = this.selectedEngineId;
|
|
534
|
+
if (!engineId) {
|
|
535
|
+
toastError("No SQL engine available");
|
|
536
|
+
return;
|
|
537
|
+
}
|
|
538
|
+
const db = await this.getOrLoadDatabase(engineId);
|
|
539
|
+
if (!db) {
|
|
540
|
+
toastError("Could not initialize SQL engine");
|
|
541
|
+
return;
|
|
542
|
+
}
|
|
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);
|
|
547
|
+
}
|
|
548
|
+
this.running = true;
|
|
549
|
+
const label = truncateLabel(sql);
|
|
550
|
+
this.requestUpdate();
|
|
551
|
+
const timeoutId = window.setTimeout(() => this.clearRunningState(), 6e4);
|
|
552
|
+
try {
|
|
553
|
+
const result = await db.runQuery(sql);
|
|
554
|
+
const adapter = this.availableAdapters.find((c) => c.id === engineId);
|
|
555
|
+
publish("dataview/publish", {
|
|
556
|
+
title: label,
|
|
557
|
+
data: {
|
|
558
|
+
columns: result.columns,
|
|
559
|
+
rows: result.rows
|
|
560
|
+
},
|
|
561
|
+
source: adapter?.label ?? engineId
|
|
562
|
+
});
|
|
563
|
+
} catch (err) {
|
|
564
|
+
toastError(err instanceof Error ? err.message : String(err));
|
|
565
|
+
} finally {
|
|
566
|
+
window.clearTimeout(timeoutId);
|
|
567
|
+
this.running = false;
|
|
568
|
+
this.requestUpdate();
|
|
569
|
+
}
|
|
570
|
+
}
|
|
571
|
+
clearRunningState() {
|
|
572
|
+
if (!this.running) return;
|
|
573
|
+
this.running = false;
|
|
574
|
+
this.requestUpdate();
|
|
575
|
+
}
|
|
576
|
+
async createConnection() {
|
|
577
|
+
const engineId = this.selectedEngineId;
|
|
578
|
+
if (!engineId) return;
|
|
579
|
+
const db = await this.getOrLoadDatabase(engineId);
|
|
580
|
+
if (!db || !db.createConnection) return;
|
|
581
|
+
const info = await db.createConnection();
|
|
582
|
+
if (!info) return;
|
|
583
|
+
await this.refreshConnections();
|
|
584
|
+
this.selectedConnectionId = info.id;
|
|
585
|
+
await db.selectConnection(info.id ?? null);
|
|
586
|
+
toastInfo(`Connection "${info.label}" created`);
|
|
587
|
+
this.requestUpdate();
|
|
588
|
+
}
|
|
589
|
+
async deleteConnection() {
|
|
590
|
+
const engineId = this.selectedEngineId;
|
|
591
|
+
if (!engineId) return;
|
|
592
|
+
const db = await this.getOrLoadDatabase(engineId);
|
|
593
|
+
if (!db || !db.deleteConnection) return;
|
|
594
|
+
const id = this.selectedConnectionId;
|
|
595
|
+
if (!await confirmDialog(`Delete connection "${this.availableConnections.find((info) => info.id === id)?.label ?? (id === null ? "In-memory" : id ?? "Current connection")}"?`)) return;
|
|
596
|
+
if (id !== null) await db.deleteConnection(id);
|
|
597
|
+
else await db.selectConnection(null);
|
|
598
|
+
await this.refreshConnections();
|
|
599
|
+
this.requestUpdate();
|
|
600
|
+
}
|
|
601
|
+
getCurrentConnectionLabel() {
|
|
602
|
+
const id = this.selectedConnectionId;
|
|
603
|
+
if (id === null) return "In-memory";
|
|
604
|
+
if (!id) return null;
|
|
605
|
+
return this.availableConnections.find((c) => c.id === id)?.label ?? id;
|
|
606
|
+
}
|
|
607
|
+
async openExtensionManager() {
|
|
608
|
+
const engineId = this.selectedEngineId;
|
|
609
|
+
if (!engineId) return;
|
|
610
|
+
const db = await this.getOrLoadDatabase(engineId);
|
|
611
|
+
if (!db || !db.listDbExtensions) {
|
|
612
|
+
toastInfo("Extensions are not available for the selected SQL engine.");
|
|
613
|
+
return;
|
|
614
|
+
}
|
|
615
|
+
const engineLabel = (this.availableAdapters.find((c) => c.id === engineId) ?? null)?.label ?? engineId;
|
|
616
|
+
const connectionLabel = this.getCurrentConnectionLabel();
|
|
617
|
+
const databaseLabel = connectionLabel ? `${engineLabel} – ${connectionLabel}` : engineLabel;
|
|
618
|
+
sqlExtensionManagerService.showExtensionManager({
|
|
619
|
+
db,
|
|
620
|
+
databaseLabel
|
|
621
|
+
});
|
|
622
|
+
}
|
|
623
|
+
renderToolbar() {
|
|
624
|
+
const adapters = this.availableAdapters;
|
|
625
|
+
const hasEngines = adapters.length > 0;
|
|
626
|
+
const hasConnections = this.availableConnections.length > 0;
|
|
627
|
+
const engineId = this.selectedEngineId;
|
|
628
|
+
const dbForEngine = engineId ? this.databases.get(engineId) : null;
|
|
629
|
+
const supportsExtensions = Boolean(dbForEngine?.listDbExtensions);
|
|
630
|
+
return html$1`
|
|
631
|
+
<wa-dropdown
|
|
632
|
+
class="engine-select"
|
|
633
|
+
placement="bottom-start"
|
|
634
|
+
distance="4"
|
|
635
|
+
size="small"
|
|
636
|
+
@wa-select=${(e) => void this.onEngineDropdownSelect(e)}
|
|
637
|
+
>
|
|
638
|
+
<wa-button
|
|
639
|
+
slot="trigger"
|
|
640
|
+
appearance="plain"
|
|
641
|
+
size="small"
|
|
642
|
+
with-caret
|
|
643
|
+
title="SQL engine"
|
|
644
|
+
>
|
|
645
|
+
${this.selectedEngineId ? adapters.find((a) => a.id === this.selectedEngineId)?.label ?? this.selectedEngineId : "Select engine"}
|
|
646
|
+
</wa-button>
|
|
647
|
+
${adapters.map((adapter) => html$1`
|
|
648
|
+
<wa-dropdown-item
|
|
649
|
+
value=${adapter.id}
|
|
650
|
+
type="checkbox"
|
|
651
|
+
?checked=${adapter.id === this.selectedEngineId}
|
|
652
|
+
>
|
|
653
|
+
${adapter.label}
|
|
654
|
+
</wa-dropdown-item>
|
|
655
|
+
`)}
|
|
656
|
+
</wa-dropdown>
|
|
657
|
+
<wa-dropdown
|
|
658
|
+
class="connection-select"
|
|
659
|
+
placement="bottom-start"
|
|
660
|
+
distance="4"
|
|
661
|
+
size="small"
|
|
662
|
+
@wa-select=${(e) => void this.onConnectionDropdownSelect(e)}
|
|
663
|
+
>
|
|
664
|
+
<wa-button
|
|
665
|
+
slot="trigger"
|
|
666
|
+
appearance="plain"
|
|
667
|
+
size="small"
|
|
668
|
+
with-caret
|
|
669
|
+
title="Connection"
|
|
670
|
+
?disabled=${!hasEngines || !hasConnections}
|
|
671
|
+
>
|
|
672
|
+
${this.selectedConnectionId === null ? "In-memory" : this.availableConnections.find((c) => c.id === this.selectedConnectionId)?.label ?? "Select connection"}
|
|
673
|
+
</wa-button>
|
|
674
|
+
${this.availableConnections.map((info) => html$1`
|
|
675
|
+
<wa-dropdown-item
|
|
676
|
+
value=${info.id ?? ""}
|
|
677
|
+
type="checkbox"
|
|
678
|
+
?checked=${info.id === this.selectedConnectionId}
|
|
679
|
+
>
|
|
680
|
+
${info.label}
|
|
681
|
+
<wa-button
|
|
682
|
+
slot="details"
|
|
683
|
+
appearance="plain"
|
|
684
|
+
size="small"
|
|
685
|
+
title=${info.id === null ? "Reset in-memory connection" : "Delete connection"}
|
|
686
|
+
@click=${(e) => this.deleteConnectionById(e, info.id)}
|
|
687
|
+
>
|
|
688
|
+
<wa-icon
|
|
689
|
+
name=${info.id === null ? "rotate-right" : "trash"}
|
|
690
|
+
label=${info.id === null ? "Reset" : "Delete"}
|
|
691
|
+
></wa-icon>
|
|
692
|
+
</wa-button>
|
|
693
|
+
</wa-dropdown-item>
|
|
694
|
+
`)}
|
|
695
|
+
</wa-dropdown>
|
|
696
|
+
<wa-button
|
|
697
|
+
size="small"
|
|
698
|
+
appearance="plain"
|
|
699
|
+
title="New connection"
|
|
700
|
+
@click=${() => void this.createConnection()}
|
|
701
|
+
>
|
|
702
|
+
<wa-icon name="plus" label="New"></wa-icon>
|
|
703
|
+
</wa-button>
|
|
704
|
+
${supportsExtensions ? html$1`
|
|
705
|
+
<wa-button
|
|
706
|
+
size="small"
|
|
707
|
+
appearance="plain"
|
|
708
|
+
title="Manage extensions"
|
|
709
|
+
?disabled=${!hasEngines || !hasConnections}
|
|
710
|
+
@click=${() => void this.openExtensionManager()}
|
|
711
|
+
>
|
|
712
|
+
<wa-icon name="puzzle-piece" label="Extensions"></wa-icon>
|
|
713
|
+
Extensions
|
|
714
|
+
</wa-button>
|
|
715
|
+
` : null}
|
|
716
|
+
<wa-button
|
|
717
|
+
size="small"
|
|
718
|
+
appearance="plain"
|
|
719
|
+
?disabled=${this.running}
|
|
720
|
+
@click=${() => void this.runQuery(true)}
|
|
721
|
+
title="Run selection only"
|
|
722
|
+
>
|
|
723
|
+
<wa-icon name="i-cursor" label="Run selection"></wa-icon>
|
|
724
|
+
${this.running ? "Running…" : "Run selection"}
|
|
725
|
+
</wa-button>
|
|
726
|
+
<wa-button
|
|
727
|
+
size="small"
|
|
728
|
+
appearance="plain"
|
|
729
|
+
?disabled=${this.running}
|
|
730
|
+
@click=${() => void this.runQuery(false)}
|
|
731
|
+
title="Run all SQL"
|
|
732
|
+
>
|
|
733
|
+
<wa-icon name="play" label="Run"></wa-icon>
|
|
734
|
+
${this.running ? "Running…" : "Run all"}
|
|
735
|
+
</wa-button>
|
|
736
|
+
`;
|
|
737
|
+
}
|
|
738
|
+
renderContent() {
|
|
739
|
+
if (this.initialContent === void 0) return html$1`<div class="editor-placeholder"></div>`;
|
|
740
|
+
return html$1`
|
|
741
|
+
<div class="editor-area">
|
|
742
|
+
<docks-monaco-widget
|
|
743
|
+
.value=${this.initialContent}
|
|
744
|
+
.uri=${this.initialUri}
|
|
745
|
+
.language=${"sql"}
|
|
746
|
+
.readOnly=${this.readOnly}
|
|
747
|
+
@content-change=${this._onContentChange}
|
|
748
|
+
${ref(this.widgetRef)}
|
|
749
|
+
></docks-monaco-widget>
|
|
750
|
+
</div>
|
|
751
|
+
`;
|
|
752
|
+
}
|
|
753
|
+
static {
|
|
754
|
+
this.styles = css`
|
|
755
|
+
:host {
|
|
756
|
+
display: flex;
|
|
757
|
+
flex-direction: column;
|
|
758
|
+
position: relative;
|
|
759
|
+
width: 100%;
|
|
760
|
+
height: 100%;
|
|
761
|
+
}
|
|
762
|
+
.engine-select {
|
|
763
|
+
max-width: 10rem;
|
|
764
|
+
}
|
|
765
|
+
.connection-select {
|
|
766
|
+
max-width: 12rem;
|
|
767
|
+
}
|
|
768
|
+
.editor-area {
|
|
769
|
+
flex: 1;
|
|
770
|
+
min-height: 0;
|
|
771
|
+
height: 100%;
|
|
772
|
+
display: flex;
|
|
773
|
+
flex-direction: column;
|
|
774
|
+
overflow: hidden;
|
|
775
|
+
}
|
|
776
|
+
.editor-area docks-monaco-widget,
|
|
777
|
+
.editor-area monaco-widget {
|
|
778
|
+
flex: 1;
|
|
779
|
+
min-height: 0;
|
|
780
|
+
}
|
|
781
|
+
.editor-placeholder {
|
|
782
|
+
flex: 1;
|
|
783
|
+
min-height: 0;
|
|
784
|
+
}
|
|
785
|
+
`;
|
|
786
|
+
}
|
|
787
|
+
};
|
|
788
|
+
_decorate([property({ attribute: false })], DocksSqlEditor.prototype, "input", void 0);
|
|
789
|
+
_decorate([property({ type: Boolean })], DocksSqlEditor.prototype, "readOnly", void 0);
|
|
790
|
+
_decorate([state()], DocksSqlEditor.prototype, "initialContent", void 0);
|
|
791
|
+
_decorate([state()], DocksSqlEditor.prototype, "initialUri", void 0);
|
|
792
|
+
_decorate([state()], DocksSqlEditor.prototype, "running", void 0);
|
|
793
|
+
_decorate([state()], DocksSqlEditor.prototype, "availableAdapters", void 0);
|
|
794
|
+
_decorate([state()], DocksSqlEditor.prototype, "selectedEngineId", void 0);
|
|
795
|
+
_decorate([state()], DocksSqlEditor.prototype, "availableConnections", void 0);
|
|
796
|
+
_decorate([state()], DocksSqlEditor.prototype, "selectedConnectionId", void 0);
|
|
797
|
+
DocksSqlEditor = _decorate([customElement("docks-sql-editor")], DocksSqlEditor);
|
|
798
|
+
//#endregion
|
|
799
|
+
//#region src/sqleditor-extension.ts
|
|
800
|
+
function activate() {
|
|
801
|
+
editorRegistry.registerEditorInputHandler({
|
|
802
|
+
editorId: "system.sqleditor",
|
|
803
|
+
label: "SQL Editor",
|
|
804
|
+
icon: "database",
|
|
805
|
+
canHandle: (input) => input instanceof File && input.getName().toLowerCase().endsWith(".sql"),
|
|
806
|
+
ranking: 900,
|
|
807
|
+
handle: async (input) => {
|
|
808
|
+
const editorInput = {
|
|
809
|
+
title: input.getWorkspacePath(),
|
|
810
|
+
data: input,
|
|
811
|
+
key: input.getWorkspacePath(),
|
|
812
|
+
icon: "database",
|
|
813
|
+
state: {},
|
|
814
|
+
component: () => null
|
|
815
|
+
};
|
|
816
|
+
editorInput.component = (id) => html`<docks-sql-editor id="${id}" .input=${editorInput}></docks-sql-editor>`;
|
|
817
|
+
return editorInput;
|
|
818
|
+
}
|
|
819
|
+
});
|
|
820
|
+
}
|
|
821
|
+
//#endregion
|
|
822
|
+
export { activate as default };
|
|
823
|
+
|
|
824
|
+
//# sourceMappingURL=sqleditor-extension-CFNQ6Cj0.js.map
|
|
@@ -0,0 +1 @@
|
|
|
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 {\n SqlDatabase,\n SqlDatabaseExtensionInfo,\n} from '@eclipse-docks/extension-sqleditor';\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 {\n SqlAdapterContribution,\n SqlConnectionInfo,\n SqlDatabase,\n} from '@eclipse-docks/extension-sqleditor';\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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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sqleditor-extension.d.ts","sourceRoot":"","sources":["../src/sqleditor-extension.ts"],"names":[],"mappings":"AAEA,OAAO,cAAc,CAAC;AAEtB,MAAM,CAAC,OAAO,UAAU,QAAQ,SAsB/B"}
|
package/package.json
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@eclipse-docks/extension-sqleditor",
|
|
3
|
+
"version": "0.7.68",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"main": "./dist/index.js",
|
|
6
|
+
"module": "./dist/index.js",
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"types": "./dist/index.d.ts",
|
|
11
|
+
"import": "./dist/index.js"
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
"files": [
|
|
15
|
+
"dist"
|
|
16
|
+
],
|
|
17
|
+
"scripts": {
|
|
18
|
+
"build": "vite build"
|
|
19
|
+
},
|
|
20
|
+
"dependencies": {
|
|
21
|
+
"@eclipse-docks/core": "*",
|
|
22
|
+
"@eclipse-docks/extension-monaco-editor": "*"
|
|
23
|
+
},
|
|
24
|
+
"devDependencies": {
|
|
25
|
+
"typescript": "^6.0.0",
|
|
26
|
+
"vite": "^8.0.0",
|
|
27
|
+
"vite-plugin-dts": "^4.5.4"
|
|
28
|
+
},
|
|
29
|
+
"repository": {
|
|
30
|
+
"type": "git",
|
|
31
|
+
"url": "https://github.com/eclipse-docks/core"
|
|
32
|
+
}
|
|
33
|
+
}
|