sqlite-hub 0.17.2 → 1.1.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 +143 -47
- package/bin/sqlite-hub.js +206 -444
- package/examples/api/queries.js +31 -0
- package/examples/api/rows.js +27 -0
- package/frontend/assets/mockups/charts_1_bars_1200.webp +0 -0
- package/frontend/assets/mockups/charts_2_pie_1200.webp +0 -0
- package/frontend/assets/mockups/charts_3_scatter_plot_1200.webp +0 -0
- package/frontend/assets/mockups/connections_1200.webp +0 -0
- package/frontend/assets/mockups/data_1_1200.webp +0 -0
- package/frontend/assets/mockups/data_2_row_editor_1200.webp +0 -0
- package/frontend/assets/mockups/documents_1200.webp +0 -0
- package/frontend/assets/mockups/media_tagging_1_setup_1200.webp +0 -0
- package/frontend/assets/mockups/media_tagging_2_tagging_queue_1200.webp +0 -0
- package/frontend/assets/mockups/media_tagging_3_media_viewer_1200.webp +0 -0
- package/frontend/assets/mockups/overview_1200.webp +0 -0
- package/frontend/assets/mockups/settings_1200.webp +0 -0
- package/frontend/assets/mockups/sql_editor_1_1200.webp +0 -0
- package/frontend/assets/mockups/sql_editor_2_query_details_1200.webp +0 -0
- package/frontend/assets/mockups/sql_editor_3_export_column_1200.webp +0 -0
- package/frontend/assets/mockups/sql_editor_4_export_column_as_markdown_1200.webp +0 -0
- package/frontend/assets/mockups/sql_editor_5_export_query_result_1200.webp +0 -0
- package/frontend/assets/mockups/structure_1_1200.webp +0 -0
- package/frontend/assets/mockups/structure_2_inspector_1200.webp +0 -0
- package/frontend/assets/mockups/table_designer_1_1200.webp +0 -0
- package/frontend/assets/mockups/table_designer_2_checks_1200.webp +0 -0
- package/frontend/js/api.js +25 -0
- package/frontend/js/app.js +263 -34
- package/frontend/js/components/formControls.js +38 -0
- package/frontend/js/components/modal.js +77 -21
- package/frontend/js/components/queryChartRenderer.js +28 -3
- package/frontend/js/components/queryEditor.js +20 -24
- package/frontend/js/components/queryHistoryDetail.js +1 -1
- package/frontend/js/components/queryHistoryHeader.js +48 -0
- package/frontend/js/components/queryHistoryList.js +132 -0
- package/frontend/js/components/queryHistoryPanel.js +72 -136
- package/frontend/js/components/structureGraph.js +699 -89
- package/frontend/js/components/tableDesignerEditor.js +3 -5
- package/frontend/js/store.js +188 -7
- package/frontend/js/utils/exportFilenames.js +3 -1
- package/frontend/js/views/charts.js +320 -169
- package/frontend/js/views/connections.js +59 -64
- package/frontend/js/views/data.js +12 -20
- package/frontend/js/views/editor.js +0 -2
- package/frontend/js/views/settings.js +219 -5
- package/frontend/js/views/structure.js +27 -13
- package/frontend/styles/components.css +155 -0
- package/frontend/styles/structure-graph.css +140 -35
- package/frontend/styles/tailwind.generated.css +2 -2
- package/frontend/styles/views.css +12 -6
- package/package.json +7 -6
- package/server/middleware/apiTokenAuth.js +30 -0
- package/server/routes/connections.js +17 -0
- package/server/routes/export.js +89 -22
- package/server/routes/externalApi.js +304 -0
- package/server/routes/settings.js +90 -21
- package/server/server.js +22 -1
- package/server/services/apiTokenService.js +101 -0
- package/server/services/appInfoService.js +215 -0
- package/server/services/databaseCommandService.js +443 -0
- package/server/services/nativeFileDialogService.js +93 -1
- package/server/services/sqlite/exportService.js +307 -22
- package/server/services/storage/appStateStore.js +113 -0
- package/server/utils/errors.js +7 -0
- package/tests/api-token-auth.test.js +236 -0
- package/tests/cli-args.test.js +16 -3
- package/tests/cli-service-delegation.test.js +43 -0
- package/tests/connections-file-dialog-route.test.js +43 -0
- package/tests/copy-column-modal.test.js +34 -0
- package/tests/database-command-service.test.js +139 -0
- package/tests/export-blob.test.js +54 -1
- package/tests/export-filenames.test.js +4 -0
- package/tests/form-controls.test.js +34 -0
- package/tests/native-file-dialog.test.js +27 -0
- package/tests/settings-api-tokens-route.test.js +97 -0
- package/tests/settings-metadata.test.js +99 -1
- package/tests/settings-view.test.js +75 -0
- package/frontend/assets/mockups/connections.png +0 -0
- package/frontend/assets/mockups/data.png +0 -0
- package/frontend/assets/mockups/data_row_editor.png +0 -0
- package/frontend/assets/mockups/home.png +0 -0
- package/frontend/assets/mockups/sql_editor.png +0 -0
- package/frontend/assets/mockups/sql_editor_croped.png +0 -0
- package/frontend/assets/mockups/sql_editor_querydetail.png +0 -0
- package/frontend/assets/mockups/structure.png +0 -0
- package/frontend/assets/mockups/structure_inspector.png +0 -0
|
@@ -1,114 +1,65 @@
|
|
|
1
|
-
import { escapeHtml
|
|
1
|
+
import { escapeHtml } from '../utils/format.js';
|
|
2
2
|
import { renderStatusBadge } from './badges.js';
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
return 'muted';
|
|
14
|
-
}
|
|
3
|
+
import { renderQueryHistoryHeader, renderQueryHistorySearch } from './queryHistoryHeader.js';
|
|
4
|
+
import {
|
|
5
|
+
getQueryTypeTone,
|
|
6
|
+
renderQueryHistoryActionGroup,
|
|
7
|
+
renderQueryHistoryBadgeRow,
|
|
8
|
+
renderQueryHistoryIconButton,
|
|
9
|
+
renderQueryHistoryListItem as renderSharedQueryHistoryListItem,
|
|
10
|
+
renderQueryHistoryTabs,
|
|
11
|
+
} from './queryHistoryList.js';
|
|
15
12
|
|
|
16
13
|
export function renderQueryHistoryListItem(item, activeHistoryId, selectedHistoryId) {
|
|
17
14
|
const isActive = Number(activeHistoryId) === Number(item.id);
|
|
18
15
|
const isSelected = Number(selectedHistoryId) === Number(item.id);
|
|
19
|
-
const
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
16
|
+
const badgesMarkup = renderQueryHistoryBadgeRow(
|
|
17
|
+
[
|
|
18
|
+
renderStatusBadge(item.queryType, getQueryTypeTone(item.queryType)),
|
|
19
|
+
item.isSaved ? renderStatusBadge('saved', 'primary') : '',
|
|
20
|
+
item.isDestructive ? renderStatusBadge('destructive', 'warning') : '',
|
|
21
|
+
].join(''),
|
|
22
|
+
);
|
|
23
|
+
const actionsMarkup = renderQueryHistoryActionGroup([
|
|
24
|
+
renderQueryHistoryIconButton({
|
|
25
|
+
action: 'open-query-history',
|
|
26
|
+
historyId: item.id,
|
|
27
|
+
icon: 'edit_note',
|
|
28
|
+
title: 'Open in editor',
|
|
29
|
+
}),
|
|
30
|
+
renderQueryHistoryIconButton({
|
|
31
|
+
action: 'run-query-history',
|
|
32
|
+
historyId: item.id,
|
|
33
|
+
icon: 'play_arrow',
|
|
34
|
+
title: 'Run query',
|
|
35
|
+
}),
|
|
36
|
+
renderQueryHistoryIconButton({
|
|
37
|
+
action: 'select-query-history-item',
|
|
38
|
+
historyId: item.id,
|
|
39
|
+
icon: 'info',
|
|
40
|
+
title: 'Open query detail',
|
|
41
|
+
active: isSelected,
|
|
42
|
+
}),
|
|
43
|
+
renderQueryHistoryIconButton({
|
|
44
|
+
action: 'toggle-query-history-saved',
|
|
45
|
+
historyId: item.id,
|
|
46
|
+
icon: item.isSaved ? 'bookmark' : 'bookmark_add',
|
|
47
|
+
title: item.isSaved ? 'Remove from saved' : 'Save query',
|
|
48
|
+
active: item.isSaved,
|
|
49
|
+
nextValue: item.isSaved ? 'false' : 'true',
|
|
50
|
+
}),
|
|
51
|
+
]);
|
|
36
52
|
|
|
37
|
-
return
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
'</span>',
|
|
48
|
-
renderStatusBadge(item.queryType, getQueryTypeTone(item.queryType)),
|
|
49
|
-
item.isSaved ? renderStatusBadge('saved', 'primary') : '',
|
|
50
|
-
item.isDestructive ? renderStatusBadge('destructive', 'warning') : '',
|
|
51
|
-
'</div>',
|
|
52
|
-
'<p class="query-history-sql-preview mt-2 text-left font-mono text-xs leading-5 text-on-surface-variant/75">',
|
|
53
|
-
escapeHtml(item.previewSql),
|
|
54
|
-
'</p></button>',
|
|
55
|
-
'<div class="flex items-center justify-between gap-3 border-t border-outline-variant/10 px-3 pb-3 pt-2">',
|
|
56
|
-
'<div class="min-w-0 flex flex-wrap gap-2 text-[10px] font-mono uppercase tracking-[0.14em] text-on-surface-variant/55">',
|
|
57
|
-
tableMarkup,
|
|
58
|
-
'</div><div class="flex items-center gap-1">',
|
|
59
|
-
'<button class="query-history-icon-button" data-action="open-query-history" data-history-id="',
|
|
60
|
-
escapeHtml(item.id),
|
|
61
|
-
'" title="Open in editor" type="button"><span class="material-symbols-outlined text-[18px]">edit_note</span></button>',
|
|
62
|
-
'<button class="query-history-icon-button" data-action="run-query-history" data-history-id="',
|
|
63
|
-
escapeHtml(item.id),
|
|
64
|
-
'" title="Run query" type="button"><span class="material-symbols-outlined text-[18px]">play_arrow</span></button>',
|
|
65
|
-
'<button class="query-history-icon-button ',
|
|
66
|
-
item.isSaved ? 'is-active' : '',
|
|
67
|
-
'" data-action="toggle-query-history-saved" data-history-id="',
|
|
68
|
-
escapeHtml(item.id),
|
|
69
|
-
'" data-next-value="',
|
|
70
|
-
item.isSaved ? 'false' : 'true',
|
|
71
|
-
'" title="',
|
|
72
|
-
item.isSaved ? 'Remove from saved' : 'Save query',
|
|
73
|
-
'" type="button"><span class="material-symbols-outlined text-[18px]">',
|
|
74
|
-
item.isSaved ? 'bookmark' : 'bookmark_add',
|
|
75
|
-
'</span></button>',
|
|
76
|
-
'<button class="query-history-icon-button ',
|
|
77
|
-
isSelected ? 'is-active' : '',
|
|
78
|
-
'" data-action="select-query-history-item" data-history-id="',
|
|
79
|
-
escapeHtml(item.id),
|
|
80
|
-
'" title="Open query detail" type="button"><span class="material-symbols-outlined text-[18px]">info</span></button>',
|
|
81
|
-
'</div></div></article>',
|
|
82
|
-
].join('');
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
function renderQueryHistoryTabs(activeTab, historyTotal) {
|
|
86
|
-
const tabs = [
|
|
87
|
-
{ id: 'recent', label: 'Recent' },
|
|
88
|
-
{ id: 'saved', label: 'Saved' },
|
|
89
|
-
{ id: 'unsaved', label: 'Unsaved' },
|
|
90
|
-
{ id: 'failed', label: 'Failed' },
|
|
91
|
-
];
|
|
92
|
-
|
|
93
|
-
return [
|
|
94
|
-
'<div class="flex items-center gap-2">',
|
|
95
|
-
tabs
|
|
96
|
-
.map(tab =>
|
|
97
|
-
[
|
|
98
|
-
'<button class="query-history-tab ',
|
|
99
|
-
activeTab === tab.id ? 'is-active' : '',
|
|
100
|
-
'" data-action="set-query-history-tab" data-tab="',
|
|
101
|
-
tab.id,
|
|
102
|
-
'" type="button">',
|
|
103
|
-
escapeHtml(tab.label),
|
|
104
|
-
'</button>',
|
|
105
|
-
].join(''),
|
|
106
|
-
)
|
|
107
|
-
.join(''),
|
|
108
|
-
'<span class="ml-auto text-[10px] font-mono uppercase tracking-[0.16em] text-on-surface-variant/50">',
|
|
109
|
-
escapeHtml(formatNumber(historyTotal)),
|
|
110
|
-
'</span></div>',
|
|
111
|
-
].join('');
|
|
53
|
+
return renderSharedQueryHistoryListItem({
|
|
54
|
+
title: item.displayTitle,
|
|
55
|
+
preview: item.previewSql,
|
|
56
|
+
historyId: item.id,
|
|
57
|
+
active: isActive,
|
|
58
|
+
error: item.lastRun?.status === 'error',
|
|
59
|
+
hitAction: 'select-query-history-item',
|
|
60
|
+
badgesMarkup,
|
|
61
|
+
actionsMarkup,
|
|
62
|
+
});
|
|
112
63
|
}
|
|
113
64
|
|
|
114
65
|
export function renderQueryHistoryPanel({
|
|
@@ -126,38 +77,23 @@ export function renderQueryHistoryPanel({
|
|
|
126
77
|
}) {
|
|
127
78
|
return `
|
|
128
79
|
<aside class="query-history-panel border-l border-outline-variant/10 bg-surface-container-lowest">
|
|
129
|
-
<div class="
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
>
|
|
144
|
-
<span class="material-symbols-outlined text-[18px]">close</span>
|
|
145
|
-
</button>
|
|
146
|
-
</div>
|
|
147
|
-
<div class="mt-4">${renderQueryHistoryTabs(activeTab, total)}</div>
|
|
148
|
-
<label class="mt-4 block">
|
|
149
|
-
<span class="sr-only">Search query history</span>
|
|
150
|
-
<input
|
|
151
|
-
class="control-input w-full border border-outline-variant/20 bg-surface-container text-sm text-on-surface outline-none placeholder:text-on-surface-variant/35 focus:border-primary-container"
|
|
152
|
-
data-bind="query-history-search"
|
|
153
|
-
placeholder="Search SQL, titles, notes..."
|
|
154
|
-
type="search"
|
|
155
|
-
value="${escapeHtml(search)}"
|
|
156
|
-
/>
|
|
157
|
-
</label>
|
|
80
|
+
<div class="query-history-panel__header">
|
|
81
|
+
${renderQueryHistoryHeader()}
|
|
82
|
+
${renderQueryHistoryTabs({
|
|
83
|
+
tabs: [
|
|
84
|
+
{ id: 'recent', label: 'Recent' },
|
|
85
|
+
{ id: 'saved', label: 'Saved' },
|
|
86
|
+
{ id: 'unsaved', label: 'Unsaved' },
|
|
87
|
+
{ id: 'failed', label: 'Failed' },
|
|
88
|
+
],
|
|
89
|
+
activeTab,
|
|
90
|
+
action: 'set-query-history-tab',
|
|
91
|
+
count: total,
|
|
92
|
+
})}
|
|
93
|
+
${renderQueryHistorySearch({ value: search })}
|
|
158
94
|
</div>
|
|
159
95
|
<div
|
|
160
|
-
class="
|
|
96
|
+
class="query-history-list-scroll custom-scrollbar"
|
|
161
97
|
data-query-history-committed-search="${escapeHtml(committedSearch)}"
|
|
162
98
|
data-query-history-loading-more="${loadingMore ? 'true' : 'false'}"
|
|
163
99
|
data-query-history-search="${escapeHtml(search)}"
|
|
@@ -188,7 +124,7 @@ export function renderQueryHistoryPanel({
|
|
|
188
124
|
`
|
|
189
125
|
: ''
|
|
190
126
|
}
|
|
191
|
-
<div class="
|
|
127
|
+
<div class="query-history-list">
|
|
192
128
|
${items.map(item => renderQueryHistoryListItem(item, activeHistoryId, selectedHistoryId)).join('')}
|
|
193
129
|
</div>
|
|
194
130
|
${
|