sqlite-hub 1.2.0 → 1.4.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 (152) hide show
  1. package/README.md +106 -73
  2. package/bin/sqlite-hub.js +176 -2
  3. package/docs/API.md +122 -0
  4. package/docs/CLI.md +227 -0
  5. package/docs/DESIGN_GUIDELINES.md +45 -0
  6. package/docs/changelog.md +141 -0
  7. package/docs/shortkeys.md +27 -0
  8. package/docs/todo.md +16 -0
  9. package/examples/api/generate-types.js +52 -0
  10. package/frontend/assets/mockups/backups_1_1920.webp +0 -0
  11. package/frontend/assets/mockups/backups_2_create_backup_modal_1920.webp +0 -0
  12. package/frontend/assets/mockups/backups_3_edit_backup_modal_1920.webp +0 -0
  13. package/frontend/assets/mockups/backups_4_restore_backup_modal_1920.webp +0 -0
  14. package/frontend/assets/mockups/backups_5_delete_backup_modal_1920.webp +0 -0
  15. package/frontend/assets/mockups/charts_1_1920.webp +0 -0
  16. package/frontend/assets/mockups/charts_2_query_detail_1920.webp +0 -0
  17. package/frontend/assets/mockups/charts_3_create_query_chart_modal_1920.webp +0 -0
  18. package/frontend/assets/mockups/charts_4_edit_query_chart_modal_1920.webp +0 -0
  19. package/frontend/assets/mockups/charts_5_delete_query_chart_modal_1920.webp +0 -0
  20. package/frontend/assets/mockups/charts_6_copy_column_modal_1920.webp +0 -0
  21. package/frontend/assets/mockups/connections_1_1920.webp +0 -0
  22. package/frontend/assets/mockups/connections_2_create_connection_modal_1920.webp +0 -0
  23. package/frontend/assets/mockups/connections_3_open_connection_modal_1920.webp +0 -0
  24. package/frontend/assets/mockups/data_1_1920.webp +0 -0
  25. package/frontend/assets/mockups/data_2_roweditor_1920.webp +0 -0
  26. package/frontend/assets/mockups/data_3_data_export_modal_1920.webp +0 -0
  27. package/frontend/assets/mockups/documents_1_1920.webp +0 -0
  28. package/frontend/assets/mockups/documents_2_document_insert_table_modal_1920.webp +0 -0
  29. package/frontend/assets/mockups/documents_3_document_insert_note_modal_1920.webp +0 -0
  30. package/frontend/assets/mockups/media_tagging_queue_1_1920.webp +0 -0
  31. package/frontend/assets/mockups/media_tagging_setup_1_1920.webp +0 -0
  32. package/frontend/assets/mockups/media_tagging_setup_2_create_media_tagging_tag_table_modal_1920.webp +0 -0
  33. package/frontend/assets/mockups/media_tagging_setup_3_create_media_tagging_mapping_table_modal_1920.webp +0 -0
  34. package/frontend/assets/mockups/overview_1_1920.webp +0 -0
  35. package/frontend/assets/mockups/settings_1_1920.webp +0 -0
  36. package/frontend/assets/mockups/sql_editor_1_1920.webp +0 -0
  37. package/frontend/assets/mockups/sql_editor_2_query_detail_1920.webp +0 -0
  38. package/frontend/assets/mockups/sql_editor_3_query_export_modal_1920.webp +0 -0
  39. package/frontend/assets/mockups/structure_1_1920.webp +0 -0
  40. package/frontend/assets/mockups/structure_2_generate_types_modal_1920.webp +0 -0
  41. package/frontend/assets/mockups/structure_3_generate_types_modal_1920.webp +0 -0
  42. package/frontend/assets/mockups/table_designer_1_1920.webp +0 -0
  43. package/frontend/assets/mockups/table_designer_2_table_designer_constraints_modal_1920.webp +0 -0
  44. package/frontend/js/api.js +18 -0
  45. package/frontend/js/app.js +118 -8
  46. package/frontend/js/components/connectionCard.js +1 -1
  47. package/frontend/js/components/emptyState.js +4 -4
  48. package/frontend/js/components/generateTypesDropdown.js +33 -0
  49. package/frontend/js/components/metricCard.js +1 -1
  50. package/frontend/js/components/modal.js +211 -18
  51. package/frontend/js/components/pageHeader.js +1 -1
  52. package/frontend/js/components/queryHistoryDetail.js +3 -3
  53. package/frontend/js/components/queryHistoryHeader.js +1 -1
  54. package/frontend/js/components/queryHistoryPanel.js +1 -1
  55. package/frontend/js/components/rowEditorPanel.js +13 -3
  56. package/frontend/js/router.js +28 -6
  57. package/frontend/js/store.js +422 -8
  58. package/frontend/js/views/backups.js +529 -37
  59. package/frontend/js/views/charts.js +9 -9
  60. package/frontend/js/views/connections.js +2 -2
  61. package/frontend/js/views/data.js +1 -1
  62. package/frontend/js/views/documents.js +3 -3
  63. package/frontend/js/views/editor.js +6 -6
  64. package/frontend/js/views/mediaTagging.js +7 -5
  65. package/frontend/js/views/overview.js +3 -3
  66. package/frontend/js/views/settings.js +3 -3
  67. package/frontend/js/views/structure.js +6 -1
  68. package/frontend/styles/base.css +1 -40
  69. package/frontend/styles/components.css +109 -232
  70. package/frontend/styles/structure-graph.css +32 -68
  71. package/frontend/styles/tailwind.css +8 -4
  72. package/frontend/styles/tailwind.generated.css +1 -1
  73. package/frontend/styles/tokens.css +28 -21
  74. package/frontend/styles/views.css +94 -261
  75. package/package.json +18 -2
  76. package/server/routes/backups.js +18 -2
  77. package/server/routes/externalApi.js +36 -0
  78. package/server/routes/structure.js +22 -0
  79. package/server/services/databaseCommandService.js +14 -0
  80. package/server/services/sqlite/backupDiff.js +914 -0
  81. package/server/services/sqlite/backupService.js +77 -1
  82. package/server/services/sqlite/structureService.js +7 -0
  83. package/server/services/typeGenerationService.js +663 -0
  84. package/tailwind.config.cjs +0 -1
  85. package/.github/funding.yml +0 -2
  86. package/.github/workflows/ci.yml +0 -36
  87. package/database.sqlite +0 -0
  88. package/frontend/assets/mockups/charts_1_bars_1200.webp +0 -0
  89. package/frontend/assets/mockups/charts_2_pie_1200.webp +0 -0
  90. package/frontend/assets/mockups/charts_3_scatter_plot_1200.webp +0 -0
  91. package/frontend/assets/mockups/connections_1200.webp +0 -0
  92. package/frontend/assets/mockups/data_1_1200.webp +0 -0
  93. package/frontend/assets/mockups/data_2_row_editor_1200.webp +0 -0
  94. package/frontend/assets/mockups/documents_1200.webp +0 -0
  95. package/frontend/assets/mockups/media_tagging_1_setup_1200.webp +0 -0
  96. package/frontend/assets/mockups/media_tagging_2_tagging_queue_1200.webp +0 -0
  97. package/frontend/assets/mockups/media_tagging_3_media_viewer_1200.webp +0 -0
  98. package/frontend/assets/mockups/overview_1200.webp +0 -0
  99. package/frontend/assets/mockups/settings_1200.webp +0 -0
  100. package/frontend/assets/mockups/sql_editor_1_1200.webp +0 -0
  101. package/frontend/assets/mockups/sql_editor_2_query_details_1200.webp +0 -0
  102. package/frontend/assets/mockups/sql_editor_3_export_column_1200.webp +0 -0
  103. package/frontend/assets/mockups/sql_editor_4_export_column_as_markdown_1200.webp +0 -0
  104. package/frontend/assets/mockups/sql_editor_5_export_query_result_1200.webp +0 -0
  105. package/frontend/assets/mockups/structure_1_1200.webp +0 -0
  106. package/frontend/assets/mockups/structure_2_inspector_1200.webp +0 -0
  107. package/frontend/assets/mockups/table_designer_1_1200.webp +0 -0
  108. package/frontend/assets/mockups/table_designer_2_checks_1200.webp +0 -0
  109. package/tests/api-token-auth.test.js +0 -279
  110. package/tests/backup-manager.test.js +0 -140
  111. package/tests/backups-view.test.js +0 -70
  112. package/tests/charts-height-preset-storage.test.js +0 -60
  113. package/tests/charts-route-state.test.js +0 -144
  114. package/tests/check-constraint-options.test.js +0 -90
  115. package/tests/cli-args.test.js +0 -113
  116. package/tests/cli-service-delegation.test.js +0 -140
  117. package/tests/connection-removal.test.js +0 -52
  118. package/tests/connections-file-dialog-route.test.js +0 -89
  119. package/tests/copy-column-modal.test.js +0 -131
  120. package/tests/database-command-service.test.js +0 -174
  121. package/tests/database-documents.test.js +0 -85
  122. package/tests/documents-view.test.js +0 -132
  123. package/tests/dropdown-button.test.js +0 -101
  124. package/tests/email-preview.test.js +0 -89
  125. package/tests/export-blob.test.js +0 -99
  126. package/tests/export-filenames.test.js +0 -38
  127. package/tests/file-path-preview.test.js +0 -165
  128. package/tests/form-controls.test.js +0 -34
  129. package/tests/json-preview.test.js +0 -49
  130. package/tests/local-request-security.test.js +0 -85
  131. package/tests/markdown-documents.test.js +0 -103
  132. package/tests/native-file-dialog.test.js +0 -105
  133. package/tests/query-editor.test.js +0 -28
  134. package/tests/query-history-detail.test.js +0 -37
  135. package/tests/query-history-header.test.js +0 -30
  136. package/tests/query-results-truncation.test.js +0 -20
  137. package/tests/risky-sql.test.js +0 -30
  138. package/tests/row-editor-json.test.js +0 -82
  139. package/tests/row-editor-null-values.test.js +0 -184
  140. package/tests/row-editor-timestamp-preview.test.js +0 -192
  141. package/tests/security-paths.test.js +0 -84
  142. package/tests/settings-api-tokens-route.test.js +0 -97
  143. package/tests/settings-metadata.test.js +0 -114
  144. package/tests/settings-view.test.js +0 -108
  145. package/tests/sql-formatter.test.js +0 -173
  146. package/tests/sql-highlight.test.js +0 -38
  147. package/tests/sql-identifier-safety.test.js +0 -171
  148. package/tests/sql-result-limit.test.js +0 -66
  149. package/tests/structure-view.test.js +0 -60
  150. package/tests/table-designer-v2-unique-constraints.test.js +0 -78
  151. package/tests/table-scroll-state.test.js +0 -70
  152. package/tests/text-cell-stats.test.js +0 -38
package/package.json CHANGED
@@ -1,12 +1,26 @@
1
1
  {
2
2
  "name": "sqlite-hub",
3
- "version": "1.2.0",
3
+ "version": "1.4.0",
4
4
  "description": "SQLite-only local management app backend and SPA shell",
5
5
  "license": "MIT",
6
6
  "main": "server/server.js",
7
7
  "bin": {
8
8
  "sqlite-hub": "bin/sqlite-hub.js"
9
9
  },
10
+ "files": [
11
+ "bin/",
12
+ "docs/",
13
+ "examples/",
14
+ "frontend/",
15
+ "server/data/.gitkeep",
16
+ "server/data/db_logos/.gitkeep",
17
+ "server/middleware/",
18
+ "server/routes/",
19
+ "server/server.js",
20
+ "server/services/",
21
+ "server/utils/",
22
+ "tailwind.config.cjs"
23
+ ],
10
24
  "scripts": {
11
25
  "build": "npm run build:css",
12
26
  "build:css": "tailwindcss -i ./frontend/styles/tailwind.css -o ./frontend/styles/tailwind.generated.css --minify",
@@ -15,7 +29,9 @@
15
29
  "start": "node bin/sqlite-hub.js",
16
30
  "dev": "node --watch server/server.js --port:4180",
17
31
  "prepack": "npm run build:css",
18
- "publish": "bash scripts/publish_brew.sh && sleep 10 && npm login --auth-type=web && bash scripts/publish_npm.sh"
32
+ "publish": "bash scripts/publish_brew.sh && sleep 10 && bash scripts/publish_npm.sh",
33
+ "screenshots": "node scripts/screenshot_sqlite_hub.js --width:1920 --height:1280",
34
+ "screenshots:backup-drawer": "node scripts/screenshot_backup_drawer.js"
19
35
  },
20
36
  "dependencies": {
21
37
  "better-sqlite3": "^12.10.1",
@@ -27,6 +27,19 @@ function createBackupsRouter({ backupService }) {
27
27
  })
28
28
  );
29
29
 
30
+ router.get(
31
+ "/:backupId/diff",
32
+ route((req, res) => {
33
+ res.json(
34
+ successResponse({
35
+ data: backupService.diffBackupWithCurrent(req.params.backupId, {
36
+ sampleLimit: req.query.sampleLimit,
37
+ }),
38
+ })
39
+ );
40
+ })
41
+ );
42
+
30
43
  router.post(
31
44
  "/",
32
45
  route(async (req, res) => {
@@ -49,11 +62,14 @@ function createBackupsRouter({ backupService }) {
49
62
  router.patch(
50
63
  "/:backupId",
51
64
  route((req, res) => {
52
- const backup = backupService.updateBackupNotes(req.params.backupId, req.body?.notes ?? "");
65
+ const backup = backupService.updateBackupDetails(req.params.backupId, {
66
+ name: req.body?.name,
67
+ notes: req.body?.notes,
68
+ });
53
69
 
54
70
  res.json(
55
71
  successResponse({
56
- message: "Backup notes updated.",
72
+ message: "Backup updated.",
57
73
  data: backup,
58
74
  })
59
75
  );
@@ -154,6 +154,42 @@ function createExternalApiRouter({ databaseService, tokenService, appInfoService
154
154
  })
155
155
  );
156
156
 
157
+ router.post(
158
+ "/databases/:databaseId/tables/:tableName/types",
159
+ route((req, res) => {
160
+ const target = String(req.body?.target ?? "").trim();
161
+
162
+ if (!["typescript", "rust", "kotlin", "swift"].includes(target)) {
163
+ throw new ValidationError(
164
+ `Unsupported type target "${req.body?.target}". Supported targets: typescript, rust, kotlin, swift.`,
165
+ { code: "INVALID_TYPE_TARGET" }
166
+ );
167
+ }
168
+
169
+ const result = databaseService.generateTableTypes(
170
+ req.params.databaseId,
171
+ req.params.tableName,
172
+ target,
173
+ req.body?.options ?? {}
174
+ );
175
+ const { warnings, metadata, ...data } = result;
176
+
177
+ res.json(
178
+ successResponse({
179
+ message: "Types generated.",
180
+ data,
181
+ metadata: {
182
+ databaseId: req.params.databaseId,
183
+ tableName: req.params.tableName,
184
+ ...metadata,
185
+ },
186
+ warnings,
187
+ readOnly: true,
188
+ })
189
+ );
190
+ })
191
+ );
192
+
157
193
  router.get(
158
194
  "/databases/:databaseId/queries",
159
195
  route((req, res) => {
@@ -30,6 +30,28 @@ function createStructureRouter({ structureService }) {
30
30
  })
31
31
  );
32
32
 
33
+ router.post(
34
+ "/:tableName/types",
35
+ route((req, res) => {
36
+ const result = structureService.generateTableTypes(
37
+ req.params.tableName,
38
+ req.body?.target,
39
+ req.body?.options ?? {}
40
+ );
41
+ const { warnings, metadata, ...data } = result;
42
+
43
+ res.json(
44
+ successResponse({
45
+ message: "Types generated.",
46
+ data,
47
+ metadata,
48
+ warnings,
49
+ readOnly: true,
50
+ })
51
+ );
52
+ })
53
+ );
54
+
33
55
  return router;
34
56
  }
35
57
 
@@ -5,6 +5,7 @@ const { DataBrowserService } = require("./sqlite/dataBrowserService");
5
5
  const { ExportService } = require("./sqlite/exportService");
6
6
  const { getTableDetail } = require("./sqlite/introspection");
7
7
  const { SqlExecutor } = require("./sqlite/sqlExecutor");
8
+ const { TypeGenerationService } = require("./typeGenerationService");
8
9
 
9
10
  function normalizeLookupValue(value, label) {
10
11
  const normalized = String(value ?? "").trim();
@@ -166,6 +167,7 @@ class DatabaseCommandService {
166
167
  constructor({ appStateStore, runtimeFactory } = {}) {
167
168
  this.appStateStore = appStateStore;
168
169
  this.runtimeFactory = runtimeFactory ?? ((connection, options) => this.createRuntime(connection, options));
170
+ this.typeGenerationService = new TypeGenerationService();
169
171
  }
170
172
 
171
173
  listDatabases() {
@@ -250,6 +252,18 @@ class DatabaseCommandService {
250
252
  );
251
253
  }
252
254
 
255
+ generateTableTypes(databaseReference, tableName, target, options = {}) {
256
+ const normalizedTableName = normalizeLookupValue(tableName, "Table name");
257
+ return this.withDatabase(databaseReference, ({ runtime }) =>
258
+ this.typeGenerationService.generateTypesFromDatabase(
259
+ runtime.db,
260
+ normalizedTableName,
261
+ target,
262
+ options
263
+ )
264
+ );
265
+ }
266
+
253
267
  getTableRow(databaseReference, tableName, exportTarget) {
254
268
  const normalizedTableName = normalizeLookupValue(tableName, "Table name");
255
269
  normalizeLookupValue(exportTarget, "Row key");