mongoku 2.0.4 → 2.1.1

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 (426) hide show
  1. package/README.md +18 -4
  2. package/build/client/_app/immutable/assets/0.egX7ddQL.css +1 -0
  3. package/build/client/_app/immutable/assets/0.egX7ddQL.css.br +0 -0
  4. package/build/client/_app/immutable/assets/0.egX7ddQL.css.gz +0 -0
  5. package/build/client/_app/immutable/assets/10.59aTjJn9.css +1 -0
  6. package/build/client/_app/immutable/assets/10.59aTjJn9.css.br +0 -0
  7. package/build/client/_app/immutable/assets/10.59aTjJn9.css.gz +0 -0
  8. package/build/client/_app/immutable/assets/11.CEtFGlZU.css +1 -0
  9. package/build/client/_app/immutable/assets/11.CEtFGlZU.css.br +1 -0
  10. package/build/client/_app/immutable/assets/11.CEtFGlZU.css.gz +0 -0
  11. package/build/client/_app/immutable/assets/12.BdCOhvz0.css +1 -0
  12. package/build/client/_app/immutable/assets/12.BdCOhvz0.css.br +0 -0
  13. package/build/client/_app/immutable/assets/12.BdCOhvz0.css.gz +0 -0
  14. package/build/client/_app/immutable/assets/JsonValue.BEbzuWqZ.css +1 -0
  15. package/build/client/_app/immutable/assets/JsonValue.BEbzuWqZ.css.br +0 -0
  16. package/build/client/_app/immutable/assets/JsonValue.BEbzuWqZ.css.gz +0 -0
  17. package/build/client/_app/immutable/assets/Modal.DIIFkbGB.css +1 -0
  18. package/build/client/_app/immutable/assets/Modal.DIIFkbGB.css.br +0 -0
  19. package/build/client/_app/immutable/assets/Modal.DIIFkbGB.css.gz +0 -0
  20. package/build/client/_app/immutable/assets/Panel.B3aWupye.css +1 -0
  21. package/build/client/_app/immutable/assets/Panel.B3aWupye.css.br +0 -0
  22. package/build/client/_app/immutable/assets/Panel.B3aWupye.css.gz +0 -0
  23. package/build/client/_app/immutable/chunks/3iRu_dUj.js +2 -0
  24. package/build/client/_app/immutable/chunks/3iRu_dUj.js.br +0 -0
  25. package/build/client/_app/immutable/chunks/3iRu_dUj.js.gz +0 -0
  26. package/build/client/_app/immutable/chunks/{ChWB6xnu.js → 4l_AWZos.js} +1 -1
  27. package/build/client/_app/immutable/chunks/4l_AWZos.js.br +0 -0
  28. package/build/client/_app/immutable/chunks/4l_AWZos.js.gz +0 -0
  29. package/build/client/_app/immutable/chunks/5nAxkTTP.js +1 -0
  30. package/build/client/_app/immutable/chunks/5nAxkTTP.js.br +5 -0
  31. package/build/client/_app/immutable/chunks/5nAxkTTP.js.gz +0 -0
  32. package/build/client/_app/immutable/chunks/BBg-V8FE.js +1 -0
  33. package/build/client/_app/immutable/chunks/BBg-V8FE.js.br +0 -0
  34. package/build/client/_app/immutable/chunks/BBg-V8FE.js.gz +0 -0
  35. package/build/client/_app/immutable/chunks/BE8UzJuY.js +1 -0
  36. package/build/client/_app/immutable/chunks/BE8UzJuY.js.br +0 -0
  37. package/build/client/_app/immutable/chunks/BE8UzJuY.js.gz +0 -0
  38. package/build/client/_app/immutable/chunks/BUNgwIS0.js +1 -0
  39. package/build/client/_app/immutable/chunks/BUNgwIS0.js.br +0 -0
  40. package/build/client/_app/immutable/chunks/BUNgwIS0.js.gz +0 -0
  41. package/build/client/_app/immutable/chunks/BjzB4NFq.js +1 -0
  42. package/build/client/_app/immutable/chunks/BjzB4NFq.js.br +0 -0
  43. package/build/client/_app/immutable/chunks/BjzB4NFq.js.gz +0 -0
  44. package/build/client/_app/immutable/chunks/BtCOrwSt.js +1 -0
  45. package/build/client/_app/immutable/chunks/BtCOrwSt.js.br +0 -0
  46. package/build/client/_app/immutable/chunks/BtCOrwSt.js.gz +0 -0
  47. package/build/client/_app/immutable/chunks/BvKY81hz.js +1 -0
  48. package/build/client/_app/immutable/chunks/BvKY81hz.js.br +0 -0
  49. package/build/client/_app/immutable/chunks/BvKY81hz.js.gz +0 -0
  50. package/build/client/_app/immutable/chunks/{DQkpHJGc.js → C0PCwpqt.js} +1 -1
  51. package/build/client/_app/immutable/chunks/C0PCwpqt.js.br +0 -0
  52. package/build/client/_app/immutable/chunks/C0PCwpqt.js.gz +0 -0
  53. package/build/client/_app/immutable/chunks/C82Rp5eQ.js +1 -0
  54. package/build/client/_app/immutable/chunks/C82Rp5eQ.js.br +0 -0
  55. package/build/client/_app/immutable/chunks/C82Rp5eQ.js.gz +0 -0
  56. package/build/client/_app/immutable/chunks/CEvYYWlm.js +2 -0
  57. package/build/client/_app/immutable/chunks/CEvYYWlm.js.br +0 -0
  58. package/build/client/_app/immutable/chunks/CEvYYWlm.js.gz +0 -0
  59. package/build/client/_app/immutable/chunks/CT5SFbzp.js +1 -0
  60. package/build/client/_app/immutable/chunks/CT5SFbzp.js.br +0 -0
  61. package/build/client/_app/immutable/chunks/CT5SFbzp.js.gz +0 -0
  62. package/build/client/_app/immutable/chunks/CcyPStn-.js +1 -0
  63. package/build/client/_app/immutable/chunks/CcyPStn-.js.br +0 -0
  64. package/build/client/_app/immutable/chunks/CcyPStn-.js.gz +0 -0
  65. package/build/client/_app/immutable/chunks/Cx2cA4gg.js +1 -0
  66. package/build/client/_app/immutable/chunks/Cx2cA4gg.js.br +0 -0
  67. package/build/client/_app/immutable/chunks/Cx2cA4gg.js.gz +0 -0
  68. package/build/client/_app/immutable/chunks/D5ccpaXt.js +1 -0
  69. package/build/client/_app/immutable/chunks/D5ccpaXt.js.br +0 -0
  70. package/build/client/_app/immutable/chunks/D5ccpaXt.js.gz +0 -0
  71. package/build/client/_app/immutable/chunks/D64wQeYi.js +1 -0
  72. package/build/client/_app/immutable/chunks/D64wQeYi.js.br +0 -0
  73. package/build/client/_app/immutable/chunks/D64wQeYi.js.gz +0 -0
  74. package/build/client/_app/immutable/chunks/D7E46CWw.js +1 -0
  75. package/build/client/_app/immutable/chunks/D7E46CWw.js.br +0 -0
  76. package/build/client/_app/immutable/chunks/D7E46CWw.js.gz +0 -0
  77. package/build/client/_app/immutable/chunks/DR9xdhsg.js +1 -0
  78. package/build/client/_app/immutable/chunks/DR9xdhsg.js.br +0 -0
  79. package/build/client/_app/immutable/chunks/DR9xdhsg.js.gz +0 -0
  80. package/build/client/_app/immutable/chunks/DVJuGan7.js +1 -0
  81. package/build/client/_app/immutable/chunks/DVJuGan7.js.br +0 -0
  82. package/build/client/_app/immutable/chunks/DVJuGan7.js.gz +0 -0
  83. package/build/client/_app/immutable/chunks/Dx86XS0G.js +1 -0
  84. package/build/client/_app/immutable/chunks/Dx86XS0G.js.br +4 -0
  85. package/build/client/_app/immutable/chunks/Dx86XS0G.js.gz +0 -0
  86. package/build/client/_app/immutable/chunks/lkkUcQuO.js +29 -0
  87. package/build/client/_app/immutable/chunks/lkkUcQuO.js.br +0 -0
  88. package/build/client/_app/immutable/chunks/lkkUcQuO.js.gz +0 -0
  89. package/build/client/_app/immutable/chunks/nVJvgG3c.js +4 -0
  90. package/build/client/_app/immutable/chunks/nVJvgG3c.js.br +0 -0
  91. package/build/client/_app/immutable/chunks/nVJvgG3c.js.gz +0 -0
  92. package/build/client/_app/immutable/entry/app.g5qLQ5x2.js +2 -0
  93. package/build/client/_app/immutable/entry/app.g5qLQ5x2.js.br +0 -0
  94. package/build/client/_app/immutable/entry/app.g5qLQ5x2.js.gz +0 -0
  95. package/build/client/_app/immutable/entry/start.C1uqw3sp.js +1 -0
  96. package/build/client/_app/immutable/entry/start.C1uqw3sp.js.br +2 -0
  97. package/build/client/_app/immutable/entry/start.C1uqw3sp.js.gz +0 -0
  98. package/build/client/_app/immutable/nodes/0.CD9yR-49.js +5 -0
  99. package/build/client/_app/immutable/nodes/0.CD9yR-49.js.br +0 -0
  100. package/build/client/_app/immutable/nodes/0.CD9yR-49.js.gz +0 -0
  101. package/build/client/_app/immutable/nodes/1.DztuiMqq.js +1 -0
  102. package/build/client/_app/immutable/nodes/1.DztuiMqq.js.br +0 -0
  103. package/build/client/_app/immutable/nodes/1.DztuiMqq.js.gz +0 -0
  104. package/build/client/_app/immutable/nodes/10.CWMFKPcE.js +2 -0
  105. package/build/client/_app/immutable/nodes/10.CWMFKPcE.js.br +0 -0
  106. package/build/client/_app/immutable/nodes/10.CWMFKPcE.js.gz +0 -0
  107. package/build/client/_app/immutable/nodes/11.-Y7Cu3Uv.js +1 -0
  108. package/build/client/_app/immutable/nodes/11.-Y7Cu3Uv.js.br +0 -0
  109. package/build/client/_app/immutable/nodes/11.-Y7Cu3Uv.js.gz +0 -0
  110. package/build/client/_app/immutable/nodes/12.wxif1TtN.js +1 -0
  111. package/build/client/_app/immutable/nodes/12.wxif1TtN.js.br +0 -0
  112. package/build/client/_app/immutable/nodes/12.wxif1TtN.js.gz +0 -0
  113. package/build/client/_app/immutable/nodes/13.CpyTaRSN.js +66 -0
  114. package/build/client/_app/immutable/nodes/13.CpyTaRSN.js.br +0 -0
  115. package/build/client/_app/immutable/nodes/13.CpyTaRSN.js.gz +0 -0
  116. package/build/client/_app/immutable/nodes/2.DwwrLLW4.js +1 -0
  117. package/build/client/_app/immutable/nodes/2.DwwrLLW4.js.br +1 -0
  118. package/build/client/_app/immutable/nodes/2.DwwrLLW4.js.gz +0 -0
  119. package/build/client/_app/immutable/nodes/3.t20GootO.js +1 -0
  120. package/build/client/_app/immutable/nodes/3.t20GootO.js.br +0 -0
  121. package/build/client/_app/immutable/nodes/3.t20GootO.js.gz +0 -0
  122. package/build/client/_app/immutable/nodes/4.CXHjkPtf.js +1 -0
  123. package/build/client/_app/immutable/nodes/4.CXHjkPtf.js.br +0 -0
  124. package/build/client/_app/immutable/nodes/4.CXHjkPtf.js.gz +0 -0
  125. package/build/client/_app/immutable/nodes/5.C9tcr5B0.js +1 -0
  126. package/build/client/_app/immutable/nodes/5.C9tcr5B0.js.br +0 -0
  127. package/build/client/_app/immutable/nodes/5.C9tcr5B0.js.gz +0 -0
  128. package/build/client/_app/immutable/nodes/7.DoT-dNUk.js +1 -0
  129. package/build/client/_app/immutable/nodes/7.DoT-dNUk.js.br +0 -0
  130. package/build/client/_app/immutable/nodes/7.DoT-dNUk.js.gz +0 -0
  131. package/build/client/_app/immutable/nodes/8.BFPkGTSl.js +1 -0
  132. package/build/client/_app/immutable/nodes/8.BFPkGTSl.js.br +0 -0
  133. package/build/client/_app/immutable/nodes/8.BFPkGTSl.js.gz +0 -0
  134. package/build/client/_app/immutable/nodes/9.Bk397TaK.js +2 -0
  135. package/build/client/_app/immutable/nodes/9.Bk397TaK.js.br +0 -0
  136. package/build/client/_app/immutable/nodes/9.Bk397TaK.js.gz +0 -0
  137. package/build/client/_app/version.json +1 -1
  138. package/build/client/_app/version.json.br +0 -0
  139. package/build/client/_app/version.json.gz +0 -0
  140. package/build/handler.js +14 -0
  141. package/build/server/chunks/{0-Cb5ytlMI.js → 0-hDOo8HzQ.js} +7 -6
  142. package/build/server/chunks/0-hDOo8HzQ.js.map +1 -0
  143. package/build/server/chunks/1-Dsw_dVjH.js +9 -0
  144. package/build/server/chunks/1-Dsw_dVjH.js.map +1 -0
  145. package/build/server/chunks/10-Xy0rxLNm.js +213 -0
  146. package/build/server/chunks/10-Xy0rxLNm.js.map +1 -0
  147. package/build/server/chunks/11-DBYsQ3ww.js +42 -0
  148. package/build/server/chunks/11-DBYsQ3ww.js.map +1 -0
  149. package/build/server/chunks/12-D4aSEhYN.js +102 -0
  150. package/build/server/chunks/12-D4aSEhYN.js.map +1 -0
  151. package/build/server/chunks/13-CNu_Hz8r.js +52 -0
  152. package/build/server/chunks/13-CNu_Hz8r.js.map +1 -0
  153. package/build/server/chunks/2-ClkERMhY.js +24 -0
  154. package/build/server/chunks/2-ClkERMhY.js.map +1 -0
  155. package/build/server/chunks/3-CTpqmxdo.js +25 -0
  156. package/build/server/chunks/3-CTpqmxdo.js.map +1 -0
  157. package/build/server/chunks/4-CUH4fZn8.js +25 -0
  158. package/build/server/chunks/4-CUH4fZn8.js.map +1 -0
  159. package/build/server/chunks/5-BSEdxfut.js +25 -0
  160. package/build/server/chunks/5-BSEdxfut.js.map +1 -0
  161. package/build/server/chunks/{2-B39zPvzn.js → 6-ifXBeMPA.js} +2 -2
  162. package/build/server/chunks/{2-B39zPvzn.js.map → 6-ifXBeMPA.js.map} +1 -1
  163. package/build/server/chunks/7-CJJMTAtJ.js +82 -0
  164. package/build/server/chunks/7-CJJMTAtJ.js.map +1 -0
  165. package/build/server/chunks/{4-DzHoLo__.js → 8-jBgxYwFg.js} +19 -10
  166. package/build/server/chunks/8-jBgxYwFg.js.map +1 -0
  167. package/build/server/chunks/{5-CCWbCDpk.js → 9-U8SAVx43.js} +7 -8
  168. package/build/server/chunks/9-U8SAVx43.js.map +1 -0
  169. package/build/server/chunks/JsonValue-B5gcBFcA.js +290 -0
  170. package/build/server/chunks/JsonValue-B5gcBFcA.js.map +1 -0
  171. package/build/server/chunks/Modal-zVnoAfFx.js +36 -0
  172. package/build/server/chunks/Modal-zVnoAfFx.js.map +1 -0
  173. package/build/server/chunks/{Panel-Bz0b85EW.js → Panel-yg5YKL4d.js} +4 -3
  174. package/build/server/chunks/Panel-yg5YKL4d.js.map +1 -0
  175. package/build/server/chunks/PrettyJson-mXYQacEL.js +137 -0
  176. package/build/server/chunks/PrettyJson-mXYQacEL.js.map +1 -0
  177. package/build/server/chunks/Tooltip-DflJLumT.js +38 -0
  178. package/build/server/chunks/Tooltip-DflJLumT.js.map +1 -0
  179. package/build/server/chunks/TooltipTable-BPMzcmqQ.js +60 -0
  180. package/build/server/chunks/TooltipTable-BPMzcmqQ.js.map +1 -0
  181. package/build/server/chunks/_layout.svelte-DMm1Ill8.js +168 -0
  182. package/build/server/chunks/_layout.svelte-DMm1Ill8.js.map +1 -0
  183. package/build/server/chunks/_page.svelte-B-dLNs2Q.js +199 -0
  184. package/build/server/chunks/_page.svelte-B-dLNs2Q.js.map +1 -0
  185. package/build/server/chunks/{_page.svelte-FLzHOuyK.js → _page.svelte-BBpDrOEz.js} +40 -22
  186. package/build/server/chunks/_page.svelte-BBpDrOEz.js.map +1 -0
  187. package/build/server/chunks/_page.svelte-C9OCv4Hv.js +204 -0
  188. package/build/server/chunks/_page.svelte-C9OCv4Hv.js.map +1 -0
  189. package/build/server/chunks/{_page.svelte-w9cxGvUf.js → _page.svelte-CvWJ35oO.js} +33 -13
  190. package/build/server/chunks/_page.svelte-CvWJ35oO.js.map +1 -0
  191. package/build/server/chunks/_page.svelte-DYHUokXG.js +297 -0
  192. package/build/server/chunks/_page.svelte-DYHUokXG.js.map +1 -0
  193. package/build/server/chunks/{_page.svelte-FIp-IsOo.js → _page.svelte-Ds1-yUh2.js} +64 -13
  194. package/build/server/chunks/_page.svelte-Ds1-yUh2.js.map +1 -0
  195. package/build/server/chunks/{_page.svelte-jxFKbZdN.js → _page.svelte-DzPMpozq.js} +9 -6
  196. package/build/server/chunks/_page.svelte-DzPMpozq.js.map +1 -0
  197. package/build/server/chunks/_server.ts-06lGoPp8.js +8 -0
  198. package/build/server/chunks/_server.ts-06lGoPp8.js.map +1 -0
  199. package/build/server/chunks/async-lVJA8xJZ.js +9 -0
  200. package/build/server/chunks/async-lVJA8xJZ.js.map +1 -0
  201. package/build/server/chunks/client-BFlyU7ZU.js +7 -0
  202. package/build/server/chunks/{client-bj7sePQc.js.map → client-BFlyU7ZU.js.map} +1 -1
  203. package/build/server/chunks/{client2-BX4-xbM4.js → client2-DYaMKWrc.js} +4 -4
  204. package/build/server/chunks/{client2-BX4-xbM4.js.map → client2-DYaMKWrc.js.map} +1 -1
  205. package/build/server/chunks/{async-BfR0vYHo.js → context-C22hLSHK.js} +2 -8
  206. package/build/server/chunks/context-C22hLSHK.js.map +1 -0
  207. package/build/server/chunks/error.svelte-BENdaVOT.js +19 -0
  208. package/build/server/chunks/error.svelte-BENdaVOT.js.map +1 -0
  209. package/build/server/chunks/event-DVH-6ISX.js.map +1 -1
  210. package/build/server/chunks/hooks.server-CagAPNr2.js +40 -0
  211. package/build/server/chunks/hooks.server-CagAPNr2.js.map +1 -0
  212. package/build/server/chunks/{index-EKt9-9bV.js → index-DFXVwu6p.js} +2 -2
  213. package/build/server/chunks/{index-EKt9-9bV.js.map → index-DFXVwu6p.js.map} +1 -1
  214. package/build/server/chunks/index-Djsj11qr.js.map +1 -1
  215. package/build/server/chunks/index-server-Bf-hP5gL.js +5 -0
  216. package/build/server/chunks/index-server-Bf-hP5gL.js.map +1 -0
  217. package/build/server/chunks/{routing-DcR4fCSD.js → index2-DBFlGzWV.js} +23 -100
  218. package/build/server/chunks/index2-DBFlGzWV.js.map +1 -0
  219. package/build/server/chunks/{index3-DquTjlmp.js → index3-CoOO2o9t.js} +6 -6
  220. package/build/server/chunks/index3-CoOO2o9t.js.map +1 -0
  221. package/build/server/chunks/jsonParser-CraFXJs8.js +174 -0
  222. package/build/server/chunks/jsonParser-CraFXJs8.js.map +1 -0
  223. package/build/server/chunks/layout.svelte-CJcHX-Na.js +10 -0
  224. package/build/server/chunks/layout.svelte-CJcHX-Na.js.map +1 -0
  225. package/build/server/chunks/logger-D71iWOkl.js +36 -0
  226. package/build/server/chunks/logger-D71iWOkl.js.map +1 -0
  227. package/build/server/chunks/{mongo-dLmCShL_.js → mongo-BogiTfnG.js} +54 -12
  228. package/build/server/chunks/mongo-BogiTfnG.js.map +1 -0
  229. package/build/server/chunks/remote-xxtqbu-BJDSUh3k.js +17 -0
  230. package/build/server/chunks/remote-xxtqbu-BJDSUh3k.js.map +1 -0
  231. package/build/server/chunks/routing-e10vGH37.js +81 -0
  232. package/build/server/chunks/routing-e10vGH37.js.map +1 -0
  233. package/build/server/chunks/{server2-BiqGvkCy.js → server2-_mGVuBoG.js} +2 -2
  234. package/build/server/chunks/{server2-BiqGvkCy.js.map → server2-_mGVuBoG.js.map} +1 -1
  235. package/build/server/chunks/servers.remote-C2HuT43p.js +690 -0
  236. package/build/server/chunks/servers.remote-C2HuT43p.js.map +1 -0
  237. package/build/server/chunks/shared-Buki-xt5.js +506 -0
  238. package/build/server/chunks/shared-Buki-xt5.js.map +1 -0
  239. package/build/server/chunks/{state.svelte-CRHA9yov.js → state.svelte-C8IWmp_n.js} +2 -2
  240. package/build/server/chunks/{state.svelte-CRHA9yov.js.map → state.svelte-C8IWmp_n.js.map} +1 -1
  241. package/build/server/chunks/{utils-DGYJFmnf.js → utils-kjxf7BZO.js} +2 -2
  242. package/build/server/chunks/{utils-DGYJFmnf.js.map → utils-kjxf7BZO.js.map} +1 -1
  243. package/build/server/index.js +189 -610
  244. package/build/server/index.js.map +1 -1
  245. package/build/server/manifest.js +45 -18
  246. package/build/server/manifest.js.map +1 -1
  247. package/package.json +13 -2
  248. package/src/api/servers.remote.ts +381 -20
  249. package/src/app.css +98 -3
  250. package/src/app.html +15 -0
  251. package/src/hooks.server.ts +18 -1
  252. package/src/lib/actions/jsonTextarea.ts +395 -0
  253. package/src/lib/components/Breadcrumbs.svelte +7 -58
  254. package/src/lib/components/JsonValue.svelte +279 -85
  255. package/src/lib/components/Modal.svelte +59 -0
  256. package/src/lib/components/OriginWarning.svelte +109 -0
  257. package/src/lib/components/PageSwitcher.svelte +37 -0
  258. package/src/lib/components/Panel.svelte +1 -1
  259. package/src/lib/components/PrettyJson.svelte +112 -36
  260. package/src/lib/components/SearchBox.svelte +161 -97
  261. package/src/lib/components/ThemeSwitcher.svelte +66 -0
  262. package/src/lib/components/Tooltip.svelte +83 -0
  263. package/src/lib/components/TooltipTable.svelte +45 -102
  264. package/src/lib/server/HostsManager.ts +4 -0
  265. package/src/lib/server/aggregation.ts +62 -0
  266. package/src/lib/server/mongo.ts +78 -15
  267. package/src/lib/types.ts +60 -0
  268. package/src/lib/utils/isEmptyObject.ts +6 -0
  269. package/src/lib/utils/jsonParser.ts +9 -1
  270. package/src/lib/utils/logger.ts +42 -0
  271. package/src/lib/utils/omit.ts +3 -0
  272. package/src/routes/+layout.server.ts +2 -1
  273. package/src/routes/+layout.svelte +15 -2
  274. package/src/routes/favicon.ico/+server.ts +8 -0
  275. package/src/routes/servers/+page.server.ts +23 -10
  276. package/src/routes/servers/+page.svelte +44 -10
  277. package/src/routes/servers/[server]/databases/+layout.ts +8 -0
  278. package/src/routes/servers/[server]/databases/+page.server.ts +15 -4
  279. package/src/routes/servers/[server]/databases/[database]/collections/+layout.ts +9 -0
  280. package/src/routes/servers/[server]/databases/[database]/collections/+page.server.ts +0 -2
  281. package/src/routes/servers/[server]/databases/[database]/collections/+page.svelte +67 -8
  282. package/src/routes/servers/[server]/databases/[database]/collections/[collection]/+layout.ts +9 -0
  283. package/src/routes/servers/[server]/databases/[database]/collections/[collection]/documents/+page.server.ts +217 -0
  284. package/src/routes/servers/[server]/databases/[database]/collections/[collection]/documents/+page.svelte +342 -0
  285. package/src/routes/servers/[server]/databases/[database]/collections/[collection]/documents/+page.ts +10 -0
  286. package/src/routes/servers/[server]/databases/[database]/collections/[collection]/documents/[document]/+layout.ts +9 -0
  287. package/src/routes/servers/[server]/databases/[database]/collections/[collection]/documents/[document]/+page.server.ts +15 -12
  288. package/src/routes/servers/[server]/databases/[database]/collections/[collection]/documents/[document]/+page.svelte +81 -7
  289. package/src/routes/servers/[server]/databases/[database]/collections/[collection]/indexes/+page.server.ts +88 -0
  290. package/src/routes/servers/[server]/databases/[database]/collections/[collection]/indexes/+page.svelte +333 -0
  291. package/src/routes/servers/[server]/databases/[database]/collections/[collection]/indexes/+page.ts +10 -0
  292. package/src/routes/servers/[server]/databases/[database]/collections/[collection]/mappings/+page.server.ts +18 -0
  293. package/src/routes/servers/[server]/databases/[database]/collections/[collection]/mappings/+page.svelte +378 -0
  294. package/src/routes/servers/[server]/databases/[database]/collections/[collection]/mappings/+page.ts +10 -0
  295. package/src/tests/api/aggregation.test.ts +125 -0
  296. package/build/client/_app/immutable/assets/0.CEsPYTp2.css +0 -1
  297. package/build/client/_app/immutable/assets/0.CEsPYTp2.css.br +0 -0
  298. package/build/client/_app/immutable/assets/0.CEsPYTp2.css.gz +0 -0
  299. package/build/client/_app/immutable/assets/6.DawdmtJd.css +0 -1
  300. package/build/client/_app/immutable/assets/6.DawdmtJd.css.br +0 -2
  301. package/build/client/_app/immutable/assets/6.DawdmtJd.css.gz +0 -0
  302. package/build/client/_app/immutable/assets/Panel.BDHMtO-3.css +0 -1
  303. package/build/client/_app/immutable/assets/Panel.BDHMtO-3.css.br +0 -0
  304. package/build/client/_app/immutable/assets/Panel.BDHMtO-3.css.gz +0 -0
  305. package/build/client/_app/immutable/assets/PrettyJson.CtngcfyW.css +0 -1
  306. package/build/client/_app/immutable/assets/PrettyJson.CtngcfyW.css.br +0 -0
  307. package/build/client/_app/immutable/assets/PrettyJson.CtngcfyW.css.gz +0 -0
  308. package/build/client/_app/immutable/chunks/B2-iEFN3.js +0 -2
  309. package/build/client/_app/immutable/chunks/B2-iEFN3.js.br +0 -0
  310. package/build/client/_app/immutable/chunks/B2-iEFN3.js.gz +0 -0
  311. package/build/client/_app/immutable/chunks/B5y2vsNr.js +0 -1
  312. package/build/client/_app/immutable/chunks/B5y2vsNr.js.br +0 -0
  313. package/build/client/_app/immutable/chunks/B5y2vsNr.js.gz +0 -0
  314. package/build/client/_app/immutable/chunks/BN_N9-2s.js +0 -1
  315. package/build/client/_app/immutable/chunks/BN_N9-2s.js.br +0 -0
  316. package/build/client/_app/immutable/chunks/BN_N9-2s.js.gz +0 -0
  317. package/build/client/_app/immutable/chunks/C1z4TjN7.js +0 -1
  318. package/build/client/_app/immutable/chunks/C1z4TjN7.js.br +0 -0
  319. package/build/client/_app/immutable/chunks/C1z4TjN7.js.gz +0 -0
  320. package/build/client/_app/immutable/chunks/CQBaNlA9.js +0 -1
  321. package/build/client/_app/immutable/chunks/CQBaNlA9.js.br +0 -0
  322. package/build/client/_app/immutable/chunks/CQBaNlA9.js.gz +0 -0
  323. package/build/client/_app/immutable/chunks/CVoOGazw.js +0 -4
  324. package/build/client/_app/immutable/chunks/CVoOGazw.js.br +0 -0
  325. package/build/client/_app/immutable/chunks/CVoOGazw.js.gz +0 -0
  326. package/build/client/_app/immutable/chunks/CapOg2jD.js +0 -1
  327. package/build/client/_app/immutable/chunks/CapOg2jD.js.br +0 -0
  328. package/build/client/_app/immutable/chunks/CapOg2jD.js.gz +0 -0
  329. package/build/client/_app/immutable/chunks/ChWB6xnu.js.br +0 -0
  330. package/build/client/_app/immutable/chunks/ChWB6xnu.js.gz +0 -0
  331. package/build/client/_app/immutable/chunks/CqnBT2zJ.js +0 -1
  332. package/build/client/_app/immutable/chunks/CqnBT2zJ.js.br +0 -0
  333. package/build/client/_app/immutable/chunks/CqnBT2zJ.js.gz +0 -0
  334. package/build/client/_app/immutable/chunks/D069mncP.js +0 -1
  335. package/build/client/_app/immutable/chunks/D069mncP.js.br +0 -0
  336. package/build/client/_app/immutable/chunks/D069mncP.js.gz +0 -0
  337. package/build/client/_app/immutable/chunks/DACrOfV_.js +0 -14
  338. package/build/client/_app/immutable/chunks/DACrOfV_.js.br +0 -0
  339. package/build/client/_app/immutable/chunks/DACrOfV_.js.gz +0 -0
  340. package/build/client/_app/immutable/chunks/DQkpHJGc.js.br +0 -0
  341. package/build/client/_app/immutable/chunks/DQkpHJGc.js.gz +0 -0
  342. package/build/client/_app/immutable/chunks/DSDD_hFT.js +0 -1
  343. package/build/client/_app/immutable/chunks/DSDD_hFT.js.br +0 -0
  344. package/build/client/_app/immutable/chunks/DSDD_hFT.js.gz +0 -0
  345. package/build/client/_app/immutable/chunks/D_aTX_ol.js +0 -1
  346. package/build/client/_app/immutable/chunks/D_aTX_ol.js.br +0 -0
  347. package/build/client/_app/immutable/chunks/D_aTX_ol.js.gz +0 -0
  348. package/build/client/_app/immutable/chunks/Dg3qHExF.js +0 -1
  349. package/build/client/_app/immutable/chunks/Dg3qHExF.js.br +0 -0
  350. package/build/client/_app/immutable/chunks/Dg3qHExF.js.gz +0 -0
  351. package/build/client/_app/immutable/chunks/Dt6-JRym.js +0 -2
  352. package/build/client/_app/immutable/chunks/Dt6-JRym.js.br +0 -0
  353. package/build/client/_app/immutable/chunks/Dt6-JRym.js.gz +0 -0
  354. package/build/client/_app/immutable/chunks/QoKxaG0e.js +0 -1
  355. package/build/client/_app/immutable/chunks/QoKxaG0e.js.br +0 -2
  356. package/build/client/_app/immutable/chunks/QoKxaG0e.js.gz +0 -0
  357. package/build/client/_app/immutable/chunks/rtveiEyS.js +0 -1
  358. package/build/client/_app/immutable/chunks/rtveiEyS.js.br +0 -0
  359. package/build/client/_app/immutable/chunks/rtveiEyS.js.gz +0 -0
  360. package/build/client/_app/immutable/entry/app.Cc1FNLNH.js +0 -2
  361. package/build/client/_app/immutable/entry/app.Cc1FNLNH.js.br +0 -0
  362. package/build/client/_app/immutable/entry/app.Cc1FNLNH.js.gz +0 -0
  363. package/build/client/_app/immutable/entry/start.CwqlbFyy.js +0 -1
  364. package/build/client/_app/immutable/entry/start.CwqlbFyy.js.br +0 -2
  365. package/build/client/_app/immutable/entry/start.CwqlbFyy.js.gz +0 -0
  366. package/build/client/_app/immutable/nodes/0.wBQEpdjZ.js +0 -1
  367. package/build/client/_app/immutable/nodes/0.wBQEpdjZ.js.br +0 -0
  368. package/build/client/_app/immutable/nodes/0.wBQEpdjZ.js.gz +0 -0
  369. package/build/client/_app/immutable/nodes/1.K6-n7D0b.js +0 -1
  370. package/build/client/_app/immutable/nodes/1.K6-n7D0b.js.br +0 -0
  371. package/build/client/_app/immutable/nodes/1.K6-n7D0b.js.gz +0 -0
  372. package/build/client/_app/immutable/nodes/3.DkGcIF98.js +0 -1
  373. package/build/client/_app/immutable/nodes/3.DkGcIF98.js.br +0 -0
  374. package/build/client/_app/immutable/nodes/3.DkGcIF98.js.gz +0 -0
  375. package/build/client/_app/immutable/nodes/4.C_NxbT98.js +0 -1
  376. package/build/client/_app/immutable/nodes/4.C_NxbT98.js.br +0 -0
  377. package/build/client/_app/immutable/nodes/4.C_NxbT98.js.gz +0 -0
  378. package/build/client/_app/immutable/nodes/5.CFvfYaLM.js +0 -1
  379. package/build/client/_app/immutable/nodes/5.CFvfYaLM.js.br +0 -0
  380. package/build/client/_app/immutable/nodes/5.CFvfYaLM.js.gz +0 -0
  381. package/build/client/_app/immutable/nodes/6.h34Zyorq.js +0 -1
  382. package/build/client/_app/immutable/nodes/6.h34Zyorq.js.br +0 -0
  383. package/build/client/_app/immutable/nodes/6.h34Zyorq.js.gz +0 -0
  384. package/build/client/_app/immutable/nodes/7.BVJmNbU5.js +0 -1
  385. package/build/client/_app/immutable/nodes/7.BVJmNbU5.js.br +0 -0
  386. package/build/client/_app/immutable/nodes/7.BVJmNbU5.js.gz +0 -0
  387. package/build/server/chunks/0-Cb5ytlMI.js.map +0 -1
  388. package/build/server/chunks/1-Cpb7zRtJ.js +0 -9
  389. package/build/server/chunks/1-Cpb7zRtJ.js.map +0 -1
  390. package/build/server/chunks/3-B_DkgZkc.js +0 -69
  391. package/build/server/chunks/3-B_DkgZkc.js.map +0 -1
  392. package/build/server/chunks/4-DzHoLo__.js.map +0 -1
  393. package/build/server/chunks/5-CCWbCDpk.js.map +0 -1
  394. package/build/server/chunks/6-Dok8svjB.js +0 -202
  395. package/build/server/chunks/6-Dok8svjB.js.map +0 -1
  396. package/build/server/chunks/7-CmgJSG2j.js +0 -42
  397. package/build/server/chunks/7-CmgJSG2j.js.map +0 -1
  398. package/build/server/chunks/Panel-Bz0b85EW.js.map +0 -1
  399. package/build/server/chunks/PrettyJson-CX6-dNsW.js +0 -291
  400. package/build/server/chunks/PrettyJson-CX6-dNsW.js.map +0 -1
  401. package/build/server/chunks/TooltipTable-0z4HkHlH.js +0 -17
  402. package/build/server/chunks/TooltipTable-0z4HkHlH.js.map +0 -1
  403. package/build/server/chunks/_layout.svelte-UiDiCQEz.js +0 -111
  404. package/build/server/chunks/_layout.svelte-UiDiCQEz.js.map +0 -1
  405. package/build/server/chunks/_page.svelte-FIp-IsOo.js.map +0 -1
  406. package/build/server/chunks/_page.svelte-FLzHOuyK.js.map +0 -1
  407. package/build/server/chunks/_page.svelte-jxFKbZdN.js.map +0 -1
  408. package/build/server/chunks/_page.svelte-k8avSQW1.js +0 -215
  409. package/build/server/chunks/_page.svelte-k8avSQW1.js.map +0 -1
  410. package/build/server/chunks/_page.svelte-w9cxGvUf.js.map +0 -1
  411. package/build/server/chunks/async-BfR0vYHo.js.map +0 -1
  412. package/build/server/chunks/client-bj7sePQc.js +0 -7
  413. package/build/server/chunks/error.svelte-D5sIJv3P.js +0 -18
  414. package/build/server/chunks/error.svelte-D5sIJv3P.js.map +0 -1
  415. package/build/server/chunks/hooks.server-_TKfdzGA.js +0 -26
  416. package/build/server/chunks/hooks.server-_TKfdzGA.js.map +0 -1
  417. package/build/server/chunks/index3-DquTjlmp.js.map +0 -1
  418. package/build/server/chunks/mongo-dLmCShL_.js.map +0 -1
  419. package/build/server/chunks/remote-xxtqbu-BFzaWXy0.js +0 -234
  420. package/build/server/chunks/remote-xxtqbu-BFzaWXy0.js.map +0 -1
  421. package/build/server/chunks/routing-DcR4fCSD.js.map +0 -1
  422. package/src/routes/servers/[server]/databases/[database]/collections/[collection]/+page.server.ts +0 -106
  423. package/src/routes/servers/[server]/databases/[database]/collections/[collection]/+page.svelte +0 -174
  424. /package/build/client/_app/immutable/assets/{3.CRKE8WvY.css → 7.CRKE8WvY.css} +0 -0
  425. /package/build/client/_app/immutable/assets/{3.CRKE8WvY.css.br → 7.CRKE8WvY.css.br} +0 -0
  426. /package/build/client/_app/immutable/assets/{3.CRKE8WvY.css.gz → 7.CRKE8WvY.css.gz} +0 -0
@@ -0,0 +1,342 @@
1
+ <script lang="ts">
2
+ import {
3
+ deleteDocument as deleteDocumentCommand,
4
+ loadDocuments,
5
+ updateDocument as updateDocumentCommand,
6
+ updateMany as updateManyCommand,
7
+ } from "$api/servers.remote";
8
+ import { pushState } from "$app/navigation";
9
+ import { resolve } from "$app/paths";
10
+ import { jsonTextarea } from "$lib/actions/jsonTextarea";
11
+ import Panel from "$lib/components/Panel.svelte";
12
+ import PrettyJson from "$lib/components/PrettyJson.svelte";
13
+ import SearchBox from "$lib/components/SearchBox.svelte";
14
+ import { notificationStore } from "$lib/stores/notifications.svelte";
15
+ import type { MongoDocument, SearchParams } from "$lib/types";
16
+ import { formatNumber } from "$lib/utils/filters";
17
+ import { logger } from "$lib/utils/logger";
18
+ import { SvelteURLSearchParams } from "svelte/reactivity";
19
+ import type { PageData } from "./$types";
20
+
21
+ let { data }: { data: PageData } = $props();
22
+
23
+ /* eslint-disable-next-line svelte/prefer-writable-derived */
24
+ let params = $state<SearchParams>({ ...data.params });
25
+ let dataPromise = $derived(data.results);
26
+ let editMode = $state(false);
27
+ let updateQuery = $state("{}");
28
+ let isUpdating = $state(false);
29
+
30
+ let finalCount = $state<number | null>(null);
31
+ let countCount = 0;
32
+
33
+ $effect(() => {
34
+ params = { ...data.params };
35
+ });
36
+
37
+ $effect(() => {
38
+ const currentCount = ++countCount;
39
+ finalCount = null;
40
+ data.count.then((result) => {
41
+ if (currentCount !== countCount) {
42
+ return;
43
+ }
44
+ finalCount = result.error ? null : result.data;
45
+ });
46
+ });
47
+
48
+ // Handle errors from streamed promises
49
+ $effect(() => {
50
+ // @ts-expect-error I just want to trigger the dependency
51
+ if (dataPromise) {
52
+ modifiedItems = null;
53
+ }
54
+ dataPromise.then((result) => {
55
+ if (result.error) {
56
+ notificationStore.notifyError(result.error);
57
+ }
58
+ });
59
+ });
60
+
61
+ $effect(() => {
62
+ data.count.then((result) => {
63
+ // Don't show notification for timeout errors - they're displayed in the UI
64
+ if (result.error && !result.error.includes("operation exceeded time limit")) {
65
+ notificationStore.notifyError(result.error);
66
+ }
67
+ });
68
+ });
69
+
70
+ let modifiedItems = $state<MongoDocument[] | null>(null);
71
+ let items = $derived(modifiedItems ? { data: modifiedItems, error: null } : dataPromise);
72
+
73
+ async function editDocument(_id: { $value?: string } | undefined, json: MongoDocument, items: MongoDocument[]) {
74
+ const partial = Boolean(
75
+ params.project && params.project !== "{}" && Object.keys(JSON.parse(params.project)).length > 0,
76
+ );
77
+ const newId = json?._id?.$value;
78
+ const oldId = _id?.$value;
79
+
80
+ if (newId !== oldId) {
81
+ notificationStore.notifyError("ObjectId changed. This is not supported, update canceled.");
82
+ return;
83
+ }
84
+
85
+ if (!oldId) return;
86
+
87
+ try {
88
+ const result = await updateDocumentCommand({
89
+ server: data.server,
90
+ database: data.database,
91
+ collection: data.collection,
92
+ document: oldId,
93
+ value: json,
94
+ partial,
95
+ });
96
+
97
+ if (result.ok) {
98
+ notificationStore.notifySuccess("Document updated successfully");
99
+ // Update the document in the list
100
+ const index = items.findIndex((item) => item._id?.$value === oldId);
101
+ if (index !== -1) {
102
+ items[index] = result.update;
103
+ }
104
+ modifiedItems = items;
105
+ }
106
+ } catch (error) {
107
+ logger.log(error);
108
+ notificationStore.notifyError(error, "Failed to update document");
109
+ }
110
+ }
111
+
112
+ async function removeDocument(_id: { $value?: string } | undefined, items: MongoDocument[]) {
113
+ const documentId = _id?.$value;
114
+ if (!documentId) return;
115
+
116
+ try {
117
+ await deleteDocumentCommand({
118
+ server: data.server,
119
+ database: data.database,
120
+ collection: data.collection,
121
+ document: documentId,
122
+ });
123
+
124
+ notificationStore.notifySuccess("Document removed successfully");
125
+ modifiedItems = items.filter((item) => item._id?.$value !== documentId);
126
+ } catch (error) {
127
+ notificationStore.notifyError(error, "Failed to remove document");
128
+ }
129
+ }
130
+
131
+ function buildUrl(skip: number) {
132
+ const queryParams = new SvelteURLSearchParams();
133
+ queryParams.set("query", params.query || "{}");
134
+ queryParams.set("sort", params.sort || "");
135
+ queryParams.set("project", params.project || "");
136
+ queryParams.set("skip", String(skip));
137
+ queryParams.set("limit", String(params.limit));
138
+
139
+ return `/servers/${encodeURIComponent(data.server)}/databases/${encodeURIComponent(data.database)}/collections/${encodeURIComponent(data.collection)}/documents?${queryParams.toString()}`;
140
+ }
141
+
142
+ const nextUrl = $derived(buildUrl(params.skip + params.limit));
143
+ const previousUrl = $derived(buildUrl(Math.max(0, params.skip - params.limit)));
144
+
145
+ function navigateNext(e: MouseEvent) {
146
+ e.preventDefault();
147
+ data.params.skip += data.params.limit;
148
+ params.skip = data.params.skip;
149
+ /* eslint-disable-next-line svelte/no-navigation-without-resolve */
150
+ pushState(nextUrl, {});
151
+ dataPromise = loadDocuments({
152
+ server: data.server,
153
+ database: data.database,
154
+ collection: data.collection,
155
+ query: params.query,
156
+ sort: params.sort,
157
+ project: params.project,
158
+ skip: params.skip,
159
+ limit: params.limit,
160
+ });
161
+ }
162
+
163
+ function navigatePrevious(e: MouseEvent) {
164
+ e.preventDefault();
165
+ data.params.skip = Math.max(0, data.params.skip - data.params.limit);
166
+ params.skip = data.params.skip;
167
+ /* eslint-disable-next-line svelte/no-navigation-without-resolve */
168
+ pushState(previousUrl, {});
169
+ dataPromise = loadDocuments({
170
+ server: data.server,
171
+ database: data.database,
172
+ collection: data.collection,
173
+ query: params.query,
174
+ sort: params.sort,
175
+ project: params.project,
176
+ skip: params.skip,
177
+ limit: params.limit,
178
+ });
179
+ }
180
+
181
+ async function executeUpdateMany() {
182
+ isUpdating = true;
183
+ try {
184
+ const result = await updateManyCommand({
185
+ server: data.server,
186
+ database: data.database,
187
+ collection: data.collection,
188
+ filter: params.query || "{}",
189
+ update: updateQuery,
190
+ });
191
+
192
+ if (result.ok) {
193
+ notificationStore.notifySuccess(`Updated ${result.modifiedCount} document(s) (matched ${result.matchedCount})`);
194
+ // Reset the modified items to force a refresh
195
+ modifiedItems = null;
196
+ editMode = false;
197
+ }
198
+ } catch (error) {
199
+ logger.error(error);
200
+ notificationStore.notifyError(error, "Failed to update documents");
201
+ } finally {
202
+ isUpdating = false;
203
+ }
204
+ }
205
+ </script>
206
+
207
+ <SearchBox bind:params bind:editMode readonly={data.readOnly} />
208
+
209
+ {#if editMode}
210
+ <Panel title="Update Multiple Documents">
211
+ <div class="p-4 space-y-4">
212
+ <div>
213
+ <label for="update-filter" class="block text-sm font-medium mb-2">Filter (which documents to update):</label>
214
+ <input
215
+ type="text"
216
+ id="update-filter"
217
+ value={params.query || "{}"}
218
+ readonly
219
+ class="w-full p-2 border border-[var(--color-4)] bg-[var(--light-background)] rounded font-mono text-sm opacity-75 cursor-not-allowed"
220
+ />
221
+ <p class="text-xs text-[var(--text-secondary,#888)] mt-1">
222
+ This filter is taken from the query above. Modify the query to change which documents will be updated.
223
+ </p>
224
+ </div>
225
+ <div>
226
+ <label for="update-operation" class="block text-sm font-medium mb-2"
227
+ >Update Operation (e.g., $set, $inc, $unset):</label
228
+ >
229
+ <textarea
230
+ bind:value={updateQuery}
231
+ placeholder="Update operation"
232
+ rows="4"
233
+ use:jsonTextarea={{ onsubmit: executeUpdateMany }}
234
+ class="w-full p-2 border border-[var(--color-4)] bg-[var(--color-3)] rounded font-mono text-sm"
235
+ ></textarea>
236
+ </div>
237
+ <div class="flex gap-2">
238
+ <button class="btn btn-success" disabled={isUpdating} onclick={executeUpdateMany}>
239
+ {isUpdating ? "Updating..." : "Execute Update"}
240
+ </button>
241
+ <button class="btn btn-default" onclick={() => (editMode = false)}>Cancel</button>
242
+ </div>
243
+ <div class="text-sm text-[var(--text-secondary,#888)]">
244
+ <p class="mb-1"><strong>Examples:</strong></p>
245
+ <p class="mb-1">
246
+ • Set a field: <code class="bg-[var(--color-3)] px-1 rounded">{'{"$set": {"status": "active"}}'}</code>
247
+ </p>
248
+ <p class="mb-1">
249
+ • Increment a value: <code class="bg-[var(--color-3)] px-1 rounded">{'{"$inc": {"count": 1}}'}</code>
250
+ </p>
251
+ <p>• Unset a field: <code class="bg-[var(--color-3)] px-1 rounded">{'{"$unset": {"oldField": ""}}'}</code></p>
252
+ </div>
253
+ </div>
254
+ </Panel>
255
+ {/if}
256
+
257
+ {#await items}
258
+ <Panel
259
+ title={finalCount !== null
260
+ ? `${formatNumber(data.params.skip + 1)} - ${formatNumber(data.params.skip + data.params.limit)} of ${formatNumber(finalCount)} documents...`
261
+ : "Loading documents..."}
262
+ >
263
+ {#snippet actions()}
264
+ {#if finalCount !== null}
265
+ {#if data.params.skip > 0}
266
+ <!-- eslint-disable-next-line @typescript-eslint/no-explicit-any -->
267
+ <a href={resolve(previousUrl as any)} onclick={navigatePrevious} class="btn btn-default btn-sm -my-2">
268
+ Previous
269
+ </a>
270
+ {/if}
271
+ {#if data.params.skip + data.params.limit < finalCount}
272
+ <!-- eslint-disable-next-line @typescript-eslint/no-explicit-any -->
273
+ <a href={resolve(nextUrl as any)} onclick={navigateNext} class="btn btn-default btn-sm -my-2">Next</a>
274
+ {/if}
275
+ {/if}
276
+ {/snippet}
277
+ </Panel>
278
+ {:then resultsData}
279
+ <!-- Sometimes resultsData is undefined when navigating to indexes page -->
280
+ {@const items = resultsData?.data ?? []}
281
+ {#await data.count}
282
+ <Panel
283
+ title={items.length > 0
284
+ ? `${formatNumber(data.params.skip + 1)} - ${formatNumber(data.params.skip + items.length)} Documents (counting...)`
285
+ : "No documents"}
286
+ >
287
+ {#snippet actions()}
288
+ {#if data.params.skip > 0}
289
+ <!-- eslint-disable-next-line @typescript-eslint/no-explicit-any -->
290
+ <a href={resolve(previousUrl as any)} onclick={navigatePrevious} class="btn btn-default btn-sm -my-2">
291
+ Previous
292
+ </a>
293
+ {/if}
294
+ {#if items.length >= data.params.limit}
295
+ <!-- eslint-disable-next-line @typescript-eslint/no-explicit-any -->
296
+ <a href={resolve(nextUrl as any)} onclick={navigateNext} class="btn btn-default btn-sm -my-2">Next</a>
297
+ {/if}
298
+ {/snippet}
299
+ </Panel>
300
+ {:then countData}
301
+ <!-- Sometimes data.params can be undefined when switching to indexes page-->
302
+ {#if data.params}
303
+ {@const count = countData.data}
304
+ {@const hasNext = countData.error ? items.length >= data.params.limit : data.params.skip + items.length < count}
305
+ {@const hasPrevious = data.params.skip > 0}
306
+ {@const isTimeout = countData.error?.includes("operation exceeded time limit")}
307
+ <Panel
308
+ title={items.length > 0
309
+ ? count > 0
310
+ ? `${formatNumber(data.params.skip + 1)} - ${formatNumber(data.params.skip + items.length)} of ${formatNumber(count)} Documents`
311
+ : `${formatNumber(data.params.skip + 1)} - ${formatNumber(data.params.skip + items.length)} Documents (count ${isTimeout ? "timeout" : "unavailable"})`
312
+ : "No documents"}
313
+ >
314
+ {#snippet actions()}
315
+ {#if hasPrevious}
316
+ <!-- eslint-disable-next-line @typescript-eslint/no-explicit-any -->
317
+ <a href={resolve(previousUrl as any)} onclick={navigatePrevious} class="btn btn-default btn-sm -my-2">
318
+ Previous
319
+ </a>
320
+ {/if}
321
+ {#if hasNext}
322
+ <!-- eslint-disable-next-line @typescript-eslint/no-explicit-any -->
323
+ <a href={resolve(nextUrl as any)} onclick={navigateNext} class="btn btn-default btn-sm -my-2">Next</a>
324
+ {/if}
325
+ {/snippet}
326
+ </Panel>
327
+ {/if}
328
+ {/await}
329
+
330
+ {#each items as item, index (item._id?.$value || index)}
331
+ <PrettyJson
332
+ json={item}
333
+ autoCollapse={true}
334
+ onedit={data.isAggregation || data.readOnly ? undefined : (json) => editDocument(item._id, json, items)}
335
+ onremove={data.isAggregation || data.readOnly ? undefined : () => removeDocument(item._id, items)}
336
+ server={data.server}
337
+ database={data.database}
338
+ collection={data.collection}
339
+ mappings={data.mappings}
340
+ />
341
+ {/each}
342
+ {/await}
@@ -0,0 +1,10 @@
1
+ export const load = async (data) => {
2
+ return {
3
+ ...data.data,
4
+ categories: [
5
+ { key: "documents", label: "Documents" },
6
+ { key: "indexes", label: "Indexes" },
7
+ { key: "mappings", label: "Mappings" },
8
+ ],
9
+ };
10
+ };
@@ -0,0 +1,9 @@
1
+ export const load = async (event) => {
2
+ return {
3
+ document: event.params.document,
4
+ breadcrumbs: [
5
+ ...(await event.parent()).breadcrumbs,
6
+ { label: event.params.document, path: `/documents/${event.params.document}` },
7
+ ],
8
+ };
9
+ };
@@ -3,23 +3,26 @@ import { getMongo } from "$lib/server/mongo";
3
3
  import { ObjectId } from "mongodb";
4
4
  import type { PageServerLoad } from "./$types";
5
5
 
6
- export const load: PageServerLoad = async ({ params }) => {
6
+ export const load: PageServerLoad = async ({ params, parent }) => {
7
7
  const mongo = await getMongo();
8
- const collection = mongo.getCollection(params.server, params.database, params.collection);
8
+ const client = mongo.getClient(params.server);
9
+ const collection = client.db(params.database).collection(params.collection);
9
10
 
10
11
  let document = null;
11
- if (collection) {
12
- const obj = await collection.findOne({
13
- _id: new ObjectId(params.document),
14
- });
15
- document = JsonEncoder.encode(obj);
16
- }
12
+ const obj = await collection.findOne({
13
+ _id: /^[0-9a-fA-F]{24}$/.test(params.document)
14
+ ? new ObjectId(params.document)
15
+ : (params.document as unknown as ObjectId),
16
+ });
17
+
18
+ document = obj ? JsonEncoder.encode(obj) : null;
19
+
20
+ const parentData = await parent();
17
21
 
18
22
  return {
19
- server: params.server,
20
- database: params.database,
21
- collection: params.collection,
22
- documentId: params.document,
23
23
  document,
24
+ documentId: params.document,
25
+ mappings: await client.getMappings(params.database, params.collection),
26
+ readOnly: parentData.readOnly,
24
27
  };
25
28
  };
@@ -1,6 +1,7 @@
1
1
  <script lang="ts">
2
2
  import {
3
3
  deleteDocument as deleteDocumentCommand,
4
+ insertDocument as insertDocumentCommand,
4
5
  updateDocument as updateDocumentCommand,
5
6
  } from "$api/servers.remote";
6
7
  import { goto } from "$app/navigation";
@@ -14,10 +15,11 @@
14
15
 
15
16
  let loading = $state(false);
16
17
  let item = $derived(data.document);
18
+ let showInsertEditor = $state(false);
17
19
 
18
20
  async function editDocument(json: MongoDocument) {
19
- const newId = json?._id?.$value;
20
- const oldId = item?._id?.$value;
21
+ const newId = json?._id?.$value ?? json?._id;
22
+ const oldId = item?._id?.$value ?? item?._id;
21
23
 
22
24
  if (newId !== oldId) {
23
25
  notificationStore.notifyError("ObjectId changed. This is not supported, update canceled.");
@@ -49,7 +51,7 @@
49
51
  }
50
52
 
51
53
  async function removeDocument() {
52
- const documentId = item?._id?.$value;
54
+ const documentId = item?._id?.$value ?? item?._id;
53
55
  if (!documentId) return;
54
56
 
55
57
  try {
@@ -71,6 +73,33 @@
71
73
  notificationStore.notifyError(error, "Failed to remove document");
72
74
  }
73
75
  }
76
+
77
+ async function insertDocument(json: MongoDocument) {
78
+ loading = true;
79
+ try {
80
+ const result = await insertDocumentCommand({
81
+ server: data.server,
82
+ database: data.database,
83
+ collection: data.collection,
84
+ document: data.documentId,
85
+ value: json,
86
+ });
87
+
88
+ if (result.ok) {
89
+ notificationStore.notifySuccess("Document inserted successfully");
90
+ // Reload the page to show the newly inserted document
91
+ window.location.reload();
92
+ }
93
+ } catch (error) {
94
+ notificationStore.notifyError(error, "Failed to insert document");
95
+ } finally {
96
+ loading = false;
97
+ }
98
+ }
99
+
100
+ function handleInsertClick() {
101
+ showInsertEditor = true;
102
+ }
74
103
  </script>
75
104
 
76
105
  {#if loading}
@@ -78,13 +107,58 @@
78
107
  {:else if item}
79
108
  <PrettyJson
80
109
  json={item}
81
- readOnly={data.readOnly}
82
- onedit={editDocument}
83
- onremove={removeDocument}
110
+ onedit={data.readOnly ? undefined : editDocument}
111
+ onremove={data.readOnly ? undefined : removeDocument}
84
112
  server={data.server}
85
113
  database={data.database}
86
114
  collection={data.collection}
115
+ mappings={data.mappings}
87
116
  />
117
+ {:else if showInsertEditor}
118
+ <div class="insert-container">
119
+ <h3>Insert Document with ID: {data.documentId}</h3>
120
+ <PrettyJson
121
+ json={{ _id: { $type: "ObjectId", $value: data.documentId } }}
122
+ onedit={insertDocument}
123
+ server={data.server}
124
+ database={data.database}
125
+ collection={data.collection}
126
+ mappings={data.mappings}
127
+ startInEditMode={true}
128
+ />
129
+ <button class="btn btn-default mt-4" onclick={() => (showInsertEditor = false)}>Cancel</button>
130
+ </div>
88
131
  {:else}
89
- <div class="text-center">Document not found</div>
132
+ <div class="not-found-container">
133
+ <div class="text-center">Document not found</div>
134
+ {#if !data.readOnly}
135
+ <button class="btn btn-success" onclick={handleInsertClick}>Insert Document</button>
136
+ {/if}
137
+ </div>
90
138
  {/if}
139
+
140
+ <style>
141
+ .not-found-container {
142
+ display: flex;
143
+ flex-direction: column;
144
+ align-items: center;
145
+ gap: 1rem;
146
+ margin-top: 2rem;
147
+ }
148
+
149
+ .insert-container {
150
+ padding: 1rem;
151
+ }
152
+
153
+ .insert-container h3 {
154
+ margin-bottom: 1rem;
155
+ color: var(--text);
156
+ }
157
+
158
+ .loading,
159
+ .text-center {
160
+ text-align: center;
161
+ padding: 2rem;
162
+ color: var(--text);
163
+ }
164
+ </style>
@@ -0,0 +1,88 @@
1
+ import JsonEncoder from "$lib/server/JsonEncoder";
2
+ import { getMongo } from "$lib/server/mongo";
3
+ import { logger } from "$lib/utils/logger";
4
+ import type { IndexDescription } from "mongodb";
5
+ import type { PageServerLoad } from "./$types";
6
+
7
+ export const load: PageServerLoad = async ({ params, depends }) => {
8
+ depends("app:indexes");
9
+
10
+ const mongo = await getMongo();
11
+ const client = mongo.getClient(params.server);
12
+ const collection = client.db(params.database).collection(params.collection);
13
+
14
+ const indexesPromise = (async () => {
15
+ try {
16
+ // Get index definitions
17
+ const indexList = (await collection.listIndexes().toArray()) as IndexDescription[];
18
+
19
+ // Get index usage statistics
20
+ let indexStats: Record<string, { ops: number; since: Date }> = {};
21
+ try {
22
+ const statsResult = await collection.aggregate([{ $indexStats: {} }]).toArray();
23
+
24
+ indexStats = statsResult.reduce(
25
+ (acc, stat) => {
26
+ acc[stat.name] = {
27
+ ops: stat.accesses?.ops || 0,
28
+ since: stat.accesses?.since || new Date(),
29
+ };
30
+ return acc;
31
+ },
32
+ {} as Record<string, { ops: number; since: Date }>,
33
+ );
34
+ } catch (err) {
35
+ logger.error("Error fetching index stats:", err);
36
+ // Continue without stats if unavailable
37
+ }
38
+
39
+ // Get index sizes from collection stats
40
+ let indexSizes: Record<string, number> = {};
41
+ try {
42
+ const collStatsResult = (await collection
43
+ .aggregate([
44
+ {
45
+ $collStats: {
46
+ storageStats: {},
47
+ },
48
+ },
49
+ ])
50
+ .next()) as {
51
+ storageStats?: {
52
+ indexSizes?: Record<string, number>;
53
+ };
54
+ } | null;
55
+
56
+ if (collStatsResult?.storageStats?.indexSizes) {
57
+ indexSizes = collStatsResult.storageStats.indexSizes;
58
+ }
59
+ } catch (err) {
60
+ logger.error("Error fetching index sizes:", err);
61
+ // Continue without sizes if unavailable
62
+ }
63
+
64
+ // Merge index definitions with stats and sizes
65
+ const indexesWithStats = indexList.map((index) => ({
66
+ ...index,
67
+ stats: index.name ? indexStats[index.name] || null : null,
68
+ size: index.name ? indexSizes[index.name] || 0 : 0,
69
+ }));
70
+
71
+ // Encode to handle MongoDB types like ObjectId, etc.
72
+ return {
73
+ data: indexesWithStats.map((index) => JsonEncoder.encode(index)),
74
+ error: null as string | null,
75
+ };
76
+ } catch (err) {
77
+ logger.error("Error fetching indexes:", err);
78
+ return {
79
+ data: [],
80
+ error: `Failed to fetch indexes: ${err instanceof Error ? err.message : String(err)}`,
81
+ };
82
+ }
83
+ })();
84
+
85
+ return {
86
+ indexes: indexesPromise,
87
+ };
88
+ };