@hienlh/ppm 0.13.48 → 0.13.49

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.
Files changed (55) hide show
  1. package/assets/skills/ppm/SKILL.md +1 -1
  2. package/assets/skills/ppm/references/http-api.md +1 -1
  3. package/dist/web/assets/{audio-preview-BFc4v5Tx.js → audio-preview-CQ-l5P8I.js} +2 -2
  4. package/dist/web/assets/{audio-preview-BFc4v5Tx.js.map → audio-preview-CQ-l5P8I.js.map} +1 -1
  5. package/dist/web/assets/{chat-tab-x1rBGHj5.js → chat-tab-DbuBr2ax.js} +4 -4
  6. package/dist/web/assets/{chat-tab-x1rBGHj5.js.map → chat-tab-DbuBr2ax.js.map} +1 -1
  7. package/dist/web/assets/{code-editor-BgyAZcQX.js → code-editor-DEa0t62y.js} +3 -3
  8. package/dist/web/assets/{code-editor-BgyAZcQX.js.map → code-editor-DEa0t62y.js.map} +1 -1
  9. package/dist/web/assets/{conflict-editor-Dhc1lem7.js → conflict-editor-D5H9urYy.js} +2 -2
  10. package/dist/web/assets/{conflict-editor-Dhc1lem7.js.map → conflict-editor-D5H9urYy.js.map} +1 -1
  11. package/dist/web/assets/{database-viewer-DnnjO38W.js → database-viewer-CW60ytCl.js} +2 -2
  12. package/dist/web/assets/{database-viewer-DnnjO38W.js.map → database-viewer-CW60ytCl.js.map} +1 -1
  13. package/dist/web/assets/{diff-viewer-B6q9wXD6.js → diff-viewer-BfatMgWw.js} +2 -2
  14. package/dist/web/assets/{diff-viewer-B6q9wXD6.js.map → diff-viewer-BfatMgWw.js.map} +1 -1
  15. package/dist/web/assets/{extension-webview-CMBEb4FF.js → extension-webview-DKSDoW_g.js} +2 -2
  16. package/dist/web/assets/{extension-webview-CMBEb4FF.js.map → extension-webview-DKSDoW_g.js.map} +1 -1
  17. package/dist/web/assets/{glide-data-grid-BLcBAxgp.js → glide-data-grid-Bx48618B.js} +2 -2
  18. package/dist/web/assets/{glide-data-grid-BLcBAxgp.js.map → glide-data-grid-Bx48618B.js.map} +1 -1
  19. package/dist/web/assets/{image-preview-YpWk7AOb.js → image-preview-ClY2xl1B.js} +2 -2
  20. package/dist/web/assets/{image-preview-YpWk7AOb.js.map → image-preview-ClY2xl1B.js.map} +1 -1
  21. package/dist/web/assets/{index-hxAGD2rx.js → index-DkQ6jVSH.js} +5 -5
  22. package/dist/web/assets/{index-hxAGD2rx.js.map → index-DkQ6jVSH.js.map} +1 -1
  23. package/dist/web/assets/keybindings-store-DrAeg6Gw.js +1 -0
  24. package/dist/web/assets/{markdown-renderer-BAAmsTL9.js → markdown-renderer-BmMmo0F-.js} +2 -2
  25. package/dist/web/assets/{markdown-renderer-BAAmsTL9.js.map → markdown-renderer-BmMmo0F-.js.map} +1 -1
  26. package/dist/web/assets/notification-store-Bukl8bKo.js +1 -0
  27. package/dist/web/assets/{pdf-preview-DWe7ARXI.js → pdf-preview-YylEP_Su.js} +2 -2
  28. package/dist/web/assets/{pdf-preview-DWe7ARXI.js.map → pdf-preview-YylEP_Su.js.map} +1 -1
  29. package/dist/web/assets/{port-forwarding-tab-R5V7zkKO.js → port-forwarding-tab-COdo70kU.js} +2 -2
  30. package/dist/web/assets/{port-forwarding-tab-R5V7zkKO.js.map → port-forwarding-tab-COdo70kU.js.map} +1 -1
  31. package/dist/web/assets/{postgres-viewer-AxCUyDQP.js → postgres-viewer-3y9VshZZ.js} +2 -2
  32. package/dist/web/assets/{postgres-viewer-AxCUyDQP.js.map → postgres-viewer-3y9VshZZ.js.map} +1 -1
  33. package/dist/web/assets/{settings-tab-CJ6w6q2s.js → settings-tab-sYavdJk-.js} +1 -1
  34. package/dist/web/assets/{sql-query-editor-DhZvNbKv.js → sql-query-editor-DlBYx1Ye.js} +2 -2
  35. package/dist/web/assets/{sql-query-editor-DhZvNbKv.js.map → sql-query-editor-DlBYx1Ye.js.map} +1 -1
  36. package/dist/web/assets/{sqlite-viewer-Qv8TlhPb.js → sqlite-viewer-Bj8oPYho.js} +2 -2
  37. package/dist/web/assets/{sqlite-viewer-Qv8TlhPb.js.map → sqlite-viewer-Bj8oPYho.js.map} +1 -1
  38. package/dist/web/assets/{terminal-tab-9hLQtUUT.js → terminal-tab-B7ECmf95.js} +2 -2
  39. package/dist/web/assets/{terminal-tab-9hLQtUUT.js.map → terminal-tab-B7ECmf95.js.map} +1 -1
  40. package/dist/web/assets/{video-preview-C-tj7tok.js → video-preview-CT78iZBo.js} +2 -2
  41. package/dist/web/assets/{video-preview-C-tj7tok.js.map → video-preview-CT78iZBo.js.map} +1 -1
  42. package/dist/web/index.html +1 -1
  43. package/dist/web/sw.js +1 -1
  44. package/package.json +1 -1
  45. package/src/services/db.service.ts +28 -0
  46. package/src/types/extension.ts +1 -1
  47. package/src/web/components/settings/extension-manager-section.tsx +2 -2
  48. package/dist/web/assets/keybindings-store-Dn9ANcCK.js +0 -1
  49. package/dist/web/assets/notification-store-DyVQiPv9.js +0 -1
  50. package/packages/ext-database/package.json +0 -48
  51. package/packages/ext-database/src/connection-tree.ts +0 -201
  52. package/packages/ext-database/src/extension.ts +0 -578
  53. package/packages/ext-database/src/query-panel.ts +0 -133
  54. package/packages/ext-database/src/table-viewer-panel.ts +0 -420
  55. package/packages/ext-database/tsconfig.json +0 -8
@@ -97,7 +97,7 @@ export function ExtensionManagerSection() {
97
97
  value={installName}
98
98
  onChange={(e) => setInstallName(e.target.value)}
99
99
  onKeyDown={(e) => { if (e.key === "Enter") handleInstall(); }}
100
- placeholder="npm package name (e.g. @ppm/ext-database)"
100
+ placeholder="npm package name (e.g. @ppm/ext-myext)"
101
101
  className="h-8 text-xs flex-1"
102
102
  />
103
103
  <Button
@@ -122,7 +122,7 @@ export function ExtensionManagerSection() {
122
122
  <Input
123
123
  value={devPath}
124
124
  onChange={(e) => setDevPath(e.target.value)}
125
- placeholder="Local path (e.g. ./packages/ext-database)"
125
+ placeholder="Local path (e.g. ./packages/ext-myext)"
126
126
  className="h-8 text-xs flex-1"
127
127
  />
128
128
  <Button
@@ -1 +0,0 @@
1
- import"./vendor-markdown-0Mxgxy0L.js";import"./api-client-DIhJ5qVW.js";import{T as e}from"./index-hxAGD2rx.js";export{e as useKeybindingsStore};
@@ -1 +0,0 @@
1
- import"./vendor-markdown-0Mxgxy0L.js";import"./api-client-DIhJ5qVW.js";import{j as e}from"./index-hxAGD2rx.js";export{e as useNotificationStore};
@@ -1,48 +0,0 @@
1
- {
2
- "name": "@ppm/ext-database",
3
- "version": "0.1.0",
4
- "main": "src/extension.ts",
5
- "engines": { "ppm": ">=0.9.0" },
6
- "activationEvents": ["onCommand:ppm-db.openViewer", "onView:ppm-db.connections"],
7
- "contributes": {
8
- "commands": [
9
- { "command": "ppm-db.openViewer", "title": "Database: Open Viewer" },
10
- { "command": "ppm-db.runQuery", "title": "Database: Run SQL Query" },
11
- { "command": "ppm-db.refreshConnections", "title": "Database: Refresh Connections", "icon": "refresh" },
12
- { "command": "ppm-db.addConnection", "title": "Add connection", "icon": "plus" },
13
- { "command": "ppm-db.editConnection", "title": "Database: Edit Connection" },
14
- { "command": "ppm-db.deleteConnection", "title": "Database: Delete Connection" },
15
- { "command": "ppm-db.testConnection", "title": "Database: Test Connection" },
16
- { "command": "ppm-db.exportConnections", "title": "Database: Export Connections" },
17
- { "command": "ppm-db.importConnections", "title": "Database: Import Connections" }
18
- ],
19
- "views": {
20
- "sidebar": [
21
- { "id": "ppm-db.connections", "name": "DB Connections", "type": "tree" }
22
- ]
23
- },
24
- "menus": {
25
- "commandPalette": [
26
- { "command": "ppm-db.openViewer" },
27
- { "command": "ppm-db.runQuery" },
28
- { "command": "ppm-db.exportConnections" },
29
- { "command": "ppm-db.importConnections" }
30
- ],
31
- "view/title": [
32
- { "command": "ppm-db.refreshConnections", "when": "view == ppm-db.connections", "group": "navigation" },
33
- { "command": "ppm-db.addConnection", "when": "view == ppm-db.connections", "group": "navigation" }
34
- ]
35
- },
36
- "configuration": {
37
- "properties": {
38
- "ppm-db.maxRows": { "type": "number", "default": 100, "description": "Max rows to display" },
39
- "ppm-db.autoConnect": { "type": "boolean", "default": true, "description": "Auto-connect on open" }
40
- }
41
- }
42
- },
43
- "ppm": {
44
- "displayName": "Database Viewer",
45
- "icon": "database",
46
- "webviewDir": "webview"
47
- }
48
- }
@@ -1,201 +0,0 @@
1
- /**
2
- * TreeDataProvider for database connections → tables → columns.
3
- * Fetches data from PPM REST API (/api/db/*).
4
- */
5
-
6
- interface ConnectionNode {
7
- id: string;
8
- name: string;
9
- type: "connection" | "group" | "table" | "column";
10
- connectionId?: number;
11
- connectionName?: string;
12
- connectionType?: string;
13
- connectionColor?: string | null;
14
- connectionReadonly?: number;
15
- groupName?: string | null;
16
- schemaName?: string;
17
- dataType?: string;
18
- rowCount?: number;
19
- children?: ConnectionNode[];
20
- }
21
-
22
- interface ApiConnection {
23
- id: number;
24
- name: string;
25
- type: string;
26
- color: string | null;
27
- readonly: number;
28
- group_name: string | null;
29
- }
30
-
31
- interface ApiTable {
32
- name: string;
33
- schema: string;
34
- rowCount: number;
35
- }
36
-
37
- interface ApiColumn {
38
- name: string;
39
- type: string;
40
- nullable: boolean;
41
- pk: boolean;
42
- defaultValue: string | null;
43
- }
44
-
45
- export class ConnectionTreeProvider {
46
- private _onDidChange: { fire: (el?: ConnectionNode) => void; event: unknown };
47
- private baseUrl: string;
48
-
49
- constructor(eventEmitter: { fire: (el?: ConnectionNode) => void; event: unknown }, baseUrl = "") {
50
- this._onDidChange = eventEmitter;
51
- this.baseUrl = baseUrl;
52
- }
53
-
54
- get onDidChangeTreeData() {
55
- return this._onDidChange.event;
56
- }
57
-
58
- refresh(): void {
59
- this._onDidChange.fire(undefined);
60
- }
61
-
62
- async getChildren(element?: ConnectionNode): Promise<ConnectionNode[]> {
63
- if (!element) return this.getRootNodes();
64
- if (element.type === "group") return element.children ?? [];
65
- if (element.type === "connection") return this.getTables(element);
66
- if (element.type === "table") return this.getColumns(element);
67
- return [];
68
- }
69
-
70
- getTreeItem(element: ConnectionNode): Record<string, unknown> {
71
- const isConn = element.type === "connection";
72
- const isGroup = element.type === "group";
73
- const isTable = element.type === "table";
74
- const isCol = element.type === "column";
75
-
76
- // Table description: row count
77
- let description: string | undefined;
78
- if (isCol) description = element.dataType;
79
- else if (isTable && element.rowCount !== undefined) description = `${element.rowCount.toLocaleString()} rows`;
80
-
81
- // Connection badge: type + readonly
82
- let badge: string | undefined;
83
- if (isConn) {
84
- badge = element.connectionType === "postgres" ? "PG" : "DB";
85
- if (element.connectionReadonly === 1) badge += " 🔒";
86
- }
87
-
88
- return {
89
- id: element.id,
90
- label: element.name,
91
- description,
92
- collapsibleState: isCol ? "none" : "collapsed",
93
- contextValue: element.type,
94
- command: isTable ? "ppm-db.openViewer" : undefined,
95
- commandArgs: isTable
96
- ? [element.connectionId, element.connectionName ?? "Database", element.name, element.schemaName ?? "public"]
97
- : undefined,
98
- color: isConn ? (element.connectionColor ?? undefined) : undefined,
99
- badge,
100
- actions: isConn ? [
101
- { icon: "refresh", tooltip: "Refresh tables", command: "ppm-db.refreshConnection", commandArgs: [element.connectionId] },
102
- { icon: "edit", tooltip: "Edit connection", command: "ppm-db.editConnection", commandArgs: [element.connectionId] },
103
- { icon: "trash", tooltip: "Delete connection", command: "ppm-db.deleteConnection", commandArgs: [element.connectionId, element.name] },
104
- ] : isGroup ? [] : undefined,
105
- };
106
- }
107
-
108
- /** Build root tree: group nodes wrapping connection nodes, or flat if no groups */
109
- private async getRootNodes(): Promise<ConnectionNode[]> {
110
- const connections = await this.getConnections();
111
- // Group by group_name
112
- const groups = new Map<string, ConnectionNode[]>();
113
- for (const conn of connections) {
114
- const key = conn.groupName ?? "__ungrouped__";
115
- const list = groups.get(key) ?? [];
116
- list.push(conn);
117
- groups.set(key, list);
118
- }
119
- // If only one group (ungrouped), return connections flat
120
- if (groups.size <= 1 && groups.has("__ungrouped__")) {
121
- return connections;
122
- }
123
- // Build group nodes
124
- const result: ConnectionNode[] = [];
125
- const sortedKeys = Array.from(groups.keys()).sort((a, b) => {
126
- if (a === "__ungrouped__") return 1;
127
- if (b === "__ungrouped__") return -1;
128
- return a.localeCompare(b);
129
- });
130
- for (const key of sortedKeys) {
131
- const label = key === "__ungrouped__" ? "Ungrouped" : key;
132
- result.push({
133
- id: `group:${key}`,
134
- name: label,
135
- type: "group",
136
- children: groups.get(key) ?? [],
137
- });
138
- }
139
- return result;
140
- }
141
-
142
- private async getConnections(): Promise<ConnectionNode[]> {
143
- try {
144
- const res = await fetch(`${this.baseUrl}/api/db/connections`);
145
- const json = await res.json() as { ok: boolean; data?: ApiConnection[] };
146
- if (!json.ok || !json.data) return [];
147
- return json.data.map((c) => ({
148
- id: `conn:${c.id}`,
149
- name: c.name,
150
- type: "connection" as const,
151
- connectionId: c.id,
152
- connectionType: c.type,
153
- connectionColor: c.color,
154
- connectionReadonly: c.readonly,
155
- groupName: c.group_name,
156
- }));
157
- } catch {
158
- return [];
159
- }
160
- }
161
-
162
- private async getTables(conn: ConnectionNode): Promise<ConnectionNode[]> {
163
- try {
164
- const res = await fetch(`${this.baseUrl}/api/db/connections/${conn.connectionId}/tables`);
165
- const json = await res.json() as { ok: boolean; data?: ApiTable[] };
166
- if (!json.ok || !json.data) return [];
167
- return json.data.map((t) => ({
168
- id: `table:${conn.connectionId}:${t.schema}.${t.name}`,
169
- name: t.name,
170
- type: "table" as const,
171
- connectionId: conn.connectionId,
172
- connectionName: conn.name,
173
- connectionType: conn.connectionType,
174
- schemaName: t.schema,
175
- rowCount: t.rowCount,
176
- }));
177
- } catch {
178
- return [];
179
- }
180
- }
181
-
182
- private async getColumns(table: ConnectionNode): Promise<ConnectionNode[]> {
183
- try {
184
- const schema = table.schemaName ?? "public";
185
- const res = await fetch(
186
- `${this.baseUrl}/api/db/connections/${table.connectionId}/schema?table=${encodeURIComponent(table.name)}&schema=${schema}`,
187
- );
188
- const json = await res.json() as { ok: boolean; data?: ApiColumn[] };
189
- if (!json.ok || !json.data) return [];
190
- return json.data.map((c) => ({
191
- id: `col:${table.connectionId}:${table.name}.${c.name}`,
192
- name: c.name,
193
- type: "column" as const,
194
- connectionId: table.connectionId,
195
- dataType: c.type + (c.pk ? " PK" : ""),
196
- }));
197
- } catch {
198
- return [];
199
- }
200
- }
201
- }