sqlite-hub 0.11.1 → 0.16.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 (52) hide show
  1. package/README.md +52 -13
  2. package/database.sqlite +0 -0
  3. package/frontend/js/api.js +64 -12
  4. package/frontend/js/app.js +723 -37
  5. package/frontend/js/components/emptyState.js +42 -46
  6. package/frontend/js/components/modal.js +526 -2
  7. package/frontend/js/components/queryEditor.js +12 -3
  8. package/frontend/js/components/queryResults.js +79 -17
  9. package/frontend/js/components/rowEditorPanel.js +345 -12
  10. package/frontend/js/components/sidebar.js +106 -23
  11. package/frontend/js/components/tableDesignerEditor.js +69 -11
  12. package/frontend/js/store.js +437 -26
  13. package/frontend/js/utils/copyColumnExport.js +117 -0
  14. package/frontend/js/utils/exportFilenames.js +32 -0
  15. package/frontend/js/utils/filePathPreview.js +315 -0
  16. package/frontend/js/utils/format.js +1 -1
  17. package/frontend/js/utils/rowEditorJson.js +65 -0
  18. package/frontend/js/utils/sqlFormatter.js +691 -0
  19. package/frontend/js/utils/tableDesigner.js +178 -6
  20. package/frontend/js/utils/textCellStats.js +20 -0
  21. package/frontend/js/utils/timestampPreview.js +264 -0
  22. package/frontend/js/views/charts.js +3 -1
  23. package/frontend/js/views/data.js +39 -4
  24. package/frontend/js/views/editor.js +50 -1
  25. package/frontend/js/views/settings.js +1 -4
  26. package/frontend/js/views/structure.js +154 -212
  27. package/frontend/styles/base.css +6 -0
  28. package/frontend/styles/components.css +463 -2
  29. package/frontend/styles/structure-graph.css +0 -3
  30. package/frontend/styles/tailwind.generated.css +1 -1
  31. package/frontend/styles/tokens.css +95 -95
  32. package/package.json +2 -3
  33. package/server/routes/export.js +97 -12
  34. package/server/services/sqlite/dataBrowserService.js +2 -68
  35. package/server/services/sqlite/exportService.js +74 -15
  36. package/server/services/sqlite/introspection.js +209 -1
  37. package/server/services/sqlite/sqlExecutor.js +31 -0
  38. package/server/services/sqlite/tableDesigner/changeAnalysis.js +25 -1
  39. package/server/services/sqlite/tableDesigner/schemaMapping.js +105 -10
  40. package/server/services/sqlite/tableDesigner/validation.js +60 -2
  41. package/server/services/sqlite/tableDesignerService.js +1 -1
  42. package/server/services/sqlite/tableFilter.js +75 -0
  43. package/server/utils/csv.js +30 -4
  44. package/tests/check-constraint-options.test.js +90 -0
  45. package/tests/export-filenames.test.js +34 -0
  46. package/tests/file-path-preview.test.js +165 -0
  47. package/tests/row-editor-json.test.js +82 -0
  48. package/tests/row-editor-timestamp-preview.test.js +192 -0
  49. package/tests/sql-formatter.test.js +173 -0
  50. package/tests/sql-highlight.test.js +38 -0
  51. package/tests/table-designer-v2-unique-constraints.test.js +78 -0
  52. package/tests/text-cell-stats.test.js +38 -0
@@ -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,129 @@
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
+
306
591
  .metric-card {
307
592
  background: var(--color-surface-low);
308
593
  display: flex;
@@ -799,6 +1084,10 @@ input.table-designer-main__name[type='text'] {
799
1084
  background: var(--primary-alpha-06);
800
1085
  }
801
1086
 
1087
+ .table-designer-banner.is-note {
1088
+ background: rgb(var(--rgb-on-surface-variant) / 0.035);
1089
+ }
1090
+
802
1091
  .table-designer-banner.is-validation {
803
1092
  background: rgb(var(--rgb-error-container) / 0.12);
804
1093
  }
@@ -853,6 +1142,18 @@ input.table-designer-main__name[type='text'] {
853
1142
  padding: var(--spacing-2) 0 var(--spacing-4);
854
1143
  }
855
1144
 
1145
+ .table-designer-main__section-actions {
1146
+ align-items: center;
1147
+ display: flex;
1148
+ flex-wrap: wrap;
1149
+ gap: var(--spacing-2);
1150
+ justify-content: flex-end;
1151
+ }
1152
+
1153
+ .table-designer-main__section-actions .standard-button {
1154
+ gap: var(--spacing-2);
1155
+ }
1156
+
856
1157
  .table-designer-grid {
857
1158
  background: var(--color-surface-container-lowest);
858
1159
  border: 1px solid rgb(var(--rgb-outline) / 0.14);
@@ -874,8 +1175,8 @@ input.table-designer-main__name[type='text'] {
874
1175
  minmax(10rem, 1fr)
875
1176
  minmax(10rem, 1fr)
876
1177
  minmax(10rem, 1fr)
877
- minmax(7rem, max-content);
878
- min-width: 82rem;
1178
+ minmax(13rem, max-content);
1179
+ min-width: 88rem;
879
1180
  padding: var(--spacing-3);
880
1181
  }
881
1182
 
@@ -892,11 +1193,171 @@ input.table-designer-main__name[type='text'] {
892
1193
  z-index: 2;
893
1194
  }
894
1195
 
1196
+ .table-designer-constraints__list {
1197
+ align-items: start;
1198
+ display: grid;
1199
+ gap: var(--spacing-3);
1200
+ grid-template-columns: repeat(auto-fit, minmax(min(24rem, 100%), 1fr));
1201
+ }
1202
+
1203
+ .table-designer-constraints-modal {
1204
+ display: flex;
1205
+ flex-direction: column;
1206
+ gap: var(--spacing-4);
1207
+ max-height: min(62vh, 44rem);
1208
+ overflow: auto;
1209
+ padding-right: 0.1rem;
1210
+ }
1211
+
1212
+ .table-designer-constraints-modal__summary {
1213
+ align-items: center;
1214
+ background: var(--color-surface-container-lowest);
1215
+ border: 1px solid rgb(var(--rgb-outline) / 0.1);
1216
+ display: flex;
1217
+ gap: var(--spacing-3);
1218
+ justify-content: space-between;
1219
+ min-width: 0;
1220
+ padding: var(--spacing-3) var(--spacing-4);
1221
+ }
1222
+
1223
+ .table-designer-constraints-modal__summary code {
1224
+ color: var(--color-primary-container);
1225
+ display: block;
1226
+ font-family: var(--font-family-mono);
1227
+ font-size: 0.875rem;
1228
+ margin-top: var(--spacing-1);
1229
+ overflow: hidden;
1230
+ text-overflow: ellipsis;
1231
+ white-space: nowrap;
1232
+ }
1233
+
1234
+ .table-designer-constraints-modal__label,
1235
+ .table-designer-constraints-modal__section-title {
1236
+ color: rgb(var(--rgb-on-surface-variant) / 0.62);
1237
+ font-family: var(--font-family-mono);
1238
+ font-size: var(--font-size-status);
1239
+ font-weight: 700;
1240
+ letter-spacing: 0.12em;
1241
+ text-transform: uppercase;
1242
+ }
1243
+
1244
+ .table-designer-constraints-modal__section {
1245
+ display: flex;
1246
+ flex-direction: column;
1247
+ gap: var(--spacing-3);
1248
+ }
1249
+
1250
+ .table-designer-constraints-modal__section-header {
1251
+ align-items: center;
1252
+ display: flex;
1253
+ gap: var(--spacing-3);
1254
+ justify-content: space-between;
1255
+ }
1256
+
1257
+ .table-designer-constraints-modal__empty {
1258
+ background: var(--color-surface-container-lowest);
1259
+ border: 1px solid rgb(var(--rgb-outline) / 0.1);
1260
+ color: rgb(var(--rgb-on-surface) / 0.58);
1261
+ font-size: 0.8125rem;
1262
+ padding: var(--spacing-4);
1263
+ }
1264
+
1265
+ .table-designer-constraint-editor {
1266
+ background: var(--color-surface-container-lowest);
1267
+ border: 1px solid rgb(var(--rgb-outline) / 0.14);
1268
+ display: flex;
1269
+ flex-direction: column;
1270
+ gap: var(--spacing-3);
1271
+ min-width: 0;
1272
+ padding: var(--spacing-3);
1273
+ }
1274
+
1275
+ .table-designer-constraint-editor__header {
1276
+ align-items: flex-start;
1277
+ display: flex;
1278
+ gap: var(--spacing-3);
1279
+ justify-content: space-between;
1280
+ }
1281
+
1282
+ .table-designer-constraint-editor__name {
1283
+ margin-top: var(--spacing-2);
1284
+ width: min(22rem, 100%);
1285
+ }
1286
+
1287
+ .table-designer-constraint-editor__type {
1288
+ color: var(--color-on-surface);
1289
+ font-family: var(--font-family-mono);
1290
+ font-size: var(--font-size-status);
1291
+ font-weight: 700;
1292
+ letter-spacing: 0.12em;
1293
+ overflow: hidden;
1294
+ text-overflow: ellipsis;
1295
+ text-transform: uppercase;
1296
+ white-space: nowrap;
1297
+ }
1298
+
1299
+ .table-designer-constraint__columns {
1300
+ display: flex;
1301
+ flex-wrap: wrap;
1302
+ gap: var(--spacing-2);
1303
+ }
1304
+
1305
+ .table-designer-constraint__columns span,
1306
+ .table-designer-constraint__values span {
1307
+ border: 1px solid rgb(var(--rgb-outline) / 0.16);
1308
+ color: rgb(var(--rgb-on-surface) / 0.72);
1309
+ font-family: var(--font-family-mono);
1310
+ font-size: var(--font-size-status);
1311
+ padding: 0.2rem 0.45rem;
1312
+ }
1313
+
1314
+ .table-designer-constraint__values {
1315
+ display: flex;
1316
+ flex-wrap: wrap;
1317
+ gap: var(--spacing-2);
1318
+ max-height: 8rem;
1319
+ overflow: auto;
1320
+ }
1321
+
1322
+ .table-designer-constraint__values span {
1323
+ background: var(--primary-alpha-06);
1324
+ border-color: var(--primary-alpha-18);
1325
+ color: var(--color-primary-container);
1326
+ }
1327
+
1328
+ .table-designer-constraint-editor__sql {
1329
+ background: var(--color-surface-low);
1330
+ border: 1px solid rgb(var(--rgb-outline) / 0.1);
1331
+ color: rgb(var(--rgb-on-surface) / 0.68);
1332
+ font-family: var(--font-family-mono);
1333
+ font-size: 0.72rem;
1334
+ line-height: 1.5;
1335
+ margin: 0;
1336
+ min-height: 7rem;
1337
+ overflow: auto;
1338
+ padding: var(--spacing-3);
1339
+ resize: vertical;
1340
+ width: 100%;
1341
+ }
1342
+
895
1343
  .table-designer-grid__row {
896
1344
  border-bottom: 1px solid rgb(var(--rgb-outline) / 0.1);
897
1345
  align-items: center;
898
1346
  }
899
1347
 
1348
+ .table-designer-row-actions {
1349
+ align-items: center;
1350
+ display: flex;
1351
+ gap: var(--spacing-2);
1352
+ justify-content: flex-end;
1353
+ min-width: 0;
1354
+ }
1355
+
1356
+ .table-designer-row-check-button {
1357
+ gap: var(--spacing-2);
1358
+ white-space: nowrap;
1359
+ }
1360
+
900
1361
  .table-designer-field {
901
1362
  height: var(--control-height);
902
1363
  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;