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.
Files changed (98) hide show
  1. package/README.md +21 -9
  2. package/docs/MCP.md +8 -0
  3. package/docs/changelog.md +16 -0
  4. package/docs/guidelines/DESIGN.md +64 -0
  5. package/docs/todo.md +2 -0
  6. package/frontend/assets/mockups/backups_1_1920.webp +0 -0
  7. package/frontend/assets/mockups/backups_2_compare_drawer_1920.webp +0 -0
  8. package/frontend/assets/mockups/backups_3_create_backup_modal_1920.webp +0 -0
  9. package/frontend/assets/mockups/backups_4_edit_backup_modal_1920.webp +0 -0
  10. package/frontend/assets/mockups/backups_5_restore_backup_modal_1920.webp +0 -0
  11. package/frontend/assets/mockups/backups_6_delete_backup_modal_1920.webp +0 -0
  12. package/frontend/assets/mockups/charts_1_1920.webp +0 -0
  13. package/frontend/assets/mockups/charts_2_query_detail_1920.webp +0 -0
  14. package/frontend/assets/mockups/charts_3_create_query_chart_modal_1920.webp +0 -0
  15. package/frontend/assets/mockups/charts_4_edit_query_chart_modal_1920.webp +0 -0
  16. package/frontend/assets/mockups/charts_5_delete_query_chart_modal_1920.webp +0 -0
  17. package/frontend/assets/mockups/charts_6_copy_column_modal_1920.webp +0 -0
  18. package/frontend/assets/mockups/connections_1_1920.webp +0 -0
  19. package/frontend/assets/mockups/connections_2_create_connection_modal_1920.webp +0 -0
  20. package/frontend/assets/mockups/connections_3_open_connection_modal_1920.webp +0 -0
  21. package/frontend/assets/mockups/data_1_1920.webp +0 -0
  22. package/frontend/assets/mockups/data_2_roweditor_1920.webp +0 -0
  23. package/frontend/assets/mockups/data_3_generate_data_modal_1920.webp +0 -0
  24. package/frontend/assets/mockups/data_4_data_export_modal_1920.webp +0 -0
  25. package/frontend/assets/mockups/documents_1_1920.webp +0 -0
  26. package/frontend/assets/mockups/documents_2_document_insert_table_modal_1920.webp +0 -0
  27. package/frontend/assets/mockups/documents_3_document_insert_note_modal_1920.webp +0 -0
  28. package/frontend/assets/mockups/logs_1_1920.webp +0 -0
  29. package/frontend/assets/mockups/media_tagging_queue_1_1920.webp +0 -0
  30. package/frontend/assets/mockups/media_tagging_setup_1_1920.webp +0 -0
  31. package/frontend/assets/mockups/media_tagging_setup_2_create_media_tagging_tag_table_modal_1920.webp +0 -0
  32. package/frontend/assets/mockups/media_tagging_setup_3_create_media_tagging_mapping_table_modal_1920.webp +0 -0
  33. package/frontend/assets/mockups/overview_1_1920.webp +0 -0
  34. package/frontend/assets/mockups/settings_1_1920.webp +0 -0
  35. package/frontend/assets/mockups/sql_editor_1_1920.webp +0 -0
  36. package/frontend/assets/mockups/sql_editor_2_query_detail_1920.webp +0 -0
  37. package/frontend/assets/mockups/sql_editor_3_query_export_modal_1920.webp +0 -0
  38. package/frontend/assets/mockups/structure_1_1920.webp +0 -0
  39. package/frontend/assets/mockups/structure_2_generate_types_modal_1920.webp +0 -0
  40. package/frontend/assets/mockups/structure_3_generate_types_modal_1920.webp +0 -0
  41. package/frontend/assets/mockups/table_designer_1_1920.webp +0 -0
  42. package/frontend/assets/mockups/table_designer_2_table_designer_constraints_modal_1920.webp +0 -0
  43. package/frontend/js/api.js +18 -0
  44. package/frontend/js/app.js +567 -15
  45. package/frontend/js/components/badges.js +16 -0
  46. package/frontend/js/components/connectionCard.js +35 -0
  47. package/frontend/js/components/modal.js +268 -247
  48. package/frontend/js/components/queryHistoryDetail.js +25 -45
  49. package/frontend/js/components/rowEditorPanel.js +7 -60
  50. package/frontend/js/components/structureGraph.js +292 -13
  51. package/frontend/js/components/tableDesignerConstraintsDrawer.js +400 -0
  52. package/frontend/js/components/tableDesignerEditor.js +51 -16
  53. package/frontend/js/components/tableDesignerSidebar.js +9 -5
  54. package/frontend/js/store.js +1847 -190
  55. package/frontend/js/utils/connectionRegistry.js +76 -0
  56. package/frontend/js/utils/markdownDocuments.js +21 -4
  57. package/frontend/js/utils/tableDesigner.js +431 -62
  58. package/frontend/js/views/backups.js +2 -5
  59. package/frontend/js/views/charts.js +20 -10
  60. package/frontend/js/views/connections.js +101 -6
  61. package/frontend/js/views/data.js +52 -9
  62. package/frontend/js/views/documents.js +153 -59
  63. package/frontend/js/views/structure.js +28 -5
  64. package/frontend/js/views/tableAdvisor.js +14 -6
  65. package/frontend/js/views/tableDesigner.js +44 -9
  66. package/frontend/styles/base.css +9 -0
  67. package/frontend/styles/components.css +676 -79
  68. package/frontend/styles/structure-graph.css +49 -0
  69. package/frontend/styles/tailwind.generated.css +1 -1
  70. package/frontend/styles/views.css +12 -0
  71. package/package.json +1 -1
  72. package/server/routes/backups.js +37 -1
  73. package/server/routes/charts.js +28 -0
  74. package/server/routes/connections.js +12 -0
  75. package/server/routes/data.js +30 -2
  76. package/server/routes/documents.js +61 -5
  77. package/server/routes/settings.js +32 -0
  78. package/server/routes/tableDesigner.js +35 -2
  79. package/server/server.js +3 -3
  80. package/server/services/mcpToolService.js +30 -0
  81. package/server/services/sqlite/connectionManager.js +25 -2
  82. package/server/services/sqlite/dataBrowserService.js +21 -0
  83. package/server/services/sqlite/introspection.js +39 -1
  84. package/server/services/sqlite/overviewService.js +1 -0
  85. package/server/services/sqlite/structureService.js +66 -11
  86. package/server/services/sqlite/tableAdvisor.js +6 -0
  87. package/server/services/sqlite/tableDesigner/schemaMapping.js +7 -1
  88. package/server/services/sqlite/tableDesigner/sql.js +31 -2
  89. package/server/services/sqlite/tableDesigner/validation.js +69 -9
  90. package/server/services/sqlite/tableDesignerService.js +110 -5
  91. package/server/services/storage/appStateStore.js +590 -10
  92. package/server/utils/fileValidation.js +5 -0
  93. package/server/utils/userActionLog.js +49 -0
  94. package/frontend/assets/mockups/backups_2_create_backup_modal_1920.webp +0 -0
  95. package/frontend/assets/mockups/backups_3_edit_backup_modal_1920.webp +0 -0
  96. package/frontend/assets/mockups/backups_4_restore_backup_modal_1920.webp +0 -0
  97. package/frontend/assets/mockups/backups_5_delete_backup_modal_1920.webp +0 -0
  98. package/frontend/assets/mockups/data_3_data_export_modal_1920.webp +0 -0
@@ -0,0 +1,76 @@
1
+ export const MAX_CONNECTION_TAG_NAME_LENGTH = 40;
2
+
3
+ export function normalizeConnectionSearchQuery(query) {
4
+ return String(query ?? '').trim().toLowerCase();
5
+ }
6
+
7
+ export function normalizeConnectionTagName(value) {
8
+ const name = String(value ?? '')
9
+ .replace(/[\u0000-\u001f\u007f]/g, ' ')
10
+ .trim();
11
+
12
+ if (!name || name.length > MAX_CONNECTION_TAG_NAME_LENGTH) {
13
+ return '';
14
+ }
15
+
16
+ return name;
17
+ }
18
+
19
+ export function normalizeConnectionTagKey(value) {
20
+ return String(value ?? '').trim().toLowerCase();
21
+ }
22
+
23
+ function getConnectionFilename(connection = {}) {
24
+ const segments = String(connection.path ?? '').split(/[\\/]/);
25
+ return segments[segments.length - 1] ?? '';
26
+ }
27
+
28
+ function getConnectionSearchText(connection = {}) {
29
+ const tagNames = Array.isArray(connection.tags)
30
+ ? connection.tags.map(tag => tag?.name ?? '').join(' ')
31
+ : '';
32
+
33
+ return [
34
+ connection.label,
35
+ getConnectionFilename(connection),
36
+ connection.path,
37
+ tagNames,
38
+ ]
39
+ .map(value => String(value ?? '').toLowerCase())
40
+ .join(' ');
41
+ }
42
+
43
+ export function filterConnections(connections = [], { searchQuery = '', selectedTagIds = [] } = {}) {
44
+ const query = normalizeConnectionSearchQuery(searchQuery);
45
+ const selectedTagSet = new Set(
46
+ selectedTagIds
47
+ .map(tagId => String(tagId ?? '').trim())
48
+ .filter(Boolean),
49
+ );
50
+
51
+ return [...connections].filter(connection => {
52
+ if (query && !getConnectionSearchText(connection).includes(query)) {
53
+ return false;
54
+ }
55
+
56
+ if (!selectedTagSet.size) {
57
+ return true;
58
+ }
59
+
60
+ return (connection.tags ?? []).some(tag => selectedTagSet.has(String(tag.id)));
61
+ });
62
+ }
63
+
64
+ export function getConnectionTagCounts(connections = []) {
65
+ const counts = new Map();
66
+
67
+ for (const connection of connections) {
68
+ const tagIds = new Set((connection.tags ?? []).map(tag => String(tag.id)));
69
+
70
+ for (const tagId of tagIds) {
71
+ counts.set(tagId, (counts.get(tagId) ?? 0) + 1);
72
+ }
73
+ }
74
+
75
+ return counts;
76
+ }
@@ -2,6 +2,8 @@ import { escapeHtml } from './format.js';
2
2
 
3
3
  const FENCED_CODE_PATTERN = /^\s*(```|~~~)/;
4
4
  const TASK_LINE_PATTERN = /^(\s*)([-*+])\s+\[([ xX])\]\s+(.*?)(\r?)$/;
5
+ const SQLITE_HUB_MAGIC_COMMENT_PATTERN =
6
+ /^\s*<!--\s*\/?sqlite-hub:magic(?:\s+[^>]*)?-->\s*$/i;
5
7
 
6
8
  function decodeBasicHtmlEntities(value = '') {
7
9
  return String(value)
@@ -26,6 +28,15 @@ function sanitizeRenderedMarkdown(html = '') {
26
28
  });
27
29
  }
28
30
 
31
+ function openRenderedMarkdownLinksInNewTabs(html = '') {
32
+ return String(html).replace(/<a\b([^>]*)>/gi, (match, attributes = '') => {
33
+ const targetAttribute = /\starget\s*=/i.test(attributes) ? '' : ' target="_blank"';
34
+ const relAttribute = /\srel\s*=/i.test(attributes) ? '' : ' rel="noopener noreferrer"';
35
+
36
+ return `<a${attributes}${targetAttribute}${relAttribute}>`;
37
+ });
38
+ }
39
+
29
40
  function renderFallbackMarkdown(markdown = '') {
30
41
  const lines = String(markdown).split(/\r?\n/);
31
42
  const html = [];
@@ -108,13 +119,13 @@ function renderMarkdownBlock(markdown = '') {
108
119
  return renderFallbackMarkdown(markdown);
109
120
  }
110
121
 
111
- return sanitizeRenderedMarkdown(
122
+ return openRenderedMarkdownLinksInNewTabs(sanitizeRenderedMarkdown(
112
123
  parser(source, {
113
124
  async: false,
114
125
  breaks: false,
115
126
  gfm: true,
116
127
  }),
117
- );
128
+ ));
118
129
  }
119
130
 
120
131
  function renderMarkdownInline(markdown = '') {
@@ -127,13 +138,13 @@ function renderMarkdownInline(markdown = '') {
127
138
  return source;
128
139
  }
129
140
 
130
- return sanitizeRenderedMarkdown(
141
+ return openRenderedMarkdownLinksInNewTabs(sanitizeRenderedMarkdown(
131
142
  parser(source, {
132
143
  async: false,
133
144
  breaks: false,
134
145
  gfm: true,
135
146
  }),
136
- );
147
+ ));
137
148
  }
138
149
 
139
150
  function renderTaskList(items = []) {
@@ -193,6 +204,12 @@ export function renderMarkdownPreview(markdown = '') {
193
204
  };
194
205
 
195
206
  lines.forEach((line, lineIndex) => {
207
+ if (!inFence && SQLITE_HUB_MAGIC_COMMENT_PATTERN.test(line)) {
208
+ flushTasks();
209
+ flushMarkdown();
210
+ return;
211
+ }
212
+
196
213
  const fenceLine = FENCED_CODE_PATTERN.test(line);
197
214
 
198
215
  if (fenceLine) {