sqlite-hub 0.12.0 → 0.17.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 (64) hide show
  1. package/README.md +118 -23
  2. package/bin/sqlite-hub.js +1041 -224
  3. package/frontend/index.html +1 -0
  4. package/frontend/js/api.js +32 -2
  5. package/frontend/js/app.js +989 -13
  6. package/frontend/js/components/modal.js +644 -15
  7. package/frontend/js/components/pageHeader.js +14 -16
  8. package/frontend/js/components/queryEditor.js +9 -1
  9. package/frontend/js/components/queryHistoryPanel.js +126 -131
  10. package/frontend/js/components/queryResults.js +79 -17
  11. package/frontend/js/components/rowEditorPanel.js +204 -10
  12. package/frontend/js/components/sidebar.js +102 -18
  13. package/frontend/js/components/tableDesignerEditor.js +69 -11
  14. package/frontend/js/router.js +8 -0
  15. package/frontend/js/store.js +868 -9
  16. package/frontend/js/utils/copyColumnExport.js +117 -0
  17. package/frontend/js/utils/exportFilenames.js +32 -0
  18. package/frontend/js/utils/filePathPreview.js +315 -0
  19. package/frontend/js/utils/format.js +1 -1
  20. package/frontend/js/utils/markdownDocuments.js +248 -0
  21. package/frontend/js/utils/rowEditorJson.js +65 -0
  22. package/frontend/js/utils/sqlFormatter.js +691 -0
  23. package/frontend/js/utils/tableDesigner.js +178 -6
  24. package/frontend/js/utils/textCellStats.js +20 -0
  25. package/frontend/js/utils/timestampPreview.js +264 -0
  26. package/frontend/js/views/charts.js +3 -1
  27. package/frontend/js/views/data.js +34 -2
  28. package/frontend/js/views/documents.js +300 -0
  29. package/frontend/js/views/editor.js +48 -1
  30. package/frontend/js/views/settings.js +39 -6
  31. package/frontend/js/views/structure.js +154 -212
  32. package/frontend/styles/base.css +6 -0
  33. package/frontend/styles/components.css +476 -2
  34. package/frontend/styles/structure-graph.css +0 -3
  35. package/frontend/styles/tailwind.generated.css +1 -1
  36. package/frontend/styles/tokens.css +1 -1
  37. package/frontend/styles/views.css +422 -0
  38. package/package.json +3 -3
  39. package/server/routes/documents.js +163 -0
  40. package/server/routes/settings.js +22 -6
  41. package/server/server.js +6 -0
  42. package/server/services/sqlite/introspection.js +10 -0
  43. package/server/services/sqlite/sqlExecutor.js +29 -0
  44. package/server/services/sqlite/tableDesigner/changeAnalysis.js +25 -1
  45. package/server/services/sqlite/tableDesigner/schemaMapping.js +105 -10
  46. package/server/services/sqlite/tableDesigner/validation.js +60 -2
  47. package/server/services/sqlite/tableDesignerService.js +1 -1
  48. package/server/services/storage/appStateStore.js +313 -0
  49. package/tests/check-constraint-options.test.js +14 -0
  50. package/tests/cli-args.test.js +100 -0
  51. package/tests/copy-column-modal.test.js +83 -0
  52. package/tests/database-documents.test.js +85 -0
  53. package/tests/export-filenames.test.js +34 -0
  54. package/tests/file-path-preview.test.js +165 -0
  55. package/tests/markdown-documents.test.js +79 -0
  56. package/tests/row-editor-json.test.js +82 -0
  57. package/tests/row-editor-timestamp-preview.test.js +192 -0
  58. package/tests/settings-metadata.test.js +16 -0
  59. package/tests/settings-view.test.js +32 -0
  60. package/tests/sql-formatter.test.js +173 -0
  61. package/tests/sql-highlight.test.js +38 -0
  62. package/tests/table-designer-v2-unique-constraints.test.js +78 -0
  63. package/tests/text-cell-stats.test.js +38 -0
  64. package/fill.js +0 -526
@@ -156,14 +156,32 @@
156
156
  .sidebar-footer {
157
157
  margin-top: auto;
158
158
  padding: 0 var(--spacing-6);
159
+ position: relative;
159
160
  }
160
161
 
161
162
  .sidebar-footer-card {
162
163
  align-items: center;
163
164
  background: var(--color-surface-lowest);
165
+ border: 1px solid rgb(var(--rgb-outline) / 0.12);
166
+ cursor: pointer;
164
167
  display: flex;
165
168
  gap: var(--spacing-3);
169
+ list-style: none;
166
170
  padding: var(--spacing-2);
171
+ transition:
172
+ background-color var(--transition-fast),
173
+ border-color var(--transition-fast),
174
+ color var(--transition-fast);
175
+ }
176
+
177
+ .sidebar-footer-card:hover,
178
+ .sidebar-db-picker[open] .sidebar-footer-card {
179
+ background: var(--color-surface-container);
180
+ border-color: var(--primary-alpha-24);
181
+ }
182
+
183
+ .sidebar-footer-card::-webkit-details-marker {
184
+ display: none;
167
185
  }
168
186
 
169
187
  .sidebar-footer-mark {
@@ -178,6 +196,146 @@
178
196
  width: 2rem;
179
197
  }
180
198
 
199
+ .sidebar-db-picker {
200
+ position: relative;
201
+ }
202
+
203
+ .sidebar-db-picker__chevron {
204
+ color: rgb(var(--rgb-on-surface-variant) / 0.55);
205
+ font-size: 18px;
206
+ line-height: 1;
207
+ transition:
208
+ color var(--transition-fast),
209
+ transform var(--transition-fast);
210
+ }
211
+
212
+ .sidebar-db-picker[open] .sidebar-db-picker__chevron {
213
+ color: var(--color-primary-container);
214
+ transform: rotate(180deg);
215
+ }
216
+
217
+ .sidebar-db-picker__panel {
218
+ background: var(--color-surface-container);
219
+ border: 1px solid rgb(var(--rgb-outline) / 0.2);
220
+ bottom: calc(100% + var(--spacing-3));
221
+ box-shadow: 0 18px 48px rgb(0 0 0 / 0.42);
222
+ display: flex;
223
+ flex-direction: column;
224
+ gap: var(--spacing-2);
225
+ left: 0;
226
+ padding: var(--spacing-2);
227
+ position: absolute;
228
+ right: 0;
229
+ z-index: 35;
230
+ }
231
+
232
+ .sidebar-db-picker__header {
233
+ align-items: center;
234
+ color: rgb(var(--rgb-on-surface-variant) / 0.62);
235
+ display: flex;
236
+ font-family: var(--font-family-mono);
237
+ font-size: 9px;
238
+ font-weight: 700;
239
+ justify-content: space-between;
240
+ letter-spacing: 0.16em;
241
+ padding: var(--spacing-1) var(--spacing-2);
242
+ text-transform: uppercase;
243
+ }
244
+
245
+ .sidebar-db-picker__list {
246
+ display: flex;
247
+ flex-direction: column;
248
+ gap: var(--spacing-2);
249
+ }
250
+
251
+ .sidebar-db-picker-card {
252
+ align-items: center;
253
+ background: var(--color-surface-low);
254
+ border: 1px solid rgb(var(--rgb-outline) / 0.12);
255
+ color: var(--color-on-surface);
256
+ cursor: pointer;
257
+ display: flex;
258
+ gap: var(--spacing-3);
259
+ min-width: 0;
260
+ padding: var(--spacing-2);
261
+ text-align: left;
262
+ transition:
263
+ background-color var(--transition-fast),
264
+ border-color var(--transition-fast),
265
+ box-shadow var(--transition-fast);
266
+ width: 100%;
267
+ }
268
+
269
+ .sidebar-db-picker-card:hover {
270
+ background: var(--color-surface-high);
271
+ border-color: var(--primary-alpha-24);
272
+ }
273
+
274
+ .sidebar-db-picker-card.is-active {
275
+ box-shadow: inset 2px 0 0 var(--color-primary-container);
276
+ }
277
+
278
+ .sidebar-db-picker-card__mark {
279
+ align-items: center;
280
+ background: var(--color-surface-container-highest);
281
+ color: var(--color-outline-variant);
282
+ display: flex;
283
+ flex: 0 0 2rem;
284
+ height: 2rem;
285
+ justify-content: center;
286
+ width: 2rem;
287
+ }
288
+
289
+ .sidebar-db-picker-card.is-active .sidebar-db-picker-card__mark {
290
+ background: var(--color-primary-container);
291
+ color: var(--color-on-primary);
292
+ }
293
+
294
+ .sidebar-db-picker-card__body {
295
+ display: block;
296
+ min-width: 0;
297
+ }
298
+
299
+ .sidebar-db-picker-card__label,
300
+ .sidebar-db-picker-card__path,
301
+ .sidebar-db-picker-card__meta {
302
+ display: block;
303
+ overflow: hidden;
304
+ text-overflow: ellipsis;
305
+ white-space: nowrap;
306
+ }
307
+
308
+ .sidebar-db-picker-card__label {
309
+ color: var(--color-on-surface);
310
+ font-size: 0.72rem;
311
+ font-weight: 700;
312
+ }
313
+
314
+ .sidebar-db-picker-card__path {
315
+ color: rgb(var(--rgb-on-surface-variant) / 0.54);
316
+ font-family: var(--font-family-mono);
317
+ font-size: 9px;
318
+ margin-top: 1px;
319
+ }
320
+
321
+ .sidebar-db-picker-card__meta {
322
+ color: rgb(var(--rgb-primary) / 0.78);
323
+ font-family: var(--font-family-mono);
324
+ font-size: 8px;
325
+ font-weight: 700;
326
+ letter-spacing: 0.12em;
327
+ margin-top: 2px;
328
+ text-transform: uppercase;
329
+ }
330
+
331
+ .sidebar-db-picker__empty {
332
+ border: 1px dashed rgb(var(--rgb-outline) / 0.16);
333
+ color: rgb(var(--rgb-on-surface-variant) / 0.55);
334
+ font-size: 0.72rem;
335
+ padding: var(--spacing-3);
336
+ text-align: center;
337
+ }
338
+
181
339
  .status-bar-shell {
182
340
  align-items: center;
183
341
  background: var(--color-surface-lowest);
@@ -277,6 +435,8 @@
277
435
  .signature-button:focus-visible,
278
436
  .delete-button:focus-visible,
279
437
  .toolbar-button:focus-visible,
438
+ .query-result-column-menu__toggle:focus-visible,
439
+ .query-result-column-menu__item:focus-visible,
280
440
  .query-history-icon-button:focus-visible,
281
441
  .top-nav-icon:focus-visible,
282
442
  .query-history-item-hit:focus-visible,
@@ -284,6 +444,8 @@
284
444
  .bottom-tab:focus-visible,
285
445
  .sidebar-link:focus-visible,
286
446
  .sidebar-sublink:focus-visible,
447
+ .sidebar-footer-card:focus-visible,
448
+ .sidebar-db-picker-card:focus-visible,
287
449
  .charts-height-toggle__button:focus-visible {
288
450
  box-shadow: var(--focus-ring);
289
451
  outline: none;
@@ -303,6 +465,142 @@
303
465
  color var(--transition-fast);
304
466
  }
305
467
 
468
+ .query-result-header-cell {
469
+ min-width: 10rem;
470
+ position: relative;
471
+ }
472
+
473
+ .query-result-column-header {
474
+ align-items: center;
475
+ display: flex;
476
+ gap: 6px;
477
+ min-width: 0;
478
+ position: relative;
479
+ }
480
+
481
+ .query-result-column-sort {
482
+ align-items: center;
483
+ display: flex;
484
+ gap: var(--spacing-2);
485
+ justify-content: space-between;
486
+ min-width: 0;
487
+ text-align: left;
488
+ transition: color var(--transition-fast);
489
+ width: 100%;
490
+ }
491
+
492
+ .query-result-column-static {
493
+ display: block;
494
+ min-width: 0;
495
+ width: 100%;
496
+ }
497
+
498
+ .query-result-column-label {
499
+ display: block;
500
+ min-width: 0;
501
+ }
502
+
503
+ .query-result-column-menu {
504
+ cursor: pointer;
505
+ flex: 0 0 auto;
506
+ position: relative;
507
+ }
508
+
509
+ .query-result-column-menu__toggle {
510
+ align-items: center;
511
+ color: var(--color-on-surface-variant);
512
+ cursor: pointer;
513
+ display: flex;
514
+ height: 22px;
515
+ justify-content: center;
516
+ list-style: none;
517
+ opacity: 0.22;
518
+ transition:
519
+ background-color var(--transition-fast),
520
+ color var(--transition-fast),
521
+ opacity var(--transition-fast);
522
+ width: 22px;
523
+ }
524
+
525
+ .query-result-column-menu__toggle::-webkit-details-marker {
526
+ display: none;
527
+ }
528
+
529
+ .query-result-column-header:hover .query-result-column-menu__toggle,
530
+ .query-result-column-menu[open] .query-result-column-menu__toggle {
531
+ opacity: 1;
532
+ }
533
+
534
+ .query-result-column-menu[open] .query-result-column-menu__toggle {
535
+ background: var(--color-surface-bright);
536
+ color: var(--color-primary-container);
537
+ }
538
+
539
+ .query-result-column-menu__toggle .material-symbols-outlined {
540
+ font-size: 18px;
541
+ line-height: 1;
542
+ }
543
+
544
+ .query-result-column-menu__panel {
545
+ background: var(--color-surface-container);
546
+ border: 1px solid rgb(var(--rgb-outline) / 0.22);
547
+ box-shadow: 0 18px 40px rgb(0 0 0 / 0.35);
548
+ min-width: 13rem;
549
+ padding: 4px;
550
+ position: absolute;
551
+ right: 0;
552
+ top: calc(100% + 6px);
553
+ z-index: 30;
554
+ }
555
+
556
+ .query-result-column-menu__item {
557
+ color: var(--color-on-surface);
558
+ cursor: pointer;
559
+ display: block;
560
+ font-family: var(--font-family-body);
561
+ font-size: 0.75rem;
562
+ line-height: 1.3;
563
+ padding: 0.55rem 0.7rem;
564
+ text-align: left;
565
+ transition:
566
+ background-color var(--transition-fast),
567
+ color var(--transition-fast);
568
+ width: 100%;
569
+ }
570
+
571
+ .query-result-column-menu__item:hover {
572
+ background: var(--color-surface-highest);
573
+ color: var(--color-primary-container);
574
+ }
575
+
576
+ .copy-column-preview {
577
+ background: var(--color-surface-lowest);
578
+ border: 1px solid rgb(var(--rgb-outline) / 0.12);
579
+ color: rgb(var(--rgb-on-surface) / 0.72);
580
+ font-family: var(--font-family-mono);
581
+ font-size: 0.75rem;
582
+ line-height: 1.55;
583
+ margin: 0;
584
+ max-height: 7.5rem;
585
+ overflow: auto;
586
+ overflow-wrap: anywhere;
587
+ padding: var(--spacing-3);
588
+ white-space: pre-wrap;
589
+ }
590
+
591
+ .copy-column-preview--editable {
592
+ display: block;
593
+ min-height: 10rem;
594
+ outline: none;
595
+ resize: vertical;
596
+ width: 100%;
597
+ }
598
+
599
+ .copy-column-preview--editable:focus {
600
+ border-color: rgb(var(--rgb-primary) / 0.55);
601
+ color: rgb(var(--rgb-on-surface) / 0.9);
602
+ }
603
+
306
604
  .metric-card {
307
605
  background: var(--color-surface-low);
308
606
  display: flex;
@@ -799,6 +1097,10 @@ input.table-designer-main__name[type='text'] {
799
1097
  background: var(--primary-alpha-06);
800
1098
  }
801
1099
 
1100
+ .table-designer-banner.is-note {
1101
+ background: rgb(var(--rgb-on-surface-variant) / 0.035);
1102
+ }
1103
+
802
1104
  .table-designer-banner.is-validation {
803
1105
  background: rgb(var(--rgb-error-container) / 0.12);
804
1106
  }
@@ -853,6 +1155,18 @@ input.table-designer-main__name[type='text'] {
853
1155
  padding: var(--spacing-2) 0 var(--spacing-4);
854
1156
  }
855
1157
 
1158
+ .table-designer-main__section-actions {
1159
+ align-items: center;
1160
+ display: flex;
1161
+ flex-wrap: wrap;
1162
+ gap: var(--spacing-2);
1163
+ justify-content: flex-end;
1164
+ }
1165
+
1166
+ .table-designer-main__section-actions .standard-button {
1167
+ gap: var(--spacing-2);
1168
+ }
1169
+
856
1170
  .table-designer-grid {
857
1171
  background: var(--color-surface-container-lowest);
858
1172
  border: 1px solid rgb(var(--rgb-outline) / 0.14);
@@ -874,8 +1188,8 @@ input.table-designer-main__name[type='text'] {
874
1188
  minmax(10rem, 1fr)
875
1189
  minmax(10rem, 1fr)
876
1190
  minmax(10rem, 1fr)
877
- minmax(7rem, max-content);
878
- min-width: 82rem;
1191
+ minmax(13rem, max-content);
1192
+ min-width: 88rem;
879
1193
  padding: var(--spacing-3);
880
1194
  }
881
1195
 
@@ -892,11 +1206,171 @@ input.table-designer-main__name[type='text'] {
892
1206
  z-index: 2;
893
1207
  }
894
1208
 
1209
+ .table-designer-constraints__list {
1210
+ align-items: start;
1211
+ display: grid;
1212
+ gap: var(--spacing-3);
1213
+ grid-template-columns: repeat(auto-fit, minmax(min(24rem, 100%), 1fr));
1214
+ }
1215
+
1216
+ .table-designer-constraints-modal {
1217
+ display: flex;
1218
+ flex-direction: column;
1219
+ gap: var(--spacing-4);
1220
+ max-height: min(62vh, 44rem);
1221
+ overflow: auto;
1222
+ padding-right: 0.1rem;
1223
+ }
1224
+
1225
+ .table-designer-constraints-modal__summary {
1226
+ align-items: center;
1227
+ background: var(--color-surface-container-lowest);
1228
+ border: 1px solid rgb(var(--rgb-outline) / 0.1);
1229
+ display: flex;
1230
+ gap: var(--spacing-3);
1231
+ justify-content: space-between;
1232
+ min-width: 0;
1233
+ padding: var(--spacing-3) var(--spacing-4);
1234
+ }
1235
+
1236
+ .table-designer-constraints-modal__summary code {
1237
+ color: var(--color-primary-container);
1238
+ display: block;
1239
+ font-family: var(--font-family-mono);
1240
+ font-size: 0.875rem;
1241
+ margin-top: var(--spacing-1);
1242
+ overflow: hidden;
1243
+ text-overflow: ellipsis;
1244
+ white-space: nowrap;
1245
+ }
1246
+
1247
+ .table-designer-constraints-modal__label,
1248
+ .table-designer-constraints-modal__section-title {
1249
+ color: rgb(var(--rgb-on-surface-variant) / 0.62);
1250
+ font-family: var(--font-family-mono);
1251
+ font-size: var(--font-size-status);
1252
+ font-weight: 700;
1253
+ letter-spacing: 0.12em;
1254
+ text-transform: uppercase;
1255
+ }
1256
+
1257
+ .table-designer-constraints-modal__section {
1258
+ display: flex;
1259
+ flex-direction: column;
1260
+ gap: var(--spacing-3);
1261
+ }
1262
+
1263
+ .table-designer-constraints-modal__section-header {
1264
+ align-items: center;
1265
+ display: flex;
1266
+ gap: var(--spacing-3);
1267
+ justify-content: space-between;
1268
+ }
1269
+
1270
+ .table-designer-constraints-modal__empty {
1271
+ background: var(--color-surface-container-lowest);
1272
+ border: 1px solid rgb(var(--rgb-outline) / 0.1);
1273
+ color: rgb(var(--rgb-on-surface) / 0.58);
1274
+ font-size: 0.8125rem;
1275
+ padding: var(--spacing-4);
1276
+ }
1277
+
1278
+ .table-designer-constraint-editor {
1279
+ background: var(--color-surface-container-lowest);
1280
+ border: 1px solid rgb(var(--rgb-outline) / 0.14);
1281
+ display: flex;
1282
+ flex-direction: column;
1283
+ gap: var(--spacing-3);
1284
+ min-width: 0;
1285
+ padding: var(--spacing-3);
1286
+ }
1287
+
1288
+ .table-designer-constraint-editor__header {
1289
+ align-items: flex-start;
1290
+ display: flex;
1291
+ gap: var(--spacing-3);
1292
+ justify-content: space-between;
1293
+ }
1294
+
1295
+ .table-designer-constraint-editor__name {
1296
+ margin-top: var(--spacing-2);
1297
+ width: min(22rem, 100%);
1298
+ }
1299
+
1300
+ .table-designer-constraint-editor__type {
1301
+ color: var(--color-on-surface);
1302
+ font-family: var(--font-family-mono);
1303
+ font-size: var(--font-size-status);
1304
+ font-weight: 700;
1305
+ letter-spacing: 0.12em;
1306
+ overflow: hidden;
1307
+ text-overflow: ellipsis;
1308
+ text-transform: uppercase;
1309
+ white-space: nowrap;
1310
+ }
1311
+
1312
+ .table-designer-constraint__columns {
1313
+ display: flex;
1314
+ flex-wrap: wrap;
1315
+ gap: var(--spacing-2);
1316
+ }
1317
+
1318
+ .table-designer-constraint__columns span,
1319
+ .table-designer-constraint__values span {
1320
+ border: 1px solid rgb(var(--rgb-outline) / 0.16);
1321
+ color: rgb(var(--rgb-on-surface) / 0.72);
1322
+ font-family: var(--font-family-mono);
1323
+ font-size: var(--font-size-status);
1324
+ padding: 0.2rem 0.45rem;
1325
+ }
1326
+
1327
+ .table-designer-constraint__values {
1328
+ display: flex;
1329
+ flex-wrap: wrap;
1330
+ gap: var(--spacing-2);
1331
+ max-height: 8rem;
1332
+ overflow: auto;
1333
+ }
1334
+
1335
+ .table-designer-constraint__values span {
1336
+ background: var(--primary-alpha-06);
1337
+ border-color: var(--primary-alpha-18);
1338
+ color: var(--color-primary-container);
1339
+ }
1340
+
1341
+ .table-designer-constraint-editor__sql {
1342
+ background: var(--color-surface-low);
1343
+ border: 1px solid rgb(var(--rgb-outline) / 0.1);
1344
+ color: rgb(var(--rgb-on-surface) / 0.68);
1345
+ font-family: var(--font-family-mono);
1346
+ font-size: 0.72rem;
1347
+ line-height: 1.5;
1348
+ margin: 0;
1349
+ min-height: 7rem;
1350
+ overflow: auto;
1351
+ padding: var(--spacing-3);
1352
+ resize: vertical;
1353
+ width: 100%;
1354
+ }
1355
+
895
1356
  .table-designer-grid__row {
896
1357
  border-bottom: 1px solid rgb(var(--rgb-outline) / 0.1);
897
1358
  align-items: center;
898
1359
  }
899
1360
 
1361
+ .table-designer-row-actions {
1362
+ align-items: center;
1363
+ display: flex;
1364
+ gap: var(--spacing-2);
1365
+ justify-content: flex-end;
1366
+ min-width: 0;
1367
+ }
1368
+
1369
+ .table-designer-row-check-button {
1370
+ gap: var(--spacing-2);
1371
+ white-space: nowrap;
1372
+ }
1373
+
900
1374
  .table-designer-field {
901
1375
  height: var(--control-height);
902
1376
  min-height: var(--control-height);
@@ -1,6 +1,5 @@
1
1
  .structure-graph {
2
2
  background: var(--color-surface-container);
3
- border: 1px solid rgba(138, 123, 52, 0.26);
4
3
  display: flex;
5
4
  flex-direction: column;
6
5
  height: 100%;
@@ -10,8 +9,6 @@
10
9
 
11
10
  .structure-graph__toolbar {
12
11
  align-items: center;
13
- background: linear-gradient(to bottom, rgba(45, 43, 37, 0.97), rgba(23, 23, 20, 0.96));
14
- border-bottom: 1px solid rgba(138, 123, 52, 0.24);
15
12
  display: flex;
16
13
  flex-wrap: wrap;
17
14
  gap: 1rem;