mongoku 2.0.3 → 2.1.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 (418) hide show
  1. package/Dockerfile +3 -1
  2. package/README.md +23 -9
  3. package/build/client/_app/immutable/assets/0.egX7ddQL.css +1 -0
  4. package/build/client/_app/immutable/assets/0.egX7ddQL.css.br +0 -0
  5. package/build/client/_app/immutable/assets/0.egX7ddQL.css.gz +0 -0
  6. package/build/client/_app/immutable/assets/10.59aTjJn9.css +1 -0
  7. package/build/client/_app/immutable/assets/10.59aTjJn9.css.br +0 -0
  8. package/build/client/_app/immutable/assets/10.59aTjJn9.css.gz +0 -0
  9. package/build/client/_app/immutable/assets/11.CEtFGlZU.css +1 -0
  10. package/build/client/_app/immutable/assets/11.CEtFGlZU.css.br +1 -0
  11. package/build/client/_app/immutable/assets/11.CEtFGlZU.css.gz +0 -0
  12. package/build/client/_app/immutable/assets/12.BdCOhvz0.css +1 -0
  13. package/build/client/_app/immutable/assets/12.BdCOhvz0.css.br +0 -0
  14. package/build/client/_app/immutable/assets/12.BdCOhvz0.css.gz +0 -0
  15. package/build/client/_app/immutable/assets/JsonValue.BEbzuWqZ.css +1 -0
  16. package/build/client/_app/immutable/assets/JsonValue.BEbzuWqZ.css.br +0 -0
  17. package/build/client/_app/immutable/assets/JsonValue.BEbzuWqZ.css.gz +0 -0
  18. package/build/client/_app/immutable/assets/Modal.DIIFkbGB.css +1 -0
  19. package/build/client/_app/immutable/assets/Modal.DIIFkbGB.css.br +0 -0
  20. package/build/client/_app/immutable/assets/Modal.DIIFkbGB.css.gz +0 -0
  21. package/build/client/_app/immutable/assets/Panel.B3aWupye.css +1 -0
  22. package/build/client/_app/immutable/assets/Panel.B3aWupye.css.br +0 -0
  23. package/build/client/_app/immutable/assets/Panel.B3aWupye.css.gz +0 -0
  24. package/build/client/_app/immutable/chunks/7rjwS0Fa.js +1 -0
  25. package/build/client/_app/immutable/chunks/7rjwS0Fa.js.br +0 -0
  26. package/build/client/_app/immutable/chunks/7rjwS0Fa.js.gz +0 -0
  27. package/build/client/_app/immutable/chunks/BLDrwdCC.js +1 -0
  28. package/build/client/_app/immutable/chunks/BLDrwdCC.js.br +0 -0
  29. package/build/client/_app/immutable/chunks/BLDrwdCC.js.gz +0 -0
  30. package/build/client/_app/immutable/chunks/BNpv6iz_.js +1 -0
  31. package/build/client/_app/immutable/chunks/BNpv6iz_.js.br +0 -0
  32. package/build/client/_app/immutable/chunks/BNpv6iz_.js.gz +0 -0
  33. package/build/client/_app/immutable/chunks/BY7rCWFm.js +1 -0
  34. package/build/client/_app/immutable/chunks/BY7rCWFm.js.br +0 -0
  35. package/build/client/_app/immutable/chunks/BY7rCWFm.js.gz +0 -0
  36. package/build/client/_app/immutable/chunks/BirzSxMb.js +2 -0
  37. package/build/client/_app/immutable/chunks/BirzSxMb.js.br +0 -0
  38. package/build/client/_app/immutable/chunks/BirzSxMb.js.gz +0 -0
  39. package/build/client/_app/immutable/chunks/BsxVnnsB.js +1 -0
  40. package/build/client/_app/immutable/chunks/BsxVnnsB.js.br +0 -0
  41. package/build/client/_app/immutable/chunks/BsxVnnsB.js.gz +0 -0
  42. package/build/client/_app/immutable/chunks/BtVcRw28.js +29 -0
  43. package/build/client/_app/immutable/chunks/BtVcRw28.js.br +0 -0
  44. package/build/client/_app/immutable/chunks/BtVcRw28.js.gz +0 -0
  45. package/build/client/_app/immutable/chunks/CdQ4HxbR.js +2 -0
  46. package/build/client/_app/immutable/chunks/CdQ4HxbR.js.br +0 -0
  47. package/build/client/_app/immutable/chunks/CdQ4HxbR.js.gz +0 -0
  48. package/build/client/_app/immutable/chunks/CeUVbZ2h.js +1 -0
  49. package/build/client/_app/immutable/chunks/CeUVbZ2h.js.br +0 -0
  50. package/build/client/_app/immutable/chunks/CeUVbZ2h.js.gz +0 -0
  51. package/build/client/_app/immutable/chunks/CsO4V9Pl.js +1 -0
  52. package/build/client/_app/immutable/chunks/CsO4V9Pl.js.br +0 -0
  53. package/build/client/_app/immutable/chunks/CsO4V9Pl.js.gz +0 -0
  54. package/build/client/_app/immutable/chunks/Cy5AtpEx.js +1 -0
  55. package/build/client/_app/immutable/chunks/Cy5AtpEx.js.br +0 -0
  56. package/build/client/_app/immutable/chunks/Cy5AtpEx.js.gz +0 -0
  57. package/build/client/_app/immutable/chunks/DD3Ma7mI.js +1 -0
  58. package/build/client/_app/immutable/chunks/DD3Ma7mI.js.br +1 -0
  59. package/build/client/_app/immutable/chunks/DD3Ma7mI.js.gz +0 -0
  60. package/build/client/_app/immutable/chunks/DDOxwa8G.js +1 -0
  61. package/build/client/_app/immutable/chunks/DDOxwa8G.js.br +0 -0
  62. package/build/client/_app/immutable/chunks/DDOxwa8G.js.gz +0 -0
  63. package/build/client/_app/immutable/chunks/DPilZ31q.js +4 -0
  64. package/build/client/_app/immutable/chunks/DPilZ31q.js.br +0 -0
  65. package/build/client/_app/immutable/chunks/DPilZ31q.js.gz +0 -0
  66. package/build/client/_app/immutable/chunks/DkcM24tw.js +1 -0
  67. package/build/client/_app/immutable/chunks/DkcM24tw.js.br +0 -0
  68. package/build/client/_app/immutable/chunks/DkcM24tw.js.gz +0 -0
  69. package/build/client/_app/immutable/chunks/{uMNMODvc.js → DzIzGsAN.js} +1 -1
  70. package/build/client/_app/immutable/chunks/DzIzGsAN.js.br +0 -0
  71. package/build/client/_app/immutable/chunks/DzIzGsAN.js.gz +0 -0
  72. package/build/client/_app/immutable/chunks/Dzn375RV.js +1 -0
  73. package/build/client/_app/immutable/chunks/Dzn375RV.js.br +0 -0
  74. package/build/client/_app/immutable/chunks/Dzn375RV.js.gz +0 -0
  75. package/build/client/_app/immutable/chunks/hzkOq89z.js +1 -0
  76. package/build/client/_app/immutable/chunks/hzkOq89z.js.br +0 -0
  77. package/build/client/_app/immutable/chunks/hzkOq89z.js.gz +0 -0
  78. package/build/client/_app/immutable/chunks/myWOS8Ad.js +1 -0
  79. package/build/client/_app/immutable/chunks/myWOS8Ad.js.br +0 -0
  80. package/build/client/_app/immutable/chunks/myWOS8Ad.js.gz +0 -0
  81. package/build/client/_app/immutable/chunks/{BKCvWebR.js → pwiEVMhR.js} +1 -1
  82. package/build/client/_app/immutable/chunks/pwiEVMhR.js.br +0 -0
  83. package/build/client/_app/immutable/chunks/pwiEVMhR.js.gz +0 -0
  84. package/build/client/_app/immutable/chunks/woTmcqT7.js +1 -0
  85. package/build/client/_app/immutable/chunks/woTmcqT7.js.br +0 -0
  86. package/build/client/_app/immutable/chunks/woTmcqT7.js.gz +0 -0
  87. package/build/client/_app/immutable/chunks/zDi6mm3o.js +1 -0
  88. package/build/client/_app/immutable/chunks/zDi6mm3o.js.br +0 -0
  89. package/build/client/_app/immutable/chunks/zDi6mm3o.js.gz +0 -0
  90. package/build/client/_app/immutable/entry/app.CxQNYOR7.js +2 -0
  91. package/build/client/_app/immutable/entry/app.CxQNYOR7.js.br +0 -0
  92. package/build/client/_app/immutable/entry/app.CxQNYOR7.js.gz +0 -0
  93. package/build/client/_app/immutable/entry/start.CUo1ZpWZ.js +1 -0
  94. package/build/client/_app/immutable/entry/start.CUo1ZpWZ.js.br +2 -0
  95. package/build/client/_app/immutable/entry/start.CUo1ZpWZ.js.gz +0 -0
  96. package/build/client/_app/immutable/nodes/0.NM9sLghd.js +5 -0
  97. package/build/client/_app/immutable/nodes/0.NM9sLghd.js.br +0 -0
  98. package/build/client/_app/immutable/nodes/0.NM9sLghd.js.gz +0 -0
  99. package/build/client/_app/immutable/nodes/1.DbC3260o.js +1 -0
  100. package/build/client/_app/immutable/nodes/1.DbC3260o.js.br +2 -0
  101. package/build/client/_app/immutable/nodes/1.DbC3260o.js.gz +0 -0
  102. package/build/client/_app/immutable/nodes/10.BVQvX3m0.js +2 -0
  103. package/build/client/_app/immutable/nodes/10.BVQvX3m0.js.br +0 -0
  104. package/build/client/_app/immutable/nodes/10.BVQvX3m0.js.gz +0 -0
  105. package/build/client/_app/immutable/nodes/11.Bxvf_-yk.js +1 -0
  106. package/build/client/_app/immutable/nodes/11.Bxvf_-yk.js.br +0 -0
  107. package/build/client/_app/immutable/nodes/11.Bxvf_-yk.js.gz +0 -0
  108. package/build/client/_app/immutable/nodes/12.Prhpx9Ma.js +1 -0
  109. package/build/client/_app/immutable/nodes/12.Prhpx9Ma.js.br +0 -0
  110. package/build/client/_app/immutable/nodes/12.Prhpx9Ma.js.gz +0 -0
  111. package/build/client/_app/immutable/nodes/13.Bgj5oOSN.js +66 -0
  112. package/build/client/_app/immutable/nodes/13.Bgj5oOSN.js.br +0 -0
  113. package/build/client/_app/immutable/nodes/13.Bgj5oOSN.js.gz +0 -0
  114. package/build/client/_app/immutable/nodes/2.UoL1FlSn.js +1 -0
  115. package/build/client/_app/immutable/nodes/2.UoL1FlSn.js.br +1 -0
  116. package/build/client/_app/immutable/nodes/2.UoL1FlSn.js.gz +0 -0
  117. package/build/client/_app/immutable/nodes/3.oJ7_29Md.js +1 -0
  118. package/build/client/_app/immutable/nodes/3.oJ7_29Md.js.br +0 -0
  119. package/build/client/_app/immutable/nodes/3.oJ7_29Md.js.gz +0 -0
  120. package/build/client/_app/immutable/nodes/4.BbmkM0ZH.js +1 -0
  121. package/build/client/_app/immutable/nodes/4.BbmkM0ZH.js.br +0 -0
  122. package/build/client/_app/immutable/nodes/4.BbmkM0ZH.js.gz +0 -0
  123. package/build/client/_app/immutable/nodes/5.CUeb6mKm.js +1 -0
  124. package/build/client/_app/immutable/nodes/5.CUeb6mKm.js.br +0 -0
  125. package/build/client/_app/immutable/nodes/5.CUeb6mKm.js.gz +0 -0
  126. package/build/client/_app/immutable/nodes/7.BiyUd38g.js +1 -0
  127. package/build/client/_app/immutable/nodes/7.BiyUd38g.js.br +0 -0
  128. package/build/client/_app/immutable/nodes/7.BiyUd38g.js.gz +0 -0
  129. package/build/client/_app/immutable/nodes/8.DhezXfEp.js +1 -0
  130. package/build/client/_app/immutable/nodes/8.DhezXfEp.js.br +0 -0
  131. package/build/client/_app/immutable/nodes/8.DhezXfEp.js.gz +0 -0
  132. package/build/client/_app/immutable/nodes/9.tIbM6W_7.js +2 -0
  133. package/build/client/_app/immutable/nodes/9.tIbM6W_7.js.br +0 -0
  134. package/build/client/_app/immutable/nodes/9.tIbM6W_7.js.gz +0 -0
  135. package/build/client/_app/version.json +1 -1
  136. package/build/client/_app/version.json.br +0 -0
  137. package/build/client/_app/version.json.gz +0 -0
  138. package/build/handler.js +14 -0
  139. package/build/server/chunks/{0-C1NyHW8A.js → 0-Xn_28PLT.js} +7 -6
  140. package/build/server/chunks/0-Xn_28PLT.js.map +1 -0
  141. package/build/server/chunks/1-CBgVE2FQ.js +9 -0
  142. package/build/server/chunks/1-CBgVE2FQ.js.map +1 -0
  143. package/build/server/chunks/10-nsD-CCn7.js +212 -0
  144. package/build/server/chunks/10-nsD-CCn7.js.map +1 -0
  145. package/build/server/chunks/11-BmqLuLNb.js +41 -0
  146. package/build/server/chunks/11-BmqLuLNb.js.map +1 -0
  147. package/build/server/chunks/12-PgTuaplb.js +101 -0
  148. package/build/server/chunks/12-PgTuaplb.js.map +1 -0
  149. package/build/server/chunks/13-BSGYMCpC.js +51 -0
  150. package/build/server/chunks/13-BSGYMCpC.js.map +1 -0
  151. package/build/server/chunks/2-BJxJqjul.js +24 -0
  152. package/build/server/chunks/2-BJxJqjul.js.map +1 -0
  153. package/build/server/chunks/3-D2ftoQkX.js +25 -0
  154. package/build/server/chunks/3-D2ftoQkX.js.map +1 -0
  155. package/build/server/chunks/4-CdkZadEU.js +25 -0
  156. package/build/server/chunks/4-CdkZadEU.js.map +1 -0
  157. package/build/server/chunks/5-ClD9AjJX.js +25 -0
  158. package/build/server/chunks/5-ClD9AjJX.js.map +1 -0
  159. package/build/server/chunks/{2-B39zPvzn.js → 6-ifXBeMPA.js} +2 -2
  160. package/build/server/chunks/{2-B39zPvzn.js.map → 6-ifXBeMPA.js.map} +1 -1
  161. package/build/server/chunks/7-D0jTAIl_.js +81 -0
  162. package/build/server/chunks/7-D0jTAIl_.js.map +1 -0
  163. package/build/server/chunks/{4-Dfbpsagm.js → 8-CgDL2fiA.js} +18 -10
  164. package/build/server/chunks/8-CgDL2fiA.js.map +1 -0
  165. package/build/server/chunks/{5-DLB6GOjf.js → 9-Dn6eMY6x.js} +6 -8
  166. package/build/server/chunks/9-Dn6eMY6x.js.map +1 -0
  167. package/build/server/chunks/JsonValue-DjUulYwg.js +290 -0
  168. package/build/server/chunks/JsonValue-DjUulYwg.js.map +1 -0
  169. package/build/server/chunks/Modal-zVnoAfFx.js +36 -0
  170. package/build/server/chunks/Modal-zVnoAfFx.js.map +1 -0
  171. package/build/server/chunks/{Panel-Box8ld78.js → Panel-BM545RWK.js} +4 -3
  172. package/build/server/chunks/Panel-BM545RWK.js.map +1 -0
  173. package/build/server/chunks/PrettyJson-CVemKT9n.js +137 -0
  174. package/build/server/chunks/PrettyJson-CVemKT9n.js.map +1 -0
  175. package/build/server/chunks/Tooltip-ByN2a8nn.js +38 -0
  176. package/build/server/chunks/Tooltip-ByN2a8nn.js.map +1 -0
  177. package/build/server/chunks/TooltipTable-CftpgkMV.js +60 -0
  178. package/build/server/chunks/TooltipTable-CftpgkMV.js.map +1 -0
  179. package/build/server/chunks/_layout.svelte-D8Erqrch.js +163 -0
  180. package/build/server/chunks/_layout.svelte-D8Erqrch.js.map +1 -0
  181. package/build/server/chunks/{_page.svelte-PuIVQ52p.js → _page.svelte-BZL67-Tl.js} +32 -13
  182. package/build/server/chunks/_page.svelte-BZL67-Tl.js.map +1 -0
  183. package/build/server/chunks/{_page.svelte-B_T8EFk3.js → _page.svelte-BwdDcghe.js} +63 -13
  184. package/build/server/chunks/_page.svelte-BwdDcghe.js.map +1 -0
  185. package/build/server/chunks/{_page.svelte-CflJkclc.js → _page.svelte-CwGhs70Z.js} +9 -6
  186. package/build/server/chunks/_page.svelte-CwGhs70Z.js.map +1 -0
  187. package/build/server/chunks/_page.svelte-DI3cZxuK.js +197 -0
  188. package/build/server/chunks/_page.svelte-DI3cZxuK.js.map +1 -0
  189. package/build/server/chunks/_page.svelte-DPUr13fG.js +203 -0
  190. package/build/server/chunks/_page.svelte-DPUr13fG.js.map +1 -0
  191. package/build/server/chunks/{_page.svelte-zlHeUnJK.js → _page.svelte-mO3b8YSb.js} +37 -20
  192. package/build/server/chunks/_page.svelte-mO3b8YSb.js.map +1 -0
  193. package/build/server/chunks/{_page.svelte-D1QIZqLv.js → _page.svelte-mPOsEew6.js} +105 -30
  194. package/build/server/chunks/_page.svelte-mPOsEew6.js.map +1 -0
  195. package/build/server/chunks/_server.ts-06lGoPp8.js +8 -0
  196. package/build/server/chunks/_server.ts-06lGoPp8.js.map +1 -0
  197. package/build/server/chunks/async-lVJA8xJZ.js +9 -0
  198. package/build/server/chunks/async-lVJA8xJZ.js.map +1 -0
  199. package/build/server/chunks/client-BFlyU7ZU.js +7 -0
  200. package/build/server/chunks/{client-bj7sePQc.js.map → client-BFlyU7ZU.js.map} +1 -1
  201. package/build/server/chunks/{client2-BX4-xbM4.js → client2-DYaMKWrc.js} +4 -4
  202. package/build/server/chunks/{client2-BX4-xbM4.js.map → client2-DYaMKWrc.js.map} +1 -1
  203. package/build/server/chunks/{async-BfR0vYHo.js → context-C22hLSHK.js} +2 -8
  204. package/build/server/chunks/context-C22hLSHK.js.map +1 -0
  205. package/build/server/chunks/error.svelte-BENdaVOT.js +19 -0
  206. package/build/server/chunks/error.svelte-BENdaVOT.js.map +1 -0
  207. package/build/server/chunks/event-DVH-6ISX.js.map +1 -1
  208. package/build/server/chunks/{index-EKt9-9bV.js → index-DFXVwu6p.js} +2 -2
  209. package/build/server/chunks/{index-EKt9-9bV.js.map → index-DFXVwu6p.js.map} +1 -1
  210. package/build/server/chunks/index-Djsj11qr.js.map +1 -1
  211. package/build/server/chunks/index-server-Bf-hP5gL.js +5 -0
  212. package/build/server/chunks/index-server-Bf-hP5gL.js.map +1 -0
  213. package/build/server/chunks/{routing-Ddj5b-2K.js → index2-d4SCF7oA.js} +8 -88
  214. package/build/server/chunks/index2-d4SCF7oA.js.map +1 -0
  215. package/build/server/chunks/{index3-DquTjlmp.js → index3-CoOO2o9t.js} +6 -6
  216. package/build/server/chunks/index3-CoOO2o9t.js.map +1 -0
  217. package/build/server/chunks/jsonParser-CraFXJs8.js +174 -0
  218. package/build/server/chunks/jsonParser-CraFXJs8.js.map +1 -0
  219. package/build/server/chunks/layout.svelte-CJcHX-Na.js +10 -0
  220. package/build/server/chunks/layout.svelte-CJcHX-Na.js.map +1 -0
  221. package/build/server/chunks/{mongo-dLmCShL_.js → mongo-DMG2RTBR.js} +51 -10
  222. package/build/server/chunks/mongo-DMG2RTBR.js.map +1 -0
  223. package/build/server/chunks/remote-xxtqbu-BUzBKv3P.js +16 -0
  224. package/build/server/chunks/remote-xxtqbu-BUzBKv3P.js.map +1 -0
  225. package/build/server/chunks/routing-e10vGH37.js +81 -0
  226. package/build/server/chunks/routing-e10vGH37.js.map +1 -0
  227. package/build/server/chunks/{server2-BOoUfKd7.js → server2-_mGVuBoG.js} +2 -2
  228. package/build/server/chunks/{server2-BOoUfKd7.js.map → server2-_mGVuBoG.js.map} +1 -1
  229. package/build/server/chunks/servers.remote-DKhy8wTJ.js +678 -0
  230. package/build/server/chunks/servers.remote-DKhy8wTJ.js.map +1 -0
  231. package/build/server/chunks/shared-Buki-xt5.js +506 -0
  232. package/build/server/chunks/shared-Buki-xt5.js.map +1 -0
  233. package/build/server/chunks/{state.svelte-CRHA9yov.js → state.svelte-C8IWmp_n.js} +2 -2
  234. package/build/server/chunks/{state.svelte-CRHA9yov.js.map → state.svelte-C8IWmp_n.js.map} +1 -1
  235. package/build/server/chunks/{utils-DGYJFmnf.js → utils-kjxf7BZO.js} +2 -2
  236. package/build/server/chunks/{utils-DGYJFmnf.js.map → utils-kjxf7BZO.js.map} +1 -1
  237. package/build/server/index.js +188 -609
  238. package/build/server/index.js.map +1 -1
  239. package/build/server/manifest.js +45 -18
  240. package/build/server/manifest.js.map +1 -1
  241. package/cli.ts +7 -1
  242. package/dist/cli.js +7 -1
  243. package/ecosystem.config.js +0 -3
  244. package/package.json +13 -2
  245. package/src/api/servers.remote.ts +369 -20
  246. package/src/app.css +98 -3
  247. package/src/app.html +15 -0
  248. package/src/lib/actions/jsonTextarea.ts +395 -0
  249. package/src/lib/components/Breadcrumbs.svelte +7 -58
  250. package/src/lib/components/JsonValue.svelte +279 -85
  251. package/src/lib/components/Modal.svelte +59 -0
  252. package/src/lib/components/OriginWarning.svelte +109 -0
  253. package/src/lib/components/PageSwitcher.svelte +37 -0
  254. package/src/lib/components/Panel.svelte +1 -1
  255. package/src/lib/components/PrettyJson.svelte +124 -38
  256. package/src/lib/components/SearchBox.svelte +161 -97
  257. package/src/lib/components/ThemeSwitcher.svelte +66 -0
  258. package/src/lib/components/Tooltip.svelte +83 -0
  259. package/src/lib/components/TooltipTable.svelte +45 -102
  260. package/src/lib/server/HostsManager.ts +4 -0
  261. package/src/lib/server/aggregation.ts +62 -0
  262. package/src/lib/server/mongo.ts +75 -13
  263. package/src/lib/types.ts +60 -0
  264. package/src/lib/utils/isEmptyObject.ts +6 -0
  265. package/src/lib/utils/jsonParser.ts +9 -1
  266. package/src/lib/utils/omit.ts +3 -0
  267. package/src/routes/+layout.server.ts +2 -1
  268. package/src/routes/+layout.svelte +11 -2
  269. package/src/routes/favicon.ico/+server.ts +8 -0
  270. package/src/routes/servers/+page.server.ts +22 -10
  271. package/src/routes/servers/+page.svelte +44 -10
  272. package/src/routes/servers/[server]/databases/+layout.ts +8 -0
  273. package/src/routes/servers/[server]/databases/+page.server.ts +14 -4
  274. package/src/routes/servers/[server]/databases/[database]/collections/+layout.ts +9 -0
  275. package/src/routes/servers/[server]/databases/[database]/collections/+page.server.ts +0 -2
  276. package/src/routes/servers/[server]/databases/[database]/collections/+page.svelte +67 -8
  277. package/src/routes/servers/[server]/databases/[database]/collections/[collection]/+layout.ts +9 -0
  278. package/src/routes/servers/[server]/databases/[database]/collections/[collection]/documents/+page.server.ts +216 -0
  279. package/src/routes/servers/[server]/databases/[database]/collections/[collection]/documents/+page.svelte +337 -0
  280. package/src/routes/servers/[server]/databases/[database]/collections/[collection]/documents/+page.ts +10 -0
  281. package/src/routes/servers/[server]/databases/[database]/collections/[collection]/documents/[document]/+layout.ts +9 -0
  282. package/src/routes/servers/[server]/databases/[database]/collections/[collection]/documents/[document]/+page.server.ts +15 -12
  283. package/src/routes/servers/[server]/databases/[database]/collections/[collection]/documents/[document]/+page.svelte +79 -5
  284. package/src/routes/servers/[server]/databases/[database]/collections/[collection]/indexes/+page.server.ts +87 -0
  285. package/src/routes/servers/[server]/databases/[database]/collections/[collection]/indexes/+page.svelte +333 -0
  286. package/src/routes/servers/[server]/databases/[database]/collections/[collection]/indexes/+page.ts +10 -0
  287. package/src/routes/servers/[server]/databases/[database]/collections/[collection]/mappings/+page.server.ts +18 -0
  288. package/src/routes/servers/[server]/databases/[database]/collections/[collection]/mappings/+page.svelte +377 -0
  289. package/src/routes/servers/[server]/databases/[database]/collections/[collection]/mappings/+page.ts +10 -0
  290. package/src/tests/api/aggregation.test.ts +125 -0
  291. package/build/client/_app/immutable/assets/0.BHsXFfsc.css +0 -1
  292. package/build/client/_app/immutable/assets/0.BHsXFfsc.css.br +0 -0
  293. package/build/client/_app/immutable/assets/0.BHsXFfsc.css.gz +0 -0
  294. package/build/client/_app/immutable/assets/6.DawdmtJd.css +0 -1
  295. package/build/client/_app/immutable/assets/6.DawdmtJd.css.br +0 -2
  296. package/build/client/_app/immutable/assets/6.DawdmtJd.css.gz +0 -0
  297. package/build/client/_app/immutable/assets/Panel.BDHMtO-3.css +0 -1
  298. package/build/client/_app/immutable/assets/Panel.BDHMtO-3.css.br +0 -0
  299. package/build/client/_app/immutable/assets/Panel.BDHMtO-3.css.gz +0 -0
  300. package/build/client/_app/immutable/assets/PrettyJson.CtngcfyW.css +0 -1
  301. package/build/client/_app/immutable/assets/PrettyJson.CtngcfyW.css.br +0 -0
  302. package/build/client/_app/immutable/assets/PrettyJson.CtngcfyW.css.gz +0 -0
  303. package/build/client/_app/immutable/chunks/BAM9w9EL.js +0 -1
  304. package/build/client/_app/immutable/chunks/BAM9w9EL.js.br +0 -0
  305. package/build/client/_app/immutable/chunks/BAM9w9EL.js.gz +0 -0
  306. package/build/client/_app/immutable/chunks/BKCvWebR.js.br +0 -0
  307. package/build/client/_app/immutable/chunks/BKCvWebR.js.gz +0 -0
  308. package/build/client/_app/immutable/chunks/BMa204Dm.js +0 -14
  309. package/build/client/_app/immutable/chunks/BMa204Dm.js.br +0 -0
  310. package/build/client/_app/immutable/chunks/BMa204Dm.js.gz +0 -0
  311. package/build/client/_app/immutable/chunks/BN_N9-2s.js +0 -1
  312. package/build/client/_app/immutable/chunks/BN_N9-2s.js.br +0 -0
  313. package/build/client/_app/immutable/chunks/BN_N9-2s.js.gz +0 -0
  314. package/build/client/_app/immutable/chunks/BY57TmdO.js +0 -1
  315. package/build/client/_app/immutable/chunks/BY57TmdO.js.br +0 -0
  316. package/build/client/_app/immutable/chunks/BY57TmdO.js.gz +0 -0
  317. package/build/client/_app/immutable/chunks/BaB-cr9N.js +0 -2
  318. package/build/client/_app/immutable/chunks/BaB-cr9N.js.br +0 -0
  319. package/build/client/_app/immutable/chunks/BaB-cr9N.js.gz +0 -0
  320. package/build/client/_app/immutable/chunks/BdR-m9Ad.js +0 -1
  321. package/build/client/_app/immutable/chunks/BdR-m9Ad.js.br +0 -0
  322. package/build/client/_app/immutable/chunks/BdR-m9Ad.js.gz +0 -0
  323. package/build/client/_app/immutable/chunks/ByjLCPv2.js +0 -1
  324. package/build/client/_app/immutable/chunks/ByjLCPv2.js.br +0 -0
  325. package/build/client/_app/immutable/chunks/ByjLCPv2.js.gz +0 -0
  326. package/build/client/_app/immutable/chunks/BzAcxkRZ.js +0 -4
  327. package/build/client/_app/immutable/chunks/BzAcxkRZ.js.br +0 -0
  328. package/build/client/_app/immutable/chunks/BzAcxkRZ.js.gz +0 -0
  329. package/build/client/_app/immutable/chunks/CyQLXPZI.js +0 -2
  330. package/build/client/_app/immutable/chunks/CyQLXPZI.js.br +0 -0
  331. package/build/client/_app/immutable/chunks/CyQLXPZI.js.gz +0 -0
  332. package/build/client/_app/immutable/chunks/D17Lj1H7.js +0 -1
  333. package/build/client/_app/immutable/chunks/D17Lj1H7.js.br +0 -0
  334. package/build/client/_app/immutable/chunks/D17Lj1H7.js.gz +0 -0
  335. package/build/client/_app/immutable/chunks/D4VhtiDg.js +0 -1
  336. package/build/client/_app/immutable/chunks/D4VhtiDg.js.br +0 -0
  337. package/build/client/_app/immutable/chunks/D4VhtiDg.js.gz +0 -0
  338. package/build/client/_app/immutable/chunks/D72Du7TF.js +0 -1
  339. package/build/client/_app/immutable/chunks/D72Du7TF.js.br +0 -2
  340. package/build/client/_app/immutable/chunks/D72Du7TF.js.gz +0 -0
  341. package/build/client/_app/immutable/chunks/XYFbSe2V.js +0 -1
  342. package/build/client/_app/immutable/chunks/XYFbSe2V.js.br +0 -0
  343. package/build/client/_app/immutable/chunks/XYFbSe2V.js.gz +0 -0
  344. package/build/client/_app/immutable/chunks/iHsChU5o.js +0 -1
  345. package/build/client/_app/immutable/chunks/iHsChU5o.js.br +0 -0
  346. package/build/client/_app/immutable/chunks/iHsChU5o.js.gz +0 -0
  347. package/build/client/_app/immutable/chunks/p23QjN60.js +0 -1
  348. package/build/client/_app/immutable/chunks/p23QjN60.js.br +0 -2
  349. package/build/client/_app/immutable/chunks/p23QjN60.js.gz +0 -0
  350. package/build/client/_app/immutable/chunks/sBKW2MYH.js +0 -1
  351. package/build/client/_app/immutable/chunks/sBKW2MYH.js.br +0 -0
  352. package/build/client/_app/immutable/chunks/sBKW2MYH.js.gz +0 -0
  353. package/build/client/_app/immutable/chunks/uMNMODvc.js.br +0 -0
  354. package/build/client/_app/immutable/chunks/uMNMODvc.js.gz +0 -0
  355. package/build/client/_app/immutable/entry/app.9nC_873E.js +0 -2
  356. package/build/client/_app/immutable/entry/app.9nC_873E.js.br +0 -0
  357. package/build/client/_app/immutable/entry/app.9nC_873E.js.gz +0 -0
  358. package/build/client/_app/immutable/entry/start.Bn88Alw2.js +0 -1
  359. package/build/client/_app/immutable/entry/start.Bn88Alw2.js.br +0 -2
  360. package/build/client/_app/immutable/entry/start.Bn88Alw2.js.gz +0 -0
  361. package/build/client/_app/immutable/nodes/0.COxTCtn2.js +0 -1
  362. package/build/client/_app/immutable/nodes/0.COxTCtn2.js.br +0 -0
  363. package/build/client/_app/immutable/nodes/0.COxTCtn2.js.gz +0 -0
  364. package/build/client/_app/immutable/nodes/1.Bc8yPK_D.js +0 -1
  365. package/build/client/_app/immutable/nodes/1.Bc8yPK_D.js.br +0 -0
  366. package/build/client/_app/immutable/nodes/1.Bc8yPK_D.js.gz +0 -0
  367. package/build/client/_app/immutable/nodes/3.CI2GcqTf.js +0 -1
  368. package/build/client/_app/immutable/nodes/3.CI2GcqTf.js.br +0 -0
  369. package/build/client/_app/immutable/nodes/3.CI2GcqTf.js.gz +0 -0
  370. package/build/client/_app/immutable/nodes/4.ChSdW7ac.js +0 -1
  371. package/build/client/_app/immutable/nodes/4.ChSdW7ac.js.br +0 -0
  372. package/build/client/_app/immutable/nodes/4.ChSdW7ac.js.gz +0 -0
  373. package/build/client/_app/immutable/nodes/5.DaMML2go.js +0 -1
  374. package/build/client/_app/immutable/nodes/5.DaMML2go.js.br +0 -0
  375. package/build/client/_app/immutable/nodes/5.DaMML2go.js.gz +0 -0
  376. package/build/client/_app/immutable/nodes/6.Dcq0qwvO.js +0 -1
  377. package/build/client/_app/immutable/nodes/6.Dcq0qwvO.js.br +0 -0
  378. package/build/client/_app/immutable/nodes/6.Dcq0qwvO.js.gz +0 -0
  379. package/build/client/_app/immutable/nodes/7.CU-ncPes.js +0 -1
  380. package/build/client/_app/immutable/nodes/7.CU-ncPes.js.br +0 -0
  381. package/build/client/_app/immutable/nodes/7.CU-ncPes.js.gz +0 -0
  382. package/build/server/chunks/0-C1NyHW8A.js.map +0 -1
  383. package/build/server/chunks/1-CThf4W5r.js +0 -9
  384. package/build/server/chunks/1-CThf4W5r.js.map +0 -1
  385. package/build/server/chunks/3-CJf0NbiV.js +0 -69
  386. package/build/server/chunks/3-CJf0NbiV.js.map +0 -1
  387. package/build/server/chunks/4-Dfbpsagm.js.map +0 -1
  388. package/build/server/chunks/5-DLB6GOjf.js.map +0 -1
  389. package/build/server/chunks/6-DfCARDKO.js +0 -202
  390. package/build/server/chunks/6-DfCARDKO.js.map +0 -1
  391. package/build/server/chunks/7-B5o4OymX.js +0 -42
  392. package/build/server/chunks/7-B5o4OymX.js.map +0 -1
  393. package/build/server/chunks/Panel-Box8ld78.js.map +0 -1
  394. package/build/server/chunks/PrettyJson-C2c9xGNo.js +0 -290
  395. package/build/server/chunks/PrettyJson-C2c9xGNo.js.map +0 -1
  396. package/build/server/chunks/TooltipTable-0z4HkHlH.js +0 -17
  397. package/build/server/chunks/TooltipTable-0z4HkHlH.js.map +0 -1
  398. package/build/server/chunks/_layout.svelte-CU7AVRSZ.js +0 -111
  399. package/build/server/chunks/_layout.svelte-CU7AVRSZ.js.map +0 -1
  400. package/build/server/chunks/_page.svelte-B_T8EFk3.js.map +0 -1
  401. package/build/server/chunks/_page.svelte-CflJkclc.js.map +0 -1
  402. package/build/server/chunks/_page.svelte-D1QIZqLv.js.map +0 -1
  403. package/build/server/chunks/_page.svelte-PuIVQ52p.js.map +0 -1
  404. package/build/server/chunks/_page.svelte-zlHeUnJK.js.map +0 -1
  405. package/build/server/chunks/async-BfR0vYHo.js.map +0 -1
  406. package/build/server/chunks/client-bj7sePQc.js +0 -7
  407. package/build/server/chunks/error.svelte-D5sIJv3P.js +0 -18
  408. package/build/server/chunks/error.svelte-D5sIJv3P.js.map +0 -1
  409. package/build/server/chunks/index3-DquTjlmp.js.map +0 -1
  410. package/build/server/chunks/mongo-dLmCShL_.js.map +0 -1
  411. package/build/server/chunks/remote-xxtqbu-BFzaWXy0.js +0 -234
  412. package/build/server/chunks/remote-xxtqbu-BFzaWXy0.js.map +0 -1
  413. package/build/server/chunks/routing-Ddj5b-2K.js.map +0 -1
  414. package/src/routes/servers/[server]/databases/[database]/collections/[collection]/+page.server.ts +0 -106
  415. package/src/routes/servers/[server]/databases/[database]/collections/[collection]/+page.svelte +0 -174
  416. /package/build/client/_app/immutable/assets/{3.CRKE8WvY.css → 7.CRKE8WvY.css} +0 -0
  417. /package/build/client/_app/immutable/assets/{3.CRKE8WvY.css.br → 7.CRKE8WvY.css.br} +0 -0
  418. /package/build/client/_app/immutable/assets/{3.CRKE8WvY.css.gz → 7.CRKE8WvY.css.gz} +0 -0
@@ -0,0 +1,337 @@
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 { SvelteURLSearchParams } from "svelte/reactivity";
18
+ import type { PageData } from "./$types";
19
+
20
+ let { data }: { data: PageData } = $props();
21
+
22
+ /* eslint-disable-next-line svelte/prefer-writable-derived */
23
+ let params = $state<SearchParams>({ ...data.params });
24
+ let dataPromise = $derived(data.results);
25
+ let editMode = $state(false);
26
+ let updateQuery = $state("{}");
27
+ let isUpdating = $state(false);
28
+
29
+ let finalCount = $state<number | null>(null);
30
+ let countCount = 0;
31
+
32
+ $effect(() => {
33
+ params = { ...data.params };
34
+ });
35
+
36
+ $effect(() => {
37
+ const currentCount = ++countCount;
38
+ finalCount = null;
39
+ data.count.then((result) => {
40
+ if (currentCount !== countCount) {
41
+ return;
42
+ }
43
+ finalCount = result.error ? null : result.data;
44
+ });
45
+ });
46
+
47
+ // Handle errors from streamed promises
48
+ $effect(() => {
49
+ // @ts-expect-error I just want to trigger the dependency
50
+ if (dataPromise) {
51
+ modifiedItems = null;
52
+ }
53
+ dataPromise.then((result) => {
54
+ if (result.error) {
55
+ notificationStore.notifyError(result.error);
56
+ }
57
+ });
58
+ });
59
+
60
+ $effect(() => {
61
+ data.count.then((result) => {
62
+ // Don't show notification for timeout errors - they're displayed in the UI
63
+ if (result.error && !result.error.includes("operation exceeded time limit")) {
64
+ notificationStore.notifyError(result.error);
65
+ }
66
+ });
67
+ });
68
+
69
+ let modifiedItems = $state<MongoDocument[] | null>(null);
70
+ let items = $derived(modifiedItems ? { data: modifiedItems, error: null } : dataPromise);
71
+
72
+ async function editDocument(_id: { $value?: string } | undefined, json: MongoDocument, items: MongoDocument[]) {
73
+ const partial = Boolean(
74
+ params.project && params.project !== "{}" && Object.keys(JSON.parse(params.project)).length > 0,
75
+ );
76
+ const newId = json?._id?.$value;
77
+ const oldId = _id?.$value;
78
+
79
+ if (newId !== oldId) {
80
+ notificationStore.notifyError("ObjectId changed. This is not supported, update canceled.");
81
+ return;
82
+ }
83
+
84
+ if (!oldId) return;
85
+
86
+ try {
87
+ const result = await updateDocumentCommand({
88
+ server: data.server,
89
+ database: data.database,
90
+ collection: data.collection,
91
+ document: oldId,
92
+ value: json,
93
+ partial,
94
+ });
95
+
96
+ if (result.ok) {
97
+ notificationStore.notifySuccess("Document updated successfully");
98
+ // Update the document in the list
99
+ const index = items.findIndex((item) => item._id?.$value === oldId);
100
+ if (index !== -1) {
101
+ items[index] = result.update;
102
+ }
103
+ modifiedItems = items;
104
+ }
105
+ } catch (error) {
106
+ console.log(error);
107
+ notificationStore.notifyError(error, "Failed to update document");
108
+ }
109
+ }
110
+
111
+ async function removeDocument(_id: { $value?: string } | undefined, items: MongoDocument[]) {
112
+ const documentId = _id?.$value;
113
+ if (!documentId) return;
114
+
115
+ try {
116
+ await deleteDocumentCommand({
117
+ server: data.server,
118
+ database: data.database,
119
+ collection: data.collection,
120
+ document: documentId,
121
+ });
122
+
123
+ notificationStore.notifySuccess("Document removed successfully");
124
+ modifiedItems = items.filter((item) => item._id?.$value !== documentId);
125
+ } catch (error) {
126
+ notificationStore.notifyError(error, "Failed to remove document");
127
+ }
128
+ }
129
+
130
+ function buildUrl(skip: number) {
131
+ const queryParams = new SvelteURLSearchParams();
132
+ queryParams.set("query", params.query || "{}");
133
+ queryParams.set("sort", params.sort || "");
134
+ queryParams.set("project", params.project || "");
135
+ queryParams.set("skip", String(skip));
136
+ queryParams.set("limit", String(params.limit));
137
+
138
+ return `/servers/${encodeURIComponent(data.server)}/databases/${encodeURIComponent(data.database)}/collections/${encodeURIComponent(data.collection)}/documents?${queryParams.toString()}`;
139
+ }
140
+
141
+ const nextUrl = $derived(buildUrl(params.skip + params.limit));
142
+ const previousUrl = $derived(buildUrl(Math.max(0, params.skip - params.limit)));
143
+
144
+ function navigateNext(e: MouseEvent) {
145
+ e.preventDefault();
146
+ data.params.skip += data.params.limit;
147
+ params.skip = data.params.skip;
148
+ /* eslint-disable-next-line svelte/no-navigation-without-resolve */
149
+ pushState(nextUrl, {});
150
+ dataPromise = loadDocuments({
151
+ server: data.server,
152
+ database: data.database,
153
+ collection: data.collection,
154
+ query: params.query,
155
+ sort: params.sort,
156
+ project: params.project,
157
+ skip: params.skip,
158
+ limit: params.limit,
159
+ });
160
+ }
161
+
162
+ function navigatePrevious(e: MouseEvent) {
163
+ e.preventDefault();
164
+ data.params.skip = Math.max(0, data.params.skip - data.params.limit);
165
+ params.skip = data.params.skip;
166
+ /* eslint-disable-next-line svelte/no-navigation-without-resolve */
167
+ pushState(previousUrl, {});
168
+ dataPromise = loadDocuments({
169
+ server: data.server,
170
+ database: data.database,
171
+ collection: data.collection,
172
+ query: params.query,
173
+ sort: params.sort,
174
+ project: params.project,
175
+ skip: params.skip,
176
+ limit: params.limit,
177
+ });
178
+ }
179
+
180
+ async function executeUpdateMany() {
181
+ isUpdating = true;
182
+ try {
183
+ const result = await updateManyCommand({
184
+ server: data.server,
185
+ database: data.database,
186
+ collection: data.collection,
187
+ filter: params.query || "{}",
188
+ update: updateQuery,
189
+ });
190
+
191
+ if (result.ok) {
192
+ notificationStore.notifySuccess(`Updated ${result.modifiedCount} document(s) (matched ${result.matchedCount})`);
193
+ // Reset the modified items to force a refresh
194
+ modifiedItems = null;
195
+ editMode = false;
196
+ }
197
+ } catch (error) {
198
+ console.error(error);
199
+ notificationStore.notifyError(error, "Failed to update documents");
200
+ } finally {
201
+ isUpdating = false;
202
+ }
203
+ }
204
+ </script>
205
+
206
+ <SearchBox bind:params bind:editMode readonly={data.readOnly} />
207
+
208
+ {#if editMode}
209
+ <Panel title="Update Multiple Documents">
210
+ <div class="p-4 space-y-4">
211
+ <div>
212
+ <label for="update-filter" class="block text-sm font-medium mb-2">Filter (which documents to update):</label>
213
+ <input
214
+ type="text"
215
+ id="update-filter"
216
+ value={params.query || "{}"}
217
+ readonly
218
+ class="w-full p-2 border border-[var(--color-4)] bg-[var(--light-background)] rounded font-mono text-sm opacity-75 cursor-not-allowed"
219
+ />
220
+ <p class="text-xs text-[var(--text-secondary,#888)] mt-1">
221
+ This filter is taken from the query above. Modify the query to change which documents will be updated.
222
+ </p>
223
+ </div>
224
+ <div>
225
+ <label for="update-operation" class="block text-sm font-medium mb-2"
226
+ >Update Operation (e.g., $set, $inc, $unset):</label
227
+ >
228
+ <textarea
229
+ bind:value={updateQuery}
230
+ placeholder="Update operation"
231
+ rows="4"
232
+ use:jsonTextarea={{ onsubmit: executeUpdateMany }}
233
+ class="w-full p-2 border border-[var(--color-4)] bg-[var(--color-3)] rounded font-mono text-sm"
234
+ ></textarea>
235
+ </div>
236
+ <div class="flex gap-2">
237
+ <button class="btn btn-success" disabled={isUpdating} onclick={executeUpdateMany}>
238
+ {isUpdating ? "Updating..." : "Execute Update"}
239
+ </button>
240
+ <button class="btn btn-default" onclick={() => (editMode = false)}>Cancel</button>
241
+ </div>
242
+ <div class="text-sm text-[var(--text-secondary,#888)]">
243
+ <p class="mb-1"><strong>Examples:</strong></p>
244
+ <p class="mb-1">
245
+ • Set a field: <code class="bg-[var(--color-3)] px-1 rounded">{'{"$set": {"status": "active"}}'}</code>
246
+ </p>
247
+ <p class="mb-1">
248
+ • Increment a value: <code class="bg-[var(--color-3)] px-1 rounded">{'{"$inc": {"count": 1}}'}</code>
249
+ </p>
250
+ <p>• Unset a field: <code class="bg-[var(--color-3)] px-1 rounded">{'{"$unset": {"oldField": ""}}'}</code></p>
251
+ </div>
252
+ </div>
253
+ </Panel>
254
+ {/if}
255
+
256
+ {#await items}
257
+ <Panel
258
+ title={finalCount !== null
259
+ ? `${formatNumber(data.params.skip + 1)} - ${formatNumber(data.params.skip + data.params.limit)} of ${formatNumber(finalCount)} documents...`
260
+ : "Loading documents..."}
261
+ >
262
+ {#snippet actions()}
263
+ {#if finalCount !== null}
264
+ {#if data.params.skip > 0}
265
+ <!-- eslint-disable-next-line @typescript-eslint/no-explicit-any -->
266
+ <a href={resolve(previousUrl as any)} onclick={navigatePrevious} class="btn btn-default btn-sm -my-2">
267
+ Previous
268
+ </a>
269
+ {/if}
270
+ {#if data.params.skip + data.params.limit < finalCount}
271
+ <!-- eslint-disable-next-line @typescript-eslint/no-explicit-any -->
272
+ <a href={resolve(nextUrl as any)} onclick={navigateNext} class="btn btn-default btn-sm -my-2">Next</a>
273
+ {/if}
274
+ {/if}
275
+ {/snippet}
276
+ </Panel>
277
+ {:then resultsData}
278
+ {@const items = resultsData.data}
279
+ {#await data.count}
280
+ <Panel
281
+ title={items.length > 0
282
+ ? `${formatNumber(data.params.skip + 1)} - ${formatNumber(data.params.skip + items.length)} Documents (counting...)`
283
+ : "No documents"}
284
+ >
285
+ {#snippet actions()}
286
+ {#if data.params.skip > 0}
287
+ <!-- eslint-disable-next-line @typescript-eslint/no-explicit-any -->
288
+ <a href={resolve(previousUrl as any)} onclick={navigatePrevious} class="btn btn-default btn-sm -my-2">
289
+ Previous
290
+ </a>
291
+ {/if}
292
+ {#if items.length >= data.params.limit}
293
+ <!-- eslint-disable-next-line @typescript-eslint/no-explicit-any -->
294
+ <a href={resolve(nextUrl as any)} onclick={navigateNext} class="btn btn-default btn-sm -my-2">Next</a>
295
+ {/if}
296
+ {/snippet}
297
+ </Panel>
298
+ {:then countData}
299
+ {@const count = countData.data}
300
+ {@const hasNext = countData.error ? items.length >= data.params.limit : data.params.skip + items.length < count}
301
+ {@const hasPrevious = data.params.skip > 0}
302
+ {@const isTimeout = countData.error?.includes("operation exceeded time limit")}
303
+ <Panel
304
+ title={items.length > 0
305
+ ? count > 0
306
+ ? `${formatNumber(data.params.skip + 1)} - ${formatNumber(data.params.skip + items.length)} of ${formatNumber(count)} Documents`
307
+ : `${formatNumber(data.params.skip + 1)} - ${formatNumber(data.params.skip + items.length)} Documents (count ${isTimeout ? "timeout" : "unavailable"})`
308
+ : "No documents"}
309
+ >
310
+ {#snippet actions()}
311
+ {#if hasPrevious}
312
+ <!-- eslint-disable-next-line @typescript-eslint/no-explicit-any -->
313
+ <a href={resolve(previousUrl as any)} onclick={navigatePrevious} class="btn btn-default btn-sm -my-2">
314
+ Previous
315
+ </a>
316
+ {/if}
317
+ {#if hasNext}
318
+ <!-- eslint-disable-next-line @typescript-eslint/no-explicit-any -->
319
+ <a href={resolve(nextUrl as any)} onclick={navigateNext} class="btn btn-default btn-sm -my-2">Next</a>
320
+ {/if}
321
+ {/snippet}
322
+ </Panel>
323
+ {/await}
324
+
325
+ {#each items as item, index (item._id?.$value || index)}
326
+ <PrettyJson
327
+ json={item}
328
+ autoCollapse={true}
329
+ onedit={data.isAggregation || data.readOnly ? undefined : (json) => editDocument(item._id, json, items)}
330
+ onremove={data.isAggregation || data.readOnly ? undefined : () => removeDocument(item._id, items)}
331
+ server={data.server}
332
+ database={data.database}
333
+ collection={data.collection}
334
+ mappings={data.mappings}
335
+ />
336
+ {/each}
337
+ {/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
110
  onedit={editDocument}
83
111
  onremove={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,87 @@
1
+ import JsonEncoder from "$lib/server/JsonEncoder";
2
+ import { getMongo } from "$lib/server/mongo";
3
+ import type { IndexDescription } from "mongodb";
4
+ import type { PageServerLoad } from "./$types";
5
+
6
+ export const load: PageServerLoad = async ({ params, depends }) => {
7
+ depends("app:indexes");
8
+
9
+ const mongo = await getMongo();
10
+ const client = mongo.getClient(params.server);
11
+ const collection = client.db(params.database).collection(params.collection);
12
+
13
+ const indexesPromise = (async () => {
14
+ try {
15
+ // Get index definitions
16
+ const indexList = (await collection.listIndexes().toArray()) as IndexDescription[];
17
+
18
+ // Get index usage statistics
19
+ let indexStats: Record<string, { ops: number; since: Date }> = {};
20
+ try {
21
+ const statsResult = await collection.aggregate([{ $indexStats: {} }]).toArray();
22
+
23
+ indexStats = statsResult.reduce(
24
+ (acc, stat) => {
25
+ acc[stat.name] = {
26
+ ops: stat.accesses?.ops || 0,
27
+ since: stat.accesses?.since || new Date(),
28
+ };
29
+ return acc;
30
+ },
31
+ {} as Record<string, { ops: number; since: Date }>,
32
+ );
33
+ } catch (err) {
34
+ console.error("Error fetching index stats:", err);
35
+ // Continue without stats if unavailable
36
+ }
37
+
38
+ // Get index sizes from collection stats
39
+ let indexSizes: Record<string, number> = {};
40
+ try {
41
+ const collStatsResult = (await collection
42
+ .aggregate([
43
+ {
44
+ $collStats: {
45
+ storageStats: {},
46
+ },
47
+ },
48
+ ])
49
+ .next()) as {
50
+ storageStats?: {
51
+ indexSizes?: Record<string, number>;
52
+ };
53
+ } | null;
54
+
55
+ if (collStatsResult?.storageStats?.indexSizes) {
56
+ indexSizes = collStatsResult.storageStats.indexSizes;
57
+ }
58
+ } catch (err) {
59
+ console.error("Error fetching index sizes:", err);
60
+ // Continue without sizes if unavailable
61
+ }
62
+
63
+ // Merge index definitions with stats and sizes
64
+ const indexesWithStats = indexList.map((index) => ({
65
+ ...index,
66
+ stats: index.name ? indexStats[index.name] || null : null,
67
+ size: index.name ? indexSizes[index.name] || 0 : 0,
68
+ }));
69
+
70
+ // Encode to handle MongoDB types like ObjectId, etc.
71
+ return {
72
+ data: indexesWithStats.map((index) => JsonEncoder.encode(index)),
73
+ error: null as string | null,
74
+ };
75
+ } catch (err) {
76
+ console.error("Error fetching indexes:", err);
77
+ return {
78
+ data: [],
79
+ error: `Failed to fetch indexes: ${err instanceof Error ? err.message : String(err)}`,
80
+ };
81
+ }
82
+ })();
83
+
84
+ return {
85
+ indexes: indexesPromise,
86
+ };
87
+ };