sqlite-hub 2.0.1 → 2.2.0
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/README.md +21 -9
- package/docs/MCP.md +8 -0
- package/docs/changelog.md +16 -0
- package/docs/guidelines/DESIGN.md +64 -0
- package/docs/todo.md +2 -0
- package/frontend/assets/mockups/backups_1_1920.webp +0 -0
- package/frontend/assets/mockups/backups_2_compare_drawer_1920.webp +0 -0
- package/frontend/assets/mockups/backups_3_create_backup_modal_1920.webp +0 -0
- package/frontend/assets/mockups/backups_4_edit_backup_modal_1920.webp +0 -0
- package/frontend/assets/mockups/backups_5_restore_backup_modal_1920.webp +0 -0
- package/frontend/assets/mockups/backups_6_delete_backup_modal_1920.webp +0 -0
- package/frontend/assets/mockups/charts_1_1920.webp +0 -0
- package/frontend/assets/mockups/charts_2_query_detail_1920.webp +0 -0
- package/frontend/assets/mockups/charts_3_create_query_chart_modal_1920.webp +0 -0
- package/frontend/assets/mockups/charts_4_edit_query_chart_modal_1920.webp +0 -0
- package/frontend/assets/mockups/charts_5_delete_query_chart_modal_1920.webp +0 -0
- package/frontend/assets/mockups/charts_6_copy_column_modal_1920.webp +0 -0
- package/frontend/assets/mockups/connections_1_1920.webp +0 -0
- package/frontend/assets/mockups/connections_2_create_connection_modal_1920.webp +0 -0
- package/frontend/assets/mockups/connections_3_open_connection_modal_1920.webp +0 -0
- package/frontend/assets/mockups/data_1_1920.webp +0 -0
- package/frontend/assets/mockups/data_2_roweditor_1920.webp +0 -0
- package/frontend/assets/mockups/data_3_generate_data_modal_1920.webp +0 -0
- package/frontend/assets/mockups/data_4_data_export_modal_1920.webp +0 -0
- package/frontend/assets/mockups/documents_1_1920.webp +0 -0
- package/frontend/assets/mockups/documents_2_document_insert_table_modal_1920.webp +0 -0
- package/frontend/assets/mockups/documents_3_document_insert_note_modal_1920.webp +0 -0
- package/frontend/assets/mockups/logs_1_1920.webp +0 -0
- package/frontend/assets/mockups/media_tagging_queue_1_1920.webp +0 -0
- package/frontend/assets/mockups/media_tagging_setup_1_1920.webp +0 -0
- package/frontend/assets/mockups/media_tagging_setup_2_create_media_tagging_tag_table_modal_1920.webp +0 -0
- package/frontend/assets/mockups/media_tagging_setup_3_create_media_tagging_mapping_table_modal_1920.webp +0 -0
- package/frontend/assets/mockups/overview_1_1920.webp +0 -0
- package/frontend/assets/mockups/settings_1_1920.webp +0 -0
- package/frontend/assets/mockups/sql_editor_1_1920.webp +0 -0
- package/frontend/assets/mockups/sql_editor_2_query_detail_1920.webp +0 -0
- package/frontend/assets/mockups/sql_editor_3_query_export_modal_1920.webp +0 -0
- package/frontend/assets/mockups/structure_1_1920.webp +0 -0
- package/frontend/assets/mockups/structure_2_generate_types_modal_1920.webp +0 -0
- package/frontend/assets/mockups/structure_3_generate_types_modal_1920.webp +0 -0
- package/frontend/assets/mockups/table_designer_1_1920.webp +0 -0
- package/frontend/assets/mockups/table_designer_2_table_designer_constraints_modal_1920.webp +0 -0
- package/frontend/js/api.js +18 -0
- package/frontend/js/app.js +567 -15
- package/frontend/js/components/badges.js +16 -0
- package/frontend/js/components/connectionCard.js +35 -0
- package/frontend/js/components/modal.js +268 -247
- package/frontend/js/components/queryHistoryDetail.js +25 -45
- package/frontend/js/components/rowEditorPanel.js +7 -60
- package/frontend/js/components/structureGraph.js +292 -13
- package/frontend/js/components/tableDesignerConstraintsDrawer.js +400 -0
- package/frontend/js/components/tableDesignerEditor.js +51 -16
- package/frontend/js/components/tableDesignerSidebar.js +9 -5
- package/frontend/js/store.js +1847 -190
- package/frontend/js/utils/connectionRegistry.js +76 -0
- package/frontend/js/utils/markdownDocuments.js +21 -4
- package/frontend/js/utils/tableDesigner.js +431 -62
- package/frontend/js/views/backups.js +2 -5
- package/frontend/js/views/charts.js +20 -10
- package/frontend/js/views/connections.js +101 -6
- package/frontend/js/views/data.js +52 -9
- package/frontend/js/views/documents.js +153 -59
- package/frontend/js/views/structure.js +28 -5
- package/frontend/js/views/tableAdvisor.js +14 -6
- package/frontend/js/views/tableDesigner.js +44 -9
- package/frontend/styles/base.css +9 -0
- package/frontend/styles/components.css +676 -79
- package/frontend/styles/structure-graph.css +49 -0
- package/frontend/styles/tailwind.generated.css +1 -1
- package/frontend/styles/views.css +12 -0
- package/package.json +1 -1
- package/server/routes/backups.js +37 -1
- package/server/routes/charts.js +28 -0
- package/server/routes/connections.js +12 -0
- package/server/routes/data.js +30 -2
- package/server/routes/documents.js +61 -5
- package/server/routes/settings.js +32 -0
- package/server/routes/tableDesigner.js +35 -2
- package/server/server.js +3 -3
- package/server/services/mcpToolService.js +30 -0
- package/server/services/sqlite/connectionManager.js +25 -2
- package/server/services/sqlite/dataBrowserService.js +21 -0
- package/server/services/sqlite/introspection.js +39 -1
- package/server/services/sqlite/overviewService.js +1 -0
- package/server/services/sqlite/structureService.js +66 -11
- package/server/services/sqlite/tableAdvisor.js +6 -0
- package/server/services/sqlite/tableDesigner/schemaMapping.js +7 -1
- package/server/services/sqlite/tableDesigner/sql.js +31 -2
- package/server/services/sqlite/tableDesigner/validation.js +69 -9
- package/server/services/sqlite/tableDesignerService.js +110 -5
- package/server/services/storage/appStateStore.js +590 -10
- package/server/utils/fileValidation.js +5 -0
- package/server/utils/userActionLog.js +49 -0
- package/frontend/assets/mockups/backups_2_create_backup_modal_1920.webp +0 -0
- package/frontend/assets/mockups/backups_3_edit_backup_modal_1920.webp +0 -0
- package/frontend/assets/mockups/backups_4_restore_backup_modal_1920.webp +0 -0
- package/frontend/assets/mockups/backups_5_delete_backup_modal_1920.webp +0 -0
- package/frontend/assets/mockups/data_3_data_export_modal_1920.webp +0 -0
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { clearInspector, renderDdlSection, renderInspector } from '../components/structureGraph.js';
|
|
2
|
+
import { renderVirtualTableBadge } from '../components/badges.js';
|
|
2
3
|
import { renderDropdownButton } from '../components/dropdownButton.js';
|
|
3
4
|
import { renderGenerateTypesDropdown } from '../components/generateTypesDropdown.js';
|
|
4
5
|
import { renderWorkspaceOpenDropdown } from '../components/workspaceOpenDropdown.js';
|
|
@@ -36,11 +37,14 @@ function renderEntryGroup(title, entries, activeName, options = {}) {
|
|
|
36
37
|
'" ',
|
|
37
38
|
entryAttributes,
|
|
38
39
|
' type="button">',
|
|
39
|
-
'<div class="
|
|
40
|
+
'<div class="flex min-w-0 items-center gap-2">',
|
|
41
|
+
'<div class="min-w-0 flex-1 truncate font-mono text-xs ',
|
|
40
42
|
isActive ? 'text-primary-container' : 'text-on-surface',
|
|
41
43
|
'">',
|
|
42
44
|
escapeHtml(entry.name),
|
|
43
45
|
'</div>',
|
|
46
|
+
renderVirtualTableBadge(entry),
|
|
47
|
+
'</div>',
|
|
44
48
|
metaMarkup,
|
|
45
49
|
'</button>',
|
|
46
50
|
].join('');
|
|
@@ -76,6 +80,10 @@ function getFilteredTables(tables, searchQuery) {
|
|
|
76
80
|
return tables.filter(table => table.name.toLowerCase().includes(normalizedSearch));
|
|
77
81
|
}
|
|
78
82
|
|
|
83
|
+
function isShadowTable(table) {
|
|
84
|
+
return Boolean(table?.isShadow);
|
|
85
|
+
}
|
|
86
|
+
|
|
79
87
|
function renderStructureTableSearch(state) {
|
|
80
88
|
return `
|
|
81
89
|
<label class="table-designer-sidebar__search">
|
|
@@ -129,7 +137,10 @@ function renderObjectInspector(detail) {
|
|
|
129
137
|
<span class="material-symbols-outlined text-[18px]">close</span>
|
|
130
138
|
</button>
|
|
131
139
|
</div>
|
|
132
|
-
<div class="
|
|
140
|
+
<div class="flex min-w-0 flex-wrap items-center gap-2">
|
|
141
|
+
<div class="structure-graph__title min-w-0">${escapeHtml(detail.name)}</div>
|
|
142
|
+
${renderVirtualTableBadge(detail)}
|
|
143
|
+
</div>
|
|
133
144
|
${
|
|
134
145
|
detail.tableName
|
|
135
146
|
? `
|
|
@@ -336,9 +347,10 @@ function renderGraphSurface(structure, selectedName, detail, detailLoading, tabl
|
|
|
336
347
|
|
|
337
348
|
export function renderStructureView(state) {
|
|
338
349
|
const structure = state.structure.data;
|
|
339
|
-
const
|
|
340
|
-
|
|
341
|
-
|
|
350
|
+
const regularTables = (structure?.grouped.tables ?? []).filter(table => !isShadowTable(table));
|
|
351
|
+
const shadowTables = (structure?.grouped.tables ?? []).filter(isShadowTable);
|
|
352
|
+
const filteredTables = structure ? getFilteredTables(regularTables, state.structure.tableSearchQuery) : [];
|
|
353
|
+
const filteredShadowTables = structure ? getFilteredTables(shadowTables, state.structure.tableSearchQuery) : [];
|
|
342
354
|
const detail = state.structure.detail?.name === state.structure.selectedName ? state.structure.detail : null;
|
|
343
355
|
const tablesVisible = state.structure.tablesVisible !== false;
|
|
344
356
|
|
|
@@ -376,6 +388,17 @@ export function renderStructureView(state) {
|
|
|
376
388
|
? 'tables match the current search.'
|
|
377
389
|
: null,
|
|
378
390
|
})}
|
|
391
|
+
${
|
|
392
|
+
shadowTables.length
|
|
393
|
+
? renderEntryGroup('Shadow Tables', filteredShadowTables, state.structure.selectedName, {
|
|
394
|
+
compact: true,
|
|
395
|
+
showMeta: false,
|
|
396
|
+
emptyMessage: state.structure.tableSearchQuery
|
|
397
|
+
? 'shadow tables match the current search.'
|
|
398
|
+
: null,
|
|
399
|
+
})
|
|
400
|
+
: ''
|
|
401
|
+
}
|
|
379
402
|
${renderEntryGroup('Views', structure.grouped.views, state.structure.selectedName)}
|
|
380
403
|
${renderEntryGroup('Indexes', structure.grouped.indexes, state.structure.selectedName, {
|
|
381
404
|
compact: true,
|
|
@@ -5,6 +5,7 @@ import {
|
|
|
5
5
|
highlightSql,
|
|
6
6
|
truncateMiddle,
|
|
7
7
|
} from '../utils/format.js';
|
|
8
|
+
import { renderVirtualTableBadge } from '../components/badges.js';
|
|
8
9
|
import { renderWorkspaceOpenDropdown } from '../components/workspaceOpenDropdown.js';
|
|
9
10
|
|
|
10
11
|
const CATEGORY_LABELS = {
|
|
@@ -73,7 +74,8 @@ function renderRiskBadge(risk = 'low') {
|
|
|
73
74
|
}
|
|
74
75
|
|
|
75
76
|
function renderTableList(state) {
|
|
76
|
-
const {
|
|
77
|
+
const { selectedTableName } = state.tableAdvisor;
|
|
78
|
+
const tables = (state.tableAdvisor.tables ?? []).filter(table => !table?.isShadow);
|
|
77
79
|
|
|
78
80
|
if (state.tableAdvisor.loading && !tables.length) {
|
|
79
81
|
return `
|
|
@@ -107,8 +109,11 @@ function renderTableList(state) {
|
|
|
107
109
|
href="#/table-advisor/${encodeURIComponent(table.name)}"
|
|
108
110
|
title="${escapeHtml(table.name)}"
|
|
109
111
|
>
|
|
110
|
-
<div class="
|
|
111
|
-
${
|
|
112
|
+
<div class="flex min-w-0 items-center gap-2">
|
|
113
|
+
<div class="table-designer-sidebar__item-name min-w-0 flex-1 ${isActive ? 'is-active' : ''}">
|
|
114
|
+
${escapeHtml(table.name)}
|
|
115
|
+
</div>
|
|
116
|
+
${renderVirtualTableBadge(table)}
|
|
112
117
|
</div>
|
|
113
118
|
<div class="table-designer-sidebar__item-meta">
|
|
114
119
|
${escapeHtml(formatNumber(table.columnCount ?? 0))} columns
|
|
@@ -128,9 +133,12 @@ function renderSummary(result = {}) {
|
|
|
128
133
|
<div class="grid grid-cols-1 gap-3 md:grid-cols-4">
|
|
129
134
|
<div class="border border-outline-variant/10 bg-surface-container-low px-4 py-3">
|
|
130
135
|
<div class="font-mono text-[10px] uppercase tracking-[0.2em] text-on-surface-variant/55">Table</div>
|
|
131
|
-
<div class="mt-2 min-w-0
|
|
132
|
-
|
|
133
|
-
|
|
136
|
+
<div class="mt-2 flex min-w-0 items-center gap-2">
|
|
137
|
+
<div class="min-w-0 truncate text-lg font-black text-on-surface" title="${escapeHtml(
|
|
138
|
+
result.tableName ?? '',
|
|
139
|
+
)}">${escapeHtml(result.tableName ?? 'Unknown')}</div>
|
|
140
|
+
${renderVirtualTableBadge(result)}
|
|
141
|
+
</div>
|
|
134
142
|
</div>
|
|
135
143
|
<div class="border border-outline-variant/10 bg-surface-container-low px-4 py-3">
|
|
136
144
|
<div class="font-mono text-[10px] uppercase tracking-[0.2em] text-on-surface-variant/55">Score</div>
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { renderTableDesignerEditor } from "../components/tableDesignerEditor.js";
|
|
2
|
+
import { renderTableDesignerConstraintsDrawer } from "../components/tableDesignerConstraintsDrawer.js";
|
|
2
3
|
import { renderTableDesignerSidebar } from "../components/tableDesignerSidebar.js";
|
|
3
4
|
import { renderTableDesignerSqlPreview } from "../components/tableDesignerSqlPreview.js";
|
|
5
|
+
import { renderDropdownButton } from "../components/dropdownButton.js";
|
|
4
6
|
import { renderWorkspaceOpenDropdown } from "../components/workspaceOpenDropdown.js";
|
|
5
7
|
import { escapeHtml } from "../utils/format.js";
|
|
6
8
|
|
|
@@ -17,6 +19,44 @@ function renderRouteError(error) {
|
|
|
17
19
|
`;
|
|
18
20
|
}
|
|
19
21
|
|
|
22
|
+
function renderImportDropdown() {
|
|
23
|
+
return renderDropdownButton({
|
|
24
|
+
align: "right",
|
|
25
|
+
icon: "upload_file",
|
|
26
|
+
label: "Import",
|
|
27
|
+
title: "Import data",
|
|
28
|
+
items: [
|
|
29
|
+
{
|
|
30
|
+
action: "import-table-designer-data",
|
|
31
|
+
dataAttributes: {
|
|
32
|
+
importFormat: "csv",
|
|
33
|
+
importAccept: ".csv,text/csv",
|
|
34
|
+
},
|
|
35
|
+
icon: "table_chart",
|
|
36
|
+
label: "CSV",
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
action: "import-table-designer-data",
|
|
40
|
+
dataAttributes: {
|
|
41
|
+
importFormat: "tsv",
|
|
42
|
+
importAccept: ".tsv,text/tab-separated-values",
|
|
43
|
+
},
|
|
44
|
+
icon: "table_rows",
|
|
45
|
+
label: "TSV",
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
action: "import-table-designer-data",
|
|
49
|
+
dataAttributes: {
|
|
50
|
+
importFormat: "json",
|
|
51
|
+
importAccept: ".json,application/json",
|
|
52
|
+
},
|
|
53
|
+
icon: "data_object",
|
|
54
|
+
label: "JSON",
|
|
55
|
+
},
|
|
56
|
+
],
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
|
|
20
60
|
function renderWorkspaceToolbar(state) {
|
|
21
61
|
const tablesVisible = state.tableDesigner.tablesVisible !== false;
|
|
22
62
|
const tableName = state.tableDesigner.selectedTableName ?? state.tableDesigner.draft?.tableName ?? "";
|
|
@@ -62,17 +102,12 @@ function renderWorkspaceToolbar(state) {
|
|
|
62
102
|
},
|
|
63
103
|
],
|
|
64
104
|
})}
|
|
65
|
-
|
|
66
|
-
class="standard-button"
|
|
67
|
-
data-action="import-table-designer-csv"
|
|
68
|
-
type="button"
|
|
69
|
-
>
|
|
70
|
-
Import CSV
|
|
71
|
-
</button>
|
|
105
|
+
${renderImportDropdown()}
|
|
72
106
|
<input
|
|
73
|
-
accept=".csv,text/csv"
|
|
107
|
+
accept=".csv,text/csv,.tsv,text/tab-separated-values,.json,application/json"
|
|
74
108
|
class="table-designer-workspace__file-input"
|
|
75
109
|
data-bind="table-designer-import-file"
|
|
110
|
+
data-import-format="csv"
|
|
76
111
|
type="file"
|
|
77
112
|
/>
|
|
78
113
|
<button
|
|
@@ -110,6 +145,6 @@ export function renderTableDesignerView(state) {
|
|
|
110
145
|
</div>
|
|
111
146
|
</section>
|
|
112
147
|
`,
|
|
113
|
-
panel:
|
|
148
|
+
panel: renderTableDesignerConstraintsDrawer(state),
|
|
114
149
|
};
|
|
115
150
|
}
|
package/frontend/styles/base.css
CHANGED
|
@@ -70,6 +70,15 @@ textarea:disabled {
|
|
|
70
70
|
padding: 0 var(--control-padding-inline);
|
|
71
71
|
}
|
|
72
72
|
|
|
73
|
+
.control-input:focus,
|
|
74
|
+
.control-input:focus-visible,
|
|
75
|
+
.control-select:focus,
|
|
76
|
+
.control-select:focus-visible {
|
|
77
|
+
border-color: var(--color-primary-container);
|
|
78
|
+
box-shadow: none;
|
|
79
|
+
outline: none;
|
|
80
|
+
}
|
|
81
|
+
|
|
73
82
|
input.control-input--ghost {
|
|
74
83
|
appearance: none;
|
|
75
84
|
background: transparent;
|