@flowerforce/flowerbase 1.7.6-beta.0 → 1.7.6-beta.2

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 (70) hide show
  1. package/README.md +125 -1
  2. package/dist/auth/providers/custom-function/controller.d.ts.map +1 -1
  3. package/dist/auth/providers/custom-function/controller.js +3 -8
  4. package/dist/constants.d.ts +10 -0
  5. package/dist/constants.d.ts.map +1 -1
  6. package/dist/constants.js +11 -1
  7. package/dist/features/encryption/interface.d.ts +36 -0
  8. package/dist/features/encryption/interface.d.ts.map +1 -0
  9. package/dist/features/encryption/interface.js +2 -0
  10. package/dist/features/encryption/utils.d.ts +9 -0
  11. package/dist/features/encryption/utils.d.ts.map +1 -0
  12. package/dist/features/encryption/utils.js +34 -0
  13. package/dist/features/functions/controller.d.ts +2 -0
  14. package/dist/features/functions/controller.d.ts.map +1 -1
  15. package/dist/features/functions/controller.js +7 -1
  16. package/dist/features/rules/utils.d.ts.map +1 -1
  17. package/dist/features/rules/utils.js +1 -11
  18. package/dist/features/triggers/index.d.ts.map +1 -1
  19. package/dist/features/triggers/index.js +4 -0
  20. package/dist/features/triggers/utils.d.ts.map +1 -1
  21. package/dist/features/triggers/utils.js +30 -38
  22. package/dist/index.d.ts +3 -1
  23. package/dist/index.d.ts.map +1 -1
  24. package/dist/index.js +9 -4
  25. package/dist/monitoring/plugin.d.ts.map +1 -1
  26. package/dist/monitoring/plugin.js +31 -0
  27. package/dist/services/mongodb-atlas/index.d.ts +3 -0
  28. package/dist/services/mongodb-atlas/index.d.ts.map +1 -1
  29. package/dist/services/mongodb-atlas/index.js +97 -17
  30. package/dist/services/mongodb-atlas/model.d.ts +2 -1
  31. package/dist/services/mongodb-atlas/model.d.ts.map +1 -1
  32. package/dist/utils/index.d.ts +1 -0
  33. package/dist/utils/index.d.ts.map +1 -1
  34. package/dist/utils/index.js +14 -3
  35. package/dist/utils/initializer/mongodbCSFLE.d.ts +69 -0
  36. package/dist/utils/initializer/mongodbCSFLE.d.ts.map +1 -0
  37. package/dist/utils/initializer/mongodbCSFLE.js +131 -0
  38. package/dist/utils/initializer/registerPlugins.d.ts +5 -1
  39. package/dist/utils/initializer/registerPlugins.d.ts.map +1 -1
  40. package/dist/utils/initializer/registerPlugins.js +27 -5
  41. package/package.json +4 -2
  42. package/src/auth/providers/custom-function/controller.ts +4 -10
  43. package/src/constants.ts +11 -2
  44. package/src/features/encryption/interface.ts +46 -0
  45. package/src/features/encryption/utils.ts +22 -0
  46. package/src/features/functions/__tests__/watch-filter.test.ts +11 -1
  47. package/src/features/functions/controller.ts +8 -0
  48. package/src/features/rules/utils.ts +1 -11
  49. package/src/features/triggers/index.ts +5 -1
  50. package/src/features/triggers/utils.ts +31 -42
  51. package/src/index.ts +10 -2
  52. package/src/monitoring/plugin.ts +33 -0
  53. package/src/monitoring/ui.collections.js +7 -10
  54. package/src/monitoring/ui.css +378 -0
  55. package/src/monitoring/ui.endpoints.js +5 -10
  56. package/src/monitoring/ui.events.js +2 -4
  57. package/src/monitoring/ui.functions.js +64 -71
  58. package/src/monitoring/ui.html +8 -0
  59. package/src/monitoring/ui.js +189 -0
  60. package/src/monitoring/ui.shared.js +237 -2
  61. package/src/monitoring/ui.triggers.js +2 -3
  62. package/src/monitoring/ui.users.js +5 -9
  63. package/src/services/mongodb-atlas/__tests__/watch-filter.test.ts +78 -0
  64. package/src/services/mongodb-atlas/index.ts +102 -19
  65. package/src/services/mongodb-atlas/model.ts +3 -1
  66. package/src/types/fastify-raw-body.d.ts +0 -9
  67. package/src/utils/__tests__/mongodbCSFLE.test.ts +105 -0
  68. package/src/utils/index.ts +12 -1
  69. package/src/utils/initializer/mongodbCSFLE.ts +224 -0
  70. package/src/utils/initializer/registerPlugins.ts +45 -10
@@ -10,6 +10,10 @@
10
10
  --border: #1a2f22;
11
11
  --panel: #0b120d;
12
12
  --panel-2: #0d1711;
13
+ --scrollbar-track: rgba(12, 20, 14, 0.92);
14
+ --scrollbar-thumb: rgba(49, 233, 129, 0.32);
15
+ --scrollbar-thumb-hover: rgba(49, 233, 129, 0.52);
16
+ --scrollbar-border: rgba(26, 47, 34, 0.9);
13
17
  }
14
18
 
15
19
  * {
@@ -33,6 +37,36 @@ body {
33
37
  overflow: hidden;
34
38
  }
35
39
 
40
+ * {
41
+ scrollbar-width: thin;
42
+ scrollbar-color: var(--scrollbar-thumb) var(--scrollbar-track);
43
+ }
44
+
45
+ *::-webkit-scrollbar {
46
+ width: 10px;
47
+ height: 10px;
48
+ }
49
+
50
+ *::-webkit-scrollbar-track {
51
+ background: var(--scrollbar-track);
52
+ border: 1px solid var(--scrollbar-border);
53
+ border-radius: 999px;
54
+ }
55
+
56
+ *::-webkit-scrollbar-thumb {
57
+ background: linear-gradient(180deg, rgba(49, 233, 129, 0.52), rgba(49, 233, 129, 0.24));
58
+ border: 2px solid var(--scrollbar-track);
59
+ border-radius: 999px;
60
+ }
61
+
62
+ *::-webkit-scrollbar-thumb:hover {
63
+ background: linear-gradient(180deg, rgba(49, 233, 129, 0.72), var(--scrollbar-thumb-hover));
64
+ }
65
+
66
+ *::-webkit-scrollbar-corner {
67
+ background: var(--scrollbar-track);
68
+ }
69
+
36
70
  body::before {
37
71
  content: "";
38
72
  position: fixed;
@@ -169,6 +203,29 @@ main {
169
203
  min-height: 0;
170
204
  }
171
205
 
206
+ .split-grid.resizable-split-grid {
207
+ --split-left-size: 66%;
208
+ --split-handle-size: 10px;
209
+ grid-template-columns: minmax(220px, var(--split-left-size)) var(--split-handle-size) minmax(220px, 1fr);
210
+ gap: 0;
211
+ }
212
+
213
+ .split-grid.resizable-split-grid > .split-pane-left {
214
+ grid-column: 1;
215
+ min-width: 0;
216
+ margin-right: 3px;
217
+ }
218
+
219
+ .split-grid.resizable-split-grid > .split-resizer {
220
+ grid-column: 2;
221
+ }
222
+
223
+ .split-grid.resizable-split-grid > .split-pane-right {
224
+ grid-column: 3;
225
+ min-width: 0;
226
+ margin-left: 3px;
227
+ }
228
+
172
229
  .users-grid {
173
230
  grid-template-columns: minmax(0, 2fr) minmax(0, 1fr);
174
231
  }
@@ -193,6 +250,14 @@ main {
193
250
  height: 100%;
194
251
  }
195
252
 
253
+ .column-stack.resizable-stack {
254
+ gap: 0;
255
+ }
256
+
257
+ .column-stack.resizable-stack > .stack-pane {
258
+ min-height: 140px;
259
+ }
260
+
196
261
  .right-column {
197
262
  display: flex;
198
263
  flex-direction: column;
@@ -216,6 +281,62 @@ main {
216
281
  flex: 1;
217
282
  }
218
283
 
284
+ .split-resizer,
285
+ .stack-resizer {
286
+ position: relative;
287
+ background: transparent;
288
+ touch-action: none;
289
+ }
290
+
291
+ .split-resizer::before,
292
+ .stack-resizer::before {
293
+ content: '';
294
+ position: absolute;
295
+ border-radius: 999px;
296
+ background: transparent;
297
+ transition: background-color 0.12s ease;
298
+ }
299
+
300
+ .split-resizer {
301
+ cursor: col-resize;
302
+ }
303
+
304
+ .split-resizer::before {
305
+ top: 0;
306
+ bottom: 0;
307
+ left: 50%;
308
+ width: 2px;
309
+ transform: translateX(-50%);
310
+ }
311
+
312
+ .split-resizer:hover::before,
313
+ .split-resizer:focus-visible::before {
314
+ background: rgba(49, 233, 129, 0.56);
315
+ }
316
+
317
+ .stack-resizer {
318
+ height: 10px;
319
+ margin: 0;
320
+ cursor: row-resize;
321
+ }
322
+
323
+ .stack-resizer::before {
324
+ left: 0;
325
+ right: 0;
326
+ top: 50%;
327
+ height: 2px;
328
+ transform: translateY(-50%);
329
+ }
330
+
331
+ .stack-resizer:hover::before {
332
+ background: rgba(49, 233, 129, 0.56);
333
+ }
334
+
335
+ body.is-resizing,
336
+ body.is-resizing * {
337
+ user-select: none;
338
+ }
339
+
219
340
  /* Base: Panels + Controls */
220
341
  .panel {
221
342
  background: linear-gradient(180deg, rgba(12, 20, 14, 0.95), rgba(8, 14, 10, 0.95));
@@ -467,6 +588,69 @@ button.danger {
467
588
  white-space: pre-wrap;
468
589
  }
469
590
 
591
+ .event-detail.cm-json-host {
592
+ padding: 0;
593
+ overflow: hidden;
594
+ white-space: normal;
595
+ }
596
+
597
+ .event-detail.cm-json-host .CodeMirror {
598
+ height: 100%;
599
+ min-height: 140px;
600
+ width: 100%;
601
+ font-size: 11px;
602
+ line-height: 1.5;
603
+ color: #d4d4d4;
604
+ background: var(--panel);
605
+ }
606
+
607
+ .event-detail.cm-json-host .CodeMirror-gutters {
608
+ background: #141414;
609
+ border-right: 1px solid #2b2b2b;
610
+ }
611
+
612
+ .event-detail.cm-json-host .CodeMirror-linenumber,
613
+ .event-detail.cm-json-host .CodeMirror-foldgutter-open,
614
+ .event-detail.cm-json-host .CodeMirror-foldgutter-folded {
615
+ color: #8a8a8a;
616
+ }
617
+
618
+ .event-detail.cm-json-host .CodeMirror-cursor {
619
+ border-left-color: #ffffff;
620
+ }
621
+
622
+ .event-detail.cm-json-host .CodeMirror-selected {
623
+ background: rgba(88, 166, 255, 0.35);
624
+ }
625
+
626
+ .event-detail.cm-json-host .cm-comment {
627
+ color: #6a9955;
628
+ }
629
+
630
+ .event-detail.cm-json-host .cm-string,
631
+ .event-detail.cm-json-host .cm-string-2 {
632
+ color: #ce9178;
633
+ }
634
+
635
+ .event-detail.cm-json-host .cm-number {
636
+ color: #b5cea8;
637
+ }
638
+
639
+ .event-detail.cm-json-host .cm-keyword,
640
+ .event-detail.cm-json-host .cm-atom {
641
+ color: #569cd6;
642
+ }
643
+
644
+ .event-detail.cm-json-host .cm-property,
645
+ .event-detail.cm-json-host .cm-def,
646
+ .event-detail.cm-json-host .cm-variable,
647
+ .event-detail.cm-json-host .cm-variable-2,
648
+ .event-detail.cm-json-host .cm-variable-3,
649
+ .event-detail.cm-json-host .cm-operator,
650
+ .event-detail.cm-json-host .cm-bracket {
651
+ color: #d4d4d4;
652
+ }
653
+
470
654
  .subpanel {
471
655
  margin-top: 0;
472
656
  padding: 10px;
@@ -651,6 +835,7 @@ button.small {
651
835
  padding: 6px;
652
836
  border-bottom: 1px dashed rgba(26, 47, 34, 0.6);
653
837
  cursor: pointer;
838
+ min-width: 0;
654
839
  }
655
840
 
656
841
  /* Triggers Page */
@@ -662,6 +847,7 @@ button.small {
662
847
  padding: 6px;
663
848
  border-bottom: 1px dashed rgba(26, 47, 34, 0.6);
664
849
  cursor: pointer;
850
+ min-width: 0;
665
851
  }
666
852
 
667
853
  /* Endpoints Page */
@@ -673,6 +859,7 @@ button.small {
673
859
  padding: 6px;
674
860
  border-bottom: 1px dashed rgba(26, 47, 34, 0.6);
675
861
  cursor: pointer;
862
+ min-width: 0;
676
863
  }
677
864
 
678
865
  .endpoint-row.active {
@@ -692,6 +879,7 @@ button.small {
692
879
  display: flex;
693
880
  flex-direction: column;
694
881
  gap: 2px;
882
+ min-width: 0;
695
883
  }
696
884
 
697
885
  .endpoint-panel {
@@ -755,6 +943,24 @@ button.small {
755
943
  display: flex;
756
944
  flex-direction: column;
757
945
  gap: 2px;
946
+ min-width: 0;
947
+ }
948
+
949
+ .function-row .code,
950
+ .trigger-row .code,
951
+ .endpoint-row .code,
952
+ .user-row .code,
953
+ .collection-row .code {
954
+ overflow-wrap: anywhere;
955
+ }
956
+
957
+ .function-row .hint,
958
+ .trigger-row .hint,
959
+ .endpoint-row .hint,
960
+ .history-row .hint,
961
+ .user-row .hint,
962
+ .collection-row .hint {
963
+ overflow-wrap: anywhere;
758
964
  }
759
965
 
760
966
  .user-actions {
@@ -1074,6 +1280,71 @@ button.small {
1074
1280
  pointer-events: none;
1075
1281
  }
1076
1282
 
1283
+ .code-editor.cm-enabled .code-gutter,
1284
+ .code-editor.cm-enabled #functionHighlight {
1285
+ display: none;
1286
+ }
1287
+
1288
+ .code-editor.cm-enabled .code-surface {
1289
+ overflow: hidden;
1290
+ }
1291
+
1292
+ .code-editor.cm-enabled .CodeMirror {
1293
+ height: 100%;
1294
+ width: 100%;
1295
+ font-size: 12px;
1296
+ line-height: 1.5;
1297
+ color: #d4d4d4;
1298
+ background: #1e1e1e;
1299
+ }
1300
+
1301
+ .code-editor.cm-enabled .CodeMirror-gutters {
1302
+ background: #141414;
1303
+ border-right: 1px solid #2b2b2b;
1304
+ }
1305
+
1306
+ .code-editor.cm-enabled .CodeMirror-linenumber,
1307
+ .code-editor.cm-enabled .CodeMirror-foldgutter-open,
1308
+ .code-editor.cm-enabled .CodeMirror-foldgutter-folded {
1309
+ color: #8a8a8a;
1310
+ }
1311
+
1312
+ .code-editor.cm-enabled .CodeMirror-cursor {
1313
+ border-left-color: #ffffff;
1314
+ }
1315
+
1316
+ .code-editor.cm-enabled .CodeMirror-selected {
1317
+ background: rgba(88, 166, 255, 0.35);
1318
+ }
1319
+
1320
+ .code-editor.cm-enabled .cm-comment {
1321
+ color: #6a9955;
1322
+ }
1323
+
1324
+ .code-editor.cm-enabled .cm-string,
1325
+ .code-editor.cm-enabled .cm-string-2 {
1326
+ color: #ce9178;
1327
+ }
1328
+
1329
+ .code-editor.cm-enabled .cm-number {
1330
+ color: #b5cea8;
1331
+ }
1332
+
1333
+ .code-editor.cm-enabled .cm-keyword,
1334
+ .code-editor.cm-enabled .cm-atom {
1335
+ color: #569cd6;
1336
+ }
1337
+
1338
+ .code-editor.cm-enabled .cm-def,
1339
+ .code-editor.cm-enabled .cm-property,
1340
+ .code-editor.cm-enabled .cm-variable,
1341
+ .code-editor.cm-enabled .cm-variable-2,
1342
+ .code-editor.cm-enabled .cm-variable-3,
1343
+ .code-editor.cm-enabled .cm-operator,
1344
+ .code-editor.cm-enabled .cm-bracket {
1345
+ color: #d4d4d4;
1346
+ }
1347
+
1077
1348
  #functionCode {
1078
1349
  position: absolute;
1079
1350
  inset: 0;
@@ -1138,6 +1409,65 @@ button.small {
1138
1409
  color: #dcdcaa;
1139
1410
  }
1140
1411
 
1412
+ .json-highlight .json-tree,
1413
+ .json-highlight .json-node,
1414
+ .json-highlight .json-children {
1415
+ display: block;
1416
+ }
1417
+
1418
+ .json-highlight .json-line {
1419
+ display: block;
1420
+ padding-left: calc(var(--json-depth, 0) * 14px);
1421
+ white-space: pre;
1422
+ }
1423
+
1424
+ .json-highlight .json-toggle,
1425
+ .json-highlight .json-toggle-spacer {
1426
+ display: inline-flex;
1427
+ align-items: center;
1428
+ justify-content: center;
1429
+ width: 14px;
1430
+ height: 14px;
1431
+ margin-right: 4px;
1432
+ vertical-align: text-bottom;
1433
+ }
1434
+
1435
+ .json-highlight .json-toggle {
1436
+ padding: 0;
1437
+ border: 0;
1438
+ background: transparent;
1439
+ color: var(--muted);
1440
+ cursor: pointer;
1441
+ line-height: 1;
1442
+ }
1443
+
1444
+ .json-highlight .json-toggle:hover {
1445
+ color: var(--fg);
1446
+ }
1447
+
1448
+ .json-highlight .json-brace,
1449
+ .json-highlight .json-punct {
1450
+ color: #d4d4d4;
1451
+ }
1452
+
1453
+ .json-highlight .json-summary {
1454
+ display: none;
1455
+ color: var(--muted);
1456
+ }
1457
+
1458
+ .json-highlight .json-node.is-collapsed > .json-children,
1459
+ .json-highlight .json-node.is-collapsed > .json-close {
1460
+ display: none;
1461
+ }
1462
+
1463
+ .json-highlight .json-node.is-collapsed > .json-open .json-summary {
1464
+ display: inline;
1465
+ }
1466
+
1467
+ .json-highlight .json-node.is-collapsed > .json-open .json-toggle {
1468
+ transform: rotate(-90deg);
1469
+ }
1470
+
1141
1471
  .function-io {
1142
1472
  display: grid;
1143
1473
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
@@ -1325,6 +1655,20 @@ button.small {
1325
1655
  grid-template-columns: 1fr;
1326
1656
  }
1327
1657
 
1658
+ .split-grid.resizable-split-grid {
1659
+ grid-template-columns: 1fr;
1660
+ }
1661
+
1662
+ .split-grid.resizable-split-grid > .split-pane-left,
1663
+ .split-grid.resizable-split-grid > .split-pane-right {
1664
+ grid-column: 1;
1665
+ margin: 0;
1666
+ }
1667
+
1668
+ .split-grid.resizable-split-grid > .split-resizer {
1669
+ display: none;
1670
+ }
1671
+
1328
1672
  .users-grid {
1329
1673
  grid-template-columns: minmax(0, 2fr) minmax(0, 1fr);
1330
1674
  }
@@ -1333,3 +1677,37 @@ button.small {
1333
1677
  grid-template-columns: minmax(0, 1fr);
1334
1678
  }
1335
1679
  }
1680
+
1681
+ @media (max-width: 760px) {
1682
+ header,
1683
+ .panel-header,
1684
+ .detail-header,
1685
+ .status,
1686
+ .panel-actions,
1687
+ .editor-actions,
1688
+ .pager {
1689
+ flex-wrap: wrap;
1690
+ }
1691
+
1692
+ .status {
1693
+ justify-content: flex-end;
1694
+ }
1695
+
1696
+ .function-row,
1697
+ .trigger-row,
1698
+ .endpoint-row {
1699
+ flex-direction: column;
1700
+ align-items: flex-start;
1701
+ justify-content: flex-start;
1702
+ }
1703
+
1704
+ .history-row,
1705
+ .user-row,
1706
+ .collection-row {
1707
+ grid-template-columns: minmax(0, 1fr);
1708
+ }
1709
+
1710
+ .function-actions {
1711
+ justify-content: flex-start;
1712
+ }
1713
+ }
@@ -51,7 +51,7 @@
51
51
  endpointTabButtons,
52
52
  endpointTabPanels
53
53
  } = dom;
54
- const { api, parseOptionalJsonValue, highlightJson, escapeHtml, formatTime, safeStringify } = utils;
54
+ const { api, parseOptionalJsonValue, renderJsonViewer, clearJsonViewer, escapeHtml, formatTime, safeStringify } = utils;
55
55
  const { setActiveTab } = helpers;
56
56
 
57
57
  const ENDPOINT_RESULT_PLACEHOLDER = state.endpointResult;
@@ -76,11 +76,9 @@
76
76
  const setEndpointResultContent = (text, highlight = false) => {
77
77
  if (!endpointResult) return;
78
78
  if (highlight) {
79
- endpointResult.classList.add('json-highlight');
80
- endpointResult.innerHTML = highlightJson(text || '');
79
+ renderJsonViewer(endpointResult, text || '', { collapsible: true });
81
80
  } else {
82
- endpointResult.classList.remove('json-highlight');
83
- endpointResult.textContent = text || '';
81
+ clearJsonViewer(endpointResult, text || '');
84
82
  }
85
83
  };
86
84
 
@@ -104,8 +102,7 @@
104
102
  const setEndpointDetail = (endpoint) => {
105
103
  if (!endpointMeta) return;
106
104
  if (!endpoint) {
107
- endpointMeta.textContent = 'select an endpoint to inspect';
108
- endpointMeta.classList.remove('json-highlight');
105
+ clearJsonViewer(endpointMeta, 'select an endpoint to inspect');
109
106
  if (endpointHint) endpointHint.textContent = 'select an endpoint';
110
107
  if (endpointFunctionButton) {
111
108
  endpointFunctionButton.classList.add('is-hidden');
@@ -121,9 +118,7 @@
121
118
  const route = endpoint.route || '';
122
119
  const functionName = endpoint.function_name || 'unknown';
123
120
  const status = endpoint.disabled ? 'disabled' : 'active';
124
- const jsonPayload = JSON.stringify(endpoint, null, 2) || '';
125
- endpointMeta.classList.add('json-highlight');
126
- endpointMeta.innerHTML = highlightJson(jsonPayload);
121
+ renderJsonViewer(endpointMeta, endpoint, { collapsible: true });
127
122
  if (endpointHint) endpointHint.textContent = status;
128
123
  if (endpointMethod) endpointMethod.value = method;
129
124
  if (endpointFunctionButton) {
@@ -183,8 +183,7 @@
183
183
  state.selectedId = event.id;
184
184
  state.selectedEvent = event;
185
185
  const text = JSON.stringify(event, null, 2) || '';
186
- eventDetail.classList.add('json-highlight');
187
- eventDetail.innerHTML = highlightJson(text);
186
+ renderJsonViewer(eventDetail, text, { collapsible: true });
188
187
  const functionData = getFunctionEventData(event);
189
188
  if (functionData && eventFunctionButton) {
190
189
  eventFunctionButton.classList.remove('is-hidden');
@@ -247,8 +246,7 @@
247
246
  typeFilter.value = '';
248
247
  state.events = [];
249
248
  state.selectedEvent = null;
250
- eventDetail.classList.remove('json-highlight');
251
- eventDetail.textContent = 'select an event to inspect payload';
249
+ clearJsonViewer(eventDetail, 'select an event to inspect payload');
252
250
  if (eventFunctionButton) {
253
251
  eventFunctionButton.classList.add('is-hidden');
254
252
  eventFunctionButton.textContent = 'use in invoke';