@selvajs/selva 3.0.0 → 4.0.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 (1199) hide show
  1. package/build/client/_app/immutable/assets/0.D882LCPK.css +1 -0
  2. package/build/client/_app/immutable/assets/0.D882LCPK.css.br +0 -0
  3. package/build/client/_app/immutable/assets/0.D882LCPK.css.gz +0 -0
  4. package/build/client/_app/immutable/assets/20.DvtWUFNX.css +1 -0
  5. package/build/client/_app/immutable/assets/20.DvtWUFNX.css.br +0 -0
  6. package/build/client/_app/immutable/assets/20.DvtWUFNX.css.gz +0 -0
  7. package/build/client/_app/immutable/chunks/-UMoMsui.js +1 -0
  8. package/build/client/_app/immutable/chunks/-UMoMsui.js.br +0 -0
  9. package/build/client/_app/immutable/chunks/-UMoMsui.js.gz +0 -0
  10. package/build/client/_app/immutable/chunks/7DlWX6a_.js +2 -0
  11. package/build/client/_app/immutable/chunks/7DlWX6a_.js.br +0 -0
  12. package/build/client/_app/immutable/chunks/7DlWX6a_.js.gz +0 -0
  13. package/build/client/_app/immutable/chunks/7OGPJeUM.js +1 -0
  14. package/build/client/_app/immutable/chunks/7OGPJeUM.js.br +0 -0
  15. package/build/client/_app/immutable/chunks/7OGPJeUM.js.gz +0 -0
  16. package/build/client/_app/immutable/chunks/B-Kuf-9K.js +1 -0
  17. package/build/client/_app/immutable/chunks/B-Kuf-9K.js.br +0 -0
  18. package/build/client/_app/immutable/chunks/B-Kuf-9K.js.gz +0 -0
  19. package/build/client/_app/immutable/chunks/B1z9if9B.js +1 -0
  20. package/build/client/_app/immutable/chunks/B1z9if9B.js.br +0 -0
  21. package/build/client/_app/immutable/chunks/B1z9if9B.js.gz +0 -0
  22. package/build/client/_app/immutable/chunks/B21bldal.js +1 -0
  23. package/build/client/_app/immutable/chunks/B21bldal.js.br +0 -0
  24. package/build/client/_app/immutable/chunks/B21bldal.js.gz +0 -0
  25. package/build/client/_app/immutable/chunks/B6_AR4oL.js +1 -0
  26. package/build/client/_app/immutable/chunks/B6_AR4oL.js.br +0 -0
  27. package/build/client/_app/immutable/chunks/B6_AR4oL.js.gz +0 -0
  28. package/build/client/_app/immutable/chunks/B6yEy6Wb.js +9 -0
  29. package/build/client/_app/immutable/chunks/B6yEy6Wb.js.br +0 -0
  30. package/build/client/_app/immutable/chunks/B6yEy6Wb.js.gz +0 -0
  31. package/build/client/_app/immutable/chunks/BEFa4rcT.js +1 -0
  32. package/build/client/_app/immutable/chunks/BEFa4rcT.js.br +4 -0
  33. package/build/client/_app/immutable/chunks/BEFa4rcT.js.gz +0 -0
  34. package/build/client/_app/immutable/chunks/BGIAOk5X.js +1 -0
  35. package/build/client/_app/immutable/chunks/BGIAOk5X.js.br +0 -0
  36. package/build/client/_app/immutable/chunks/BGIAOk5X.js.gz +0 -0
  37. package/build/client/_app/immutable/chunks/BHhjUaik.js +1 -0
  38. package/build/client/_app/immutable/chunks/BHhjUaik.js.br +0 -0
  39. package/build/client/_app/immutable/chunks/BHhjUaik.js.gz +0 -0
  40. package/build/client/_app/immutable/chunks/BIIXkPqf.js +1 -0
  41. package/build/client/_app/immutable/chunks/BIIXkPqf.js.br +0 -0
  42. package/build/client/_app/immutable/chunks/BIIXkPqf.js.gz +0 -0
  43. package/build/client/_app/immutable/chunks/BLZ195WY.js +1 -0
  44. package/build/client/_app/immutable/chunks/BLZ195WY.js.br +0 -0
  45. package/build/client/_app/immutable/chunks/BLZ195WY.js.gz +0 -0
  46. package/build/client/_app/immutable/chunks/BM8Ok6pJ.js +1 -0
  47. package/build/client/_app/immutable/chunks/BM8Ok6pJ.js.br +0 -0
  48. package/build/client/_app/immutable/chunks/BM8Ok6pJ.js.gz +0 -0
  49. package/build/client/_app/immutable/chunks/BOsr6E_d.js +1 -0
  50. package/build/client/_app/immutable/chunks/BOsr6E_d.js.br +1 -0
  51. package/build/client/_app/immutable/chunks/BOsr6E_d.js.gz +0 -0
  52. package/build/client/_app/immutable/chunks/BX0gN9mF.js +1 -0
  53. package/build/client/_app/immutable/chunks/BX0gN9mF.js.br +0 -0
  54. package/build/client/_app/immutable/chunks/BX0gN9mF.js.gz +0 -0
  55. package/build/client/_app/immutable/chunks/BaMCSMGs.js +1 -0
  56. package/build/client/_app/immutable/chunks/BaMCSMGs.js.br +0 -0
  57. package/build/client/_app/immutable/chunks/BaMCSMGs.js.gz +0 -0
  58. package/build/client/_app/immutable/chunks/BeM-GIFh.js +1 -0
  59. package/build/client/_app/immutable/chunks/BeM-GIFh.js.br +0 -0
  60. package/build/client/_app/immutable/chunks/BeM-GIFh.js.gz +0 -0
  61. package/build/client/_app/immutable/chunks/BihI7LuH.js +1 -0
  62. package/build/client/_app/immutable/chunks/BihI7LuH.js.br +0 -0
  63. package/build/client/_app/immutable/chunks/BihI7LuH.js.gz +0 -0
  64. package/build/client/_app/immutable/chunks/Bma65zV8.js +1 -0
  65. package/build/client/_app/immutable/chunks/Bma65zV8.js.br +0 -0
  66. package/build/client/_app/immutable/chunks/Bma65zV8.js.gz +0 -0
  67. package/build/client/_app/immutable/chunks/BnzoF81W.js +1 -0
  68. package/build/client/_app/immutable/chunks/BnzoF81W.js.br +1 -0
  69. package/build/client/_app/immutable/chunks/BnzoF81W.js.gz +0 -0
  70. package/build/client/_app/immutable/chunks/BpQqe39G.js +1 -0
  71. package/build/client/_app/immutable/chunks/BpQqe39G.js.br +0 -0
  72. package/build/client/_app/immutable/chunks/BpQqe39G.js.gz +0 -0
  73. package/build/client/_app/immutable/chunks/BsKtJj5h.js +1 -0
  74. package/build/client/_app/immutable/chunks/BsKtJj5h.js.br +0 -0
  75. package/build/client/_app/immutable/chunks/BsKtJj5h.js.gz +0 -0
  76. package/build/client/_app/immutable/chunks/BtugGMaj.js +1 -0
  77. package/build/client/_app/immutable/chunks/BtugGMaj.js.br +0 -0
  78. package/build/client/_app/immutable/chunks/BtugGMaj.js.gz +0 -0
  79. package/build/client/_app/immutable/chunks/Bwn5lHBl.js +1 -0
  80. package/build/client/_app/immutable/chunks/Bwn5lHBl.js.br +0 -0
  81. package/build/client/_app/immutable/chunks/Bwn5lHBl.js.gz +0 -0
  82. package/build/client/_app/immutable/chunks/C3WxOOC9.js +1 -0
  83. package/build/client/_app/immutable/chunks/C3WxOOC9.js.br +0 -0
  84. package/build/client/_app/immutable/chunks/C3WxOOC9.js.gz +0 -0
  85. package/build/client/_app/immutable/chunks/CDmA5ezP.js +1 -0
  86. package/build/client/_app/immutable/chunks/CDmA5ezP.js.br +0 -0
  87. package/build/client/_app/immutable/chunks/CDmA5ezP.js.gz +0 -0
  88. package/build/client/_app/immutable/chunks/CE_gxD9G.js +1 -0
  89. package/build/client/_app/immutable/chunks/CE_gxD9G.js.br +0 -0
  90. package/build/client/_app/immutable/chunks/CE_gxD9G.js.gz +0 -0
  91. package/build/client/_app/immutable/chunks/CGKZc1Kf.js +1 -0
  92. package/build/client/_app/immutable/chunks/CGKZc1Kf.js.br +0 -0
  93. package/build/client/_app/immutable/chunks/CGKZc1Kf.js.gz +0 -0
  94. package/build/client/_app/immutable/chunks/CIHhLSqA.js +1 -0
  95. package/build/client/_app/immutable/chunks/CIHhLSqA.js.br +0 -0
  96. package/build/client/_app/immutable/chunks/CIHhLSqA.js.gz +0 -0
  97. package/build/client/_app/immutable/chunks/CNC_mCsM.js +1 -0
  98. package/build/client/_app/immutable/chunks/CNC_mCsM.js.br +0 -0
  99. package/build/client/_app/immutable/chunks/CNC_mCsM.js.gz +0 -0
  100. package/build/client/_app/immutable/chunks/C_pyGEAV.js +1 -0
  101. package/build/client/_app/immutable/chunks/C_pyGEAV.js.br +0 -0
  102. package/build/client/_app/immutable/chunks/C_pyGEAV.js.gz +0 -0
  103. package/build/client/_app/immutable/chunks/Cal8_SqL.js +1 -0
  104. package/build/client/_app/immutable/chunks/Cal8_SqL.js.br +0 -0
  105. package/build/client/_app/immutable/chunks/Cal8_SqL.js.gz +0 -0
  106. package/build/client/_app/immutable/chunks/CeS0GhtF.js +1 -0
  107. package/build/client/_app/immutable/chunks/CeS0GhtF.js.br +0 -0
  108. package/build/client/_app/immutable/chunks/CeS0GhtF.js.gz +0 -0
  109. package/build/client/_app/immutable/chunks/CnXIg_dO.js +1 -0
  110. package/build/client/_app/immutable/chunks/CnXIg_dO.js.br +0 -0
  111. package/build/client/_app/immutable/chunks/CnXIg_dO.js.gz +0 -0
  112. package/build/client/_app/immutable/chunks/CumXBEVX.js +1 -0
  113. package/build/client/_app/immutable/chunks/CumXBEVX.js.br +0 -0
  114. package/build/client/_app/immutable/chunks/CumXBEVX.js.gz +0 -0
  115. package/build/client/_app/immutable/chunks/CynIvqMH.js +1 -0
  116. package/build/client/_app/immutable/chunks/CynIvqMH.js.br +0 -0
  117. package/build/client/_app/immutable/chunks/CynIvqMH.js.gz +0 -0
  118. package/build/client/_app/immutable/chunks/D0kO1GS0.js +3 -0
  119. package/build/client/_app/immutable/chunks/D0kO1GS0.js.br +0 -0
  120. package/build/client/_app/immutable/chunks/D0kO1GS0.js.gz +0 -0
  121. package/build/client/_app/immutable/chunks/D1xkoVpc.js +1 -0
  122. package/build/client/_app/immutable/chunks/D1xkoVpc.js.br +3 -0
  123. package/build/client/_app/immutable/chunks/D1xkoVpc.js.gz +0 -0
  124. package/build/client/_app/immutable/chunks/DGr_EUx4.js +1 -0
  125. package/build/client/_app/immutable/chunks/DGr_EUx4.js.br +0 -0
  126. package/build/client/_app/immutable/chunks/DGr_EUx4.js.gz +0 -0
  127. package/build/client/_app/immutable/chunks/DRpLcVdK.js +1 -0
  128. package/build/client/_app/immutable/chunks/DRpLcVdK.js.br +0 -0
  129. package/build/client/_app/immutable/chunks/DRpLcVdK.js.gz +0 -0
  130. package/build/client/_app/immutable/chunks/DT5O4b-_.js +1 -0
  131. package/build/client/_app/immutable/chunks/DT5O4b-_.js.br +0 -0
  132. package/build/client/_app/immutable/chunks/DT5O4b-_.js.gz +0 -0
  133. package/build/client/_app/immutable/chunks/DYfK6Plb.js +1 -0
  134. package/build/client/_app/immutable/chunks/DYfK6Plb.js.br +1 -0
  135. package/build/client/_app/immutable/chunks/DYfK6Plb.js.gz +0 -0
  136. package/build/client/_app/immutable/chunks/DZM0bVcB.js +1 -0
  137. package/build/client/_app/immutable/chunks/DZM0bVcB.js.br +0 -0
  138. package/build/client/_app/immutable/chunks/DZM0bVcB.js.gz +0 -0
  139. package/build/client/_app/immutable/chunks/D_gPt7DB.js +1 -0
  140. package/build/client/_app/immutable/chunks/D_gPt7DB.js.br +0 -0
  141. package/build/client/_app/immutable/chunks/D_gPt7DB.js.gz +0 -0
  142. package/build/client/_app/immutable/chunks/DdEmEaOR.js +1 -0
  143. package/build/client/_app/immutable/chunks/DdEmEaOR.js.br +0 -0
  144. package/build/client/_app/immutable/chunks/DdEmEaOR.js.gz +0 -0
  145. package/build/client/_app/immutable/chunks/De-Sjn1V.js +1 -0
  146. package/build/client/_app/immutable/chunks/De-Sjn1V.js.br +0 -0
  147. package/build/client/_app/immutable/chunks/De-Sjn1V.js.gz +0 -0
  148. package/build/client/_app/immutable/chunks/DeMiewtM.js +1 -0
  149. package/build/client/_app/immutable/chunks/DeMiewtM.js.br +0 -0
  150. package/build/client/_app/immutable/chunks/DeMiewtM.js.gz +0 -0
  151. package/build/client/_app/immutable/chunks/DfbumCTS.js +1 -0
  152. package/build/client/_app/immutable/chunks/DfbumCTS.js.br +0 -0
  153. package/build/client/_app/immutable/chunks/DfbumCTS.js.gz +0 -0
  154. package/build/client/_app/immutable/chunks/Diyh8RG-.js +1 -0
  155. package/build/client/_app/immutable/chunks/Diyh8RG-.js.br +0 -0
  156. package/build/client/_app/immutable/chunks/Diyh8RG-.js.gz +0 -0
  157. package/build/client/_app/immutable/chunks/DkVLFJC2.js +64 -0
  158. package/build/client/_app/immutable/chunks/DkVLFJC2.js.br +0 -0
  159. package/build/client/_app/immutable/chunks/DkVLFJC2.js.gz +0 -0
  160. package/build/client/_app/immutable/chunks/Dn_lJm0y.js +1 -0
  161. package/build/client/_app/immutable/chunks/Dn_lJm0y.js.br +0 -0
  162. package/build/client/_app/immutable/chunks/Dn_lJm0y.js.gz +0 -0
  163. package/build/client/_app/immutable/chunks/DqK2lhM-.js +1 -0
  164. package/build/client/_app/immutable/chunks/DqK2lhM-.js.br +0 -0
  165. package/build/client/_app/immutable/chunks/DqK2lhM-.js.gz +0 -0
  166. package/build/client/_app/immutable/chunks/Dr-qnmvi.js +1 -0
  167. package/build/client/_app/immutable/chunks/Dr-qnmvi.js.br +0 -0
  168. package/build/client/_app/immutable/chunks/Dr-qnmvi.js.gz +0 -0
  169. package/build/client/_app/immutable/chunks/DtFVCiwY.js +1 -0
  170. package/build/client/_app/immutable/chunks/DtFVCiwY.js.br +0 -0
  171. package/build/client/_app/immutable/chunks/DtFVCiwY.js.gz +0 -0
  172. package/build/client/_app/immutable/chunks/Q9Y439fs.js +1 -0
  173. package/build/client/_app/immutable/chunks/Q9Y439fs.js.br +0 -0
  174. package/build/client/_app/immutable/chunks/Q9Y439fs.js.gz +0 -0
  175. package/build/client/_app/immutable/chunks/Uv0-HWHq.js +1 -0
  176. package/build/client/_app/immutable/chunks/Uv0-HWHq.js.br +0 -0
  177. package/build/client/_app/immutable/chunks/Uv0-HWHq.js.gz +0 -0
  178. package/build/client/_app/immutable/chunks/vyYztzrZ.js +1 -0
  179. package/build/client/_app/immutable/chunks/vyYztzrZ.js.br +0 -0
  180. package/build/client/_app/immutable/chunks/vyYztzrZ.js.gz +0 -0
  181. package/build/client/_app/immutable/entry/app.DFWfpqb0.js +2 -0
  182. package/build/client/_app/immutable/entry/app.DFWfpqb0.js.br +0 -0
  183. package/build/client/_app/immutable/entry/app.DFWfpqb0.js.gz +0 -0
  184. package/build/client/_app/immutable/entry/start.-fCdkvY6.js +1 -0
  185. package/build/client/_app/immutable/entry/start.-fCdkvY6.js.br +2 -0
  186. package/build/client/_app/immutable/entry/start.-fCdkvY6.js.gz +0 -0
  187. package/build/client/_app/immutable/nodes/0.kNRjuE1r.js +9 -0
  188. package/build/client/_app/immutable/nodes/0.kNRjuE1r.js.br +0 -0
  189. package/build/client/_app/immutable/nodes/0.kNRjuE1r.js.gz +0 -0
  190. package/build/client/_app/immutable/nodes/1.NC0eJqYH.js +1 -0
  191. package/build/client/_app/immutable/nodes/1.NC0eJqYH.js.br +0 -0
  192. package/build/client/_app/immutable/nodes/1.NC0eJqYH.js.gz +0 -0
  193. package/build/client/_app/immutable/nodes/10.DpfN1qrg.js +3 -0
  194. package/build/client/_app/immutable/nodes/10.DpfN1qrg.js.br +0 -0
  195. package/build/client/_app/immutable/nodes/10.DpfN1qrg.js.gz +0 -0
  196. package/build/client/_app/immutable/nodes/11.DegwSwS4.js +2 -0
  197. package/build/client/_app/immutable/nodes/11.DegwSwS4.js.br +0 -0
  198. package/build/client/_app/immutable/nodes/11.DegwSwS4.js.gz +0 -0
  199. package/build/client/_app/immutable/nodes/12.C3AQ8jKc.js +1 -0
  200. package/build/client/_app/immutable/nodes/12.C3AQ8jKc.js.br +0 -0
  201. package/build/client/_app/immutable/nodes/12.C3AQ8jKc.js.gz +0 -0
  202. package/build/client/_app/immutable/nodes/13.DoCSNk6B.js +2 -0
  203. package/build/client/_app/immutable/nodes/13.DoCSNk6B.js.br +0 -0
  204. package/build/client/_app/immutable/nodes/13.DoCSNk6B.js.gz +0 -0
  205. package/build/client/_app/immutable/nodes/14.CGaF6W-i.js +2 -0
  206. package/build/client/_app/immutable/nodes/14.CGaF6W-i.js.br +0 -0
  207. package/build/client/_app/immutable/nodes/14.CGaF6W-i.js.gz +0 -0
  208. package/build/client/_app/immutable/nodes/15.CCL52sqQ.js +16 -0
  209. package/build/client/_app/immutable/nodes/15.CCL52sqQ.js.br +0 -0
  210. package/build/client/_app/immutable/nodes/15.CCL52sqQ.js.gz +0 -0
  211. package/build/client/_app/immutable/nodes/16.CK0W0845.js +6 -0
  212. package/build/client/_app/immutable/nodes/16.CK0W0845.js.br +0 -0
  213. package/build/client/_app/immutable/nodes/16.CK0W0845.js.gz +0 -0
  214. package/build/client/_app/immutable/nodes/17.BLCtgsLP.js +2 -0
  215. package/build/client/_app/immutable/nodes/17.BLCtgsLP.js.br +0 -0
  216. package/build/client/_app/immutable/nodes/17.BLCtgsLP.js.gz +0 -0
  217. package/build/client/_app/immutable/nodes/19.Dx5b18Qv.js +2 -0
  218. package/build/client/_app/immutable/nodes/19.Dx5b18Qv.js.br +0 -0
  219. package/build/client/_app/immutable/nodes/19.Dx5b18Qv.js.gz +0 -0
  220. package/build/client/_app/immutable/nodes/2.BxDq9fgp.js +1 -0
  221. package/build/client/_app/immutable/nodes/2.BxDq9fgp.js.br +0 -0
  222. package/build/client/_app/immutable/nodes/2.BxDq9fgp.js.gz +0 -0
  223. package/build/client/_app/immutable/nodes/20.Q9tlws_F.js +4118 -0
  224. package/build/client/_app/immutable/nodes/20.Q9tlws_F.js.br +0 -0
  225. package/build/client/_app/immutable/nodes/20.Q9tlws_F.js.gz +0 -0
  226. package/build/client/_app/immutable/nodes/21.Bbzr4DP5.js +6 -0
  227. package/build/client/_app/immutable/nodes/21.Bbzr4DP5.js.br +0 -0
  228. package/build/client/_app/immutable/nodes/21.Bbzr4DP5.js.gz +0 -0
  229. package/build/client/_app/immutable/nodes/23.fhNJrKbS.js +16 -0
  230. package/build/client/_app/immutable/nodes/23.fhNJrKbS.js.br +0 -0
  231. package/build/client/_app/immutable/nodes/23.fhNJrKbS.js.gz +0 -0
  232. package/build/client/_app/immutable/nodes/24.B-_Qylvh.js +6 -0
  233. package/build/client/_app/immutable/nodes/24.B-_Qylvh.js.br +0 -0
  234. package/build/client/_app/immutable/nodes/24.B-_Qylvh.js.gz +0 -0
  235. package/build/client/_app/immutable/nodes/25.Boy7QQiW.js +1 -0
  236. package/build/client/_app/immutable/nodes/25.Boy7QQiW.js.br +0 -0
  237. package/build/client/_app/immutable/nodes/25.Boy7QQiW.js.gz +0 -0
  238. package/build/client/_app/immutable/nodes/26.JTwwV2O8.js +3 -0
  239. package/build/client/_app/immutable/nodes/26.JTwwV2O8.js.br +0 -0
  240. package/build/client/_app/immutable/nodes/26.JTwwV2O8.js.gz +0 -0
  241. package/build/client/_app/immutable/nodes/27.CKQ1fXCy.js +4 -0
  242. package/build/client/_app/immutable/nodes/27.CKQ1fXCy.js.br +0 -0
  243. package/build/client/_app/immutable/nodes/27.CKQ1fXCy.js.gz +0 -0
  244. package/build/client/_app/immutable/nodes/28.COTXtjAd.js +4 -0
  245. package/build/client/_app/immutable/nodes/28.COTXtjAd.js.br +0 -0
  246. package/build/client/_app/immutable/nodes/28.COTXtjAd.js.gz +0 -0
  247. package/build/client/_app/immutable/nodes/29.C1uWJrpk.js +2 -0
  248. package/build/client/_app/immutable/nodes/29.C1uWJrpk.js.br +0 -0
  249. package/build/client/_app/immutable/nodes/29.C1uWJrpk.js.gz +0 -0
  250. package/build/client/_app/immutable/nodes/3.D5k6nFAD.js +1 -0
  251. package/build/client/_app/immutable/nodes/3.D5k6nFAD.js.br +0 -0
  252. package/build/client/_app/immutable/nodes/3.D5k6nFAD.js.gz +0 -0
  253. package/build/client/_app/immutable/nodes/30.iBr8WuRu.js +2 -0
  254. package/build/client/_app/immutable/nodes/30.iBr8WuRu.js.br +0 -0
  255. package/build/client/_app/immutable/nodes/30.iBr8WuRu.js.gz +0 -0
  256. package/build/client/_app/immutable/nodes/31.SiZTd523.js +2 -0
  257. package/build/client/_app/immutable/nodes/31.SiZTd523.js.br +0 -0
  258. package/build/client/_app/immutable/nodes/31.SiZTd523.js.gz +0 -0
  259. package/build/client/_app/immutable/nodes/32.9Ta_FSIA.js +3 -0
  260. package/build/client/_app/immutable/nodes/32.9Ta_FSIA.js.br +0 -0
  261. package/build/client/_app/immutable/nodes/32.9Ta_FSIA.js.gz +0 -0
  262. package/build/client/_app/immutable/nodes/5.BNy6hwdy.js +1 -0
  263. package/build/client/_app/immutable/nodes/5.BNy6hwdy.js.br +0 -0
  264. package/build/client/_app/immutable/nodes/5.BNy6hwdy.js.gz +0 -0
  265. package/build/client/_app/immutable/nodes/6.CaYtdaf2.js +1 -0
  266. package/build/client/_app/immutable/nodes/6.CaYtdaf2.js.br +0 -0
  267. package/build/client/_app/immutable/nodes/6.CaYtdaf2.js.gz +0 -0
  268. package/build/client/_app/immutable/nodes/7.C1W_YRKU.js +1 -0
  269. package/build/client/_app/immutable/nodes/7.C1W_YRKU.js.br +0 -0
  270. package/build/client/_app/immutable/nodes/7.C1W_YRKU.js.gz +0 -0
  271. package/build/client/_app/immutable/nodes/8.B9sIt6MS.js +2 -0
  272. package/build/client/_app/immutable/nodes/8.B9sIt6MS.js.br +0 -0
  273. package/build/client/_app/immutable/nodes/8.B9sIt6MS.js.gz +0 -0
  274. package/build/client/_app/immutable/nodes/9.K1-nNvYh.js +1 -0
  275. package/build/client/_app/immutable/nodes/9.K1-nNvYh.js.br +0 -0
  276. package/build/client/_app/immutable/nodes/9.K1-nNvYh.js.gz +0 -0
  277. package/build/client/_app/version.json +1 -1
  278. package/build/client/_app/version.json.br +0 -0
  279. package/build/client/_app/version.json.gz +0 -0
  280. package/build/server/chunks/0-RraSrE7U.js +55 -0
  281. package/build/server/chunks/0-RraSrE7U.js.map +1 -0
  282. package/build/server/chunks/1-C99xqG8L.js +9 -0
  283. package/build/server/chunks/1-C99xqG8L.js.map +1 -0
  284. package/build/server/chunks/10-CpPov-q6.js +221 -0
  285. package/build/server/chunks/10-CpPov-q6.js.map +1 -0
  286. package/build/server/chunks/11-CgEVkMbf.js +58 -0
  287. package/build/server/chunks/11-CgEVkMbf.js.map +1 -0
  288. package/build/server/chunks/12-Dk9nDvlV.js +52 -0
  289. package/build/server/chunks/12-Dk9nDvlV.js.map +1 -0
  290. package/build/server/chunks/13-BsoV45dx.js +57 -0
  291. package/build/server/chunks/13-BsoV45dx.js.map +1 -0
  292. package/build/server/chunks/14-B3BJJIn3.js +100 -0
  293. package/build/server/chunks/14-B3BJJIn3.js.map +1 -0
  294. package/build/server/chunks/15-BqYjEVaA.js +43 -0
  295. package/build/server/chunks/15-BqYjEVaA.js.map +1 -0
  296. package/build/server/chunks/16-CQEqybxD.js +84 -0
  297. package/build/server/chunks/16-CQEqybxD.js.map +1 -0
  298. package/build/server/chunks/17-DPHGdRIj.js +9 -0
  299. package/build/server/chunks/17-DPHGdRIj.js.map +1 -0
  300. package/build/server/chunks/18-BTSLWMQT.js +74 -0
  301. package/build/server/chunks/18-BTSLWMQT.js.map +1 -0
  302. package/build/server/chunks/19-CkJN0M4_.js +94 -0
  303. package/build/server/chunks/19-CkJN0M4_.js.map +1 -0
  304. package/build/server/chunks/2-BJb8QIPX.js +42 -0
  305. package/build/server/chunks/2-BJb8QIPX.js.map +1 -0
  306. package/build/server/chunks/20-DGeV-MBL.js +197 -0
  307. package/build/server/chunks/20-DGeV-MBL.js.map +1 -0
  308. package/build/server/chunks/21-BQWXIChZ.js +83 -0
  309. package/build/server/chunks/21-BQWXIChZ.js.map +1 -0
  310. package/build/server/chunks/23-BmGaVmjO.js +137 -0
  311. package/build/server/chunks/23-BmGaVmjO.js.map +1 -0
  312. package/build/server/chunks/24-DC5Qi8Sm.js +144 -0
  313. package/build/server/chunks/24-DC5Qi8Sm.js.map +1 -0
  314. package/build/server/chunks/25-Oe01GQUn.js +51 -0
  315. package/build/server/chunks/25-Oe01GQUn.js.map +1 -0
  316. package/build/server/chunks/26-Bfl58Hw3.js +9 -0
  317. package/build/server/chunks/26-Bfl58Hw3.js.map +1 -0
  318. package/build/server/chunks/27-CJsZbiCR.js +57 -0
  319. package/build/server/chunks/27-CJsZbiCR.js.map +1 -0
  320. package/build/server/chunks/28-D6UoeYd3.js +69 -0
  321. package/build/server/chunks/28-D6UoeYd3.js.map +1 -0
  322. package/build/server/chunks/29-DZgNMmXD.js +55 -0
  323. package/build/server/chunks/29-DZgNMmXD.js.map +1 -0
  324. package/build/server/chunks/3-OhWAE0Wx.js +9 -0
  325. package/build/server/chunks/3-OhWAE0Wx.js.map +1 -0
  326. package/build/server/chunks/30-B_GStKPy.js +57 -0
  327. package/build/server/chunks/30-B_GStKPy.js.map +1 -0
  328. package/build/server/chunks/31-BefyQf51.js +42 -0
  329. package/build/server/chunks/31-BefyQf51.js.map +1 -0
  330. package/build/server/chunks/32-DIdNQgym.js +34 -0
  331. package/build/server/chunks/32-DIdNQgym.js.map +1 -0
  332. package/build/server/chunks/5-DLhfWemT.js +32 -0
  333. package/build/server/chunks/5-DLhfWemT.js.map +1 -0
  334. package/build/server/chunks/6-DnjCwAlp.js +40 -0
  335. package/build/server/chunks/6-DnjCwAlp.js.map +1 -0
  336. package/build/server/chunks/7-leNovc1s.js +19 -0
  337. package/build/server/chunks/7-leNovc1s.js.map +1 -0
  338. package/build/server/chunks/8-CAx64_UW.js +130 -0
  339. package/build/server/chunks/8-CAx64_UW.js.map +1 -0
  340. package/build/server/chunks/9-Dq-RLXVq.js +46 -0
  341. package/build/server/chunks/9-Dq-RLXVq.js.map +1 -0
  342. package/build/server/chunks/AppHeader-DBNR_OCa.js +271 -0
  343. package/build/server/chunks/AppHeader-DBNR_OCa.js.map +1 -0
  344. package/build/server/chunks/DefinitionCard-BeONTmrJ.js +258 -0
  345. package/build/server/chunks/DefinitionCard-BeONTmrJ.js.map +1 -0
  346. package/build/server/chunks/ErrorScreen-SHK14bo6.js +131 -0
  347. package/build/server/chunks/ErrorScreen-SHK14bo6.js.map +1 -0
  348. package/build/server/chunks/FilterableDropdown-W9AjyS0M.js +61 -0
  349. package/build/server/chunks/FilterableDropdown-W9AjyS0M.js.map +1 -0
  350. package/build/server/chunks/Icon-DbkwAOkZ.js +76 -0
  351. package/build/server/chunks/Icon-DbkwAOkZ.js.map +1 -0
  352. package/build/server/chunks/Icon2-DbkwAOkZ.js +76 -0
  353. package/build/server/chunks/Icon2-DbkwAOkZ.js.map +1 -0
  354. package/build/server/chunks/StatCard-Cj4i7_IY.js +50 -0
  355. package/build/server/chunks/StatCard-Cj4i7_IY.js.map +1 -0
  356. package/build/server/chunks/UserChip-CCZ9yMM3.js +1149 -0
  357. package/build/server/chunks/UserChip-CCZ9yMM3.js.map +1 -0
  358. package/build/server/chunks/_error.svelte-B_dLYaey.js +30 -0
  359. package/build/server/chunks/_error.svelte-B_dLYaey.js.map +1 -0
  360. package/build/server/chunks/_error.svelte-D_qATeW2.js +28 -0
  361. package/build/server/chunks/_error.svelte-D_qATeW2.js.map +1 -0
  362. package/build/server/chunks/_layout.svelte-CgAG7l2U.js +152 -0
  363. package/build/server/chunks/_layout.svelte-CgAG7l2U.js.map +1 -0
  364. package/build/server/chunks/_layout.svelte-Cjs-r7Xa.js +105 -0
  365. package/build/server/chunks/_layout.svelte-Cjs-r7Xa.js.map +1 -0
  366. package/build/server/chunks/_layout.svelte-DU36kuy0.js +1042 -0
  367. package/build/server/chunks/_layout.svelte-DU36kuy0.js.map +1 -0
  368. package/build/server/chunks/_layout.svelte-VEFMEljC.js +42 -0
  369. package/build/server/chunks/_layout.svelte-VEFMEljC.js.map +1 -0
  370. package/build/server/chunks/_page.svelte-1sc1cfuW.js +453 -0
  371. package/build/server/chunks/_page.svelte-1sc1cfuW.js.map +1 -0
  372. package/build/server/chunks/_page.svelte-2a3XlI01.js +120 -0
  373. package/build/server/chunks/_page.svelte-2a3XlI01.js.map +1 -0
  374. package/build/server/chunks/_page.svelte-BLjq8C2p.js +611 -0
  375. package/build/server/chunks/_page.svelte-BLjq8C2p.js.map +1 -0
  376. package/build/server/chunks/_page.svelte-BQZ-qC72.js +424 -0
  377. package/build/server/chunks/_page.svelte-BQZ-qC72.js.map +1 -0
  378. package/build/server/chunks/_page.svelte-BXQInprQ.js +275 -0
  379. package/build/server/chunks/_page.svelte-BXQInprQ.js.map +1 -0
  380. package/build/server/chunks/_page.svelte-BXyLutv1.js +3911 -0
  381. package/build/server/chunks/_page.svelte-BXyLutv1.js.map +1 -0
  382. package/build/server/chunks/_page.svelte-BziMQdom.js +114 -0
  383. package/build/server/chunks/_page.svelte-BziMQdom.js.map +1 -0
  384. package/build/server/chunks/_page.svelte-CYxHCZCC.js +84 -0
  385. package/build/server/chunks/_page.svelte-CYxHCZCC.js.map +1 -0
  386. package/build/server/chunks/_page.svelte-CckrYvJ6.js +147 -0
  387. package/build/server/chunks/_page.svelte-CckrYvJ6.js.map +1 -0
  388. package/build/server/chunks/_page.svelte-CeKqqMje.js +250 -0
  389. package/build/server/chunks/_page.svelte-CeKqqMje.js.map +1 -0
  390. package/build/server/chunks/_page.svelte-Cf8MfOXQ.js +596 -0
  391. package/build/server/chunks/_page.svelte-Cf8MfOXQ.js.map +1 -0
  392. package/build/server/chunks/_page.svelte-CxuFmBkK.js +302 -0
  393. package/build/server/chunks/_page.svelte-CxuFmBkK.js.map +1 -0
  394. package/build/server/chunks/_page.svelte-DAu2h8jG.js +169 -0
  395. package/build/server/chunks/_page.svelte-DAu2h8jG.js.map +1 -0
  396. package/build/server/chunks/_page.svelte-DFgszLSu.js +505 -0
  397. package/build/server/chunks/_page.svelte-DFgszLSu.js.map +1 -0
  398. package/build/server/chunks/_page.svelte-DIeTvNzN.js +69 -0
  399. package/build/server/chunks/_page.svelte-DIeTvNzN.js.map +1 -0
  400. package/build/server/chunks/_page.svelte-DJnICJdZ.js +10654 -0
  401. package/build/server/chunks/_page.svelte-DJnICJdZ.js.map +1 -0
  402. package/build/server/chunks/_page.svelte-DphuJQee.js +331 -0
  403. package/build/server/chunks/_page.svelte-DphuJQee.js.map +1 -0
  404. package/build/server/chunks/_page.svelte-Dun4nEWl.js +277 -0
  405. package/build/server/chunks/_page.svelte-Dun4nEWl.js.map +1 -0
  406. package/build/server/chunks/_page.svelte-Dz-6_oW1.js +547 -0
  407. package/build/server/chunks/_page.svelte-Dz-6_oW1.js.map +1 -0
  408. package/build/server/chunks/_page.svelte-ELmid_qG.js +120 -0
  409. package/build/server/chunks/_page.svelte-ELmid_qG.js.map +1 -0
  410. package/build/server/chunks/_page.svelte-Mwitq0vD.js +330 -0
  411. package/build/server/chunks/_page.svelte-Mwitq0vD.js.map +1 -0
  412. package/build/server/chunks/_page.svelte-UNbcR5Wq.js +715 -0
  413. package/build/server/chunks/_page.svelte-UNbcR5Wq.js.map +1 -0
  414. package/build/server/chunks/_page.svelte-XLccLxWu.js +558 -0
  415. package/build/server/chunks/_page.svelte-XLccLxWu.js.map +1 -0
  416. package/build/server/chunks/_page.svelte-pEdM2bKS.js +57 -0
  417. package/build/server/chunks/_page.svelte-pEdM2bKS.js.map +1 -0
  418. package/build/server/chunks/_server.ts-B-1avpfE.js +43 -0
  419. package/build/server/chunks/_server.ts-B-1avpfE.js.map +1 -0
  420. package/build/server/chunks/_server.ts-BHizTPVg.js +107 -0
  421. package/build/server/chunks/_server.ts-BHizTPVg.js.map +1 -0
  422. package/build/server/chunks/_server.ts-BIQdiZfW.js +30 -0
  423. package/build/server/chunks/_server.ts-BIQdiZfW.js.map +1 -0
  424. package/build/server/chunks/_server.ts-BKtKkHZS.js +52 -0
  425. package/build/server/chunks/_server.ts-BKtKkHZS.js.map +1 -0
  426. package/build/server/chunks/_server.ts-BLC5g2H_.js +95 -0
  427. package/build/server/chunks/_server.ts-BLC5g2H_.js.map +1 -0
  428. package/build/server/chunks/_server.ts-BOCvzY_U.js +104 -0
  429. package/build/server/chunks/_server.ts-BOCvzY_U.js.map +1 -0
  430. package/build/server/chunks/_server.ts-BTSLBiLL.js +111 -0
  431. package/build/server/chunks/_server.ts-BTSLBiLL.js.map +1 -0
  432. package/build/server/chunks/_server.ts-BTWwyruR.js +39 -0
  433. package/build/server/chunks/_server.ts-BTWwyruR.js.map +1 -0
  434. package/build/server/chunks/_server.ts-BUEUSAPc.js +71 -0
  435. package/build/server/chunks/_server.ts-BUEUSAPc.js.map +1 -0
  436. package/build/server/chunks/_server.ts-BXJAFFdr.js +82 -0
  437. package/build/server/chunks/_server.ts-BXJAFFdr.js.map +1 -0
  438. package/build/server/chunks/_server.ts-BeyEUs6I.js +74 -0
  439. package/build/server/chunks/_server.ts-BeyEUs6I.js.map +1 -0
  440. package/build/server/chunks/_server.ts-Bkr-33U0.js +102 -0
  441. package/build/server/chunks/_server.ts-Bkr-33U0.js.map +1 -0
  442. package/build/server/chunks/_server.ts-Bm14E-bx.js +42 -0
  443. package/build/server/chunks/_server.ts-Bm14E-bx.js.map +1 -0
  444. package/build/server/chunks/_server.ts-ByqZZZxB.js +35 -0
  445. package/build/server/chunks/_server.ts-ByqZZZxB.js.map +1 -0
  446. package/build/server/chunks/_server.ts-C-w9ogA2.js +38 -0
  447. package/build/server/chunks/_server.ts-C-w9ogA2.js.map +1 -0
  448. package/build/server/chunks/_server.ts-C1wqbTiL.js +31 -0
  449. package/build/server/chunks/_server.ts-C1wqbTiL.js.map +1 -0
  450. package/build/server/chunks/_server.ts-C2A_Oiwe.js +82 -0
  451. package/build/server/chunks/_server.ts-C2A_Oiwe.js.map +1 -0
  452. package/build/server/chunks/_server.ts-C3CKmKpW.js +87 -0
  453. package/build/server/chunks/_server.ts-C3CKmKpW.js.map +1 -0
  454. package/build/server/chunks/_server.ts-C52CTPlo.js +38 -0
  455. package/build/server/chunks/_server.ts-C52CTPlo.js.map +1 -0
  456. package/build/server/chunks/_server.ts-CJ8oDVHC.js +39 -0
  457. package/build/server/chunks/_server.ts-CJ8oDVHC.js.map +1 -0
  458. package/build/server/chunks/_server.ts-CnVtonm0.js +40 -0
  459. package/build/server/chunks/_server.ts-CnVtonm0.js.map +1 -0
  460. package/build/server/chunks/_server.ts-CpC3cdzG.js +31 -0
  461. package/build/server/chunks/_server.ts-CpC3cdzG.js.map +1 -0
  462. package/build/server/chunks/_server.ts-CqCIfPI0.js +72 -0
  463. package/build/server/chunks/_server.ts-CqCIfPI0.js.map +1 -0
  464. package/build/server/chunks/_server.ts-D9iabXf8.js +49 -0
  465. package/build/server/chunks/_server.ts-D9iabXf8.js.map +1 -0
  466. package/build/server/chunks/_server.ts-DDHHklcd.js +50 -0
  467. package/build/server/chunks/_server.ts-DDHHklcd.js.map +1 -0
  468. package/build/server/chunks/_server.ts-DWAwxfXk.js +32 -0
  469. package/build/server/chunks/_server.ts-DWAwxfXk.js.map +1 -0
  470. package/build/server/chunks/_server.ts-DXqr0BIr.js +86 -0
  471. package/build/server/chunks/_server.ts-DXqr0BIr.js.map +1 -0
  472. package/build/server/chunks/_server.ts-DcRwP_gQ.js +65 -0
  473. package/build/server/chunks/_server.ts-DcRwP_gQ.js.map +1 -0
  474. package/build/server/chunks/_server.ts-DiJ2px88.js +62 -0
  475. package/build/server/chunks/_server.ts-DiJ2px88.js.map +1 -0
  476. package/build/server/chunks/_server.ts-Dp3_io85.js +409 -0
  477. package/build/server/chunks/_server.ts-Dp3_io85.js.map +1 -0
  478. package/build/server/chunks/_server.ts-DuC2r20u.js +305 -0
  479. package/build/server/chunks/_server.ts-DuC2r20u.js.map +1 -0
  480. package/build/server/chunks/_server.ts-Dukt2veu.js +33 -0
  481. package/build/server/chunks/_server.ts-Dukt2veu.js.map +1 -0
  482. package/build/server/chunks/_server.ts-Dw630Jb2.js +85 -0
  483. package/build/server/chunks/_server.ts-Dw630Jb2.js.map +1 -0
  484. package/build/server/chunks/_server.ts-DzG1eKRC.js +76 -0
  485. package/build/server/chunks/_server.ts-DzG1eKRC.js.map +1 -0
  486. package/build/server/chunks/_server.ts-EOYMi5x8.js +59 -0
  487. package/build/server/chunks/_server.ts-EOYMi5x8.js.map +1 -0
  488. package/build/server/chunks/_server.ts-aUFaewu4.js +79 -0
  489. package/build/server/chunks/_server.ts-aUFaewu4.js.map +1 -0
  490. package/build/server/chunks/_server.ts-hg9WxMNg.js +36 -0
  491. package/build/server/chunks/_server.ts-hg9WxMNg.js.map +1 -0
  492. package/build/server/chunks/_server.ts-k9Y_t-wX.js +40 -0
  493. package/build/server/chunks/_server.ts-k9Y_t-wX.js.map +1 -0
  494. package/build/server/chunks/access.server-CGwRj2TY.js +412 -0
  495. package/build/server/chunks/access.server-CGwRj2TY.js.map +1 -0
  496. package/build/server/chunks/activity-BjtW_4T-.js +18 -0
  497. package/build/server/chunks/activity-BjtW_4T-.js.map +1 -0
  498. package/build/server/chunks/alert-description-CUK0afmb.js +59 -0
  499. package/build/server/chunks/alert-description-CUK0afmb.js.map +1 -0
  500. package/build/server/chunks/api-errors-b2AR_m1A.js +83 -0
  501. package/build/server/chunks/api-errors-b2AR_m1A.js.map +1 -0
  502. package/build/server/chunks/arrow-left-D0KqaESK.js +14 -0
  503. package/build/server/chunks/arrow-left-D0KqaESK.js.map +1 -0
  504. package/build/server/chunks/arrow-right-Bi1uWbBU.js +14 -0
  505. package/build/server/chunks/arrow-right-Bi1uWbBU.js.map +1 -0
  506. package/build/server/chunks/auth-bootstrap.server-CdwMOcYI.js +98 -0
  507. package/build/server/chunks/auth-bootstrap.server-CdwMOcYI.js.map +1 -0
  508. package/build/server/chunks/badge-Dslv369v.js +50 -0
  509. package/build/server/chunks/badge-Dslv369v.js.map +1 -0
  510. package/build/server/chunks/bootHealth.server-Ca8zFRpM.js +58 -0
  511. package/build/server/chunks/bootHealth.server-Ca8zFRpM.js.map +1 -0
  512. package/build/server/chunks/building-2-DJFEkZmC.js +22 -0
  513. package/build/server/chunks/building-2-DJFEkZmC.js.map +1 -0
  514. package/build/server/chunks/button-1GF48U_O.js +73 -0
  515. package/build/server/chunks/button-1GF48U_O.js.map +1 -0
  516. package/build/server/chunks/card-content-CLRedGcu.js +46 -0
  517. package/build/server/chunks/card-content-CLRedGcu.js.map +1 -0
  518. package/build/server/chunks/card-description-Cvz9Nl_J.js +26 -0
  519. package/build/server/chunks/card-description-Cvz9Nl_J.js.map +1 -0
  520. package/build/server/chunks/card-title-f3nMy4Cc.js +46 -0
  521. package/build/server/chunks/card-title-f3nMy4Cc.js.map +1 -0
  522. package/build/server/chunks/chevron-down-Cqowxf45.js +11 -0
  523. package/build/server/chunks/chevron-down-Cqowxf45.js.map +1 -0
  524. package/build/server/chunks/chevron-down2-HiD5tdXf.js +11 -0
  525. package/build/server/chunks/chevron-down2-HiD5tdXf.js.map +1 -0
  526. package/build/server/chunks/chevron-right-BZ8x48EK.js +11 -0
  527. package/build/server/chunks/chevron-right-BZ8x48EK.js.map +1 -0
  528. package/build/server/chunks/circle-CeSIvmWj.js +11 -0
  529. package/build/server/chunks/circle-CeSIvmWj.js.map +1 -0
  530. package/build/server/chunks/circle-alert-DNsq-x3V.js +18 -0
  531. package/build/server/chunks/circle-alert-DNsq-x3V.js.map +1 -0
  532. package/build/server/chunks/circle-alert2-Doldk45G.js +18 -0
  533. package/build/server/chunks/circle-alert2-Doldk45G.js.map +1 -0
  534. package/build/server/chunks/context-DKDYb-He.js +138 -0
  535. package/build/server/chunks/context-DKDYb-He.js.map +1 -0
  536. package/build/server/chunks/copy-DbzeZFQN.js +29 -0
  537. package/build/server/chunks/copy-DbzeZFQN.js.map +1 -0
  538. package/build/server/chunks/folder-kanban-BzEQk9ZB.js +21 -0
  539. package/build/server/chunks/folder-kanban-BzEQk9ZB.js.map +1 -0
  540. package/build/server/chunks/folder-open-CUgA3M22.js +18 -0
  541. package/build/server/chunks/folder-open-CUgA3M22.js.map +1 -0
  542. package/build/server/chunks/folders-DPJPvoz3.js +24 -0
  543. package/build/server/chunks/folders-DPJPvoz3.js.map +1 -0
  544. package/build/server/chunks/footerContext.svelte-BZEf7gVw.js +487 -0
  545. package/build/server/chunks/footerContext.svelte-BZEf7gVw.js.map +1 -0
  546. package/build/server/chunks/gauge-Az8B3w7C.js +87 -0
  547. package/build/server/chunks/gauge-Az8B3w7C.js.map +1 -0
  548. package/build/server/chunks/hooks.server-D6EnLMoG.js +218 -0
  549. package/build/server/chunks/hooks.server-D6EnLMoG.js.map +1 -0
  550. package/build/server/chunks/index2-B9qXYHIn.js +438 -0
  551. package/build/server/chunks/index2-B9qXYHIn.js.map +1 -0
  552. package/build/server/chunks/index3-AGemCGcn.js +4388 -0
  553. package/build/server/chunks/index3-AGemCGcn.js.map +1 -0
  554. package/build/server/chunks/index4-DSWKKOFB.js +541 -0
  555. package/build/server/chunks/index4-DSWKKOFB.js.map +1 -0
  556. package/build/server/chunks/input-DGJ03-ia.js +53 -0
  557. package/build/server/chunks/input-DGJ03-ia.js.map +1 -0
  558. package/build/server/chunks/label-Df1UqzdF.js +112 -0
  559. package/build/server/chunks/label-Df1UqzdF.js.map +1 -0
  560. package/build/server/chunks/link-2-dxaDBYcR.js +15 -0
  561. package/build/server/chunks/link-2-dxaDBYcR.js.map +1 -0
  562. package/build/server/chunks/mail-CXBfO_C7.js +17 -0
  563. package/build/server/chunks/mail-CXBfO_C7.js.map +1 -0
  564. package/build/server/chunks/permissions-compat.server-BDkKxDeZ.js +19 -0
  565. package/build/server/chunks/permissions-compat.server-BDkKxDeZ.js.map +1 -0
  566. package/build/server/chunks/permissions.server-cNGc9ris.js +8 -0
  567. package/build/server/chunks/permissions.server-cNGc9ris.js.map +1 -0
  568. package/build/server/chunks/plus-CY_pTStn.js +11 -0
  569. package/build/server/chunks/plus-CY_pTStn.js.map +1 -0
  570. package/build/server/chunks/providers.server-MD7TK-zQ.js +4561 -0
  571. package/build/server/chunks/providers.server-MD7TK-zQ.js.map +1 -0
  572. package/build/server/chunks/resolve.server-C5wZnxS_.js +11 -0
  573. package/build/server/chunks/resolve.server-C5wZnxS_.js.map +1 -0
  574. package/build/server/chunks/resolve.server2-BXKCfGfg.js +50 -0
  575. package/build/server/chunks/resolve.server2-BXKCfGfg.js.map +1 -0
  576. package/build/server/chunks/rotate-ccw-1C53L417.js +17 -0
  577. package/build/server/chunks/rotate-ccw-1C53L417.js.map +1 -0
  578. package/build/server/chunks/scroll-text-CxtFfkcE.js +21 -0
  579. package/build/server/chunks/scroll-text-CxtFfkcE.js.map +1 -0
  580. package/build/server/chunks/server-C3-deqCy.js +36 -0
  581. package/build/server/chunks/server-C3-deqCy.js.map +1 -0
  582. package/build/server/chunks/settings-NH5q_HtF.js +19 -0
  583. package/build/server/chunks/settings-NH5q_HtF.js.map +1 -0
  584. package/build/server/chunks/shield-CHAFruKV.js +18 -0
  585. package/build/server/chunks/shield-CHAFruKV.js.map +1 -0
  586. package/build/server/chunks/shield-check-06Iz62as.js +19 -0
  587. package/build/server/chunks/shield-check-06Iz62as.js.map +1 -0
  588. package/build/server/chunks/star-bmBg3IsG.js +18 -0
  589. package/build/server/chunks/star-bmBg3IsG.js.map +1 -0
  590. package/build/server/chunks/textarea-A5IYPwqe.js +685 -0
  591. package/build/server/chunks/textarea-A5IYPwqe.js.map +1 -0
  592. package/build/server/chunks/trash-2-swQcKEqX.js +17 -0
  593. package/build/server/chunks/trash-2-swQcKEqX.js.map +1 -0
  594. package/build/server/chunks/upload-BY_p_jpL.js +36 -0
  595. package/build/server/chunks/upload-BY_p_jpL.js.map +1 -0
  596. package/build/server/chunks/user-plus-CPEDH5dh.js +16 -0
  597. package/build/server/chunks/user-plus-CPEDH5dh.js.map +1 -0
  598. package/build/server/chunks/users-Bd7CKN4d.js +16 -0
  599. package/build/server/chunks/users-Bd7CKN4d.js.map +1 -0
  600. package/build/server/chunks/utils2-D38XWwRv.js +56 -0
  601. package/build/server/chunks/utils2-D38XWwRv.js.map +1 -0
  602. package/build/server/chunks/utils3-B05Dmz_H.js +9 -0
  603. package/build/server/chunks/utils3-B05Dmz_H.js.map +1 -0
  604. package/build/server/chunks/x-e5o-84bg.js +14 -0
  605. package/build/server/chunks/x-e5o-84bg.js.map +1 -0
  606. package/build/server/index.js +2 -2
  607. package/build/server/index.js.map +1 -1
  608. package/build/server/manifest.js +70 -70
  609. package/build/server/manifest.js.map +1 -1
  610. package/package.json +7 -7
  611. package/build/client/_app/immutable/assets/0.B0phAlf7.css +0 -1
  612. package/build/client/_app/immutable/assets/0.B0phAlf7.css.br +0 -0
  613. package/build/client/_app/immutable/assets/0.B0phAlf7.css.gz +0 -0
  614. package/build/client/_app/immutable/assets/20.DzF5JyuX.css +0 -1
  615. package/build/client/_app/immutable/assets/20.DzF5JyuX.css.br +0 -0
  616. package/build/client/_app/immutable/assets/20.DzF5JyuX.css.gz +0 -0
  617. package/build/client/_app/immutable/chunks/2BnY_oab.js +0 -1
  618. package/build/client/_app/immutable/chunks/2BnY_oab.js.br +0 -0
  619. package/build/client/_app/immutable/chunks/2BnY_oab.js.gz +0 -0
  620. package/build/client/_app/immutable/chunks/5h7wo9xN.js +0 -1
  621. package/build/client/_app/immutable/chunks/5h7wo9xN.js.br +0 -0
  622. package/build/client/_app/immutable/chunks/5h7wo9xN.js.gz +0 -0
  623. package/build/client/_app/immutable/chunks/B3KcsPFR.js +0 -1
  624. package/build/client/_app/immutable/chunks/B3KcsPFR.js.br +0 -0
  625. package/build/client/_app/immutable/chunks/B3KcsPFR.js.gz +0 -0
  626. package/build/client/_app/immutable/chunks/B48NJnzU.js +0 -1
  627. package/build/client/_app/immutable/chunks/B48NJnzU.js.br +0 -0
  628. package/build/client/_app/immutable/chunks/B48NJnzU.js.gz +0 -0
  629. package/build/client/_app/immutable/chunks/B5HD-6Ib.js +0 -1
  630. package/build/client/_app/immutable/chunks/B5HD-6Ib.js.br +0 -0
  631. package/build/client/_app/immutable/chunks/B5HD-6Ib.js.gz +0 -0
  632. package/build/client/_app/immutable/chunks/BDpsQuxH.js +0 -1
  633. package/build/client/_app/immutable/chunks/BDpsQuxH.js.br +0 -0
  634. package/build/client/_app/immutable/chunks/BDpsQuxH.js.gz +0 -0
  635. package/build/client/_app/immutable/chunks/BEya8QN5.js +0 -1
  636. package/build/client/_app/immutable/chunks/BEya8QN5.js.br +0 -0
  637. package/build/client/_app/immutable/chunks/BEya8QN5.js.gz +0 -0
  638. package/build/client/_app/immutable/chunks/BH9oGrlA.js +0 -1
  639. package/build/client/_app/immutable/chunks/BH9oGrlA.js.br +0 -0
  640. package/build/client/_app/immutable/chunks/BH9oGrlA.js.gz +0 -0
  641. package/build/client/_app/immutable/chunks/BHzbkLpq.js +0 -1
  642. package/build/client/_app/immutable/chunks/BHzbkLpq.js.br +0 -0
  643. package/build/client/_app/immutable/chunks/BHzbkLpq.js.gz +0 -0
  644. package/build/client/_app/immutable/chunks/BKZ_D8Qd.js +0 -1
  645. package/build/client/_app/immutable/chunks/BKZ_D8Qd.js.br +0 -0
  646. package/build/client/_app/immutable/chunks/BKZ_D8Qd.js.gz +0 -0
  647. package/build/client/_app/immutable/chunks/BKkYsBzb.js +0 -9
  648. package/build/client/_app/immutable/chunks/BKkYsBzb.js.br +0 -0
  649. package/build/client/_app/immutable/chunks/BKkYsBzb.js.gz +0 -0
  650. package/build/client/_app/immutable/chunks/BLBezPFp.js +0 -1
  651. package/build/client/_app/immutable/chunks/BLBezPFp.js.br +0 -0
  652. package/build/client/_app/immutable/chunks/BLBezPFp.js.gz +0 -0
  653. package/build/client/_app/immutable/chunks/BMNUAT2D.js +0 -1
  654. package/build/client/_app/immutable/chunks/BMNUAT2D.js.br +0 -0
  655. package/build/client/_app/immutable/chunks/BMNUAT2D.js.gz +0 -0
  656. package/build/client/_app/immutable/chunks/BNs1__IY.js +0 -1
  657. package/build/client/_app/immutable/chunks/BNs1__IY.js.br +0 -0
  658. package/build/client/_app/immutable/chunks/BNs1__IY.js.gz +0 -0
  659. package/build/client/_app/immutable/chunks/Ba74WbdD.js +0 -1
  660. package/build/client/_app/immutable/chunks/Ba74WbdD.js.br +0 -0
  661. package/build/client/_app/immutable/chunks/Ba74WbdD.js.gz +0 -0
  662. package/build/client/_app/immutable/chunks/Bex2dy3F.js +0 -1
  663. package/build/client/_app/immutable/chunks/Bex2dy3F.js.br +0 -0
  664. package/build/client/_app/immutable/chunks/Bex2dy3F.js.gz +0 -0
  665. package/build/client/_app/immutable/chunks/BfraRswf.js +0 -1
  666. package/build/client/_app/immutable/chunks/BfraRswf.js.br +0 -0
  667. package/build/client/_app/immutable/chunks/BfraRswf.js.gz +0 -0
  668. package/build/client/_app/immutable/chunks/BhwCS4j8.js +0 -1
  669. package/build/client/_app/immutable/chunks/BhwCS4j8.js.br +0 -0
  670. package/build/client/_app/immutable/chunks/BhwCS4j8.js.gz +0 -0
  671. package/build/client/_app/immutable/chunks/BjB88iwt.js +0 -1
  672. package/build/client/_app/immutable/chunks/BjB88iwt.js.br +0 -0
  673. package/build/client/_app/immutable/chunks/BjB88iwt.js.gz +0 -0
  674. package/build/client/_app/immutable/chunks/BsZHa2Wi.js +0 -1
  675. package/build/client/_app/immutable/chunks/BsZHa2Wi.js.br +0 -0
  676. package/build/client/_app/immutable/chunks/BsZHa2Wi.js.gz +0 -0
  677. package/build/client/_app/immutable/chunks/C5BR2Ers.js +0 -1
  678. package/build/client/_app/immutable/chunks/C5BR2Ers.js.br +0 -0
  679. package/build/client/_app/immutable/chunks/C5BR2Ers.js.gz +0 -0
  680. package/build/client/_app/immutable/chunks/CBjt6cm5.js +0 -1
  681. package/build/client/_app/immutable/chunks/CBjt6cm5.js.br +0 -1
  682. package/build/client/_app/immutable/chunks/CBjt6cm5.js.gz +0 -0
  683. package/build/client/_app/immutable/chunks/CE8BcsFf.js +0 -1
  684. package/build/client/_app/immutable/chunks/CE8BcsFf.js.br +0 -0
  685. package/build/client/_app/immutable/chunks/CE8BcsFf.js.gz +0 -0
  686. package/build/client/_app/immutable/chunks/CJPg7PqR.js +0 -1
  687. package/build/client/_app/immutable/chunks/CJPg7PqR.js.br +0 -0
  688. package/build/client/_app/immutable/chunks/CJPg7PqR.js.gz +0 -0
  689. package/build/client/_app/immutable/chunks/CKPgdp0v.js +0 -1
  690. package/build/client/_app/immutable/chunks/CKPgdp0v.js.br +0 -0
  691. package/build/client/_app/immutable/chunks/CKPgdp0v.js.gz +0 -0
  692. package/build/client/_app/immutable/chunks/CMh2kjaf.js +0 -1
  693. package/build/client/_app/immutable/chunks/CMh2kjaf.js.br +0 -0
  694. package/build/client/_app/immutable/chunks/CMh2kjaf.js.gz +0 -0
  695. package/build/client/_app/immutable/chunks/COWz2et1.js +0 -1
  696. package/build/client/_app/immutable/chunks/COWz2et1.js.br +0 -0
  697. package/build/client/_app/immutable/chunks/COWz2et1.js.gz +0 -0
  698. package/build/client/_app/immutable/chunks/CQerFpzT.js +0 -1
  699. package/build/client/_app/immutable/chunks/CQerFpzT.js.br +0 -0
  700. package/build/client/_app/immutable/chunks/CQerFpzT.js.gz +0 -0
  701. package/build/client/_app/immutable/chunks/Cauzi832.js +0 -1
  702. package/build/client/_app/immutable/chunks/Cauzi832.js.br +0 -0
  703. package/build/client/_app/immutable/chunks/Cauzi832.js.gz +0 -0
  704. package/build/client/_app/immutable/chunks/CcBbOJ-v.js +0 -1
  705. package/build/client/_app/immutable/chunks/CcBbOJ-v.js.br +0 -2
  706. package/build/client/_app/immutable/chunks/CcBbOJ-v.js.gz +0 -0
  707. package/build/client/_app/immutable/chunks/Ckd6DpGW.js +0 -1
  708. package/build/client/_app/immutable/chunks/Ckd6DpGW.js.br +0 -0
  709. package/build/client/_app/immutable/chunks/Ckd6DpGW.js.gz +0 -0
  710. package/build/client/_app/immutable/chunks/Ctxx2m1z.js +0 -3
  711. package/build/client/_app/immutable/chunks/Ctxx2m1z.js.br +0 -0
  712. package/build/client/_app/immutable/chunks/Ctxx2m1z.js.gz +0 -0
  713. package/build/client/_app/immutable/chunks/CwEiVMBL.js +0 -1
  714. package/build/client/_app/immutable/chunks/CwEiVMBL.js.br +0 -0
  715. package/build/client/_app/immutable/chunks/CwEiVMBL.js.gz +0 -0
  716. package/build/client/_app/immutable/chunks/DApsykQI.js +0 -1
  717. package/build/client/_app/immutable/chunks/DApsykQI.js.br +0 -0
  718. package/build/client/_app/immutable/chunks/DApsykQI.js.gz +0 -0
  719. package/build/client/_app/immutable/chunks/DC8WqQE0.js +0 -1
  720. package/build/client/_app/immutable/chunks/DC8WqQE0.js.br +0 -0
  721. package/build/client/_app/immutable/chunks/DC8WqQE0.js.gz +0 -0
  722. package/build/client/_app/immutable/chunks/DCgyaAAq.js +0 -1
  723. package/build/client/_app/immutable/chunks/DCgyaAAq.js.br +0 -0
  724. package/build/client/_app/immutable/chunks/DCgyaAAq.js.gz +0 -0
  725. package/build/client/_app/immutable/chunks/DFnVpznB.js +0 -1
  726. package/build/client/_app/immutable/chunks/DFnVpznB.js.br +0 -4
  727. package/build/client/_app/immutable/chunks/DFnVpznB.js.gz +0 -0
  728. package/build/client/_app/immutable/chunks/DH_OLMrQ.js +0 -1
  729. package/build/client/_app/immutable/chunks/DH_OLMrQ.js.br +0 -0
  730. package/build/client/_app/immutable/chunks/DH_OLMrQ.js.gz +0 -0
  731. package/build/client/_app/immutable/chunks/DKP3kMac.js +0 -2
  732. package/build/client/_app/immutable/chunks/DKP3kMac.js.br +0 -0
  733. package/build/client/_app/immutable/chunks/DKP3kMac.js.gz +0 -0
  734. package/build/client/_app/immutable/chunks/DU8tQv0c.js +0 -1
  735. package/build/client/_app/immutable/chunks/DU8tQv0c.js.br +0 -0
  736. package/build/client/_app/immutable/chunks/DU8tQv0c.js.gz +0 -0
  737. package/build/client/_app/immutable/chunks/DUpVdSFf.js +0 -1
  738. package/build/client/_app/immutable/chunks/DUpVdSFf.js.br +0 -0
  739. package/build/client/_app/immutable/chunks/DUpVdSFf.js.gz +0 -0
  740. package/build/client/_app/immutable/chunks/DciO9jhd.js +0 -1
  741. package/build/client/_app/immutable/chunks/DciO9jhd.js.br +0 -0
  742. package/build/client/_app/immutable/chunks/DciO9jhd.js.gz +0 -0
  743. package/build/client/_app/immutable/chunks/DfcDRMtE.js +0 -1
  744. package/build/client/_app/immutable/chunks/DfcDRMtE.js.br +0 -0
  745. package/build/client/_app/immutable/chunks/DfcDRMtE.js.gz +0 -0
  746. package/build/client/_app/immutable/chunks/DglJwvDE.js +0 -1
  747. package/build/client/_app/immutable/chunks/DglJwvDE.js.br +0 -0
  748. package/build/client/_app/immutable/chunks/DglJwvDE.js.gz +0 -0
  749. package/build/client/_app/immutable/chunks/Dw6fzgfW.js +0 -1
  750. package/build/client/_app/immutable/chunks/Dw6fzgfW.js.br +0 -0
  751. package/build/client/_app/immutable/chunks/Dw6fzgfW.js.gz +0 -0
  752. package/build/client/_app/immutable/chunks/DzNzLgOO.js +0 -1
  753. package/build/client/_app/immutable/chunks/DzNzLgOO.js.br +0 -0
  754. package/build/client/_app/immutable/chunks/DzNzLgOO.js.gz +0 -0
  755. package/build/client/_app/immutable/chunks/E7F5LllG.js +0 -1
  756. package/build/client/_app/immutable/chunks/E7F5LllG.js.br +0 -0
  757. package/build/client/_app/immutable/chunks/E7F5LllG.js.gz +0 -0
  758. package/build/client/_app/immutable/chunks/FdBsYR_f.js +0 -1
  759. package/build/client/_app/immutable/chunks/FdBsYR_f.js.br +0 -0
  760. package/build/client/_app/immutable/chunks/FdBsYR_f.js.gz +0 -0
  761. package/build/client/_app/immutable/chunks/MJK-ocUx.js +0 -1
  762. package/build/client/_app/immutable/chunks/MJK-ocUx.js.br +0 -0
  763. package/build/client/_app/immutable/chunks/MJK-ocUx.js.gz +0 -0
  764. package/build/client/_app/immutable/chunks/NPsDidaV.js +0 -1
  765. package/build/client/_app/immutable/chunks/NPsDidaV.js.br +0 -0
  766. package/build/client/_app/immutable/chunks/NPsDidaV.js.gz +0 -0
  767. package/build/client/_app/immutable/chunks/OVtUuDzp.js +0 -1
  768. package/build/client/_app/immutable/chunks/OVtUuDzp.js.br +0 -0
  769. package/build/client/_app/immutable/chunks/OVtUuDzp.js.gz +0 -0
  770. package/build/client/_app/immutable/chunks/Qf_Lg02h.js +0 -1
  771. package/build/client/_app/immutable/chunks/Qf_Lg02h.js.br +0 -0
  772. package/build/client/_app/immutable/chunks/Qf_Lg02h.js.gz +0 -0
  773. package/build/client/_app/immutable/chunks/RmXOMQTe.js +0 -1
  774. package/build/client/_app/immutable/chunks/RmXOMQTe.js.br +0 -0
  775. package/build/client/_app/immutable/chunks/RmXOMQTe.js.gz +0 -0
  776. package/build/client/_app/immutable/chunks/X4d9Q9UP.js +0 -1
  777. package/build/client/_app/immutable/chunks/X4d9Q9UP.js.br +0 -0
  778. package/build/client/_app/immutable/chunks/X4d9Q9UP.js.gz +0 -0
  779. package/build/client/_app/immutable/chunks/lyBl2EWc.js +0 -64
  780. package/build/client/_app/immutable/chunks/lyBl2EWc.js.br +0 -0
  781. package/build/client/_app/immutable/chunks/lyBl2EWc.js.gz +0 -0
  782. package/build/client/_app/immutable/entry/app.6Pcj7C1y.js +0 -2
  783. package/build/client/_app/immutable/entry/app.6Pcj7C1y.js.br +0 -0
  784. package/build/client/_app/immutable/entry/app.6Pcj7C1y.js.gz +0 -0
  785. package/build/client/_app/immutable/entry/start.DIHLwcbZ.js +0 -1
  786. package/build/client/_app/immutable/entry/start.DIHLwcbZ.js.br +0 -0
  787. package/build/client/_app/immutable/entry/start.DIHLwcbZ.js.gz +0 -0
  788. package/build/client/_app/immutable/nodes/0.jHfSJDLC.js +0 -1
  789. package/build/client/_app/immutable/nodes/0.jHfSJDLC.js.br +0 -0
  790. package/build/client/_app/immutable/nodes/0.jHfSJDLC.js.gz +0 -0
  791. package/build/client/_app/immutable/nodes/1.BhykIdRx.js +0 -1
  792. package/build/client/_app/immutable/nodes/1.BhykIdRx.js.br +0 -0
  793. package/build/client/_app/immutable/nodes/1.BhykIdRx.js.gz +0 -0
  794. package/build/client/_app/immutable/nodes/10.CFymu_sF.js +0 -3
  795. package/build/client/_app/immutable/nodes/10.CFymu_sF.js.br +0 -0
  796. package/build/client/_app/immutable/nodes/10.CFymu_sF.js.gz +0 -0
  797. package/build/client/_app/immutable/nodes/11.DyOlzJcZ.js +0 -2
  798. package/build/client/_app/immutable/nodes/11.DyOlzJcZ.js.br +0 -0
  799. package/build/client/_app/immutable/nodes/11.DyOlzJcZ.js.gz +0 -0
  800. package/build/client/_app/immutable/nodes/12.BqHQ_pQ5.js +0 -1
  801. package/build/client/_app/immutable/nodes/12.BqHQ_pQ5.js.br +0 -0
  802. package/build/client/_app/immutable/nodes/12.BqHQ_pQ5.js.gz +0 -0
  803. package/build/client/_app/immutable/nodes/13.s79JEajb.js +0 -2
  804. package/build/client/_app/immutable/nodes/13.s79JEajb.js.br +0 -0
  805. package/build/client/_app/immutable/nodes/13.s79JEajb.js.gz +0 -0
  806. package/build/client/_app/immutable/nodes/14.CYT3iXz4.js +0 -2
  807. package/build/client/_app/immutable/nodes/14.CYT3iXz4.js.br +0 -0
  808. package/build/client/_app/immutable/nodes/14.CYT3iXz4.js.gz +0 -0
  809. package/build/client/_app/immutable/nodes/15.BmUKGag9.js +0 -16
  810. package/build/client/_app/immutable/nodes/15.BmUKGag9.js.br +0 -0
  811. package/build/client/_app/immutable/nodes/15.BmUKGag9.js.gz +0 -0
  812. package/build/client/_app/immutable/nodes/16.BV1yTi0H.js +0 -6
  813. package/build/client/_app/immutable/nodes/16.BV1yTi0H.js.br +0 -0
  814. package/build/client/_app/immutable/nodes/16.BV1yTi0H.js.gz +0 -0
  815. package/build/client/_app/immutable/nodes/17.BJ9W1-Gp.js +0 -2
  816. package/build/client/_app/immutable/nodes/17.BJ9W1-Gp.js.br +0 -0
  817. package/build/client/_app/immutable/nodes/17.BJ9W1-Gp.js.gz +0 -0
  818. package/build/client/_app/immutable/nodes/19.CotcbdTq.js +0 -2
  819. package/build/client/_app/immutable/nodes/19.CotcbdTq.js.br +0 -0
  820. package/build/client/_app/immutable/nodes/19.CotcbdTq.js.gz +0 -0
  821. package/build/client/_app/immutable/nodes/2.bzOm1515.js +0 -1
  822. package/build/client/_app/immutable/nodes/2.bzOm1515.js.br +0 -0
  823. package/build/client/_app/immutable/nodes/2.bzOm1515.js.gz +0 -0
  824. package/build/client/_app/immutable/nodes/20.CA3HJZEu.js +0 -4116
  825. package/build/client/_app/immutable/nodes/20.CA3HJZEu.js.br +0 -0
  826. package/build/client/_app/immutable/nodes/20.CA3HJZEu.js.gz +0 -0
  827. package/build/client/_app/immutable/nodes/21.BJPjb8-v.js +0 -6
  828. package/build/client/_app/immutable/nodes/21.BJPjb8-v.js.br +0 -0
  829. package/build/client/_app/immutable/nodes/21.BJPjb8-v.js.gz +0 -0
  830. package/build/client/_app/immutable/nodes/23.BRvOrN4m.js +0 -16
  831. package/build/client/_app/immutable/nodes/23.BRvOrN4m.js.br +0 -0
  832. package/build/client/_app/immutable/nodes/23.BRvOrN4m.js.gz +0 -0
  833. package/build/client/_app/immutable/nodes/24.BXo-yHSI.js +0 -6
  834. package/build/client/_app/immutable/nodes/24.BXo-yHSI.js.br +0 -0
  835. package/build/client/_app/immutable/nodes/24.BXo-yHSI.js.gz +0 -0
  836. package/build/client/_app/immutable/nodes/25.DQ1u0u88.js +0 -1
  837. package/build/client/_app/immutable/nodes/25.DQ1u0u88.js.br +0 -0
  838. package/build/client/_app/immutable/nodes/25.DQ1u0u88.js.gz +0 -0
  839. package/build/client/_app/immutable/nodes/26.Ds_gf_O9.js +0 -3
  840. package/build/client/_app/immutable/nodes/26.Ds_gf_O9.js.br +0 -0
  841. package/build/client/_app/immutable/nodes/26.Ds_gf_O9.js.gz +0 -0
  842. package/build/client/_app/immutable/nodes/27.BYAdgkyp.js +0 -4
  843. package/build/client/_app/immutable/nodes/27.BYAdgkyp.js.br +0 -0
  844. package/build/client/_app/immutable/nodes/27.BYAdgkyp.js.gz +0 -0
  845. package/build/client/_app/immutable/nodes/28.LN6851SR.js +0 -4
  846. package/build/client/_app/immutable/nodes/28.LN6851SR.js.br +0 -0
  847. package/build/client/_app/immutable/nodes/28.LN6851SR.js.gz +0 -0
  848. package/build/client/_app/immutable/nodes/29.DLioElQp.js +0 -2
  849. package/build/client/_app/immutable/nodes/29.DLioElQp.js.br +0 -0
  850. package/build/client/_app/immutable/nodes/29.DLioElQp.js.gz +0 -0
  851. package/build/client/_app/immutable/nodes/3.BrNhFCwf.js +0 -1
  852. package/build/client/_app/immutable/nodes/3.BrNhFCwf.js.br +0 -0
  853. package/build/client/_app/immutable/nodes/3.BrNhFCwf.js.gz +0 -0
  854. package/build/client/_app/immutable/nodes/30.8X3_Qhc4.js +0 -2
  855. package/build/client/_app/immutable/nodes/30.8X3_Qhc4.js.br +0 -0
  856. package/build/client/_app/immutable/nodes/30.8X3_Qhc4.js.gz +0 -0
  857. package/build/client/_app/immutable/nodes/31.CaWXI_qm.js +0 -2
  858. package/build/client/_app/immutable/nodes/31.CaWXI_qm.js.br +0 -0
  859. package/build/client/_app/immutable/nodes/31.CaWXI_qm.js.gz +0 -0
  860. package/build/client/_app/immutable/nodes/32.Drmb2nxJ.js +0 -3
  861. package/build/client/_app/immutable/nodes/32.Drmb2nxJ.js.br +0 -0
  862. package/build/client/_app/immutable/nodes/32.Drmb2nxJ.js.gz +0 -0
  863. package/build/client/_app/immutable/nodes/5.Bv0v3n_x.js +0 -1
  864. package/build/client/_app/immutable/nodes/5.Bv0v3n_x.js.br +0 -1
  865. package/build/client/_app/immutable/nodes/5.Bv0v3n_x.js.gz +0 -0
  866. package/build/client/_app/immutable/nodes/6.Bcm8SZhY.js +0 -1
  867. package/build/client/_app/immutable/nodes/6.Bcm8SZhY.js.br +0 -0
  868. package/build/client/_app/immutable/nodes/6.Bcm8SZhY.js.gz +0 -0
  869. package/build/client/_app/immutable/nodes/7.BxG3WtIs.js +0 -1
  870. package/build/client/_app/immutable/nodes/7.BxG3WtIs.js.br +0 -0
  871. package/build/client/_app/immutable/nodes/7.BxG3WtIs.js.gz +0 -0
  872. package/build/client/_app/immutable/nodes/8.D5JMD1BH.js +0 -2
  873. package/build/client/_app/immutable/nodes/8.D5JMD1BH.js.br +0 -0
  874. package/build/client/_app/immutable/nodes/8.D5JMD1BH.js.gz +0 -0
  875. package/build/client/_app/immutable/nodes/9.C-ulXdlh.js +0 -1
  876. package/build/client/_app/immutable/nodes/9.C-ulXdlh.js.br +0 -0
  877. package/build/client/_app/immutable/nodes/9.C-ulXdlh.js.gz +0 -0
  878. package/build/server/chunks/0-B-R0kBeY.js +0 -55
  879. package/build/server/chunks/0-B-R0kBeY.js.map +0 -1
  880. package/build/server/chunks/1-CuAyMauj.js +0 -9
  881. package/build/server/chunks/1-CuAyMauj.js.map +0 -1
  882. package/build/server/chunks/10-Nv6D0XYy.js +0 -220
  883. package/build/server/chunks/10-Nv6D0XYy.js.map +0 -1
  884. package/build/server/chunks/11-BeesIJzU.js +0 -57
  885. package/build/server/chunks/11-BeesIJzU.js.map +0 -1
  886. package/build/server/chunks/12-BUwej7vW.js +0 -52
  887. package/build/server/chunks/12-BUwej7vW.js.map +0 -1
  888. package/build/server/chunks/13-BXJkEncV.js +0 -57
  889. package/build/server/chunks/13-BXJkEncV.js.map +0 -1
  890. package/build/server/chunks/14-znPM9Pcq.js +0 -100
  891. package/build/server/chunks/14-znPM9Pcq.js.map +0 -1
  892. package/build/server/chunks/15-DZglhlvG.js +0 -43
  893. package/build/server/chunks/15-DZglhlvG.js.map +0 -1
  894. package/build/server/chunks/16-Bn08tbq5.js +0 -83
  895. package/build/server/chunks/16-Bn08tbq5.js.map +0 -1
  896. package/build/server/chunks/17-Cso-R6ia.js +0 -9
  897. package/build/server/chunks/17-Cso-R6ia.js.map +0 -1
  898. package/build/server/chunks/18-DSqnjSZR.js +0 -74
  899. package/build/server/chunks/18-DSqnjSZR.js.map +0 -1
  900. package/build/server/chunks/19-B5ff1LX8.js +0 -94
  901. package/build/server/chunks/19-B5ff1LX8.js.map +0 -1
  902. package/build/server/chunks/2-BGvFL0S4.js +0 -41
  903. package/build/server/chunks/2-BGvFL0S4.js.map +0 -1
  904. package/build/server/chunks/20-DFsHWLTF.js +0 -220
  905. package/build/server/chunks/20-DFsHWLTF.js.map +0 -1
  906. package/build/server/chunks/21-Dn5qUx_W.js +0 -83
  907. package/build/server/chunks/21-Dn5qUx_W.js.map +0 -1
  908. package/build/server/chunks/23-BEE28B4-.js +0 -136
  909. package/build/server/chunks/23-BEE28B4-.js.map +0 -1
  910. package/build/server/chunks/24-C2tGGVXp.js +0 -144
  911. package/build/server/chunks/24-C2tGGVXp.js.map +0 -1
  912. package/build/server/chunks/25-ojiP_VIe.js +0 -51
  913. package/build/server/chunks/25-ojiP_VIe.js.map +0 -1
  914. package/build/server/chunks/26-Dia3LwgX.js +0 -9
  915. package/build/server/chunks/26-Dia3LwgX.js.map +0 -1
  916. package/build/server/chunks/27-DDqk8ntu.js +0 -57
  917. package/build/server/chunks/27-DDqk8ntu.js.map +0 -1
  918. package/build/server/chunks/28-DcIwnJDD.js +0 -69
  919. package/build/server/chunks/28-DcIwnJDD.js.map +0 -1
  920. package/build/server/chunks/29-CPECC6Qt.js +0 -55
  921. package/build/server/chunks/29-CPECC6Qt.js.map +0 -1
  922. package/build/server/chunks/3-CzLHDT1Q.js +0 -9
  923. package/build/server/chunks/3-CzLHDT1Q.js.map +0 -1
  924. package/build/server/chunks/30-Bno1WrtW.js +0 -57
  925. package/build/server/chunks/30-Bno1WrtW.js.map +0 -1
  926. package/build/server/chunks/31-DC1gGFWA.js +0 -42
  927. package/build/server/chunks/31-DC1gGFWA.js.map +0 -1
  928. package/build/server/chunks/32-BOGJTOSC.js +0 -34
  929. package/build/server/chunks/32-BOGJTOSC.js.map +0 -1
  930. package/build/server/chunks/5-C2v3v85u.js +0 -32
  931. package/build/server/chunks/5-C2v3v85u.js.map +0 -1
  932. package/build/server/chunks/6-km9_lsf3.js +0 -40
  933. package/build/server/chunks/6-km9_lsf3.js.map +0 -1
  934. package/build/server/chunks/7-DPthSRvp.js +0 -19
  935. package/build/server/chunks/7-DPthSRvp.js.map +0 -1
  936. package/build/server/chunks/8-AVVSYGmP.js +0 -130
  937. package/build/server/chunks/8-AVVSYGmP.js.map +0 -1
  938. package/build/server/chunks/9-BYsSPT2b.js +0 -46
  939. package/build/server/chunks/9-BYsSPT2b.js.map +0 -1
  940. package/build/server/chunks/AppHeader-DuJuMtMy.js +0 -271
  941. package/build/server/chunks/AppHeader-DuJuMtMy.js.map +0 -1
  942. package/build/server/chunks/DefinitionCard-CYv7Z13m.js +0 -257
  943. package/build/server/chunks/DefinitionCard-CYv7Z13m.js.map +0 -1
  944. package/build/server/chunks/ErrorScreen-d8Z8hQ1U.js +0 -131
  945. package/build/server/chunks/ErrorScreen-d8Z8hQ1U.js.map +0 -1
  946. package/build/server/chunks/FilterableDropdown-0UzIjcXJ.js +0 -61
  947. package/build/server/chunks/FilterableDropdown-0UzIjcXJ.js.map +0 -1
  948. package/build/server/chunks/SideNav-QbExg2MG.js +0 -87
  949. package/build/server/chunks/SideNav-QbExg2MG.js.map +0 -1
  950. package/build/server/chunks/StatCard-CRzbit9Z.js +0 -50
  951. package/build/server/chunks/StatCard-CRzbit9Z.js.map +0 -1
  952. package/build/server/chunks/UserChip-Ba0wRTtZ.js +0 -1113
  953. package/build/server/chunks/UserChip-Ba0wRTtZ.js.map +0 -1
  954. package/build/server/chunks/_error.svelte-DCuOEylf.js +0 -29
  955. package/build/server/chunks/_error.svelte-DCuOEylf.js.map +0 -1
  956. package/build/server/chunks/_error.svelte-DKd7sQzn.js +0 -27
  957. package/build/server/chunks/_error.svelte-DKd7sQzn.js.map +0 -1
  958. package/build/server/chunks/_layout.svelte-BmmDpTcb.js +0 -152
  959. package/build/server/chunks/_layout.svelte-BmmDpTcb.js.map +0 -1
  960. package/build/server/chunks/_layout.svelte-Bu7WpdFm.js +0 -42
  961. package/build/server/chunks/_layout.svelte-Bu7WpdFm.js.map +0 -1
  962. package/build/server/chunks/_layout.svelte-Cbs_hosi.js +0 -105
  963. package/build/server/chunks/_layout.svelte-Cbs_hosi.js.map +0 -1
  964. package/build/server/chunks/_layout.svelte-UsfBRC0f.js +0 -795
  965. package/build/server/chunks/_layout.svelte-UsfBRC0f.js.map +0 -1
  966. package/build/server/chunks/_page.svelte-B2WQ2nhU.js +0 -69
  967. package/build/server/chunks/_page.svelte-B2WQ2nhU.js.map +0 -1
  968. package/build/server/chunks/_page.svelte-B8iLZ6Zi.js +0 -119
  969. package/build/server/chunks/_page.svelte-B8iLZ6Zi.js.map +0 -1
  970. package/build/server/chunks/_page.svelte-BB3Q4U32.js +0 -595
  971. package/build/server/chunks/_page.svelte-BB3Q4U32.js.map +0 -1
  972. package/build/server/chunks/_page.svelte-BHM2cdfQ.js +0 -119
  973. package/build/server/chunks/_page.svelte-BHM2cdfQ.js.map +0 -1
  974. package/build/server/chunks/_page.svelte-BIABhE1J.js +0 -329
  975. package/build/server/chunks/_page.svelte-BIABhE1J.js.map +0 -1
  976. package/build/server/chunks/_page.svelte-BKk3pcBL.js +0 -546
  977. package/build/server/chunks/_page.svelte-BKk3pcBL.js.map +0 -1
  978. package/build/server/chunks/_page.svelte-BS4E9SvL.js +0 -10510
  979. package/build/server/chunks/_page.svelte-BS4E9SvL.js.map +0 -1
  980. package/build/server/chunks/_page.svelte-BYPZuYIR.js +0 -276
  981. package/build/server/chunks/_page.svelte-BYPZuYIR.js.map +0 -1
  982. package/build/server/chunks/_page.svelte-Big1I6tL.js +0 -274
  983. package/build/server/chunks/_page.svelte-Big1I6tL.js.map +0 -1
  984. package/build/server/chunks/_page.svelte-BjX7K7cb.js +0 -249
  985. package/build/server/chunks/_page.svelte-BjX7K7cb.js.map +0 -1
  986. package/build/server/chunks/_page.svelte-Bqwz1thf.js +0 -146
  987. package/build/server/chunks/_page.svelte-Bqwz1thf.js.map +0 -1
  988. package/build/server/chunks/_page.svelte-CEhO1-1V.js +0 -452
  989. package/build/server/chunks/_page.svelte-CEhO1-1V.js.map +0 -1
  990. package/build/server/chunks/_page.svelte-C_Jgsry_.js +0 -500
  991. package/build/server/chunks/_page.svelte-C_Jgsry_.js.map +0 -1
  992. package/build/server/chunks/_page.svelte-Cx28CapC.js +0 -3847
  993. package/build/server/chunks/_page.svelte-Cx28CapC.js.map +0 -1
  994. package/build/server/chunks/_page.svelte-D9-g6SJP.js +0 -168
  995. package/build/server/chunks/_page.svelte-D9-g6SJP.js.map +0 -1
  996. package/build/server/chunks/_page.svelte-DIn0gOqM.js +0 -609
  997. package/build/server/chunks/_page.svelte-DIn0gOqM.js.map +0 -1
  998. package/build/server/chunks/_page.svelte-DKPG7AbM.js +0 -113
  999. package/build/server/chunks/_page.svelte-DKPG7AbM.js.map +0 -1
  1000. package/build/server/chunks/_page.svelte-DU9OiqeO.js +0 -423
  1001. package/build/server/chunks/_page.svelte-DU9OiqeO.js.map +0 -1
  1002. package/build/server/chunks/_page.svelte-DUFBSMDt.js +0 -557
  1003. package/build/server/chunks/_page.svelte-DUFBSMDt.js.map +0 -1
  1004. package/build/server/chunks/_page.svelte-DcbxsxZM.js +0 -330
  1005. package/build/server/chunks/_page.svelte-DcbxsxZM.js.map +0 -1
  1006. package/build/server/chunks/_page.svelte-DtVw2EYT.js +0 -56
  1007. package/build/server/chunks/_page.svelte-DtVw2EYT.js.map +0 -1
  1008. package/build/server/chunks/_page.svelte-DyTTCbrh.js +0 -83
  1009. package/build/server/chunks/_page.svelte-DyTTCbrh.js.map +0 -1
  1010. package/build/server/chunks/_page.svelte-jwU-46Sj.js +0 -301
  1011. package/build/server/chunks/_page.svelte-jwU-46Sj.js.map +0 -1
  1012. package/build/server/chunks/_page.svelte-tP-wCOII.js +0 -714
  1013. package/build/server/chunks/_page.svelte-tP-wCOII.js.map +0 -1
  1014. package/build/server/chunks/_server.ts-B22_T7V_.js +0 -36
  1015. package/build/server/chunks/_server.ts-B22_T7V_.js.map +0 -1
  1016. package/build/server/chunks/_server.ts-BDlLVhr0.js +0 -76
  1017. package/build/server/chunks/_server.ts-BDlLVhr0.js.map +0 -1
  1018. package/build/server/chunks/_server.ts-BGuNdvh3.js +0 -85
  1019. package/build/server/chunks/_server.ts-BGuNdvh3.js.map +0 -1
  1020. package/build/server/chunks/_server.ts-BKMhht9X.js +0 -31
  1021. package/build/server/chunks/_server.ts-BKMhht9X.js.map +0 -1
  1022. package/build/server/chunks/_server.ts-BLSWyveF.js +0 -38
  1023. package/build/server/chunks/_server.ts-BLSWyveF.js.map +0 -1
  1024. package/build/server/chunks/_server.ts-BW-lT0M3.js +0 -58
  1025. package/build/server/chunks/_server.ts-BW-lT0M3.js.map +0 -1
  1026. package/build/server/chunks/_server.ts-Ba8fgvzw.js +0 -81
  1027. package/build/server/chunks/_server.ts-Ba8fgvzw.js.map +0 -1
  1028. package/build/server/chunks/_server.ts-BmAiI-M6.js +0 -75
  1029. package/build/server/chunks/_server.ts-BmAiI-M6.js.map +0 -1
  1030. package/build/server/chunks/_server.ts-BrIEBX7H.js +0 -86
  1031. package/build/server/chunks/_server.ts-BrIEBX7H.js.map +0 -1
  1032. package/build/server/chunks/_server.ts-BrlTfpwE.js +0 -71
  1033. package/build/server/chunks/_server.ts-BrlTfpwE.js.map +0 -1
  1034. package/build/server/chunks/_server.ts-C0-8Ghjh.js +0 -81
  1035. package/build/server/chunks/_server.ts-C0-8Ghjh.js.map +0 -1
  1036. package/build/server/chunks/_server.ts-C1KGgrcN.js +0 -38
  1037. package/build/server/chunks/_server.ts-C1KGgrcN.js.map +0 -1
  1038. package/build/server/chunks/_server.ts-CM1ulGpl.js +0 -94
  1039. package/build/server/chunks/_server.ts-CM1ulGpl.js.map +0 -1
  1040. package/build/server/chunks/_server.ts-CZHS4EZU.js +0 -35
  1041. package/build/server/chunks/_server.ts-CZHS4EZU.js.map +0 -1
  1042. package/build/server/chunks/_server.ts-Cc1sYV4N.js +0 -73
  1043. package/build/server/chunks/_server.ts-Cc1sYV4N.js.map +0 -1
  1044. package/build/server/chunks/_server.ts-ChAgra2R.js +0 -103
  1045. package/build/server/chunks/_server.ts-ChAgra2R.js.map +0 -1
  1046. package/build/server/chunks/_server.ts-CiS1dBE4.js +0 -110
  1047. package/build/server/chunks/_server.ts-CiS1dBE4.js.map +0 -1
  1048. package/build/server/chunks/_server.ts-Co2Yjt2k.js +0 -408
  1049. package/build/server/chunks/_server.ts-Co2Yjt2k.js.map +0 -1
  1050. package/build/server/chunks/_server.ts-CpyLZir2.js +0 -106
  1051. package/build/server/chunks/_server.ts-CpyLZir2.js.map +0 -1
  1052. package/build/server/chunks/_server.ts-CuIFnCAh.js +0 -31
  1053. package/build/server/chunks/_server.ts-CuIFnCAh.js.map +0 -1
  1054. package/build/server/chunks/_server.ts-CzolkXdt.js +0 -49
  1055. package/build/server/chunks/_server.ts-CzolkXdt.js.map +0 -1
  1056. package/build/server/chunks/_server.ts-D1D_prNC.js +0 -52
  1057. package/build/server/chunks/_server.ts-D1D_prNC.js.map +0 -1
  1058. package/build/server/chunks/_server.ts-DAmmd8N5.js +0 -29
  1059. package/build/server/chunks/_server.ts-DAmmd8N5.js.map +0 -1
  1060. package/build/server/chunks/_server.ts-DEeyDsgj.js +0 -70
  1061. package/build/server/chunks/_server.ts-DEeyDsgj.js.map +0 -1
  1062. package/build/server/chunks/_server.ts-DOEzw2-7.js +0 -94
  1063. package/build/server/chunks/_server.ts-DOEzw2-7.js.map +0 -1
  1064. package/build/server/chunks/_server.ts-DOqfhUd4.js +0 -33
  1065. package/build/server/chunks/_server.ts-DOqfhUd4.js.map +0 -1
  1066. package/build/server/chunks/_server.ts-DZngf68M.js +0 -39
  1067. package/build/server/chunks/_server.ts-DZngf68M.js.map +0 -1
  1068. package/build/server/chunks/_server.ts-D_cDSuDn.js +0 -37
  1069. package/build/server/chunks/_server.ts-D_cDSuDn.js.map +0 -1
  1070. package/build/server/chunks/_server.ts-Dev4bRG7.js +0 -37
  1071. package/build/server/chunks/_server.ts-Dev4bRG7.js.map +0 -1
  1072. package/build/server/chunks/_server.ts-DiADR0vf.js +0 -41
  1073. package/build/server/chunks/_server.ts-DiADR0vf.js.map +0 -1
  1074. package/build/server/chunks/_server.ts-DmTvYkS6.js +0 -48
  1075. package/build/server/chunks/_server.ts-DmTvYkS6.js.map +0 -1
  1076. package/build/server/chunks/_server.ts-DtqNIvuj.js +0 -30
  1077. package/build/server/chunks/_server.ts-DtqNIvuj.js.map +0 -1
  1078. package/build/server/chunks/_server.ts-PC1ANpTi.js +0 -293
  1079. package/build/server/chunks/_server.ts-PC1ANpTi.js.map +0 -1
  1080. package/build/server/chunks/_server.ts-VVJtskXo.js +0 -64
  1081. package/build/server/chunks/_server.ts-VVJtskXo.js.map +0 -1
  1082. package/build/server/chunks/_server.ts-mpVOvyBh.js +0 -42
  1083. package/build/server/chunks/_server.ts-mpVOvyBh.js.map +0 -1
  1084. package/build/server/chunks/_server.ts-rck08O_p.js +0 -78
  1085. package/build/server/chunks/_server.ts-rck08O_p.js.map +0 -1
  1086. package/build/server/chunks/_server.ts-sBiGcMzk.js +0 -39
  1087. package/build/server/chunks/_server.ts-sBiGcMzk.js.map +0 -1
  1088. package/build/server/chunks/_server.ts-uudU-YvI.js +0 -61
  1089. package/build/server/chunks/_server.ts-uudU-YvI.js.map +0 -1
  1090. package/build/server/chunks/access.server-BPceukOr.js +0 -411
  1091. package/build/server/chunks/access.server-BPceukOr.js.map +0 -1
  1092. package/build/server/chunks/activity-Dmfe6yjx.js +0 -18
  1093. package/build/server/chunks/activity-Dmfe6yjx.js.map +0 -1
  1094. package/build/server/chunks/alert-description-BNqu-OG5.js +0 -59
  1095. package/build/server/chunks/alert-description-BNqu-OG5.js.map +0 -1
  1096. package/build/server/chunks/api-errors-KUItADEX.js +0 -36
  1097. package/build/server/chunks/api-errors-KUItADEX.js.map +0 -1
  1098. package/build/server/chunks/arrow-left-KOVWDB5k.js +0 -14
  1099. package/build/server/chunks/arrow-left-KOVWDB5k.js.map +0 -1
  1100. package/build/server/chunks/arrow-right-D0bOY6-5.js +0 -14
  1101. package/build/server/chunks/arrow-right-D0bOY6-5.js.map +0 -1
  1102. package/build/server/chunks/auth-bootstrap.server-C1OnV0V5.js +0 -98
  1103. package/build/server/chunks/auth-bootstrap.server-C1OnV0V5.js.map +0 -1
  1104. package/build/server/chunks/badge-DIEbxzcl.js +0 -50
  1105. package/build/server/chunks/badge-DIEbxzcl.js.map +0 -1
  1106. package/build/server/chunks/bootHealth.server-DzX0P_m2.js +0 -58
  1107. package/build/server/chunks/bootHealth.server-DzX0P_m2.js.map +0 -1
  1108. package/build/server/chunks/building-2-DFvNRZpq.js +0 -22
  1109. package/build/server/chunks/building-2-DFvNRZpq.js.map +0 -1
  1110. package/build/server/chunks/button-DPLE4Wc8.js +0 -73
  1111. package/build/server/chunks/button-DPLE4Wc8.js.map +0 -1
  1112. package/build/server/chunks/card-content-BlxX1RCO.js +0 -46
  1113. package/build/server/chunks/card-content-BlxX1RCO.js.map +0 -1
  1114. package/build/server/chunks/card-description-Z3TpzjmK.js +0 -26
  1115. package/build/server/chunks/card-description-Z3TpzjmK.js.map +0 -1
  1116. package/build/server/chunks/card-title-CdR5nQ-b.js +0 -46
  1117. package/build/server/chunks/card-title-CdR5nQ-b.js.map +0 -1
  1118. package/build/server/chunks/check-382jBCB9.js +0 -11
  1119. package/build/server/chunks/check-382jBCB9.js.map +0 -1
  1120. package/build/server/chunks/chevron-down-D5-hWbt-.js +0 -11
  1121. package/build/server/chunks/chevron-down-D5-hWbt-.js.map +0 -1
  1122. package/build/server/chunks/chevron-right-BqxmmxHL.js +0 -11
  1123. package/build/server/chunks/chevron-right-BqxmmxHL.js.map +0 -1
  1124. package/build/server/chunks/chevron-up-StZ3cnZ8.js +0 -11
  1125. package/build/server/chunks/chevron-up-StZ3cnZ8.js.map +0 -1
  1126. package/build/server/chunks/circle-DgRVKHBX.js +0 -11
  1127. package/build/server/chunks/circle-DgRVKHBX.js.map +0 -1
  1128. package/build/server/chunks/circle-alert-DVGjYRbM.js +0 -18
  1129. package/build/server/chunks/circle-alert-DVGjYRbM.js.map +0 -1
  1130. package/build/server/chunks/context-WcuX1UXU.js +0 -134
  1131. package/build/server/chunks/context-WcuX1UXU.js.map +0 -1
  1132. package/build/server/chunks/copy-ifB2TUP_.js +0 -29
  1133. package/build/server/chunks/copy-ifB2TUP_.js.map +0 -1
  1134. package/build/server/chunks/folder-kanban-pqeOGmPr.js +0 -21
  1135. package/build/server/chunks/folder-kanban-pqeOGmPr.js.map +0 -1
  1136. package/build/server/chunks/folder-open-Cs60gLjJ.js +0 -18
  1137. package/build/server/chunks/folder-open-Cs60gLjJ.js.map +0 -1
  1138. package/build/server/chunks/folders-u0VAZ6yv.js +0 -24
  1139. package/build/server/chunks/folders-u0VAZ6yv.js.map +0 -1
  1140. package/build/server/chunks/footerContext.svelte-CJMFkrzZ.js +0 -523
  1141. package/build/server/chunks/footerContext.svelte-CJMFkrzZ.js.map +0 -1
  1142. package/build/server/chunks/hooks.server-ChS4bxJn.js +0 -218
  1143. package/build/server/chunks/hooks.server-ChS4bxJn.js.map +0 -1
  1144. package/build/server/chunks/index2-CJwvvJu6.js +0 -4379
  1145. package/build/server/chunks/index2-CJwvvJu6.js.map +0 -1
  1146. package/build/server/chunks/index3-CNrCbgC4.js +0 -541
  1147. package/build/server/chunks/index3-CNrCbgC4.js.map +0 -1
  1148. package/build/server/chunks/input-BEmCftCF.js +0 -53
  1149. package/build/server/chunks/input-BEmCftCF.js.map +0 -1
  1150. package/build/server/chunks/label-D8oB1018.js +0 -112
  1151. package/build/server/chunks/label-D8oB1018.js.map +0 -1
  1152. package/build/server/chunks/link-2-D3b2vEpL.js +0 -15
  1153. package/build/server/chunks/link-2-D3b2vEpL.js.map +0 -1
  1154. package/build/server/chunks/mail-DZDbJkFt.js +0 -17
  1155. package/build/server/chunks/mail-DZDbJkFt.js.map +0 -1
  1156. package/build/server/chunks/permissions-compat.server-CAfCu77g.js +0 -19
  1157. package/build/server/chunks/permissions-compat.server-CAfCu77g.js.map +0 -1
  1158. package/build/server/chunks/permissions.server-Ba-N3_W5.js +0 -8
  1159. package/build/server/chunks/permissions.server-Ba-N3_W5.js.map +0 -1
  1160. package/build/server/chunks/plus-j_UY0EeU.js +0 -11
  1161. package/build/server/chunks/plus-j_UY0EeU.js.map +0 -1
  1162. package/build/server/chunks/providers.server-DOymvucH.js +0 -4537
  1163. package/build/server/chunks/providers.server-DOymvucH.js.map +0 -1
  1164. package/build/server/chunks/resolve.server-fKH_sqyC.js +0 -11
  1165. package/build/server/chunks/resolve.server-fKH_sqyC.js.map +0 -1
  1166. package/build/server/chunks/resolve.server2-BnfeaGcZ.js +0 -50
  1167. package/build/server/chunks/resolve.server2-BnfeaGcZ.js.map +0 -1
  1168. package/build/server/chunks/rotate-ccw-DChq5zhW.js +0 -17
  1169. package/build/server/chunks/rotate-ccw-DChq5zhW.js.map +0 -1
  1170. package/build/server/chunks/scroll-text-Bi9gx_V4.js +0 -21
  1171. package/build/server/chunks/scroll-text-Bi9gx_V4.js.map +0 -1
  1172. package/build/server/chunks/server-LxtlHpuz.js +0 -36
  1173. package/build/server/chunks/server-LxtlHpuz.js.map +0 -1
  1174. package/build/server/chunks/settings-Cr5mYyBS.js +0 -19
  1175. package/build/server/chunks/settings-Cr5mYyBS.js.map +0 -1
  1176. package/build/server/chunks/shield-BSf8CVMT.js +0 -18
  1177. package/build/server/chunks/shield-BSf8CVMT.js.map +0 -1
  1178. package/build/server/chunks/shield-check-OpZRvDHN.js +0 -19
  1179. package/build/server/chunks/shield-check-OpZRvDHN.js.map +0 -1
  1180. package/build/server/chunks/star-KGWYAeYA.js +0 -18
  1181. package/build/server/chunks/star-KGWYAeYA.js.map +0 -1
  1182. package/build/server/chunks/textarea-CzRER9c0.js +0 -685
  1183. package/build/server/chunks/textarea-CzRER9c0.js.map +0 -1
  1184. package/build/server/chunks/trash-2-DmuR9br3.js +0 -17
  1185. package/build/server/chunks/trash-2-DmuR9br3.js.map +0 -1
  1186. package/build/server/chunks/triangle-alert-CuX-M239.js +0 -444
  1187. package/build/server/chunks/triangle-alert-CuX-M239.js.map +0 -1
  1188. package/build/server/chunks/upload-Dc1WcTjY.js +0 -62
  1189. package/build/server/chunks/upload-Dc1WcTjY.js.map +0 -1
  1190. package/build/server/chunks/user-plus-Jn4Z4v9g.js +0 -16
  1191. package/build/server/chunks/user-plus-Jn4Z4v9g.js.map +0 -1
  1192. package/build/server/chunks/users-BgwwwoIh.js +0 -16
  1193. package/build/server/chunks/users-BgwwwoIh.js.map +0 -1
  1194. package/build/server/chunks/utils2-BF28g2lj.js +0 -56
  1195. package/build/server/chunks/utils2-BF28g2lj.js.map +0 -1
  1196. package/build/server/chunks/utils3-Dv2HSd2-.js +0 -80
  1197. package/build/server/chunks/utils3-Dv2HSd2-.js.map +0 -1
  1198. package/build/server/chunks/x-B1q8Cpoy.js +0 -14
  1199. package/build/server/chunks/x-B1q8Cpoy.js.map +0 -1
@@ -1,4537 +0,0 @@
1
- import { p as private_env } from './shared-server-C3WdcJCQ.js';
2
- import { pathToFileURL } from 'node:url';
3
- import * as path from 'node:path';
4
- import { resolve } from 'node:path';
5
- import { existsSync } from 'node:fs';
6
- import { D as DEFAULT_ORG_PERMISSIONS, S as SYSTEM_CONTEXT, j as hasPermission, P as PlatformPermissionSchema } from './context-WcuX1UXU.js';
7
- import * as crypto from 'node:crypto';
8
- import { createDecipheriv, randomBytes, createCipheriv, randomUUID, createHmac, timingSafeEqual } from 'node:crypto';
9
- import * as fs from 'node:fs/promises';
10
- import { createClient } from '@supabase/supabase-js';
11
-
12
- function assertSafeKey(value, label) {
13
- if (!value || !/^[A-Za-z0-9._-]+$/.test(value) || value === "." || value === "..") {
14
- throw new Error(`Unsafe ${label}: ${JSON.stringify(value)}`);
15
- }
16
- }
17
- const definitionPaths = {
18
- version: (guid, versionNumber, ext) => {
19
- assertSafeKey(guid, "guid");
20
- if (!Number.isInteger(versionNumber) || versionNumber < 1) {
21
- throw new Error(`Unsafe versionNumber: ${versionNumber}`);
22
- }
23
- return `definitions/${guid}/versions/v${versionNumber}.${ext}`;
24
- },
25
- image: (guid) => {
26
- assertSafeKey(guid, "guid");
27
- return `definitions/${guid}/cover.webp`;
28
- },
29
- prefix: (guid) => {
30
- assertSafeKey(guid, "guid");
31
- return `definitions/${guid}/`;
32
- }
33
- };
34
- const IMAGE_MAX_WIDTH = 1200;
35
- const IMAGE_WEBP_QUALITY = 85;
36
- function isImageUpload(contentType, storagePath) {
37
- if (contentType?.startsWith("image/"))
38
- return true;
39
- return /\.(webp|png|jpe?g|gif|bmp|tif?f)$/i.test(storagePath);
40
- }
41
- function toWebpPath(storagePath) {
42
- return storagePath.replace(/\.(png|jpe?g|gif|bmp|tif?f)$/i, ".webp");
43
- }
44
- async function transcodeImageIfNeeded(data, contentType, storagePath) {
45
- if (!isImageUpload(contentType, storagePath)) {
46
- return { data, contentType: contentType ?? "application/octet-stream", path: storagePath };
47
- }
48
- const sharp = await loadSharp();
49
- const compressed = await sharp(Buffer.from(data)).resize({ width: IMAGE_MAX_WIDTH, withoutEnlargement: true }).webp({ quality: IMAGE_WEBP_QUALITY }).toBuffer();
50
- return {
51
- data: new Uint8Array(compressed),
52
- contentType: "image/webp",
53
- path: toWebpPath(storagePath)
54
- };
55
- }
56
- let cachedSharp = null;
57
- async function loadSharp() {
58
- if (cachedSharp)
59
- return cachedSharp;
60
- try {
61
- const mod = await import('sharp');
62
- cachedSharp = mod.default ?? mod;
63
- return cachedSharp;
64
- } catch (err) {
65
- throw new Error("Image transcoding requires `sharp` to be installed. Add it as a dependency in your provider package.", { cause: err });
66
- }
67
- }
68
- function isPlatformServer(s) {
69
- return s.scope === "platform";
70
- }
71
- function isOrgServer(s) {
72
- return s.scope === "org";
73
- }
74
- function actorFrom(ctx) {
75
- return ctx.userId || "system";
76
- }
77
- class NoopEventSink {
78
- async emit(_event) {
79
- }
80
- }
81
- const nowIso = () => (/* @__PURE__ */ new Date()).toISOString();
82
- function auditUpdate(ctx, fallbackActor) {
83
- return {
84
- updatedAt: nowIso(),
85
- updatedBy: ctx.userId || fallbackActor || ""
86
- };
87
- }
88
- function auditSoftDelete(ctx, fallbackActor) {
89
- const now = nowIso();
90
- return {
91
- deletedAt: now,
92
- updatedAt: now,
93
- updatedBy: ctx.userId || fallbackActor || ""
94
- };
95
- }
96
- const DEFAULT_PAGE_LIMIT = 50;
97
- const MAX_PAGE_LIMIT = 200;
98
- function isFlagEnabled(config, flag2) {
99
- return Boolean(config.flags?.[flag2]);
100
- }
101
- function defineConfig(config) {
102
- return config;
103
- }
104
- class ProviderError extends Error {
105
- statusCode;
106
- constructor(message, statusCode = 400) {
107
- super(message);
108
- this.name = "ProviderError";
109
- this.statusCode = statusCode;
110
- }
111
- }
112
- const DEFAULT_MAX_AGE_MS = 8 * 60 * 60 * 1e3;
113
- function signHmacToken(secret, userId, maxAgeMs = DEFAULT_MAX_AGE_MS) {
114
- const expiry = Date.now() + maxAgeMs;
115
- const payload = Buffer.from(`${userId}:${expiry}`).toString("base64url");
116
- const sig = createHmac("sha256", secret).update(payload).digest("base64url");
117
- return `${payload}.${sig}`;
118
- }
119
- function verifyHmacToken(token, secret) {
120
- const dot = token.lastIndexOf(".");
121
- if (dot === -1)
122
- return { userId: "", valid: false };
123
- const payload = token.slice(0, dot);
124
- const sig = token.slice(dot + 1);
125
- const expectedSig = createHmac("sha256", secret).update(payload).digest("base64url");
126
- const a = Buffer.from(sig);
127
- const b = Buffer.from(expectedSig);
128
- if (a.length !== b.length || !timingSafeEqual(a, b))
129
- return { userId: "", valid: false };
130
- const decoded = Buffer.from(payload, "base64url").toString();
131
- const colon = decoded.lastIndexOf(":");
132
- if (colon === -1)
133
- return { userId: "", valid: false };
134
- const userId = decoded.slice(0, colon);
135
- const expiry = parseInt(decoded.slice(colon + 1), 10);
136
- if (!Number.isFinite(expiry) || Date.now() >= expiry)
137
- return { userId: "", valid: false };
138
- return { userId, valid: true };
139
- }
140
- async function readJsonFile(filePath, fallback) {
141
- try {
142
- const raw = await fs.readFile(filePath, "utf-8");
143
- return JSON.parse(raw);
144
- } catch (err) {
145
- if (err.code === "ENOENT")
146
- return fallback;
147
- throw err;
148
- }
149
- }
150
- async function writeJsonFile(filePath, data) {
151
- await fs.mkdir(path.dirname(filePath), { recursive: true });
152
- const tmp = `${filePath}.tmp`;
153
- await fs.writeFile(tmp, JSON.stringify(data, null, " "), "utf-8");
154
- await fs.rename(tmp, filePath);
155
- }
156
- const LAST_LOGIN_DEBOUNCE_MS$1 = 6e4;
157
- const PBKDF2_ITERATIONS = 1e5;
158
- const PBKDF2_KEYLEN = 32;
159
- const PBKDF2_DIGEST = "sha256";
160
- async function hashPassword(password) {
161
- const salt = crypto.randomBytes(16).toString("base64url");
162
- const hash = await new Promise((resolve2, reject) => crypto.pbkdf2(password, salt, PBKDF2_ITERATIONS, PBKDF2_KEYLEN, PBKDF2_DIGEST, (err, key) => err ? reject(err) : resolve2(key)));
163
- return `pbkdf2:${PBKDF2_DIGEST}:${PBKDF2_ITERATIONS}:${salt}:${hash.toString("base64url")}`;
164
- }
165
- async function verifyPasswordHash(password, storedHash) {
166
- const parts = storedHash.split(":");
167
- if (parts.length !== 5 || parts[0] !== "pbkdf2")
168
- return false;
169
- const [, digest, iterStr, salt, expectedHashB64] = parts;
170
- const iterations = parseInt(iterStr, 10);
171
- if (!Number.isFinite(iterations) || iterations <= 0)
172
- return false;
173
- const expected = Buffer.from(expectedHashB64, "base64url");
174
- const actual = await new Promise((resolve2, reject) => crypto.pbkdf2(password, salt, iterations, PBKDF2_KEYLEN, digest, (err, key) => err ? reject(err) : resolve2(key)));
175
- if (actual.length !== expected.length)
176
- return false;
177
- return crypto.timingSafeEqual(actual, expected);
178
- }
179
- const empty$5 = () => ({ users: [] });
180
- function createLocalAuthUserStore(usersFilePath) {
181
- return {
182
- async findByEmail(email) {
183
- const { users } = await readJsonFile(usersFilePath, empty$5());
184
- return users.find((u) => u.email.toLowerCase() === email.toLowerCase()) ?? null;
185
- },
186
- async findById(id) {
187
- const { users } = await readJsonFile(usersFilePath, empty$5());
188
- return users.find((u) => u.id === id) ?? null;
189
- },
190
- async listUsers() {
191
- const { users } = await readJsonFile(usersFilePath, empty$5());
192
- return users.map(({ passwordHash: _ph, ...rest }) => rest);
193
- },
194
- async createUser(email, password) {
195
- const file = await readJsonFile(usersFilePath, empty$5());
196
- if (file.users.some((u) => u.email.toLowerCase() === email.toLowerCase())) {
197
- throw new ProviderError(`User with email "${email}" already exists`, 409);
198
- }
199
- const user = {
200
- id: randomUUID(),
201
- email,
202
- passwordHash: password !== null ? await hashPassword(password) : null,
203
- createdAt: (/* @__PURE__ */ new Date()).toISOString()
204
- };
205
- file.users.push(user);
206
- await writeJsonFile(usersFilePath, file);
207
- return user;
208
- },
209
- async setDisabled(id, disabled) {
210
- const file = await readJsonFile(usersFilePath, empty$5());
211
- const user = file.users.find((u) => u.id === id);
212
- if (!user)
213
- throw new ProviderError(`User "${id}" not found`, 404);
214
- user.disabled = disabled;
215
- await writeJsonFile(usersFilePath, file);
216
- },
217
- async touchLastLogin(id) {
218
- const file = await readJsonFile(usersFilePath, empty$5());
219
- const user = file.users.find((u) => u.id === id);
220
- if (!user)
221
- return;
222
- const now = Date.now();
223
- if (user.lastLoginAt) {
224
- const prev = Date.parse(user.lastLoginAt);
225
- if (Number.isFinite(prev) && now - prev < LAST_LOGIN_DEBOUNCE_MS$1)
226
- return;
227
- }
228
- user.lastLoginAt = new Date(now).toISOString();
229
- await writeJsonFile(usersFilePath, file);
230
- },
231
- async deleteUser(id) {
232
- const file = await readJsonFile(usersFilePath, empty$5());
233
- const before = file.users.length;
234
- file.users = file.users.filter((u) => u.id !== id);
235
- if (file.users.length === before)
236
- throw new ProviderError(`User "${id}" not found`, 404);
237
- await writeJsonFile(usersFilePath, file);
238
- }
239
- };
240
- }
241
- function paginate(items, opts) {
242
- const limit = Math.min(Math.max(1, opts?.limit ?? DEFAULT_PAGE_LIMIT), MAX_PAGE_LIMIT);
243
- const offset = opts?.cursor ? parseInt(opts.cursor, 10) || 0 : 0;
244
- const slice = items.slice(offset, offset + limit);
245
- const nextOffset = offset + slice.length;
246
- return {
247
- items: slice,
248
- nextCursor: nextOffset < items.length ? String(nextOffset) : void 0
249
- };
250
- }
251
- function applyOrder(items, opts, keyFn = (item, field) => item[field]) {
252
- const field = opts?.orderBy ?? "createdAt";
253
- const dir = opts?.orderDir ?? "desc";
254
- const mul = dir === "asc" ? 1 : -1;
255
- items.sort((a, b) => {
256
- const av = keyFn(a, field) ?? "";
257
- const bv = keyFn(b, field) ?? "";
258
- if (av < bv)
259
- return -1 * mul;
260
- if (av > bv)
261
- return 1 * mul;
262
- return 0;
263
- });
264
- return items;
265
- }
266
- const SESSION_MAX_AGE_MS = 8 * 60 * 60 * 1e3;
267
- function toAuthUser$1(u) {
268
- return {
269
- id: u.id,
270
- email: u.email,
271
- createdAt: u.createdAt,
272
- lastLoginAt: u.lastLoginAt,
273
- disabled: u.disabled
274
- };
275
- }
276
- class LocalPasswordAuth {
277
- users;
278
- mintToken;
279
- constructor(users, mintToken) {
280
- this.users = users;
281
- this.mintToken = mintToken;
282
- }
283
- async verifyLogin(email, password) {
284
- if (!this.users)
285
- return { kind: "failed", reason: "invalid_credentials" };
286
- const user = await this.users.findByEmail(email);
287
- if (!user)
288
- return { kind: "failed", reason: "invalid_credentials" };
289
- if (user.disabled)
290
- return { kind: "failed", reason: "disabled" };
291
- if (!user.passwordHash || !await verifyPasswordHash(password, user.passwordHash)) {
292
- return { kind: "failed", reason: "invalid_credentials" };
293
- }
294
- await this.users.touchLastLogin(user.id).catch(() => {
295
- });
296
- const auth = toAuthUser$1(user);
297
- return { kind: "success", user: auth, sessionToken: this.mintToken(auth) };
298
- }
299
- async createUserWithPassword(email, password) {
300
- if (!this.users) {
301
- throw new ProviderError("createUserWithPassword requires a users.json backend (DATA_PATH)", 500);
302
- }
303
- return toAuthUser$1(await this.users.createUser(email, password));
304
- }
305
- async registerUser(email, password) {
306
- if (!this.users)
307
- return null;
308
- return toAuthUser$1(await this.users.createUser(email, password));
309
- }
310
- }
311
- class LocalAuthProvider {
312
- hmacSecret;
313
- users;
314
- name = "Local";
315
- passwordAuth;
316
- constructor(config) {
317
- this.hmacSecret = config.hmacSecret;
318
- if (config.usersFilePath) {
319
- this.users = createLocalAuthUserStore(config.usersFilePath);
320
- }
321
- this.passwordAuth = new LocalPasswordAuth(this.users, (user) => signHmacToken(this.hmacSecret, user.id, SESSION_MAX_AGE_MS));
322
- }
323
- static fromEnv(env) {
324
- const hmacSecret = env.SELVA_HMAC_KEY;
325
- if (!hmacSecret)
326
- throw new Error("Missing required env var: SELVA_HMAC_KEY");
327
- return new LocalAuthProvider({
328
- hmacSecret,
329
- usersFilePath: env.DATA_PATH ? path.join(env.DATA_PATH, "auth-users.json") : void 0
330
- });
331
- }
332
- /** Verify an HMAC session token and return the live user record. */
333
- async verifyToken(token) {
334
- const { valid, userId } = verifyHmacToken(token, this.hmacSecret);
335
- if (!valid)
336
- return null;
337
- if (!this.users)
338
- return null;
339
- const u = await this.users.findById(userId);
340
- if (!u || u.disabled)
341
- return null;
342
- await this.users.touchLastLogin(u.id).catch(() => {
343
- });
344
- return toAuthUser$1(u);
345
- }
346
- async touchLastLogin(id) {
347
- if (!this.users)
348
- return;
349
- await this.users.touchLastLogin(id);
350
- }
351
- async getUser(id) {
352
- if (!this.users)
353
- return null;
354
- const u = await this.users.findById(id);
355
- return u ? toAuthUser$1(u) : null;
356
- }
357
- async listUsers(opts) {
358
- if (!this.users)
359
- return null;
360
- const users = await this.users.listUsers();
361
- return paginate(users.map(toAuthUser$1), opts);
362
- }
363
- async deleteUser(id) {
364
- if (!this.users)
365
- return "not_supported";
366
- const target = await this.users.findById(id);
367
- if (!target)
368
- return "not_found";
369
- try {
370
- await this.users.deleteUser(id);
371
- return "ok";
372
- } catch (err) {
373
- if (err instanceof ProviderError && err.statusCode === 404)
374
- return "not_found";
375
- throw err;
376
- }
377
- }
378
- async disableUser(id) {
379
- if (!this.users)
380
- return "not_supported";
381
- const target = await this.users.findById(id);
382
- if (!target)
383
- return "not_found";
384
- try {
385
- await this.users.setDisabled(id, true);
386
- return "ok";
387
- } catch (err) {
388
- if (err instanceof ProviderError && err.statusCode === 404)
389
- return "not_found";
390
- throw err;
391
- }
392
- }
393
- }
394
- const EMPTY$1 = { invites: [] };
395
- class LocalInviteStore {
396
- events;
397
- filePath;
398
- static fromEnv(env, events = new NoopEventSink()) {
399
- if (!env.DATA_PATH)
400
- throw new Error("Missing required env var: DATA_PATH");
401
- return new LocalInviteStore(env.DATA_PATH, events);
402
- }
403
- constructor(dataPath, events = new NoopEventSink()) {
404
- this.events = events;
405
- this.filePath = path.join(dataPath, "invites.json");
406
- }
407
- async load() {
408
- return readJsonFile(this.filePath, EMPTY$1);
409
- }
410
- async save(file) {
411
- await writeJsonFile(this.filePath, file);
412
- }
413
- async create(ctx, invite) {
414
- const file = await this.load();
415
- file.invites.push(invite);
416
- await this.save(file);
417
- await this.events.emit({
418
- type: "invite.created",
419
- inviteId: invite.id,
420
- orgId: invite.orgId,
421
- email: invite.email,
422
- actorId: actorFrom(ctx)
423
- });
424
- }
425
- async getByTokenHash(_ctx, tokenHash) {
426
- const { invites } = await this.load();
427
- const invite = invites.find((i) => i.tokenHash === tokenHash);
428
- if (!invite)
429
- return null;
430
- if (invite.acceptedAt)
431
- return null;
432
- if (Date.parse(invite.expiresAt) <= Date.now())
433
- return null;
434
- return invite;
435
- }
436
- async listByOrg(_ctx, orgId, opts) {
437
- const { invites } = await this.load();
438
- const filtered = invites.filter((i) => i.orgId === orgId);
439
- return paginate(applyOrder(filtered, opts), opts);
440
- }
441
- async markAccepted(ctx, id, userId) {
442
- const file = await this.load();
443
- const invite = file.invites.find((i) => i.id === id);
444
- if (!invite || invite.acceptedAt)
445
- return;
446
- invite.acceptedAt = (/* @__PURE__ */ new Date()).toISOString();
447
- invite.acceptedByUserId = userId;
448
- await this.save(file);
449
- await this.events.emit({
450
- type: "invite.accepted",
451
- inviteId: invite.id,
452
- orgId: invite.orgId,
453
- userId,
454
- actorId: actorFrom(ctx)
455
- });
456
- }
457
- async revoke(ctx, id) {
458
- const file = await this.load();
459
- const target = file.invites.find((i) => i.id === id && !i.acceptedAt);
460
- if (!target)
461
- return;
462
- file.invites = file.invites.filter((i) => i.id !== id || i.acceptedAt);
463
- await this.save(file);
464
- await this.events.emit({
465
- type: "invite.revoked",
466
- inviteId: id,
467
- orgId: target.orgId,
468
- actorId: actorFrom(ctx)
469
- });
470
- }
471
- async deleteByOrg(_ctx, orgId) {
472
- const file = await this.load();
473
- const before = file.invites.length;
474
- file.invites = file.invites.filter((i) => i.orgId !== orgId);
475
- if (file.invites.length === before)
476
- return;
477
- await this.save(file);
478
- }
479
- }
480
- const ALGO = "aes-256-gcm";
481
- const IV_BYTES = 12;
482
- const TAG_BYTES = 16;
483
- const PREFIX = "enc:v1:";
484
- function isEncryptedSecret(value) {
485
- return value.startsWith(PREFIX);
486
- }
487
- function encryptSecret(plaintext, key) {
488
- if (key.length !== 32) {
489
- throw new Error(`Secret key must be 32 bytes; got ${key.length}`);
490
- }
491
- if (isEncryptedSecret(plaintext)) {
492
- throw new Error("Refusing to encrypt a value that is already encrypted");
493
- }
494
- const iv = randomBytes(IV_BYTES);
495
- const cipher = createCipheriv(ALGO, key, iv);
496
- const ciphertext = Buffer.concat([cipher.update(plaintext, "utf8"), cipher.final()]);
497
- const tag = cipher.getAuthTag();
498
- return PREFIX + Buffer.concat([iv, tag, ciphertext]).toString("base64");
499
- }
500
- function decryptSecret(envelope, key) {
501
- if (key.length !== 32) {
502
- throw new Error(`Secret key must be 32 bytes; got ${key.length}`);
503
- }
504
- if (!isEncryptedSecret(envelope)) {
505
- throw new Error("Value is not an encrypted secret envelope");
506
- }
507
- const buf = Buffer.from(envelope.slice(PREFIX.length), "base64");
508
- const iv = buf.subarray(0, IV_BYTES);
509
- const tag = buf.subarray(IV_BYTES, IV_BYTES + TAG_BYTES);
510
- const ciphertext = buf.subarray(IV_BYTES + TAG_BYTES);
511
- const decipher = createDecipheriv(ALGO, key, iv);
512
- decipher.setAuthTag(tag);
513
- return Buffer.concat([decipher.update(ciphertext), decipher.final()]).toString("utf8");
514
- }
515
- function decodeSecretKey(raw) {
516
- if (/^[0-9a-fA-F]{64}$/.test(raw))
517
- return Buffer.from(raw, "hex");
518
- const buf = Buffer.from(raw, "base64");
519
- if (buf.length === 32)
520
- return buf;
521
- throw new Error(`SELVA_AT_REST_KEY must be 32 bytes encoded as 64-char hex or base64. Generate one with: node -e "console.log(require('crypto').randomBytes(32).toString('hex'))"`);
522
- }
523
- const EMPTY = { servers: [], orgDefaults: {} };
524
- class LocalComputeServerStore {
525
- configFilePath;
526
- secretKey;
527
- static fromEnv(env) {
528
- if (!env.DATA_PATH)
529
- throw new Error("Missing required env var: DATA_PATH");
530
- if (!env.SELVA_AT_REST_KEY) {
531
- throw new Error(`Missing required env var: SELVA_AT_REST_KEY (32-byte hex or base64). Generate one with: node -e "console.log(require('crypto').randomBytes(32).toString('hex'))"`);
532
- }
533
- return new LocalComputeServerStore(path.join(env.DATA_PATH, "compute.config.json"), decodeSecretKey(env.SELVA_AT_REST_KEY));
534
- }
535
- constructor(configFilePath, secretKey) {
536
- this.configFilePath = configFilePath;
537
- this.secretKey = secretKey;
538
- }
539
- async readAll() {
540
- const raw = await readJsonFile(this.configFilePath, EMPTY);
541
- return {
542
- servers: raw.servers ?? [],
543
- defaultServerId: raw.defaultServerId,
544
- orgDefaults: raw.orgDefaults ?? {}
545
- };
546
- }
547
- /**
548
- * Per-row tolerant decrypt. A row whose ciphertext can't be authenticated
549
- * under the current `SELVA_AT_REST_KEY` is returned with `apiKey: undefined`
550
- * and a warning logged once. The page that loaded the config keeps
551
- * rendering; solves against that server will fail later when Rhino.Compute
552
- * rejects the missing key.
553
- *
554
- * Boot-time `verifySecrets()` is the strict counterpart — call that from
555
- * the app entrypoint to refuse to start when this state is detected.
556
- *
557
- * Plaintext-on-disk is still hard-fail. That state is never produced by
558
- * the store itself (every write goes through `encryptApiKeys`), so seeing
559
- * it means someone hand-edited the file with a real secret in plaintext —
560
- * which is a security issue we should surface loudly, not paper over.
561
- */
562
- decryptApiKeys(servers) {
563
- return servers.map((s) => {
564
- if (!s.apiKey)
565
- return s;
566
- if (!isEncryptedSecret(s.apiKey)) {
567
- throw new Error(`compute.config.json contains an unencrypted apiKey for server "${s.label}" (${s.id}). Re-enter the key via /admin/compute so it is stored encrypted.`);
568
- }
569
- try {
570
- return { ...s, apiKey: decryptSecret(s.apiKey, this.secretKey) };
571
- } catch (cause) {
572
- console.warn(`[selva] Could not decrypt apiKey for compute server "${s.label}" (${s.id}). The stored ciphertext does not match the current SELVA_AT_REST_KEY. This server will be returned without an apiKey; solves against it will fail. Re-enter the key via /admin/compute, or restore the original SELVA_AT_REST_KEY. See docs/Troubleshooting.md.`, cause);
573
- return { ...s, apiKey: void 0 };
574
- }
575
- });
576
- }
577
- /**
578
- * Boot-time integrity check. Reads every server row and attempts to
579
- * decrypt each encrypted `apiKey`. Returns a structured report — does NOT
580
- * throw. The caller decides what to do (refuse boot, log + degrade, etc.).
581
- *
582
- * Use this from app startup (`hooks.server.ts`) so a key mismatch fails
583
- * loudly at deploy time instead of as a blank page when a user first hits
584
- * a route that loads compute config.
585
- */
586
- async verifySecrets() {
587
- const all = await this.readAll();
588
- const failures = [];
589
- let plaintextFound = false;
590
- for (const s of all.servers) {
591
- if (!s.apiKey)
592
- continue;
593
- if (!isEncryptedSecret(s.apiKey)) {
594
- plaintextFound = true;
595
- failures.push({
596
- serverId: s.id,
597
- serverLabel: s.label,
598
- reason: "plaintext_on_disk"
599
- });
600
- continue;
601
- }
602
- try {
603
- decryptSecret(s.apiKey, this.secretKey);
604
- } catch (cause) {
605
- failures.push({
606
- serverId: s.id,
607
- serverLabel: s.label,
608
- reason: "key_mismatch",
609
- cause: cause instanceof Error ? cause.message : String(cause)
610
- });
611
- }
612
- }
613
- return { ok: failures.length === 0, failures, plaintextFound };
614
- }
615
- encryptApiKeys(servers) {
616
- return servers.map((s) => {
617
- if (!s.apiKey)
618
- return s;
619
- if (isEncryptedSecret(s.apiKey))
620
- return s;
621
- return { ...s, apiKey: encryptSecret(s.apiKey, this.secretKey) };
622
- });
623
- }
624
- async getConfig(_ctx) {
625
- const all = await this.readAll();
626
- return {
627
- servers: this.decryptApiKeys(all.servers),
628
- defaultServerId: all.defaultServerId,
629
- orgDefaults: all.orgDefaults
630
- };
631
- }
632
- async savePlatformServers(_ctx, servers, defaultServerId) {
633
- const all = await this.readAll();
634
- const orgRows = all.servers.filter(isOrgServer);
635
- const platformRows = this.encryptApiKeys(servers.filter(isPlatformServer));
636
- await writeJsonFile(this.configFilePath, {
637
- servers: [...platformRows, ...orgRows],
638
- defaultServerId,
639
- orgDefaults: all.orgDefaults
640
- });
641
- }
642
- async saveOrgServers(_ctx, orgId, servers, defaultServerId) {
643
- const all = await this.readAll();
644
- const platformRows = all.servers.filter(isPlatformServer);
645
- const otherOrgRows = all.servers.filter((s) => isOrgServer(s) && s.ownerOrgId !== orgId);
646
- const thisOrgRows = this.encryptApiKeys(servers.filter((_s) => true).map((s) => isOrgServer(s) ? { ...s, ownerOrgId: orgId } : (
647
- // Coerce — caller passed something with the wrong/missing scope.
648
- { ...s, scope: "org", ownerOrgId: orgId }
649
- )));
650
- const orgDefaults = { ...all.orgDefaults ?? {} };
651
- if (defaultServerId === null) {
652
- delete orgDefaults[orgId];
653
- } else if (typeof defaultServerId === "string") {
654
- orgDefaults[orgId] = defaultServerId;
655
- }
656
- await writeJsonFile(this.configFilePath, {
657
- servers: [...platformRows, ...otherOrgRows, ...thisOrgRows],
658
- defaultServerId: all.defaultServerId,
659
- orgDefaults
660
- });
661
- }
662
- async setOrgDefault(_ctx, orgId, serverId) {
663
- const all = await this.readAll();
664
- const orgDefaults = { ...all.orgDefaults ?? {} };
665
- if (serverId === null) {
666
- delete orgDefaults[orgId];
667
- } else {
668
- orgDefaults[orgId] = serverId;
669
- }
670
- await writeJsonFile(this.configFilePath, { ...all, orgDefaults });
671
- }
672
- async deleteByOrg(_ctx, orgId) {
673
- const all = await this.readAll();
674
- const remaining = all.servers.filter((s) => !(isOrgServer(s) && s.ownerOrgId === orgId));
675
- const cleaned = remaining.map((s) => {
676
- if (!isPlatformServer(s))
677
- return s;
678
- if (s.sharedWith === "all")
679
- return s;
680
- if (!s.sharedWith.includes(orgId))
681
- return s;
682
- const next = {
683
- ...s,
684
- sharedWith: s.sharedWith.filter((id) => id !== orgId)
685
- };
686
- return next;
687
- });
688
- const orgDefaults = { ...all.orgDefaults ?? {} };
689
- const hadDefault = orgId in orgDefaults;
690
- delete orgDefaults[orgId];
691
- const changed = cleaned.length !== all.servers.length || hadDefault || cleaned.some((c, i) => c !== all.servers[i]);
692
- if (!changed)
693
- return;
694
- await writeJsonFile(this.configFilePath, {
695
- servers: cleaned,
696
- defaultServerId: all.defaultServerId,
697
- orgDefaults
698
- });
699
- }
700
- }
701
- const empty$4 = () => ({ grants: [] });
702
- class LocalPlatformProjectGrantStore {
703
- filePath;
704
- static fromEnv(env) {
705
- if (!env.DATA_PATH)
706
- throw new Error("Missing required env var: DATA_PATH");
707
- return new LocalPlatformProjectGrantStore(path.join(env.DATA_PATH, "platform-project-grants.json"));
708
- }
709
- constructor(filePath) {
710
- this.filePath = filePath;
711
- }
712
- async read() {
713
- return readJsonFile(this.filePath, empty$4());
714
- }
715
- async write(data) {
716
- await writeJsonFile(this.filePath, data);
717
- }
718
- async listByProject(_ctx, projectId) {
719
- const { grants } = await this.read();
720
- return grants.filter((g) => g.projectId === projectId);
721
- }
722
- async create(_ctx, grant) {
723
- const data = await this.read();
724
- if (data.grants.some((g) => g.id === grant.id)) {
725
- throw new ProviderError(`Grant '${grant.id}' already exists`, 409);
726
- }
727
- const duplicate = data.grants.find((g) => g.projectId === grant.projectId && g.granteeType === grant.granteeType && g.granteeId === grant.granteeId);
728
- if (duplicate) {
729
- throw new ProviderError(`A grant for this ${grant.granteeType} already exists on this project`, 409);
730
- }
731
- data.grants.push(grant);
732
- await this.write(data);
733
- }
734
- async delete(_ctx, id) {
735
- const data = await this.read();
736
- const idx = data.grants.findIndex((g) => g.id === id);
737
- if (idx === -1)
738
- throw new ProviderError(`Grant '${id}' not found`, 404);
739
- data.grants.splice(idx, 1);
740
- await this.write(data);
741
- }
742
- async deleteByProject(_ctx, projectId) {
743
- const data = await this.read();
744
- const before = data.grants.length;
745
- data.grants = data.grants.filter((g) => g.projectId !== projectId);
746
- if (data.grants.length !== before)
747
- await this.write(data);
748
- }
749
- async deleteByGranteeOrg(_ctx, orgId) {
750
- const data = await this.read();
751
- const before = data.grants.length;
752
- data.grants = data.grants.filter((g) => !(g.granteeType === "org" && g.granteeId === orgId));
753
- if (data.grants.length !== before)
754
- await this.write(data);
755
- }
756
- }
757
- function isLive$1(row) {
758
- return row.deletedAt == null;
759
- }
760
- class LocalOrgStoreLoader {
761
- storePath;
762
- store = null;
763
- loading = null;
764
- constructor(dataPath) {
765
- this.storePath = path.join(dataPath, "local-org.json");
766
- }
767
- async get() {
768
- if (this.store)
769
- return this.store;
770
- this.loading ??= readJsonFile(this.storePath, {
771
- orgs: [],
772
- projects: [],
773
- orgMembers: [],
774
- projectMembers: []
775
- }).then((data) => {
776
- this.store = data;
777
- this.loading = null;
778
- return data;
779
- });
780
- return this.loading;
781
- }
782
- async write(store) {
783
- this.store = store;
784
- await writeJsonFile(this.storePath, store);
785
- }
786
- }
787
- class LocalOrgStore {
788
- loader;
789
- events;
790
- invites;
791
- computeServer;
792
- grants;
793
- static fromEnv(env) {
794
- if (!env.DATA_PATH)
795
- throw new Error("Missing required env var: DATA_PATH");
796
- return new LocalOrgStore({
797
- loader: new LocalOrgStoreLoader(env.DATA_PATH),
798
- invites: LocalInviteStore.fromEnv(env),
799
- computeServer: LocalComputeServerStore.fromEnv(env),
800
- grants: LocalPlatformProjectGrantStore.fromEnv(env)
801
- });
802
- }
803
- constructor(opts) {
804
- this.loader = opts.loader;
805
- this.invites = opts.invites;
806
- this.computeServer = opts.computeServer;
807
- this.grants = opts.grants;
808
- this.events = opts.events ?? new NoopEventSink();
809
- }
810
- async listOrgs(_ctx, opts) {
811
- const { orgs } = await this.loader.get();
812
- return paginate(applyOrder(orgs.filter(isLive$1), opts), opts);
813
- }
814
- async getOrg(_ctx, id) {
815
- const { orgs } = await this.loader.get();
816
- const o = orgs.find((o2) => o2.id === id);
817
- return o && isLive$1(o) ? o : null;
818
- }
819
- async getOrgBySlug(_ctx, slug) {
820
- const { orgs } = await this.loader.get();
821
- const o = orgs.find((o2) => o2.slug === slug);
822
- return o && isLive$1(o) ? o : null;
823
- }
824
- async createOrg(ctx, org) {
825
- const store = await this.loader.get();
826
- if (store.orgs.some((o) => o.id === org.id && isLive$1(o))) {
827
- throw new ProviderError(`Org '${org.id}' already exists`, 409);
828
- }
829
- if (store.orgs.some((o) => o.slug === org.slug && isLive$1(o))) {
830
- throw new ProviderError(`Org slug '${org.slug}' already in use`, 409);
831
- }
832
- store.orgs.push({ ...org, deletedAt: null });
833
- const now = (/* @__PURE__ */ new Date()).toISOString();
834
- store.orgMembers.push({
835
- orgId: org.id,
836
- userId: org.ownerId,
837
- role: "owner",
838
- permissions: [...DEFAULT_ORG_PERMISSIONS.owner],
839
- joinedAt: now,
840
- ...auditUpdate(ctx, org.ownerId),
841
- deletedAt: null
842
- });
843
- await this.loader.write(store);
844
- await this.events.emit({ type: "org.created", orgId: org.id, actorId: actorFrom(ctx) });
845
- }
846
- async updateOrg(ctx, id, patch) {
847
- const store = await this.loader.get();
848
- const idx = store.orgs.findIndex((o) => o.id === id && isLive$1(o));
849
- if (idx === -1)
850
- throw new ProviderError(`Org '${id}' not found`, 404);
851
- if (patch.slug && patch.slug !== store.orgs[idx].slug) {
852
- if (store.orgs.some((o) => o.id !== id && o.slug === patch.slug && isLive$1(o))) {
853
- throw new ProviderError(`Org slug '${patch.slug}' already in use`, 409);
854
- }
855
- }
856
- store.orgs[idx] = {
857
- ...store.orgs[idx],
858
- ...patch,
859
- ...auditUpdate(ctx, store.orgs[idx].updatedBy ?? store.orgs[idx].ownerId)
860
- };
861
- await this.loader.write(store);
862
- }
863
- async deleteOrg(ctx, id) {
864
- const store = await this.loader.get();
865
- const idx = store.orgs.findIndex((o) => o.id === id && isLive$1(o));
866
- if (idx === -1)
867
- throw new ProviderError(`Org '${id}' not found`, 404);
868
- const stamp = auditSoftDelete(ctx, store.orgs[idx].updatedBy ?? store.orgs[idx].ownerId);
869
- store.orgs[idx] = { ...store.orgs[idx], ...stamp };
870
- store.orgMembers = store.orgMembers.map((m) => m.orgId === id && isLive$1(m) ? { ...m, ...stamp } : m);
871
- const orgProjectIds = new Set(store.projects.filter((p) => p.orgId === id && isLive$1(p)).map((p) => p.id));
872
- store.projects = store.projects.map((p) => p.orgId === id && isLive$1(p) ? { ...p, ...stamp } : p);
873
- store.projectMembers = store.projectMembers.map((m) => orgProjectIds.has(m.projectId) && isLive$1(m) ? { ...m, ...stamp } : m);
874
- await this.loader.write(store);
875
- await this.invites.deleteByOrg(ctx, id);
876
- await this.computeServer.deleteByOrg(ctx, id);
877
- for (const projectId of orgProjectIds) {
878
- await this.grants.deleteByProject(ctx, projectId);
879
- }
880
- await this.grants.deleteByGranteeOrg(ctx, id);
881
- await this.events.emit({ type: "org.deleted", orgId: id, actorId: actorFrom(ctx) });
882
- }
883
- async listOrgMembers(_ctx, orgId, opts) {
884
- const { orgMembers } = await this.loader.get();
885
- return paginate(orgMembers.filter((m) => m.orgId === orgId && isLive$1(m)), opts);
886
- }
887
- async getOrgMember(_ctx, orgId, userId) {
888
- const { orgMembers } = await this.loader.get();
889
- const m = orgMembers.find((m2) => m2.orgId === orgId && m2.userId === userId);
890
- return m && isLive$1(m) ? m : null;
891
- }
892
- async findUserMembership(_ctx, userId) {
893
- const store = await this.loader.get();
894
- const member = store.orgMembers.find((m) => m.userId === userId && isLive$1(m));
895
- if (!member)
896
- return null;
897
- const org = store.orgs.find((o) => o.id === member.orgId);
898
- if (!org || !isLive$1(org))
899
- return null;
900
- return { org, member };
901
- }
902
- async addOrgMember(ctx, member) {
903
- const store = await this.loader.get();
904
- const existing = store.orgMembers.find((m) => m.orgId === member.orgId && m.userId === member.userId);
905
- if (existing) {
906
- Object.assign(existing, member, {
907
- ...auditUpdate(ctx, member.userId),
908
- deletedAt: null
909
- });
910
- } else {
911
- store.orgMembers.push({ ...member, deletedAt: null });
912
- }
913
- await this.loader.write(store);
914
- await this.events.emit({
915
- type: "org_member.added",
916
- orgId: member.orgId,
917
- userId: member.userId,
918
- actorId: actorFrom(ctx)
919
- });
920
- }
921
- async updateOrgMemberRole(ctx, orgId, userId, role) {
922
- const store = await this.loader.get();
923
- const m = store.orgMembers.find((m2) => m2.orgId === orgId && m2.userId === userId && isLive$1(m2));
924
- if (!m)
925
- throw new ProviderError(`Org member '${userId}' not found`, 404);
926
- m.role = role;
927
- m.permissions = [...DEFAULT_ORG_PERMISSIONS[role]];
928
- Object.assign(m, auditUpdate(ctx, m.updatedBy));
929
- await this.loader.write(store);
930
- await this.events.emit({
931
- type: "org_member.role_changed",
932
- orgId,
933
- userId,
934
- role,
935
- actorId: actorFrom(ctx)
936
- });
937
- }
938
- async updateOrgMemberPermissions(ctx, orgId, userId, permissions) {
939
- const store = await this.loader.get();
940
- const m = store.orgMembers.find((m2) => m2.orgId === orgId && m2.userId === userId && isLive$1(m2));
941
- if (!m)
942
- throw new ProviderError(`Org member '${userId}' not found`, 404);
943
- m.permissions = [...permissions];
944
- Object.assign(m, auditUpdate(ctx, m.updatedBy));
945
- await this.loader.write(store);
946
- await this.events.emit({
947
- type: "org_member.permissions_changed",
948
- orgId,
949
- userId,
950
- permissions: [...permissions],
951
- actorId: actorFrom(ctx)
952
- });
953
- }
954
- async removeOrgMember(ctx, orgId, userId) {
955
- const store = await this.loader.get();
956
- const m = store.orgMembers.find((m2) => m2.orgId === orgId && m2.userId === userId && isLive$1(m2));
957
- if (!m)
958
- return;
959
- const stamp = auditSoftDelete(ctx, m.updatedBy);
960
- Object.assign(m, stamp);
961
- const projectIdsInOrg = new Set(store.projects.filter((p) => p.orgId === orgId).map((p) => p.id));
962
- store.projectMembers = store.projectMembers.map((pm) => pm.userId === userId && projectIdsInOrg.has(pm.projectId) && isLive$1(pm) ? { ...pm, ...stamp } : pm);
963
- await this.loader.write(store);
964
- await this.events.emit({
965
- type: "org_member.removed",
966
- orgId,
967
- userId,
968
- actorId: actorFrom(ctx)
969
- });
970
- }
971
- }
972
- function isLive(row) {
973
- return row.deletedAt == null;
974
- }
975
- class LocalProjectStore {
976
- loader;
977
- events;
978
- grants;
979
- constructor(opts) {
980
- this.loader = opts.loader;
981
- this.grants = opts.grants;
982
- this.events = opts.events ?? new NoopEventSink();
983
- }
984
- async listProjects(_ctx, orgId, opts) {
985
- const { projects } = await this.loader.get();
986
- return paginate(applyOrder(projects.filter((p) => p.orgId === orgId && isLive(p)), opts), opts);
987
- }
988
- async getProject(_ctx, id) {
989
- const { projects } = await this.loader.get();
990
- const p = projects.find((p2) => p2.id === id);
991
- return p && isLive(p) ? p : null;
992
- }
993
- async getProjectBySlug(_ctx, orgId, slug) {
994
- const { projects } = await this.loader.get();
995
- const p = projects.find((p2) => p2.orgId === orgId && p2.slug === slug);
996
- return p && isLive(p) ? p : null;
997
- }
998
- async createProject(ctx, project) {
999
- const store = await this.loader.get();
1000
- if (!store.orgs.some((o) => o.id === project.orgId && isLive(o))) {
1001
- throw new ProviderError(`Org '${project.orgId}' not found`, 404);
1002
- }
1003
- if (store.projects.some((p) => p.id === project.id && isLive(p))) {
1004
- throw new ProviderError(`Project '${project.id}' already exists`, 409);
1005
- }
1006
- const nameKey = project.name.toLowerCase();
1007
- if (store.projects.some((p) => p.orgId === project.orgId && isLive(p) && p.name.toLowerCase() === nameKey)) {
1008
- throw new ProviderError("projects_org_name_unique: project name already in use", 409);
1009
- }
1010
- if (store.projects.some((p) => p.orgId === project.orgId && isLive(p) && p.slug === project.slug)) {
1011
- throw new ProviderError("projects_org_id_slug_key: project slug already in use", 409);
1012
- }
1013
- store.projects.push({ ...project, deletedAt: null });
1014
- store.projectMembers.push({
1015
- projectId: project.id,
1016
- userId: project.ownerId,
1017
- role: "owner",
1018
- joinedAt: project.createdAt,
1019
- updatedAt: project.createdAt,
1020
- updatedBy: project.ownerId,
1021
- deletedAt: null
1022
- });
1023
- await this.loader.write(store);
1024
- await this.events.emit({
1025
- type: "project.created",
1026
- projectId: project.id,
1027
- orgId: project.orgId,
1028
- actorId: actorFrom(ctx)
1029
- });
1030
- }
1031
- async updateProject(ctx, id, patch) {
1032
- const store = await this.loader.get();
1033
- const idx = store.projects.findIndex((p) => p.id === id && isLive(p));
1034
- if (idx === -1)
1035
- throw new ProviderError(`Project '${id}' not found`, 404);
1036
- const current = store.projects[idx];
1037
- if (patch.name && patch.name.toLowerCase() !== current.name.toLowerCase()) {
1038
- const nameKey = patch.name.toLowerCase();
1039
- if (store.projects.some((p) => p.orgId === current.orgId && p.id !== id && isLive(p) && p.name.toLowerCase() === nameKey)) {
1040
- throw new ProviderError("projects_org_name_unique: project name already in use", 409);
1041
- }
1042
- }
1043
- if (patch.slug && patch.slug !== current.slug) {
1044
- if (store.projects.some((p) => p.orgId === current.orgId && p.slug === patch.slug && p.id !== id && isLive(p))) {
1045
- throw new ProviderError("projects_org_id_slug_key: project slug already in use", 409);
1046
- }
1047
- }
1048
- store.projects[idx] = {
1049
- ...current,
1050
- ...patch,
1051
- ...auditUpdate(ctx, current.updatedBy ?? current.ownerId)
1052
- };
1053
- await this.loader.write(store);
1054
- }
1055
- async deleteProject(ctx, id) {
1056
- const store = await this.loader.get();
1057
- const idx = store.projects.findIndex((p) => p.id === id && isLive(p));
1058
- if (idx === -1)
1059
- throw new ProviderError(`Project '${id}' not found`, 404);
1060
- const stamp = auditSoftDelete(ctx, store.projects[idx].updatedBy ?? store.projects[idx].ownerId);
1061
- store.projects[idx] = { ...store.projects[idx], ...stamp };
1062
- store.projectMembers = store.projectMembers.map((m) => m.projectId === id && isLive(m) ? { ...m, ...stamp } : m);
1063
- await this.loader.write(store);
1064
- await this.grants.deleteByProject(ctx, id);
1065
- await this.events.emit({ type: "project.deleted", projectId: id, actorId: actorFrom(ctx) });
1066
- }
1067
- async listProjectMembers(_ctx, projectId, opts) {
1068
- const { projectMembers } = await this.loader.get();
1069
- return paginate(projectMembers.filter((m) => m.projectId === projectId && isLive(m)), opts);
1070
- }
1071
- async getProjectMember(_ctx, projectId, userId) {
1072
- const { projectMembers } = await this.loader.get();
1073
- const m = projectMembers.find((m2) => m2.projectId === projectId && m2.userId === userId);
1074
- return m && isLive(m) ? m : null;
1075
- }
1076
- async addProjectMember(ctx, member) {
1077
- const store = await this.loader.get();
1078
- const existing = store.projectMembers.find((m) => m.projectId === member.projectId && m.userId === member.userId);
1079
- if (existing) {
1080
- Object.assign(existing, member, {
1081
- ...auditUpdate(ctx, member.userId),
1082
- deletedAt: null
1083
- });
1084
- } else {
1085
- const stamp = auditUpdate(ctx, member.userId);
1086
- store.projectMembers.push({
1087
- ...member,
1088
- updatedAt: member.updatedAt ?? stamp.updatedAt,
1089
- updatedBy: member.updatedBy ?? stamp.updatedBy,
1090
- deletedAt: null
1091
- });
1092
- }
1093
- await this.loader.write(store);
1094
- await this.events.emit({
1095
- type: "project_member.added",
1096
- projectId: member.projectId,
1097
- userId: member.userId,
1098
- actorId: actorFrom(ctx)
1099
- });
1100
- }
1101
- async updateProjectMemberRole(ctx, projectId, userId, role) {
1102
- const store = await this.loader.get();
1103
- const m = store.projectMembers.find((m2) => m2.projectId === projectId && m2.userId === userId && isLive(m2));
1104
- if (!m)
1105
- throw new ProviderError(`Project member '${userId}' not found`, 404);
1106
- m.role = role;
1107
- Object.assign(m, auditUpdate(ctx, m.updatedBy));
1108
- await this.loader.write(store);
1109
- await this.events.emit({
1110
- type: "project_member.role_changed",
1111
- projectId,
1112
- userId,
1113
- role,
1114
- actorId: actorFrom(ctx)
1115
- });
1116
- }
1117
- async removeProjectMember(ctx, projectId, userId) {
1118
- const store = await this.loader.get();
1119
- const m = store.projectMembers.find((m2) => m2.projectId === projectId && m2.userId === userId && isLive(m2));
1120
- if (!m)
1121
- return;
1122
- Object.assign(m, auditSoftDelete(ctx, m.updatedBy));
1123
- await this.loader.write(store);
1124
- await this.events.emit({
1125
- type: "project_member.removed",
1126
- projectId,
1127
- userId,
1128
- actorId: actorFrom(ctx)
1129
- });
1130
- }
1131
- }
1132
- const empty$3 = () => ({ definitions: {}, definitionVersions: {} });
1133
- class LocalDefinitionStore {
1134
- configPath;
1135
- events;
1136
- projectProvider;
1137
- static fromEnv(env) {
1138
- if (!env.DATA_PATH)
1139
- throw new Error("Missing required env var: DATA_PATH");
1140
- return new LocalDefinitionStore(env.DATA_PATH);
1141
- }
1142
- constructor(definitionsPath, projectProvider, events = new NoopEventSink()) {
1143
- this.configPath = path.join(definitionsPath, "definitions-config.json");
1144
- this.projectProvider = projectProvider;
1145
- this.events = events;
1146
- }
1147
- setProjectProvider(projectProvider) {
1148
- this.projectProvider = projectProvider;
1149
- }
1150
- async readConfig() {
1151
- return readJsonFile(this.configPath, empty$3());
1152
- }
1153
- live(record) {
1154
- return Boolean(record && record.deletedAt == null);
1155
- }
1156
- async writeConfig(config) {
1157
- await writeJsonFile(this.configPath, config);
1158
- }
1159
- sortedRecords(records, opts) {
1160
- const defaulted = {
1161
- ...opts,
1162
- orderBy: opts?.orderBy ?? "name",
1163
- orderDir: opts?.orderDir ?? "asc"
1164
- };
1165
- return applyOrder([...records], defaulted, (r, field) => {
1166
- if (field === "name")
1167
- return r.displayName.toLowerCase();
1168
- if (field === "solveCount")
1169
- return r.solveCount ?? 0;
1170
- return r[field];
1171
- });
1172
- }
1173
- visibleRecords(records, opts) {
1174
- const filtered = records.filter((r) => r?.displayName && this.live(r));
1175
- if (opts?.statuses?.length) {
1176
- const allowed = new Set(opts.statuses);
1177
- return filtered.filter((r) => allowed.has(r.status));
1178
- }
1179
- return filtered.filter((r) => {
1180
- if (r.status === "pending" && !opts?.includePending)
1181
- return false;
1182
- if (r.status === "archived" && !opts?.includeArchived)
1183
- return false;
1184
- return true;
1185
- });
1186
- }
1187
- async list(_ctx, opts) {
1188
- const config = await this.readConfig();
1189
- const records = this.visibleRecords(Object.values(config.definitions), opts);
1190
- return paginate(this.sortedRecords(records, opts), opts);
1191
- }
1192
- async listByProject(_ctx, projectId, opts) {
1193
- const config = await this.readConfig();
1194
- const records = this.visibleRecords(Object.values(config.definitions).filter((r) => r?.projectId === projectId), opts);
1195
- return paginate(this.sortedRecords(records, opts), opts);
1196
- }
1197
- async listPublic(ctx, opts) {
1198
- if (!this.projectProvider) {
1199
- return this.list(ctx, opts);
1200
- }
1201
- const config = await this.readConfig();
1202
- const records = Object.values(config.definitions).filter((r) => Boolean(r?.displayName && this.live(r)));
1203
- const projectIds = Array.from(new Set(records.map((r) => r.projectId)));
1204
- const projects = await Promise.all(projectIds.map((id) => this.projectProvider.getProject(ctx, id)));
1205
- const publicProjectIds = new Set(projects.filter((p) => p !== null && p.visibility === "public" && (!opts?.orgId || p.orgId === opts.orgId)).map((p) => p.id));
1206
- const publicRecords = this.visibleRecords(records.filter((r) => publicProjectIds.has(r.projectId)), opts);
1207
- return paginate(this.sortedRecords(publicRecords, opts), opts);
1208
- }
1209
- async get(_ctx, guid) {
1210
- const config = await this.readConfig();
1211
- const r = config.definitions[guid];
1212
- return this.live(r) ? r : null;
1213
- }
1214
- async create(ctx, record) {
1215
- const config = await this.readConfig();
1216
- const actor = ctx.userId || record.ownerId;
1217
- config.definitions[record.guid] = {
1218
- ...record,
1219
- createdBy: record.createdBy || actor,
1220
- updatedBy: record.updatedBy || actor,
1221
- liveVersionId: record.liveVersionId ?? null,
1222
- draftVersionId: record.draftVersionId ?? null,
1223
- deletedAt: null
1224
- };
1225
- await this.writeConfig(config);
1226
- await this.events.emit({
1227
- type: "definition.created",
1228
- definitionId: record.guid,
1229
- projectId: record.projectId,
1230
- actorId: actorFrom(ctx)
1231
- });
1232
- }
1233
- async update(ctx, guid, patch) {
1234
- const config = await this.readConfig();
1235
- const existing = config.definitions[guid];
1236
- if (!this.live(existing))
1237
- throw new ProviderError(`Definition '${guid}' not found`, 404);
1238
- const clearable = (v) => v === null ? void 0 : v;
1239
- config.definitions[guid] = {
1240
- ...existing,
1241
- ...patch.displayName !== void 0 && { displayName: patch.displayName },
1242
- ...patch.description !== void 0 && {
1243
- description: clearable(patch.description)
1244
- },
1245
- ...patch.category !== void 0 && {
1246
- category: clearable(patch.category)
1247
- },
1248
- ...patch.tags !== void 0 && { tags: clearable(patch.tags) },
1249
- ...patch.coverImage !== void 0 && {
1250
- coverImage: clearable(patch.coverImage)
1251
- },
1252
- ...patch.projectId !== void 0 && { projectId: patch.projectId },
1253
- ...patch.computeServerId !== void 0 && {
1254
- computeServerId: clearable(patch.computeServerId)
1255
- },
1256
- ...patch.status !== void 0 && { status: patch.status },
1257
- ...patch.ownerId !== void 0 && { ownerId: patch.ownerId },
1258
- ...auditUpdate(ctx, existing.updatedBy ?? existing.ownerId)
1259
- };
1260
- await this.writeConfig(config);
1261
- }
1262
- async delete(ctx, guid) {
1263
- const config = await this.readConfig();
1264
- const existing = config.definitions[guid];
1265
- if (!this.live(existing))
1266
- return;
1267
- Object.assign(existing, auditSoftDelete(ctx, existing.updatedBy ?? existing.ownerId));
1268
- await this.writeConfig(config);
1269
- await this.events.emit({
1270
- type: "definition.deleted",
1271
- definitionId: guid,
1272
- actorId: actorFrom(ctx)
1273
- });
1274
- }
1275
- async incrementSolveCount(_ctx, guid) {
1276
- const config = await this.readConfig();
1277
- const existing = config.definitions[guid];
1278
- if (!this.live(existing))
1279
- return;
1280
- existing.solveCount = (existing.solveCount ?? 0) + 1;
1281
- existing.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
1282
- await this.writeConfig(config);
1283
- }
1284
- // ============================================================================
1285
- // Versions (spec §6)
1286
- // ============================================================================
1287
- async createVersion(ctx, version) {
1288
- const config = await this.readConfig();
1289
- const parent = config.definitions[version.definitionId];
1290
- if (!this.live(parent)) {
1291
- throw new ProviderError(`Definition '${version.definitionId}' not found`, 404);
1292
- }
1293
- if (config.definitionVersions[version.id]) {
1294
- throw new ProviderError(`Version '${version.id}' already exists`, 409);
1295
- }
1296
- config.definitionVersions[version.id] = { ...version };
1297
- await this.writeConfig(config);
1298
- await this.events.emit({
1299
- type: "definition_version.created",
1300
- versionId: version.id,
1301
- definitionId: version.definitionId,
1302
- actorId: actorFrom(ctx)
1303
- });
1304
- }
1305
- async listVersions(_ctx, definitionId, opts) {
1306
- const config = await this.readConfig();
1307
- const parent = config.definitions[definitionId];
1308
- if (!this.live(parent))
1309
- return paginate([], opts);
1310
- const rows = Object.values(config.definitionVersions).filter((v) => v.definitionId === definitionId).sort((a, b) => b.versionNumber - a.versionNumber);
1311
- return paginate(rows, opts);
1312
- }
1313
- async getVersion(_ctx, versionId) {
1314
- const config = await this.readConfig();
1315
- return config.definitionVersions[versionId] ?? null;
1316
- }
1317
- async deleteVersion(ctx, versionId) {
1318
- const config = await this.readConfig();
1319
- const version = config.definitionVersions[versionId];
1320
- if (!version)
1321
- return;
1322
- const parent = config.definitions[version.definitionId];
1323
- if (parent && (parent.liveVersionId === versionId || parent.draftVersionId === versionId)) {
1324
- throw new ProviderError(`Version '${versionId}' is referenced by liveVersionId or draftVersionId`, 409);
1325
- }
1326
- delete config.definitionVersions[versionId];
1327
- await this.writeConfig(config);
1328
- await this.events.emit({
1329
- type: "definition_version.deleted",
1330
- versionId,
1331
- actorId: actorFrom(ctx)
1332
- });
1333
- }
1334
- async setLiveVersion(ctx, definitionId, versionId) {
1335
- await this.repoint("live", ctx, definitionId, versionId);
1336
- }
1337
- async setDraftVersion(ctx, definitionId, versionId) {
1338
- await this.repoint("draft", ctx, definitionId, versionId);
1339
- }
1340
- async attachInitialVersion(ctx, definitionId, versionId) {
1341
- const config = await this.readConfig();
1342
- const record = config.definitions[definitionId];
1343
- if (!this.live(record))
1344
- throw new ProviderError(`Definition '${definitionId}' not found`, 404);
1345
- const version = config.definitionVersions[versionId];
1346
- if (!version || version.definitionId !== definitionId) {
1347
- throw new ProviderError(`Version '${versionId}' not found for this definition`, 404);
1348
- }
1349
- record.liveVersionId = versionId;
1350
- record.draftVersionId = versionId;
1351
- record.status = "draft";
1352
- Object.assign(record, auditUpdate(ctx, record.updatedBy ?? record.ownerId));
1353
- await this.writeConfig(config);
1354
- }
1355
- async repoint(channel, ctx, definitionId, versionId) {
1356
- const config = await this.readConfig();
1357
- const record = config.definitions[definitionId];
1358
- if (!this.live(record))
1359
- throw new ProviderError(`Definition '${definitionId}' not found`, 404);
1360
- const version = config.definitionVersions[versionId];
1361
- if (!version || version.definitionId !== definitionId) {
1362
- throw new ProviderError(`Version '${versionId}' not found for this definition`, 404);
1363
- }
1364
- if (channel === "live")
1365
- record.liveVersionId = versionId;
1366
- else
1367
- record.draftVersionId = versionId;
1368
- Object.assign(record, auditUpdate(ctx, record.updatedBy ?? record.ownerId));
1369
- await this.writeConfig(config);
1370
- if (channel === "live") {
1371
- await this.events.emit({
1372
- type: "definition.published",
1373
- definitionId,
1374
- versionId,
1375
- actorId: actorFrom(ctx)
1376
- });
1377
- }
1378
- }
1379
- }
1380
- const empty$2 = () => ({ links: {} });
1381
- class LocalShareLinkStore {
1382
- definitionProvider;
1383
- events;
1384
- configFilePath;
1385
- static fromEnv(env) {
1386
- if (!env.DATA_PATH)
1387
- throw new Error("Missing required env var: DATA_PATH");
1388
- return new LocalShareLinkStore({
1389
- filePath: path.join(env.DATA_PATH, "share-links.json")
1390
- });
1391
- }
1392
- constructor(opts) {
1393
- this.configFilePath = opts.filePath;
1394
- this.events = opts.events ?? new NoopEventSink();
1395
- }
1396
- /**
1397
- * Wire the definition store so token resolution can check the parent
1398
- * definition's `deletedAt` (Permissions.md §7 cascade contract). Mirrors
1399
- * Supabase, which performs the equivalent JOIN. Optional: when unset, the
1400
- * store falls back to the local-only revoke check; the route layer in
1401
- * the selva app does the parent lookup as a safety net either way.
1402
- */
1403
- setDefinitionProvider(definitions) {
1404
- this.definitionProvider = definitions;
1405
- }
1406
- async readAll() {
1407
- return readJsonFile(this.configFilePath, empty$2());
1408
- }
1409
- async writeAll(data) {
1410
- await writeJsonFile(this.configFilePath, data);
1411
- }
1412
- isLive(l) {
1413
- return Boolean(l && l.revokedAt == null);
1414
- }
1415
- async create(ctx, link) {
1416
- const all = await this.readAll();
1417
- if (all.links[link.id]) {
1418
- throw new ProviderError(`Share link '${link.id}' already exists`, 409);
1419
- }
1420
- all.links[link.id] = { ...link, revokedAt: null };
1421
- await this.writeAll(all);
1422
- await this.events.emit({
1423
- type: "share_link.minted",
1424
- linkId: link.id,
1425
- definitionId: link.definitionId,
1426
- actorId: actorFrom(ctx)
1427
- });
1428
- }
1429
- async listByDefinition(_ctx, definitionId, opts) {
1430
- const all = await this.readAll();
1431
- const rows = Object.values(all.links).filter((l) => l.definitionId === definitionId && this.isLive(l)).sort((a, b) => b.createdAt.localeCompare(a.createdAt));
1432
- return paginate(rows, opts);
1433
- }
1434
- async getById(_ctx, id) {
1435
- const all = await this.readAll();
1436
- return all.links[id] ?? null;
1437
- }
1438
- async getByTokenHash(_ctx, tokenHash) {
1439
- const all = await this.readAll();
1440
- const found = Object.values(all.links).find((l) => l.tokenHash === tokenHash);
1441
- if (!this.isLive(found))
1442
- return null;
1443
- if (this.definitionProvider) {
1444
- const parent = await this.definitionProvider.get(SYSTEM_CONTEXT, found.definitionId);
1445
- if (!parent)
1446
- return null;
1447
- }
1448
- return found;
1449
- }
1450
- async revoke(ctx, id) {
1451
- const all = await this.readAll();
1452
- const l = all.links[id];
1453
- if (!l || !this.isLive(l))
1454
- return;
1455
- l.revokedAt = (/* @__PURE__ */ new Date()).toISOString();
1456
- await this.writeAll(all);
1457
- await this.events.emit({ type: "share_link.revoked", linkId: id, actorId: actorFrom(ctx) });
1458
- }
1459
- async tryIncrementSolveCount(_ctx, id) {
1460
- const all = await this.readAll();
1461
- const l = all.links[id];
1462
- if (!l || !this.isLive(l))
1463
- return null;
1464
- if (l.maxSolves != null && l.solveCount >= l.maxSolves)
1465
- return null;
1466
- l.solveCount += 1;
1467
- await this.writeAll(all);
1468
- return l.solveCount;
1469
- }
1470
- }
1471
- const MAX_RECENT_RUNS$1 = 20;
1472
- const empty$1 = () => ({ users: [] });
1473
- function emptyRow(userId) {
1474
- return {
1475
- userId,
1476
- platformPermissions: [],
1477
- starredDefinitions: [],
1478
- recentRuns: []
1479
- };
1480
- }
1481
- function createLocalUserDataStore(filePath) {
1482
- async function findOrThrow(userId) {
1483
- const file = await readJsonFile(filePath, empty$1());
1484
- const row = file.users.find((u) => u.userId === userId);
1485
- if (!row)
1486
- throw new ProviderError(`User-data row "${userId}" not found`, 404);
1487
- return { file, row };
1488
- }
1489
- return {
1490
- async ensure(userId) {
1491
- const file = await readJsonFile(filePath, empty$1());
1492
- if (file.users.some((u) => u.userId === userId))
1493
- return;
1494
- file.users.push(emptyRow(userId));
1495
- await writeJsonFile(filePath, file);
1496
- },
1497
- async findById(userId) {
1498
- const { users } = await readJsonFile(filePath, empty$1());
1499
- return users.find((u) => u.userId === userId) ?? null;
1500
- },
1501
- async listAll() {
1502
- const { users } = await readJsonFile(filePath, empty$1());
1503
- return users;
1504
- },
1505
- async updatePermissions(userId, permissions) {
1506
- const { file, row } = await findOrThrow(userId);
1507
- row.platformPermissions = permissions;
1508
- await writeJsonFile(filePath, file);
1509
- },
1510
- async updateDisplayName(userId, displayName) {
1511
- const { file, row } = await findOrThrow(userId);
1512
- if (displayName === void 0) {
1513
- delete row.displayName;
1514
- } else {
1515
- row.displayName = displayName;
1516
- }
1517
- await writeJsonFile(filePath, file);
1518
- },
1519
- async starDefinition(userId, definitionId) {
1520
- const { file, row } = await findOrThrow(userId);
1521
- if (!row.starredDefinitions.includes(definitionId)) {
1522
- row.starredDefinitions.push(definitionId);
1523
- await writeJsonFile(filePath, file);
1524
- }
1525
- },
1526
- async unstarDefinition(userId, definitionId) {
1527
- const { file, row } = await findOrThrow(userId);
1528
- row.starredDefinitions = row.starredDefinitions.filter((d) => d !== definitionId);
1529
- await writeJsonFile(filePath, file);
1530
- },
1531
- async recordRun(userId, run) {
1532
- const { file, row } = await findOrThrow(userId);
1533
- row.recentRuns = [
1534
- run,
1535
- ...row.recentRuns.filter((r) => r.definitionId !== run.definitionId)
1536
- ].slice(0, MAX_RECENT_RUNS$1);
1537
- await writeJsonFile(filePath, file);
1538
- },
1539
- async deleteUser(userId) {
1540
- const file = await readJsonFile(filePath, empty$1());
1541
- const before = file.users.length;
1542
- file.users = file.users.filter((u) => u.userId !== userId);
1543
- if (file.users.length === before) {
1544
- throw new ProviderError(`User-data row "${userId}" not found`, 404);
1545
- }
1546
- await writeJsonFile(filePath, file);
1547
- }
1548
- };
1549
- }
1550
- function toProfile(u) {
1551
- return {
1552
- userId: u.userId,
1553
- displayName: u.displayName,
1554
- starredDefinitions: u.starredDefinitions ?? [],
1555
- recentRuns: u.recentRuns ?? []
1556
- };
1557
- }
1558
- class LocalUserProfileProvider {
1559
- data;
1560
- constructor(userDataFilePath) {
1561
- this.data = createLocalUserDataStore(userDataFilePath);
1562
- }
1563
- static fromEnv(env) {
1564
- if (!env.DATA_PATH)
1565
- throw new Error("Missing required env var: DATA_PATH");
1566
- return new LocalUserProfileProvider(path.join(env.DATA_PATH, "user-data.json"));
1567
- }
1568
- async getProfile(ctx, userId) {
1569
- assertCanAccess$1(ctx, userId);
1570
- const u = await this.data.findById(userId);
1571
- return u ? toProfile(u) : null;
1572
- }
1573
- async getProfiles(_ctx, userIds) {
1574
- const all = await this.data.listAll();
1575
- const wanted = new Set(userIds);
1576
- return all.filter((u) => wanted.has(u.userId)).map(toProfile);
1577
- }
1578
- async updateProfile(ctx, userId, patch) {
1579
- assertCanAccess$1(ctx, userId);
1580
- try {
1581
- if (patch.displayName !== void 0) {
1582
- await this.data.updateDisplayName(userId, patch.displayName);
1583
- }
1584
- return "ok";
1585
- } catch (err) {
1586
- if (err instanceof ProviderError && err.statusCode === 404)
1587
- return "not_found";
1588
- throw err;
1589
- }
1590
- }
1591
- async starDefinition(ctx, userId, definitionId) {
1592
- assertCanAccess$1(ctx, userId);
1593
- try {
1594
- await this.data.starDefinition(userId, definitionId);
1595
- return "ok";
1596
- } catch (err) {
1597
- if (err instanceof ProviderError && err.statusCode === 404)
1598
- return "not_found";
1599
- throw err;
1600
- }
1601
- }
1602
- async unstarDefinition(ctx, userId, definitionId) {
1603
- assertCanAccess$1(ctx, userId);
1604
- try {
1605
- await this.data.unstarDefinition(userId, definitionId);
1606
- return "ok";
1607
- } catch (err) {
1608
- if (err instanceof ProviderError && err.statusCode === 404)
1609
- return "not_found";
1610
- throw err;
1611
- }
1612
- }
1613
- async recordRun(ctx, userId, run) {
1614
- assertCanAccess$1(ctx, userId);
1615
- try {
1616
- await this.data.recordRun(userId, run);
1617
- return "ok";
1618
- } catch (err) {
1619
- if (err instanceof ProviderError && err.statusCode === 404)
1620
- return "not_found";
1621
- throw err;
1622
- }
1623
- }
1624
- }
1625
- function assertCanAccess$1(ctx, userId) {
1626
- if (ctx.system)
1627
- return;
1628
- if (ctx.userId === userId)
1629
- return;
1630
- if (hasPermission(ctx, "instance_admin"))
1631
- return;
1632
- throw new ProviderError("Forbidden: cannot access another user’s profile", 403);
1633
- }
1634
- class LocalPlatformPermissionStore {
1635
- data;
1636
- static fromEnv(env) {
1637
- if (!env.DATA_PATH)
1638
- throw new Error("Missing required env var: DATA_PATH");
1639
- return new LocalPlatformPermissionStore(path.join(env.DATA_PATH, "user-data.json"));
1640
- }
1641
- constructor(userDataFilePath) {
1642
- this.data = createLocalUserDataStore(userDataFilePath);
1643
- }
1644
- async getFor(ctx, userId) {
1645
- assertCanRead$1(ctx, userId);
1646
- const row = await this.data.findById(userId);
1647
- return row?.platformPermissions ?? [];
1648
- }
1649
- async getForBatch(ctx, userIds) {
1650
- assertCanReadBatch(ctx);
1651
- const all = await this.data.listAll();
1652
- const wanted = new Set(userIds);
1653
- const out = /* @__PURE__ */ new Map();
1654
- for (const u of all) {
1655
- if (wanted.has(u.userId))
1656
- out.set(u.userId, u.platformPermissions ?? []);
1657
- }
1658
- return out;
1659
- }
1660
- async set(ctx, userId, permissions) {
1661
- assertAdmin$1(ctx);
1662
- const target = await this.data.findById(userId);
1663
- if (!target)
1664
- return "not_found";
1665
- const wasAdmin = target.platformPermissions.includes("instance_admin");
1666
- const willBeAdmin = permissions.includes("instance_admin");
1667
- if (wasAdmin && !willBeAdmin) {
1668
- const others = await this.countOtherAdmins(userId);
1669
- if (others === 0)
1670
- return "last_admin";
1671
- }
1672
- try {
1673
- await this.data.updatePermissions(userId, [...permissions]);
1674
- return "ok";
1675
- } catch (err) {
1676
- if (err instanceof ProviderError && err.statusCode === 404)
1677
- return "not_found";
1678
- throw err;
1679
- }
1680
- }
1681
- async hasInstanceAdmin(_ctx) {
1682
- const all = await this.data.listAll();
1683
- return all.some((u) => u.platformPermissions.includes("instance_admin"));
1684
- }
1685
- async countInstanceAdminsExcluding(_ctx, excludeUserId) {
1686
- return this.countOtherAdmins(excludeUserId);
1687
- }
1688
- async countOtherAdmins(excludeUserId) {
1689
- const all = await this.data.listAll();
1690
- return all.filter((u) => u.userId !== excludeUserId && u.platformPermissions.includes("instance_admin")).length;
1691
- }
1692
- }
1693
- function assertCanRead$1(ctx, userId) {
1694
- if (ctx.system)
1695
- return;
1696
- if (ctx.userId === userId)
1697
- return;
1698
- if (hasPermission(ctx, "instance_admin"))
1699
- return;
1700
- throw new ProviderError("Forbidden: cannot read another user’s permissions", 403);
1701
- }
1702
- function assertAdmin$1(ctx) {
1703
- if (ctx.system)
1704
- return;
1705
- if (hasPermission(ctx, "instance_admin"))
1706
- return;
1707
- throw new ProviderError("Forbidden: instance admin required", 403);
1708
- }
1709
- function assertCanReadBatch(ctx) {
1710
- if (ctx.system)
1711
- return;
1712
- if (hasPermission(ctx, "instance_admin"))
1713
- return;
1714
- if (hasPermission(ctx, "manage_instance_users"))
1715
- return;
1716
- throw new ProviderError("Forbidden: instance admin or manage_instance_users required", 403);
1717
- }
1718
- class LocalDataProvider {
1719
- orgs;
1720
- projects;
1721
- definitions;
1722
- computeServer;
1723
- invites;
1724
- shareLinks;
1725
- userProfile;
1726
- permissions;
1727
- platformProjectGrants;
1728
- userData;
1729
- constructor(stores, userData) {
1730
- this.orgs = stores.orgs;
1731
- this.projects = stores.projects;
1732
- this.definitions = stores.definitions;
1733
- this.computeServer = stores.computeServer;
1734
- this.invites = stores.invites;
1735
- this.shareLinks = stores.shareLinks;
1736
- this.userProfile = stores.userProfile;
1737
- this.permissions = stores.permissions;
1738
- this.platformProjectGrants = stores.platformProjectGrants;
1739
- this.userData = userData;
1740
- }
1741
- /**
1742
- * Idempotently register a user in the data layer. Called from
1743
- * `hooks.server.ts` on every authed request — the local equivalent of
1744
- * Supabase's `handle_new_auth_user` trigger. After this completes the
1745
- * user has an empty row in `user-data.json` that the permissions and
1746
- * profile stores can read and update.
1747
- *
1748
- * `ctx` is unused — registration runs as a system operation regardless of
1749
- * the calling user. Argument is kept for interface symmetry with adapters
1750
- * that need it.
1751
- */
1752
- async ensureUser(_ctx, userId) {
1753
- await this.userData.ensure(userId);
1754
- }
1755
- /**
1756
- * Cascade hook called after the auth provider deletes a user. Removes the
1757
- * matching `user-data.json` row so the data layer doesn't accumulate
1758
- * orphans. Tolerates missing rows.
1759
- */
1760
- async onUserDeleted(_ctx, userId) {
1761
- try {
1762
- await this.userData.deleteUser(userId);
1763
- } catch {
1764
- }
1765
- }
1766
- static fromEnv(env, events = new NoopEventSink()) {
1767
- if (!env.DATA_PATH)
1768
- throw new Error("Missing required env var: DATA_PATH");
1769
- const dataPath = env.DATA_PATH;
1770
- const userDataFilePath = path.join(dataPath, "user-data.json");
1771
- const loader = new LocalOrgStoreLoader(dataPath);
1772
- const platformProjectGrants = LocalPlatformProjectGrantStore.fromEnv(env);
1773
- const invites = LocalInviteStore.fromEnv(env, events);
1774
- const computeServer = LocalComputeServerStore.fromEnv(env);
1775
- const projects = new LocalProjectStore({ loader, grants: platformProjectGrants, events });
1776
- const definitions = new LocalDefinitionStore(dataPath, void 0, events);
1777
- const shareLinks = new LocalShareLinkStore({
1778
- filePath: path.join(dataPath, "share-links.json"),
1779
- events
1780
- });
1781
- const orgs = new LocalOrgStore({
1782
- loader,
1783
- invites,
1784
- computeServer,
1785
- grants: platformProjectGrants,
1786
- events
1787
- });
1788
- definitions.setProjectProvider(projects);
1789
- shareLinks.setDefinitionProvider(definitions);
1790
- const userData = createLocalUserDataStore(userDataFilePath);
1791
- return new LocalDataProvider({
1792
- orgs,
1793
- projects,
1794
- definitions,
1795
- computeServer,
1796
- invites,
1797
- shareLinks,
1798
- userProfile: new LocalUserProfileProvider(userDataFilePath),
1799
- permissions: new LocalPlatformPermissionStore(userDataFilePath),
1800
- platformProjectGrants
1801
- }, userData);
1802
- }
1803
- }
1804
- class LocalStorageProvider {
1805
- basePath;
1806
- publicUrlBase;
1807
- static fromEnv(env) {
1808
- if (!env.DATA_PATH)
1809
- throw new Error("Missing required env var: DATA_PATH");
1810
- return new LocalStorageProvider(env.DATA_PATH, "/api/files");
1811
- }
1812
- constructor(basePath, publicUrlBase = "/api/files") {
1813
- this.basePath = basePath;
1814
- this.publicUrlBase = publicUrlBase;
1815
- }
1816
- /**
1817
- * Resolve a caller-provided path under basePath, rejecting anything that
1818
- * would escape the root. Last line of defense against traversal — while
1819
- * platform-side helpers (definitionPaths) also assert safe keys, this
1820
- * adapter is reached by any IStorageProvider caller.
1821
- */
1822
- resolvePath(storagePath) {
1823
- const base = path.resolve(this.basePath);
1824
- const full = path.resolve(base, storagePath);
1825
- if (full !== base && !full.startsWith(base + path.sep)) {
1826
- throw new Error(`Path escapes base: ${storagePath}`);
1827
- }
1828
- return full;
1829
- }
1830
- async get(storagePath) {
1831
- try {
1832
- const buffer = await fs.readFile(this.resolvePath(storagePath));
1833
- return new Uint8Array(buffer);
1834
- } catch (err) {
1835
- if (err.code === "ENOENT")
1836
- return null;
1837
- throw err;
1838
- }
1839
- }
1840
- async put(storagePath, data, contentType) {
1841
- const transcoded = await transcodeImageIfNeeded(data, contentType, storagePath);
1842
- const fullPath = this.resolvePath(transcoded.path);
1843
- await fs.mkdir(path.dirname(fullPath), { recursive: true });
1844
- await fs.writeFile(fullPath, Buffer.from(transcoded.data));
1845
- }
1846
- async delete(storagePath) {
1847
- try {
1848
- await fs.unlink(this.resolvePath(storagePath));
1849
- } catch (err) {
1850
- if (err.code !== "ENOENT")
1851
- throw err;
1852
- }
1853
- }
1854
- async deletePrefix(prefix) {
1855
- const fullPath = this.resolvePath(prefix);
1856
- await fs.rm(fullPath, { recursive: true, force: true });
1857
- }
1858
- getPublicUrl(storagePath) {
1859
- return `${this.publicUrlBase}/${storagePath}`;
1860
- }
1861
- }
1862
- class SupabaseStorageProvider {
1863
- client;
1864
- publicBucket;
1865
- privateBucket;
1866
- publicBaseUrl;
1867
- privateUrlPrefix;
1868
- static fromEnv(env) {
1869
- const supabaseUrl = env.SUPABASE_URL;
1870
- const serviceRoleKey = env.SUPABASE_SERVICE_ROLE_KEY;
1871
- if (!supabaseUrl)
1872
- throw new Error("Missing required env var: SUPABASE_URL");
1873
- if (!serviceRoleKey)
1874
- throw new Error("Missing required env var: SUPABASE_SERVICE_ROLE_KEY");
1875
- return new SupabaseStorageProvider({
1876
- supabaseUrl,
1877
- serviceRoleKey,
1878
- publicBucket: env.SUPABASE_PUBLIC_BUCKET,
1879
- privateBucket: env.SUPABASE_PRIVATE_BUCKET,
1880
- privateUrlPrefix: env.SUPABASE_PRIVATE_URL_PREFIX
1881
- });
1882
- }
1883
- constructor(config) {
1884
- this.client = createClient(config.supabaseUrl, config.serviceRoleKey, {
1885
- auth: { persistSession: false, autoRefreshToken: false }
1886
- });
1887
- this.publicBucket = config.publicBucket ?? "selva-public";
1888
- this.privateBucket = config.privateBucket ?? "selva-private";
1889
- this.publicBaseUrl = `${config.supabaseUrl.replace(/\/$/, "")}/storage/v1/object/public/${this.publicBucket}`;
1890
- this.privateUrlPrefix = (config.privateUrlPrefix ?? "/api/files").replace(/\/$/, "");
1891
- }
1892
- /**
1893
- * Route a storage path to a bucket. Any `.gh`/`.ghx` source file is
1894
- * private — confidentiality is determined by extension, not location, so
1895
- * a path-scheme rename (e.g. `definition.gh` → `versions/v1.gh`) can't
1896
- * silently move source files into the public bucket. Everything else
1897
- * (covers, archives, thumbnails) is public.
1898
- */
1899
- bucketFor(storagePath) {
1900
- return /\.(gh|ghx)$/i.test(storagePath) ? this.privateBucket : this.publicBucket;
1901
- }
1902
- async get(storagePath) {
1903
- const bucket = this.bucketFor(storagePath);
1904
- const { data, error } = await this.client.storage.from(bucket).download(storagePath);
1905
- if (error) {
1906
- const msg = error.message ?? "";
1907
- if (/not found/i.test(msg) || /no such key/i.test(msg))
1908
- return null;
1909
- throw error;
1910
- }
1911
- const buffer = await data.arrayBuffer();
1912
- return new Uint8Array(buffer);
1913
- }
1914
- async put(storagePath, data, contentType) {
1915
- const transcoded = await transcodeImageIfNeeded(data, contentType, storagePath);
1916
- const bucket = this.bucketFor(transcoded.path);
1917
- const { error } = await this.client.storage.from(bucket).upload(transcoded.path, transcoded.data, {
1918
- contentType: transcoded.contentType,
1919
- upsert: true
1920
- });
1921
- if (error)
1922
- throw error;
1923
- }
1924
- async delete(storagePath) {
1925
- const bucket = this.bucketFor(storagePath);
1926
- const { error } = await this.client.storage.from(bucket).remove([storagePath]);
1927
- if (error)
1928
- throw error;
1929
- }
1930
- async deletePrefix(prefix) {
1931
- await Promise.all([
1932
- this.deletePrefixInBucket(this.publicBucket, prefix),
1933
- this.deletePrefixInBucket(this.privateBucket, prefix)
1934
- ]);
1935
- }
1936
- async deletePrefixInBucket(bucket, prefix) {
1937
- const normalized = prefix.replace(/\/+$/, "");
1938
- const keys = await this.listAllKeys(bucket, normalized);
1939
- if (keys.length === 0)
1940
- return;
1941
- for (let i = 0; i < keys.length; i += 1e3) {
1942
- const slice = keys.slice(i, i + 1e3);
1943
- const { error } = await this.client.storage.from(bucket).remove(slice);
1944
- if (error)
1945
- throw error;
1946
- }
1947
- }
1948
- /**
1949
- * Recursively list every key under a prefix. `storage-js`'s `list` API
1950
- * only returns the immediate children of a "folder", so we DFS.
1951
- */
1952
- async listAllKeys(bucket, prefix) {
1953
- const out = [];
1954
- const stack = [prefix];
1955
- while (stack.length > 0) {
1956
- const dir = stack.pop();
1957
- const { data, error } = await this.client.storage.from(bucket).list(dir, {
1958
- limit: 1e3,
1959
- sortBy: { column: "name", order: "asc" }
1960
- });
1961
- if (error)
1962
- throw error;
1963
- for (const entry of data ?? []) {
1964
- const full = dir ? `${dir}/${entry.name}` : entry.name;
1965
- if (entry.id === null) {
1966
- stack.push(full);
1967
- } else {
1968
- out.push(full);
1969
- }
1970
- }
1971
- }
1972
- return out;
1973
- }
1974
- getPublicUrl(storagePath) {
1975
- if (this.bucketFor(storagePath) === this.publicBucket) {
1976
- return `${this.publicBaseUrl}/${storagePath}`;
1977
- }
1978
- return `${this.privateUrlPrefix}/${storagePath}`;
1979
- }
1980
- }
1981
- function decodeCursor(cursor) {
1982
- if (!cursor)
1983
- return 0;
1984
- const n = parseInt(cursor, 10);
1985
- return Number.isFinite(n) && n >= 0 ? n : 0;
1986
- }
1987
- function encodeCursor(offset) {
1988
- return String(offset);
1989
- }
1990
- function toRange(opts) {
1991
- const limit = Math.min(Math.max(opts?.limit ?? DEFAULT_PAGE_LIMIT, 1), MAX_PAGE_LIMIT);
1992
- const from = decodeCursor(opts?.cursor);
1993
- return { from, to: from + limit - 1, limit };
1994
- }
1995
- function nextCursorFromRange(range, returnedCount, totalCount) {
1996
- const consumed = range.from + returnedCount;
1997
- if (totalCount != null) {
1998
- return consumed < totalCount ? encodeCursor(consumed) : void 0;
1999
- }
2000
- return returnedCount >= range.limit ? encodeCursor(consumed) : void 0;
2001
- }
2002
- function orderColumn(orderBy) {
2003
- switch (orderBy) {
2004
- case "name":
2005
- return "name";
2006
- case "updatedAt":
2007
- return "updated_at";
2008
- case "createdAt":
2009
- default:
2010
- return "created_at";
2011
- }
2012
- }
2013
- class SupabaseOrgStore {
2014
- clients;
2015
- events;
2016
- constructor(clients, events = new NoopEventSink()) {
2017
- this.clients = clients;
2018
- this.events = events;
2019
- }
2020
- async listOrgs(ctx, opts) {
2021
- const range = toRange(opts);
2022
- const direction = opts?.orderDir ?? "desc";
2023
- const { data, error, count } = await this.clients.forRequest(ctx).from("orgs").select("*", { count: "exact" }).is("deleted_at", null).order(orderColumn(opts?.orderBy), { ascending: direction === "asc" }).range(range.from, range.to);
2024
- if (error)
2025
- throw mapError$7(error);
2026
- const items = (data ?? []).map(rowToOrg);
2027
- return { items, nextCursor: nextCursorFromRange(range, items.length, count) };
2028
- }
2029
- async getOrg(ctx, id) {
2030
- const { data, error } = await this.clients.forRequest(ctx).from("orgs").select("*").eq("id", id).is("deleted_at", null).maybeSingle();
2031
- if (error)
2032
- throw mapError$7(error);
2033
- return data ? rowToOrg(data) : null;
2034
- }
2035
- async getOrgBySlug(ctx, slug) {
2036
- const { data, error } = await this.clients.forRequest(ctx).from("orgs").select("*").eq("slug", slug).is("deleted_at", null).maybeSingle();
2037
- if (error)
2038
- throw mapError$7(error);
2039
- return data ? rowToOrg(data) : null;
2040
- }
2041
- async createOrg(ctx, org) {
2042
- const client = this.clients.forRequest(ctx);
2043
- const { error } = await client.from("orgs").insert(orgToRow(org));
2044
- if (error)
2045
- throw mapError$7(error);
2046
- const { error: memberError } = await client.from("org_members").upsert({
2047
- org_id: org.id,
2048
- user_id: org.ownerId,
2049
- role: "owner",
2050
- permissions: [...DEFAULT_ORG_PERMISSIONS.owner],
2051
- joined_at: (/* @__PURE__ */ new Date()).toISOString(),
2052
- deleted_at: null
2053
- }, { onConflict: "org_id,user_id" });
2054
- if (memberError)
2055
- throw mapError$7(memberError);
2056
- await this.events.emit({ type: "org.created", orgId: org.id, actorId: actorFrom(ctx) });
2057
- }
2058
- async updateOrg(ctx, id, patch) {
2059
- const row = {};
2060
- if (patch.name !== void 0)
2061
- row.name = patch.name;
2062
- if (patch.slug !== void 0)
2063
- row.slug = patch.slug;
2064
- if (Object.keys(row).length === 0)
2065
- return;
2066
- if (ctx.userId)
2067
- row.updated_by = ctx.userId;
2068
- const { error, data } = await this.clients.forRequest(ctx).from("orgs").update(row).eq("id", id).is("deleted_at", null).select("id");
2069
- if (error)
2070
- throw mapError$7(error);
2071
- if (!data || data.length === 0)
2072
- throw new ProviderError(`Org '${id}' not found`, 404);
2073
- }
2074
- async deleteOrg(ctx, id) {
2075
- const client = this.clients.forRequest(ctx);
2076
- const stamp = auditSoftDelete(ctx, ctx.userId);
2077
- const stampRow = stampToRow$1(stamp);
2078
- const { error: orgErr, data: orgData } = await client.from("orgs").update(stampRow).eq("id", id).is("deleted_at", null).select("id");
2079
- if (orgErr)
2080
- throw mapError$7(orgErr);
2081
- if (!orgData || orgData.length === 0)
2082
- throw new ProviderError(`Org '${id}' not found`, 404);
2083
- const { error: omErr } = await client.from("org_members").update(stampRow).eq("org_id", id).is("deleted_at", null);
2084
- if (omErr)
2085
- throw mapError$7(omErr);
2086
- const { data: orgProjects, error: projFetchErr } = await client.from("projects").select("id").eq("org_id", id).is("deleted_at", null);
2087
- if (projFetchErr)
2088
- throw mapError$7(projFetchErr);
2089
- const projectIds = (orgProjects ?? []).map((p) => p.id);
2090
- const { error: projErr } = await client.from("projects").update(stampRow).eq("org_id", id).is("deleted_at", null);
2091
- if (projErr)
2092
- throw mapError$7(projErr);
2093
- if (projectIds.length > 0) {
2094
- const { error: pmErr } = await client.from("project_members").update(stampRow).in("project_id", projectIds).is("deleted_at", null);
2095
- if (pmErr)
2096
- throw mapError$7(pmErr);
2097
- const { error: defErr } = await client.from("definitions").update(stampRow).in("project_id", projectIds).is("deleted_at", null);
2098
- if (defErr)
2099
- throw mapError$7(defErr);
2100
- }
2101
- const { error: invErr } = await client.from("invites").delete().eq("org_id", id);
2102
- if (invErr)
2103
- throw mapError$7(invErr);
2104
- const { error: cdErr } = await client.from("compute_server_org_defaults").delete().eq("org_id", id);
2105
- if (cdErr)
2106
- throw mapError$7(cdErr);
2107
- const { error: shErr } = await client.from("compute_server_shares").delete().eq("org_id", id);
2108
- if (shErr)
2109
- throw mapError$7(shErr);
2110
- const { error: csErr } = await client.from("compute_servers").delete().eq("scope", "org").eq("owner_org_id", id);
2111
- if (csErr)
2112
- throw mapError$7(csErr);
2113
- await this.events.emit({ type: "org.deleted", orgId: id, actorId: actorFrom(ctx) });
2114
- }
2115
- // ============================================================================
2116
- // Org members
2117
- // ============================================================================
2118
- async listOrgMembers(ctx, orgId, opts) {
2119
- const range = toRange(opts);
2120
- const { data, error, count } = await this.clients.forRequest(ctx).from("org_members").select("*", { count: "exact" }).eq("org_id", orgId).is("deleted_at", null).order("joined_at", { ascending: (opts?.orderDir ?? "desc") === "asc" }).range(range.from, range.to);
2121
- if (error)
2122
- throw mapError$7(error);
2123
- const items = (data ?? []).map(rowToOrgMember);
2124
- return { items, nextCursor: nextCursorFromRange(range, items.length, count) };
2125
- }
2126
- async getOrgMember(ctx, orgId, userId) {
2127
- const { data, error } = await this.clients.forRequest(ctx).from("org_members").select("*").eq("org_id", orgId).eq("user_id", userId).is("deleted_at", null).maybeSingle();
2128
- if (error)
2129
- throw mapError$7(error);
2130
- return data ? rowToOrgMember(data) : null;
2131
- }
2132
- async findUserMembership(ctx, userId) {
2133
- const { data, error } = await this.clients.forRequest(ctx).from("org_members").select("*, org:orgs!inner(*)").eq("user_id", userId).is("deleted_at", null).is("org.deleted_at", null).order("joined_at", { ascending: true }).limit(1).maybeSingle();
2134
- if (error)
2135
- throw mapError$7(error);
2136
- if (!data)
2137
- return null;
2138
- const row = data;
2139
- const orgRow = Array.isArray(row.org) ? row.org[0] : row.org;
2140
- if (!orgRow)
2141
- return null;
2142
- const { org: _omit, ...memberRow } = row;
2143
- return {
2144
- org: rowToOrg(orgRow),
2145
- member: rowToOrgMember(memberRow)
2146
- };
2147
- }
2148
- async addOrgMember(ctx, member) {
2149
- const row = {
2150
- ...memberToRow(member),
2151
- deleted_at: null
2152
- };
2153
- if (ctx.userId)
2154
- row.updated_by = ctx.userId;
2155
- const { error } = await this.clients.forRequest(ctx).from("org_members").upsert(row, { onConflict: "org_id,user_id" });
2156
- if (error)
2157
- throw mapError$7(error);
2158
- await this.events.emit({
2159
- type: "org_member.added",
2160
- orgId: member.orgId,
2161
- userId: member.userId,
2162
- actorId: actorFrom(ctx)
2163
- });
2164
- }
2165
- async updateOrgMemberRole(ctx, orgId, userId, role) {
2166
- const row = {
2167
- role,
2168
- permissions: [...DEFAULT_ORG_PERMISSIONS[role]]
2169
- };
2170
- if (ctx.userId)
2171
- row.updated_by = ctx.userId;
2172
- const { data, error } = await this.clients.forRequest(ctx).from("org_members").update(row).eq("org_id", orgId).eq("user_id", userId).is("deleted_at", null).select("user_id");
2173
- if (error)
2174
- throw mapError$7(error);
2175
- if (!data || data.length === 0)
2176
- throw new ProviderError(`Org member '${userId}' not found`, 404);
2177
- await this.events.emit({
2178
- type: "org_member.role_changed",
2179
- orgId,
2180
- userId,
2181
- role,
2182
- actorId: actorFrom(ctx)
2183
- });
2184
- }
2185
- async updateOrgMemberPermissions(ctx, orgId, userId, permissions) {
2186
- const row = { permissions: [...permissions] };
2187
- if (ctx.userId)
2188
- row.updated_by = ctx.userId;
2189
- const { data, error } = await this.clients.forRequest(ctx).from("org_members").update(row).eq("org_id", orgId).eq("user_id", userId).is("deleted_at", null).select("user_id");
2190
- if (error)
2191
- throw mapError$7(error);
2192
- if (!data || data.length === 0)
2193
- throw new ProviderError(`Org member '${userId}' not found`, 404);
2194
- await this.events.emit({
2195
- type: "org_member.permissions_changed",
2196
- orgId,
2197
- userId,
2198
- permissions: [...permissions],
2199
- actorId: actorFrom(ctx)
2200
- });
2201
- }
2202
- async removeOrgMember(ctx, orgId, userId) {
2203
- const client = this.clients.forRequest(ctx);
2204
- const stamp = auditSoftDelete(ctx, ctx.userId);
2205
- const stampRow = stampToRow$1(stamp);
2206
- const { data: orgProjects, error: projError } = await client.from("projects").select("id").eq("org_id", orgId).is("deleted_at", null);
2207
- if (projError)
2208
- throw mapError$7(projError);
2209
- const projectIds = (orgProjects ?? []).map((p) => p.id);
2210
- if (projectIds.length > 0) {
2211
- const { error: pmError } = await client.from("project_members").update(stampRow).in("project_id", projectIds).eq("user_id", userId).is("deleted_at", null);
2212
- if (pmError)
2213
- throw mapError$7(pmError);
2214
- }
2215
- const { error } = await client.from("org_members").update(stampRow).eq("org_id", orgId).eq("user_id", userId).is("deleted_at", null);
2216
- if (error)
2217
- throw mapError$7(error);
2218
- await this.events.emit({
2219
- type: "org_member.removed",
2220
- orgId,
2221
- userId,
2222
- actorId: actorFrom(ctx)
2223
- });
2224
- }
2225
- }
2226
- function stampToRow$1(stamp) {
2227
- const row = {
2228
- deleted_at: stamp.deletedAt,
2229
- updated_at: stamp.updatedAt
2230
- };
2231
- if (stamp.updatedBy)
2232
- row.updated_by = stamp.updatedBy;
2233
- return row;
2234
- }
2235
- function rowToOrg(row) {
2236
- return {
2237
- id: row.id,
2238
- name: row.name,
2239
- slug: row.slug,
2240
- ownerId: row.owner_id,
2241
- createdBy: row.created_by ?? row.owner_id,
2242
- updatedBy: row.updated_by ?? row.owner_id,
2243
- createdAt: row.created_at,
2244
- updatedAt: row.updated_at,
2245
- deletedAt: row.deleted_at ?? null
2246
- };
2247
- }
2248
- function orgToRow(org) {
2249
- return {
2250
- id: org.id,
2251
- name: org.name,
2252
- slug: org.slug,
2253
- owner_id: org.ownerId,
2254
- created_by: org.createdBy,
2255
- updated_by: org.updatedBy,
2256
- created_at: org.createdAt,
2257
- updated_at: org.updatedAt,
2258
- deleted_at: org.deletedAt ?? null
2259
- };
2260
- }
2261
- function rowToOrgMember(row) {
2262
- return {
2263
- orgId: row.org_id,
2264
- userId: row.user_id,
2265
- role: row.role,
2266
- permissions: row.permissions ?? [],
2267
- joinedAt: row.joined_at,
2268
- updatedAt: row.updated_at ?? row.joined_at,
2269
- updatedBy: row.updated_by ?? row.user_id,
2270
- deletedAt: row.deleted_at ?? null
2271
- };
2272
- }
2273
- function memberToRow(m) {
2274
- return {
2275
- org_id: m.orgId,
2276
- user_id: m.userId,
2277
- role: m.role,
2278
- permissions: m.permissions ?? [],
2279
- joined_at: m.joinedAt
2280
- };
2281
- }
2282
- function mapError$7(e) {
2283
- const pg = e;
2284
- if (pg?.code === "23505") {
2285
- return new ProviderError(pg.message ?? "Duplicate record", 409);
2286
- }
2287
- if (pg?.code === "23503") {
2288
- return new ProviderError(pg.message ?? "Foreign key violation", 409);
2289
- }
2290
- if (e instanceof Error)
2291
- return e;
2292
- if (e && typeof e === "object") {
2293
- const obj = e;
2294
- const msg = obj.message ?? obj.details ?? obj.hint ?? "Unknown Postgres error";
2295
- const err = new Error(obj.code ? `[${obj.code}] ${msg}` : msg);
2296
- Object.assign(err, obj);
2297
- return err;
2298
- }
2299
- return new Error(String(e));
2300
- }
2301
- class SupabaseProjectStore {
2302
- clients;
2303
- events;
2304
- constructor(clients, events = new NoopEventSink()) {
2305
- this.clients = clients;
2306
- this.events = events;
2307
- }
2308
- async listProjects(ctx, orgId, opts) {
2309
- const range = toRange(opts);
2310
- const direction = opts?.orderDir ?? "desc";
2311
- const { data, error, count } = await this.clients.forRequest(ctx).from("projects").select("*", { count: "exact" }).eq("org_id", orgId).is("deleted_at", null).order(orderColumn(opts?.orderBy), { ascending: direction === "asc" }).range(range.from, range.to);
2312
- if (error)
2313
- throw mapError$6(error);
2314
- const items = (data ?? []).map(rowToProject);
2315
- return { items, nextCursor: nextCursorFromRange(range, items.length, count) };
2316
- }
2317
- async getProject(ctx, id) {
2318
- const { data, error } = await this.clients.forRequest(ctx).from("projects").select("*").eq("id", id).is("deleted_at", null).maybeSingle();
2319
- if (error)
2320
- throw mapError$6(error);
2321
- return data ? rowToProject(data) : null;
2322
- }
2323
- async getProjectBySlug(ctx, orgId, slug) {
2324
- const { data, error } = await this.clients.forRequest(ctx).from("projects").select("*").eq("org_id", orgId).eq("slug", slug).is("deleted_at", null).maybeSingle();
2325
- if (error)
2326
- throw mapError$6(error);
2327
- return data ? rowToProject(data) : null;
2328
- }
2329
- async createProject(ctx, project) {
2330
- const client = this.clients.forRequest(ctx);
2331
- const { error } = await client.from("projects").insert(projectToRow(project));
2332
- if (error)
2333
- throw mapError$6(error);
2334
- const { error: memberError } = await client.from("project_members").upsert({
2335
- project_id: project.id,
2336
- user_id: project.ownerId,
2337
- role: "owner",
2338
- joined_at: (/* @__PURE__ */ new Date()).toISOString(),
2339
- deleted_at: null
2340
- }, { onConflict: "project_id,user_id" });
2341
- if (memberError)
2342
- throw mapError$6(memberError);
2343
- await this.events.emit({
2344
- type: "project.created",
2345
- projectId: project.id,
2346
- orgId: project.orgId,
2347
- actorId: actorFrom(ctx)
2348
- });
2349
- }
2350
- async updateProject(ctx, id, patch) {
2351
- const row = {};
2352
- if (patch.name !== void 0)
2353
- row.name = patch.name;
2354
- if (patch.slug !== void 0)
2355
- row.slug = patch.slug;
2356
- if (patch.description !== void 0)
2357
- row.description = patch.description;
2358
- if (patch.visibility !== void 0)
2359
- row.visibility = patch.visibility;
2360
- if (patch.autoJoinOnUpload !== void 0)
2361
- row.auto_join_on_upload = patch.autoJoinOnUpload;
2362
- if (Object.keys(row).length === 0)
2363
- return;
2364
- if (ctx.userId)
2365
- row.updated_by = ctx.userId;
2366
- const { data, error } = await this.clients.forRequest(ctx).from("projects").update(row).eq("id", id).is("deleted_at", null).select("id");
2367
- if (error)
2368
- throw mapError$6(error);
2369
- if (!data || data.length === 0)
2370
- throw new ProviderError(`Project '${id}' not found`, 404);
2371
- }
2372
- async deleteProject(ctx, id) {
2373
- const client = this.clients.forRequest(ctx);
2374
- const stamp = auditSoftDelete(ctx, ctx.userId);
2375
- const stampRow = stampToRow(stamp);
2376
- const { data, error } = await client.from("projects").update(stampRow).eq("id", id).is("deleted_at", null).select("id");
2377
- if (error)
2378
- throw mapError$6(error);
2379
- if (!data || data.length === 0)
2380
- throw new ProviderError(`Project '${id}' not found`, 404);
2381
- const { error: pmErr } = await client.from("project_members").update(stampRow).eq("project_id", id).is("deleted_at", null);
2382
- if (pmErr)
2383
- throw mapError$6(pmErr);
2384
- const { error: defErr } = await client.from("definitions").update(stampRow).eq("project_id", id).is("deleted_at", null);
2385
- if (defErr)
2386
- throw mapError$6(defErr);
2387
- await this.events.emit({ type: "project.deleted", projectId: id, actorId: actorFrom(ctx) });
2388
- }
2389
- // ============================================================================
2390
- // Project members
2391
- // ============================================================================
2392
- async listProjectMembers(ctx, projectId, opts) {
2393
- const range = toRange(opts);
2394
- const { data, error, count } = await this.clients.forRequest(ctx).from("project_members").select("*", { count: "exact" }).eq("project_id", projectId).is("deleted_at", null).order("joined_at", { ascending: (opts?.orderDir ?? "desc") === "asc" }).range(range.from, range.to);
2395
- if (error)
2396
- throw mapError$6(error);
2397
- const items = (data ?? []).map(rowToProjectMember);
2398
- return { items, nextCursor: nextCursorFromRange(range, items.length, count) };
2399
- }
2400
- async getProjectMember(ctx, projectId, userId) {
2401
- const { data, error } = await this.clients.forRequest(ctx).from("project_members").select("*").eq("project_id", projectId).eq("user_id", userId).is("deleted_at", null).maybeSingle();
2402
- if (error)
2403
- throw mapError$6(error);
2404
- return data ? rowToProjectMember(data) : null;
2405
- }
2406
- async addProjectMember(ctx, member) {
2407
- const row = {
2408
- ...projectMemberToRow(member),
2409
- deleted_at: null
2410
- };
2411
- if (ctx.userId)
2412
- row.updated_by = ctx.userId;
2413
- const { error } = await this.clients.forRequest(ctx).from("project_members").upsert(row, { onConflict: "project_id,user_id" });
2414
- if (error)
2415
- throw mapError$6(error);
2416
- await this.events.emit({
2417
- type: "project_member.added",
2418
- projectId: member.projectId,
2419
- userId: member.userId,
2420
- actorId: actorFrom(ctx)
2421
- });
2422
- }
2423
- async updateProjectMemberRole(ctx, projectId, userId, role) {
2424
- const row = { role };
2425
- if (ctx.userId)
2426
- row.updated_by = ctx.userId;
2427
- const { data, error } = await this.clients.forRequest(ctx).from("project_members").update(row).eq("project_id", projectId).eq("user_id", userId).is("deleted_at", null).select("user_id");
2428
- if (error)
2429
- throw mapError$6(error);
2430
- if (!data || data.length === 0)
2431
- throw new ProviderError(`Project member '${userId}' not found`, 404);
2432
- await this.events.emit({
2433
- type: "project_member.role_changed",
2434
- projectId,
2435
- userId,
2436
- role,
2437
- actorId: actorFrom(ctx)
2438
- });
2439
- }
2440
- async removeProjectMember(ctx, projectId, userId) {
2441
- const stamp = auditSoftDelete(ctx, ctx.userId);
2442
- const { error } = await this.clients.forRequest(ctx).from("project_members").update(stampToRow(stamp)).eq("project_id", projectId).eq("user_id", userId).is("deleted_at", null);
2443
- if (error)
2444
- throw mapError$6(error);
2445
- await this.events.emit({
2446
- type: "project_member.removed",
2447
- projectId,
2448
- userId,
2449
- actorId: actorFrom(ctx)
2450
- });
2451
- }
2452
- }
2453
- function rowToProject(row) {
2454
- return {
2455
- id: row.id,
2456
- orgId: row.org_id,
2457
- name: row.name,
2458
- slug: row.slug,
2459
- description: row.description ?? void 0,
2460
- visibility: row.visibility,
2461
- ownerId: row.owner_id,
2462
- createdBy: row.created_by ?? row.owner_id,
2463
- updatedBy: row.updated_by ?? row.owner_id,
2464
- autoJoinOnUpload: row.auto_join_on_upload ?? false,
2465
- createdAt: row.created_at,
2466
- updatedAt: row.updated_at,
2467
- deletedAt: row.deleted_at ?? null
2468
- };
2469
- }
2470
- function projectToRow(p) {
2471
- return {
2472
- id: p.id,
2473
- org_id: p.orgId,
2474
- name: p.name,
2475
- slug: p.slug,
2476
- description: p.description ?? null,
2477
- visibility: p.visibility,
2478
- owner_id: p.ownerId,
2479
- created_by: p.createdBy,
2480
- updated_by: p.updatedBy,
2481
- auto_join_on_upload: p.autoJoinOnUpload,
2482
- created_at: p.createdAt,
2483
- updated_at: p.updatedAt,
2484
- deleted_at: p.deletedAt ?? null
2485
- };
2486
- }
2487
- function rowToProjectMember(row) {
2488
- return {
2489
- projectId: row.project_id,
2490
- userId: row.user_id,
2491
- role: row.role,
2492
- joinedAt: row.joined_at,
2493
- updatedAt: row.updated_at ?? row.joined_at,
2494
- updatedBy: row.updated_by ?? row.user_id,
2495
- deletedAt: row.deleted_at ?? null
2496
- };
2497
- }
2498
- function projectMemberToRow(m) {
2499
- return {
2500
- project_id: m.projectId,
2501
- user_id: m.userId,
2502
- role: m.role,
2503
- joined_at: m.joinedAt
2504
- };
2505
- }
2506
- function stampToRow(stamp) {
2507
- const row = {
2508
- deleted_at: stamp.deletedAt,
2509
- updated_at: stamp.updatedAt
2510
- };
2511
- if (stamp.updatedBy)
2512
- row.updated_by = stamp.updatedBy;
2513
- return row;
2514
- }
2515
- function mapError$6(e) {
2516
- const pg = e;
2517
- if (pg?.code === "23505")
2518
- return new ProviderError(pg.message ?? "Duplicate record", 409);
2519
- if (pg?.code === "23503")
2520
- return new ProviderError(pg.message ?? "Foreign key violation", 409);
2521
- if (e instanceof Error)
2522
- return e;
2523
- if (e && typeof e === "object") {
2524
- const obj = e;
2525
- const msg = obj.message ?? obj.details ?? obj.hint ?? "Unknown Postgres error";
2526
- const err = new Error(obj.code ? `[${obj.code}] ${msg}` : msg);
2527
- Object.assign(err, obj);
2528
- return err;
2529
- }
2530
- return new Error(String(e));
2531
- }
2532
- class SupabaseDefinitionStore {
2533
- clients;
2534
- events;
2535
- constructor(clients, events = new NoopEventSink()) {
2536
- this.clients = clients;
2537
- this.events = events;
2538
- }
2539
- // ============================================================================
2540
- // Definitions
2541
- // ============================================================================
2542
- async list(ctx, opts) {
2543
- return this.runList(ctx, void 0, opts);
2544
- }
2545
- async listByProject(ctx, projectId, opts) {
2546
- return this.runList(ctx, { projectId }, opts);
2547
- }
2548
- async listPublic(ctx, opts) {
2549
- return this.runList(ctx, { publicOnly: true, orgId: opts?.orgId }, opts);
2550
- }
2551
- async runList(ctx, filter, opts) {
2552
- const range = toRange(opts);
2553
- const direction = opts?.orderDir ?? "desc";
2554
- let query = this.clients.forRequest(ctx).from("definitions").select("*", { count: "exact" }).is("deleted_at", null);
2555
- if (filter?.projectId)
2556
- query = query.eq("project_id", filter.projectId);
2557
- if (filter?.publicOnly) {
2558
- query = this.clients.forRequest(ctx).from("definitions").select("*, project:projects!inner(visibility, org_id)", {
2559
- count: "exact"
2560
- }).is("deleted_at", null).eq("project.visibility", "public");
2561
- if (filter.orgId)
2562
- query = query.eq("project.org_id", filter.orgId);
2563
- if (filter.projectId)
2564
- query = query.eq("project_id", filter.projectId);
2565
- }
2566
- if (opts?.statuses?.length) {
2567
- query = query.in("status", opts.statuses);
2568
- } else {
2569
- const excluded = [];
2570
- if (!opts?.includePending)
2571
- excluded.push("pending");
2572
- if (!opts?.includeArchived)
2573
- excluded.push("archived");
2574
- if (excluded.length) {
2575
- query = query.not("status", "in", `(${excluded.join(",")})`);
2576
- }
2577
- }
2578
- query = query.order(definitionOrderColumn(opts?.orderBy), { ascending: direction === "asc" }).range(range.from, range.to);
2579
- const { data, error, count } = await query;
2580
- if (error)
2581
- throw mapError$5(error);
2582
- const items = (data ?? []).map(rowToRecord);
2583
- return { items, nextCursor: nextCursorFromRange(range, items.length, count) };
2584
- }
2585
- async get(ctx, guid) {
2586
- const { data, error } = await this.clients.forRequest(ctx).from("definitions").select("*").eq("guid", guid).is("deleted_at", null).maybeSingle();
2587
- if (error)
2588
- throw mapError$5(error);
2589
- return data ? rowToRecord(data) : null;
2590
- }
2591
- async create(ctx, record) {
2592
- const { error } = await this.clients.forRequest(ctx).from("definitions").insert(recordToRow(record));
2593
- if (error)
2594
- throw mapError$5(error);
2595
- await this.events.emit({
2596
- type: "definition.created",
2597
- definitionId: record.guid,
2598
- projectId: record.projectId,
2599
- actorId: actorFrom(ctx)
2600
- });
2601
- }
2602
- async update(ctx, guid, patch) {
2603
- const row = patchToRow(patch);
2604
- if (Object.keys(row).length === 0)
2605
- return;
2606
- if (ctx.userId)
2607
- row.updated_by = ctx.userId;
2608
- const { data, error } = await this.clients.forRequest(ctx).from("definitions").update(row).eq("guid", guid).is("deleted_at", null).select("guid");
2609
- if (error)
2610
- throw mapError$5(error);
2611
- if (!data || data.length === 0)
2612
- throw new ProviderError(`Definition '${guid}' not found`, 404);
2613
- }
2614
- async delete(ctx, guid) {
2615
- const stamp = auditSoftDelete(ctx, ctx.userId);
2616
- const row = {
2617
- deleted_at: stamp.deletedAt,
2618
- updated_at: stamp.updatedAt
2619
- };
2620
- if (stamp.updatedBy)
2621
- row.updated_by = stamp.updatedBy;
2622
- const { error } = await this.clients.forRequest(ctx).from("definitions").update(row).eq("guid", guid).is("deleted_at", null);
2623
- if (error)
2624
- throw mapError$5(error);
2625
- await this.events.emit({
2626
- type: "definition.deleted",
2627
- definitionId: guid,
2628
- actorId: actorFrom(ctx)
2629
- });
2630
- }
2631
- async incrementSolveCount(ctx, guid) {
2632
- const { error } = await this.clients.forRequest(ctx).rpc("increment_run_count", { g: guid });
2633
- if (error)
2634
- throw mapError$5(error);
2635
- }
2636
- // ============================================================================
2637
- // Versions (spec §6)
2638
- // ============================================================================
2639
- async createVersion(ctx, version) {
2640
- const { error } = await this.clients.forRequest(ctx).from("definition_versions").insert(versionToRow(version));
2641
- if (error)
2642
- throw mapError$5(error);
2643
- await this.events.emit({
2644
- type: "definition_version.created",
2645
- versionId: version.id,
2646
- definitionId: version.definitionId,
2647
- actorId: actorFrom(ctx)
2648
- });
2649
- }
2650
- async listVersions(ctx, definitionId, opts) {
2651
- const range = toRange(opts);
2652
- const { data, error, count } = await this.clients.forRequest(ctx).from("definition_versions").select("*", { count: "exact" }).eq("definition_guid", definitionId).order("version_number", { ascending: false }).range(range.from, range.to);
2653
- if (error)
2654
- throw mapError$5(error);
2655
- const items = (data ?? []).map(rowToVersion);
2656
- return { items, nextCursor: nextCursorFromRange(range, items.length, count) };
2657
- }
2658
- async getVersion(ctx, versionId) {
2659
- const { data, error } = await this.clients.forRequest(ctx).from("definition_versions").select("*").eq("id", versionId).maybeSingle();
2660
- if (error)
2661
- throw mapError$5(error);
2662
- return data ? rowToVersion(data) : null;
2663
- }
2664
- async deleteVersion(ctx, versionId) {
2665
- const { error } = await this.clients.forRequest(ctx).from("definition_versions").delete().eq("id", versionId);
2666
- if (error)
2667
- throw mapError$5(error);
2668
- await this.events.emit({
2669
- type: "definition_version.deleted",
2670
- versionId,
2671
- actorId: actorFrom(ctx)
2672
- });
2673
- }
2674
- async setLiveVersion(ctx, definitionId, versionId) {
2675
- await this.repointChannel(ctx, definitionId, versionId, "live_version_id");
2676
- await this.events.emit({
2677
- type: "definition.published",
2678
- definitionId,
2679
- versionId,
2680
- actorId: actorFrom(ctx)
2681
- });
2682
- }
2683
- async setDraftVersion(ctx, definitionId, versionId) {
2684
- await this.repointChannel(ctx, definitionId, versionId, "draft_version_id");
2685
- }
2686
- async attachInitialVersion(ctx, definitionId, versionId) {
2687
- const client = this.clients.forRequest(ctx);
2688
- const { data: version, error: vError } = await client.from("definition_versions").select("id, definition_guid").eq("id", versionId).maybeSingle();
2689
- if (vError)
2690
- throw mapError$5(vError);
2691
- if (!version || version.definition_guid !== definitionId) {
2692
- throw new ProviderError(`Version '${versionId}' not found for this definition`, 404);
2693
- }
2694
- const row = {
2695
- live_version_id: versionId,
2696
- draft_version_id: versionId,
2697
- status: "draft"
2698
- };
2699
- if (ctx.userId)
2700
- row.updated_by = ctx.userId;
2701
- const { data, error } = await client.from("definitions").update(row).eq("guid", definitionId).is("deleted_at", null).select("guid");
2702
- if (error)
2703
- throw mapError$5(error);
2704
- if (!data || data.length === 0) {
2705
- throw new ProviderError(`Definition '${definitionId}' not found`, 404);
2706
- }
2707
- }
2708
- async repointChannel(ctx, definitionId, versionId, column) {
2709
- const client = this.clients.forRequest(ctx);
2710
- const { data: version, error: vError } = await client.from("definition_versions").select("id, definition_guid").eq("id", versionId).maybeSingle();
2711
- if (vError)
2712
- throw mapError$5(vError);
2713
- if (!version || version.definition_guid !== definitionId) {
2714
- throw new ProviderError(`Version '${versionId}' not found for this definition`, 404);
2715
- }
2716
- const row = { [column]: versionId };
2717
- if (ctx.userId)
2718
- row.updated_by = ctx.userId;
2719
- const { data, error } = await client.from("definitions").update(row).eq("guid", definitionId).is("deleted_at", null).select("guid");
2720
- if (error)
2721
- throw mapError$5(error);
2722
- if (!data || data.length === 0) {
2723
- throw new ProviderError(`Definition '${definitionId}' not found`, 404);
2724
- }
2725
- }
2726
- }
2727
- function rowToRecord(row) {
2728
- return {
2729
- guid: row.guid,
2730
- projectId: row.project_id,
2731
- ownerId: row.owner_id,
2732
- createdBy: row.created_by ?? row.owner_id,
2733
- updatedBy: row.updated_by ?? row.owner_id,
2734
- liveVersionId: row.live_version_id,
2735
- draftVersionId: row.draft_version_id,
2736
- computeServerId: row.compute_server_id ?? void 0,
2737
- displayName: row.display_name,
2738
- description: row.description ?? void 0,
2739
- category: row.category ?? void 0,
2740
- tags: row.tags ?? void 0,
2741
- coverImage: row.cover_image ?? void 0,
2742
- status: row.status,
2743
- solveCount: typeof row.run_count === "string" ? Number(row.run_count) : row.run_count,
2744
- createdAt: row.created_at,
2745
- updatedAt: row.updated_at,
2746
- deletedAt: row.deleted_at ?? null
2747
- };
2748
- }
2749
- function recordToRow(r) {
2750
- const row = {
2751
- guid: r.guid,
2752
- project_id: r.projectId,
2753
- owner_id: r.ownerId,
2754
- created_by: r.createdBy,
2755
- updated_by: r.updatedBy,
2756
- live_version_id: r.liveVersionId,
2757
- draft_version_id: r.draftVersionId,
2758
- compute_server_id: r.computeServerId ?? null,
2759
- display_name: r.displayName,
2760
- description: r.description ?? null,
2761
- category: r.category ?? null,
2762
- cover_image: r.coverImage ?? null,
2763
- status: r.status,
2764
- run_count: r.solveCount,
2765
- created_at: r.createdAt,
2766
- updated_at: r.updatedAt,
2767
- deleted_at: r.deletedAt ?? null
2768
- };
2769
- if (r.tags !== void 0)
2770
- row.tags = r.tags;
2771
- return row;
2772
- }
2773
- function patchToRow(patch) {
2774
- const row = {};
2775
- if (patch.displayName !== void 0)
2776
- row.display_name = patch.displayName;
2777
- if (patch.description !== void 0)
2778
- row.description = patch.description;
2779
- if (patch.category !== void 0)
2780
- row.category = patch.category;
2781
- if (patch.tags !== void 0)
2782
- row.tags = patch.tags;
2783
- if (patch.coverImage !== void 0)
2784
- row.cover_image = patch.coverImage;
2785
- if (patch.projectId !== void 0)
2786
- row.project_id = patch.projectId;
2787
- if (patch.computeServerId !== void 0)
2788
- row.compute_server_id = patch.computeServerId;
2789
- if (patch.status !== void 0)
2790
- row.status = patch.status;
2791
- if (patch.ownerId !== void 0)
2792
- row.owner_id = patch.ownerId;
2793
- return row;
2794
- }
2795
- function rowToVersion(row) {
2796
- return {
2797
- id: row.id,
2798
- definitionId: row.definition_guid,
2799
- versionNumber: row.version_number,
2800
- fileExt: row.file_ext,
2801
- fileKey: row.file_key,
2802
- originalFilename: row.original_filename ?? void 0,
2803
- uploadedBy: row.uploaded_by,
2804
- uploadedAt: row.uploaded_at,
2805
- changeNote: row.change_note ?? void 0
2806
- };
2807
- }
2808
- function versionToRow(v) {
2809
- const row = {
2810
- id: v.id,
2811
- definition_guid: v.definitionId,
2812
- version_number: v.versionNumber,
2813
- file_ext: v.fileExt,
2814
- file_key: v.fileKey,
2815
- original_filename: v.originalFilename ?? null,
2816
- uploaded_by: v.uploadedBy,
2817
- uploaded_at: v.uploadedAt
2818
- };
2819
- if (v.changeNote !== void 0)
2820
- row.change_note = v.changeNote;
2821
- return row;
2822
- }
2823
- function definitionOrderColumn(orderBy) {
2824
- switch (orderBy) {
2825
- case "name":
2826
- return "display_name";
2827
- case "solveCount":
2828
- return "run_count";
2829
- case "updatedAt":
2830
- return "updated_at";
2831
- case "createdAt":
2832
- default:
2833
- return "created_at";
2834
- }
2835
- }
2836
- function mapError$5(e) {
2837
- const pg = e;
2838
- if (pg?.code === "23505")
2839
- return new ProviderError(pg.message ?? "Duplicate record", 409);
2840
- if (pg?.code === "23503")
2841
- return new ProviderError(pg.message ?? "Foreign key violation", 409);
2842
- if (e instanceof Error)
2843
- return e;
2844
- if (e && typeof e === "object") {
2845
- const obj = e;
2846
- const msg = obj.message ?? obj.details ?? obj.hint ?? "Unknown Postgres error";
2847
- const err = new Error(obj.code ? `[${obj.code}] ${msg}` : msg);
2848
- Object.assign(err, obj);
2849
- return err;
2850
- }
2851
- return new Error(String(e));
2852
- }
2853
- class SupabaseInviteStore {
2854
- clients;
2855
- events;
2856
- constructor(clients, events = new NoopEventSink()) {
2857
- this.clients = clients;
2858
- this.events = events;
2859
- }
2860
- async create(ctx, invite) {
2861
- const { error } = await this.clients.forRequest(ctx).from("invites").insert(inviteToRow(invite));
2862
- if (error)
2863
- throw mapError$4(error);
2864
- await this.events.emit({
2865
- type: "invite.created",
2866
- inviteId: invite.id,
2867
- orgId: invite.orgId,
2868
- email: invite.email,
2869
- actorId: actorFrom(ctx)
2870
- });
2871
- }
2872
- async getByTokenHash(ctx, tokenHash) {
2873
- const { data, error } = await this.clients.forRequest(ctx).rpc("get_invite_by_token_hash", { h: tokenHash });
2874
- if (error)
2875
- throw mapError$4(error);
2876
- const row = Array.isArray(data) ? data[0] : data;
2877
- return row ? rowToInvite(row) : null;
2878
- }
2879
- async listByOrg(ctx, orgId, opts) {
2880
- const range = toRange(opts);
2881
- const { data, error, count } = await this.clients.forRequest(ctx).from("invites").select("*", { count: "exact" }).eq("org_id", orgId).order("created_at", { ascending: (opts?.orderDir ?? "desc") === "asc" }).range(range.from, range.to);
2882
- if (error)
2883
- throw mapError$4(error);
2884
- const items = (data ?? []).map(rowToInvite);
2885
- return { items, nextCursor: nextCursorFromRange(range, items.length, count) };
2886
- }
2887
- async markAccepted(ctx, id, userId) {
2888
- const { data, error } = await this.clients.forRequest(ctx).from("invites").update({ accepted_at: (/* @__PURE__ */ new Date()).toISOString(), accepted_by_user_id: userId }).eq("id", id).is("accepted_at", null).select("org_id");
2889
- if (error)
2890
- throw mapError$4(error);
2891
- const row = data?.[0];
2892
- if (!row)
2893
- return;
2894
- await this.events.emit({
2895
- type: "invite.accepted",
2896
- inviteId: id,
2897
- orgId: row.org_id,
2898
- userId,
2899
- actorId: actorFrom(ctx)
2900
- });
2901
- }
2902
- async revoke(ctx, id) {
2903
- const { data, error } = await this.clients.forRequest(ctx).from("invites").delete().eq("id", id).is("accepted_at", null).select("org_id");
2904
- if (error)
2905
- throw mapError$4(error);
2906
- const row = data?.[0];
2907
- if (!row)
2908
- return;
2909
- await this.events.emit({
2910
- type: "invite.revoked",
2911
- inviteId: id,
2912
- orgId: row.org_id,
2913
- actorId: actorFrom(ctx)
2914
- });
2915
- }
2916
- async deleteByOrg(ctx, orgId) {
2917
- const { error } = await this.clients.forRequest(ctx).from("invites").delete().eq("org_id", orgId);
2918
- if (error)
2919
- throw mapError$4(error);
2920
- }
2921
- }
2922
- function rowToInvite(row) {
2923
- return {
2924
- id: row.id,
2925
- tokenHash: row.token_hash,
2926
- email: row.email,
2927
- orgId: row.org_id,
2928
- orgRole: row.org_role,
2929
- orgPermissions: row.org_permissions,
2930
- invitedBy: row.invited_by,
2931
- createdAt: row.created_at,
2932
- expiresAt: row.expires_at,
2933
- acceptedAt: row.accepted_at ?? void 0,
2934
- acceptedByUserId: row.accepted_by_user_id ?? void 0
2935
- };
2936
- }
2937
- function inviteToRow(i) {
2938
- return {
2939
- id: i.id,
2940
- token_hash: i.tokenHash,
2941
- email: i.email,
2942
- org_id: i.orgId,
2943
- org_role: i.orgRole,
2944
- org_permissions: i.orgPermissions,
2945
- invited_by: i.invitedBy,
2946
- created_at: i.createdAt,
2947
- expires_at: i.expiresAt,
2948
- accepted_at: i.acceptedAt ?? null,
2949
- accepted_by_user_id: i.acceptedByUserId ?? null
2950
- };
2951
- }
2952
- function mapError$4(e) {
2953
- const pg = e;
2954
- if (pg?.code === "23505")
2955
- return new ProviderError(pg.message ?? "Duplicate record", 409);
2956
- if (pg?.code === "23503")
2957
- return new ProviderError(pg.message ?? "Foreign key violation", 409);
2958
- if (e instanceof Error)
2959
- return e;
2960
- if (e && typeof e === "object") {
2961
- const obj = e;
2962
- return new Error(obj.code ? `[${obj.code}] ${obj.message ?? ""}` : obj.message ?? String(e));
2963
- }
2964
- return new Error(String(e));
2965
- }
2966
- class SupabaseComputeServerStore {
2967
- clients;
2968
- constructor(clients) {
2969
- this.clients = clients;
2970
- }
2971
- async getConfig(ctx) {
2972
- const client = this.clients.forRequest(ctx);
2973
- const [serversRes, sharesRes, orgDefRes, platDefRes] = await Promise.all([
2974
- client.from("compute_servers").select("*"),
2975
- client.from("compute_server_shares").select("*"),
2976
- client.from("compute_server_org_defaults").select("*"),
2977
- client.from("compute_server_platform_default").select("default_server_id").eq("singleton", true).maybeSingle()
2978
- ]);
2979
- if (serversRes.error)
2980
- throw mapError$3(serversRes.error);
2981
- if (sharesRes.error)
2982
- throw mapError$3(sharesRes.error);
2983
- if (orgDefRes.error)
2984
- throw mapError$3(orgDefRes.error);
2985
- if (platDefRes.error)
2986
- throw mapError$3(platDefRes.error);
2987
- const sharedByServer = /* @__PURE__ */ new Map();
2988
- for (const row of sharesRes.data ?? []) {
2989
- const list = sharedByServer.get(row.server_id) ?? [];
2990
- list.push(row.org_id);
2991
- sharedByServer.set(row.server_id, list);
2992
- }
2993
- const servers = (serversRes.data ?? []).map((row) => rowToServer(row, sharedByServer));
2994
- const orgDefaults = {};
2995
- for (const row of orgDefRes.data ?? []) {
2996
- if (row.default_server_id)
2997
- orgDefaults[row.org_id] = row.default_server_id;
2998
- }
2999
- return {
3000
- servers,
3001
- defaultServerId: platDefRes.data?.default_server_id ?? void 0,
3002
- orgDefaults
3003
- };
3004
- }
3005
- async savePlatformServers(ctx, servers, defaultServerId) {
3006
- const client = this.clients.forRequest(ctx);
3007
- const platformOnly = servers.filter(isPlatformServer);
3008
- const { error: delErr } = await client.from("compute_servers").delete().eq("scope", "platform");
3009
- if (delErr)
3010
- throw mapError$3(delErr);
3011
- if (platformOnly.length > 0) {
3012
- const { error: insErr } = await client.from("compute_servers").insert(platformOnly.map(serverToRow));
3013
- if (insErr)
3014
- throw mapError$3(insErr);
3015
- const shareRows = platformOnly.flatMap((s) => s.sharedWith === "all" ? [] : s.sharedWith.map((orgId) => ({ server_id: s.id, org_id: orgId })));
3016
- if (shareRows.length > 0) {
3017
- const { error: shErr } = await client.from("compute_server_shares").insert(shareRows);
3018
- if (shErr)
3019
- throw mapError$3(shErr);
3020
- }
3021
- }
3022
- const { error: defErr } = await client.from("compute_server_platform_default").update({ default_server_id: defaultServerId ?? null }).eq("singleton", true);
3023
- if (defErr)
3024
- throw mapError$3(defErr);
3025
- }
3026
- async saveOrgServers(ctx, orgId, servers, defaultServerId) {
3027
- const client = this.clients.forRequest(ctx);
3028
- const orgOnly = servers.filter(isOrgServer).map((s) => ({ ...s, ownerOrgId: orgId }));
3029
- const { error: delErr } = await client.from("compute_servers").delete().eq("scope", "org").eq("owner_org_id", orgId);
3030
- if (delErr)
3031
- throw mapError$3(delErr);
3032
- if (orgOnly.length > 0) {
3033
- const { error: insErr } = await client.from("compute_servers").insert(orgOnly.map(serverToRow));
3034
- if (insErr)
3035
- throw mapError$3(insErr);
3036
- }
3037
- if (defaultServerId === null) {
3038
- const { error } = await client.from("compute_server_org_defaults").delete().eq("org_id", orgId);
3039
- if (error)
3040
- throw mapError$3(error);
3041
- } else if (typeof defaultServerId === "string") {
3042
- const { error } = await client.from("compute_server_org_defaults").upsert({ org_id: orgId, default_server_id: defaultServerId });
3043
- if (error)
3044
- throw mapError$3(error);
3045
- }
3046
- }
3047
- async setOrgDefault(ctx, orgId, serverId) {
3048
- const client = this.clients.forRequest(ctx);
3049
- if (serverId === null) {
3050
- const { error: error2 } = await client.from("compute_server_org_defaults").delete().eq("org_id", orgId);
3051
- if (error2)
3052
- throw mapError$3(error2);
3053
- return;
3054
- }
3055
- const { error } = await client.from("compute_server_org_defaults").upsert({ org_id: orgId, default_server_id: serverId });
3056
- if (error)
3057
- throw mapError$3(error);
3058
- }
3059
- async deleteByOrg(ctx, orgId) {
3060
- const client = this.clients.forRequest(ctx);
3061
- const { error: defErr } = await client.from("compute_server_org_defaults").delete().eq("org_id", orgId);
3062
- if (defErr)
3063
- throw mapError$3(defErr);
3064
- const { error: srvErr } = await client.from("compute_servers").delete().eq("scope", "org").eq("owner_org_id", orgId);
3065
- if (srvErr)
3066
- throw mapError$3(srvErr);
3067
- const { error: shErr } = await client.from("compute_server_shares").delete().eq("org_id", orgId);
3068
- if (shErr)
3069
- throw mapError$3(shErr);
3070
- }
3071
- }
3072
- function rowToServer(row, sharedByServer) {
3073
- const common = {
3074
- id: row.id,
3075
- label: row.label,
3076
- serverUrl: row.server_url,
3077
- apiKey: row.api_key ?? void 0,
3078
- timeoutMs: row.timeout_ms ?? void 0,
3079
- retryCount: row.retry_count ?? void 0
3080
- };
3081
- if (row.scope === "platform") {
3082
- return {
3083
- ...common,
3084
- scope: "platform",
3085
- sharedWith: row.shared_with_all ? "all" : sharedByServer.get(row.id) ?? []
3086
- };
3087
- }
3088
- if (!row.owner_org_id) {
3089
- throw new Error(`compute_servers row ${row.id} has scope='org' but null owner_org_id`);
3090
- }
3091
- return { ...common, scope: "org", ownerOrgId: row.owner_org_id };
3092
- }
3093
- function serverToRow(s) {
3094
- const base = {
3095
- id: s.id,
3096
- label: s.label,
3097
- server_url: s.serverUrl,
3098
- api_key: s.apiKey ?? null,
3099
- timeout_ms: s.timeoutMs ?? null,
3100
- retry_count: s.retryCount ?? null
3101
- };
3102
- if (isPlatformServer(s)) {
3103
- return {
3104
- ...base,
3105
- scope: "platform",
3106
- owner_org_id: null,
3107
- shared_with_all: s.sharedWith === "all"
3108
- };
3109
- }
3110
- return {
3111
- ...base,
3112
- scope: "org",
3113
- owner_org_id: s.ownerOrgId,
3114
- shared_with_all: false
3115
- };
3116
- }
3117
- function mapError$3(e) {
3118
- const pg = e;
3119
- if (pg?.code === "23505")
3120
- return new ProviderError(pg.message ?? "Duplicate record", 409);
3121
- if (pg?.code === "23503")
3122
- return new ProviderError(pg.message ?? "Foreign key violation", 409);
3123
- if (e instanceof Error)
3124
- return e;
3125
- if (e && typeof e === "object") {
3126
- const obj = e;
3127
- return new Error(obj.code ? `[${obj.code}] ${obj.message ?? ""}` : obj.message ?? String(e));
3128
- }
3129
- return new Error(String(e));
3130
- }
3131
- class SupabaseShareLinkStore {
3132
- clients;
3133
- events;
3134
- constructor(clients, events = new NoopEventSink()) {
3135
- this.clients = clients;
3136
- this.events = events;
3137
- }
3138
- async create(ctx, link) {
3139
- const { error } = await this.clients.forRequest(ctx).from("share_links").insert(linkToRow(link));
3140
- if (error)
3141
- throw mapError$2(error);
3142
- await this.events.emit({
3143
- type: "share_link.minted",
3144
- linkId: link.id,
3145
- definitionId: link.definitionId,
3146
- actorId: actorFrom(ctx)
3147
- });
3148
- }
3149
- async listByDefinition(ctx, definitionId, opts) {
3150
- const range = toRange(opts);
3151
- const { data, error, count } = await this.clients.forRequest(ctx).from("share_links").select("*", { count: "exact" }).eq("definition_guid", definitionId).is("revoked_at", null).order("created_at", { ascending: false }).range(range.from, range.to);
3152
- if (error)
3153
- throw mapError$2(error);
3154
- const items = (data ?? []).map(rowToLink);
3155
- return { items, nextCursor: nextCursorFromRange(range, items.length, count) };
3156
- }
3157
- async getById(ctx, id) {
3158
- const { data, error } = await this.clients.forRequest(ctx).from("share_links").select("*").eq("id", id).maybeSingle();
3159
- if (error)
3160
- throw mapError$2(error);
3161
- return data ? rowToLink(data) : null;
3162
- }
3163
- async getByTokenHash(_ctx, tokenHash) {
3164
- const { data, error } = await this.clients.serviceClient.from("share_links").select("*, definitions!inner(deleted_at)").eq("token_hash", tokenHash).is("revoked_at", null).is("definitions.deleted_at", null).maybeSingle();
3165
- if (error)
3166
- throw mapError$2(error);
3167
- return data ? rowToLink(data) : null;
3168
- }
3169
- async revoke(ctx, id) {
3170
- const { error } = await this.clients.forRequest(ctx).from("share_links").update({ revoked_at: (/* @__PURE__ */ new Date()).toISOString() }).eq("id", id).is("revoked_at", null);
3171
- if (error)
3172
- throw mapError$2(error);
3173
- await this.events.emit({ type: "share_link.revoked", linkId: id, actorId: actorFrom(ctx) });
3174
- }
3175
- async tryIncrementSolveCount(_ctx, id) {
3176
- const { data, error } = await this.clients.serviceClient.rpc("try_increment_share_link_solve_count", { link_id: id });
3177
- if (error)
3178
- throw mapError$2(error);
3179
- return typeof data === "number" ? data : null;
3180
- }
3181
- }
3182
- function rowToLink(row) {
3183
- return {
3184
- id: row.id,
3185
- definitionId: row.definition_guid,
3186
- channel: row.channel,
3187
- tokenHash: row.token_hash,
3188
- name: row.name ?? void 0,
3189
- createdBy: row.created_by,
3190
- createdAt: row.created_at,
3191
- expiresAt: row.expires_at,
3192
- revokedAt: row.revoked_at,
3193
- allowSolve: row.allow_solve,
3194
- maxSolves: row.max_solves,
3195
- solveCount: row.solve_count
3196
- };
3197
- }
3198
- function linkToRow(l) {
3199
- return {
3200
- id: l.id,
3201
- definition_guid: l.definitionId,
3202
- channel: l.channel,
3203
- token_hash: l.tokenHash,
3204
- name: l.name ?? null,
3205
- created_by: l.createdBy,
3206
- created_at: l.createdAt,
3207
- expires_at: l.expiresAt ?? null,
3208
- revoked_at: l.revokedAt ?? null,
3209
- allow_solve: l.allowSolve,
3210
- max_solves: l.maxSolves ?? null,
3211
- solve_count: l.solveCount
3212
- };
3213
- }
3214
- function mapError$2(e) {
3215
- const pg = e;
3216
- if (pg?.code === "23505")
3217
- return new ProviderError(pg.message ?? "Duplicate record", 409);
3218
- if (pg?.code === "23503")
3219
- return new ProviderError(pg.message ?? "Foreign key violation", 409);
3220
- if (e instanceof Error)
3221
- return e;
3222
- if (e && typeof e === "object") {
3223
- const obj = e;
3224
- const msg = obj.message ?? obj.details ?? obj.hint ?? "Unknown Postgres error";
3225
- const err = new Error(obj.code ? `[${obj.code}] ${msg}` : msg);
3226
- Object.assign(err, obj);
3227
- return err;
3228
- }
3229
- return new Error(String(e));
3230
- }
3231
- function buildClientBundle(opts) {
3232
- const serviceClient = createClient(opts.supabaseUrl, opts.serviceRoleKey, {
3233
- auth: { persistSession: false, autoRefreshToken: false }
3234
- });
3235
- const anonClient = createClient(opts.supabaseUrl, opts.anonKey, {
3236
- auth: { persistSession: false, autoRefreshToken: false }
3237
- });
3238
- const perRequestCache = /* @__PURE__ */ new WeakMap();
3239
- return {
3240
- serviceClient,
3241
- forRequest(ctx) {
3242
- if (ctx.system)
3243
- return serviceClient;
3244
- const token = extractSessionToken(ctx.adapterContext);
3245
- if (!token)
3246
- return anonClient;
3247
- const cached = perRequestCache.get(ctx);
3248
- if (cached)
3249
- return cached;
3250
- const client = createClient(opts.supabaseUrl, opts.anonKey, {
3251
- auth: { persistSession: false, autoRefreshToken: false },
3252
- global: {
3253
- headers: { Authorization: `Bearer ${token}` }
3254
- }
3255
- });
3256
- perRequestCache.set(ctx, client);
3257
- return client;
3258
- }
3259
- };
3260
- }
3261
- function extractSessionToken(adapterContext) {
3262
- if (!adapterContext || typeof adapterContext !== "object")
3263
- return void 0;
3264
- const maybe = adapterContext.sessionToken;
3265
- return typeof maybe === "string" && maybe.length > 0 ? maybe : void 0;
3266
- }
3267
- class SupabaseEventSink {
3268
- clients;
3269
- constructor(clients) {
3270
- this.clients = clients;
3271
- }
3272
- async emit(event) {
3273
- try {
3274
- const { error } = await this.clients.serviceClient.from("audit_events").insert({
3275
- type: event.type,
3276
- actor_id: event.actorId,
3277
- data: event
3278
- });
3279
- if (error) {
3280
- console.error("[SupabaseEventSink] insert failed:", error.message, { event });
3281
- }
3282
- } catch (err) {
3283
- console.error("[SupabaseEventSink] unexpected error:", err, { event });
3284
- }
3285
- }
3286
- }
3287
- const MAX_LIMIT = 200;
3288
- const DEFAULT_LIMIT = 100;
3289
- const ISO_RE = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d+)?(?:Z|[+-]\d{2}:?\d{2})$/;
3290
- const UUID_RE = /^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$/;
3291
- class SupabaseAuditQuery {
3292
- clients;
3293
- constructor(clients) {
3294
- this.clients = clients;
3295
- }
3296
- async list(_ctx, filters) {
3297
- const limit = clampLimit(filters.limit);
3298
- let q = this.clients.serviceClient.from("audit_events").select("id, type, actor_id, occurred_at, data").order("occurred_at", { ascending: false }).order("id", { ascending: false }).limit(limit + 1);
3299
- if (filters.types && filters.types.length > 0) {
3300
- q = q.in("type", [...filters.types]);
3301
- }
3302
- if (filters.actorId) {
3303
- q = q.eq("actor_id", filters.actorId);
3304
- }
3305
- if (filters.sinceIso) {
3306
- q = q.gte("occurred_at", filters.sinceIso);
3307
- }
3308
- if (filters.untilIso) {
3309
- q = q.lte("occurred_at", filters.untilIso);
3310
- }
3311
- if (filters.cursor) {
3312
- const ts = filters.cursor.occurredAt;
3313
- const id = filters.cursor.id;
3314
- if (!ISO_RE.test(ts) || !UUID_RE.test(id)) {
3315
- throw new Error("audit_events query: malformed cursor");
3316
- }
3317
- q = q.or(`occurred_at.lt.${ts},and(occurred_at.eq.${ts},id.lt.${id})`);
3318
- }
3319
- const { data, error } = await q;
3320
- if (error) {
3321
- throw new Error(`audit_events query failed: ${error.message}`);
3322
- }
3323
- const fetched = data ?? [];
3324
- const hasMore = fetched.length > limit;
3325
- const page = hasMore ? fetched.slice(0, limit) : fetched;
3326
- const last = page[page.length - 1];
3327
- return {
3328
- rows: page.map((r) => ({
3329
- id: r.id,
3330
- type: r.type,
3331
- actorId: r.actor_id,
3332
- occurredAt: r.occurred_at,
3333
- data: r.data
3334
- })),
3335
- nextCursor: hasMore && last ? { occurredAt: last.occurred_at, id: last.id } : null
3336
- };
3337
- }
3338
- }
3339
- function clampLimit(requested) {
3340
- if (!requested || requested <= 0)
3341
- return DEFAULT_LIMIT;
3342
- if (requested > MAX_LIMIT)
3343
- return MAX_LIMIT;
3344
- return Math.floor(requested);
3345
- }
3346
- const MAX_RECENT_RUNS = 20;
3347
- class SupabaseUserProfileProvider {
3348
- clients;
3349
- constructor(clients) {
3350
- this.clients = clients;
3351
- }
3352
- client() {
3353
- return this.clients.serviceClient;
3354
- }
3355
- async getProfile(ctx, userId) {
3356
- assertCanAccess(ctx, userId);
3357
- const { data, error } = await this.client().from("user_profiles").select("user_id, display_name, starred_definitions, recent_runs").eq("user_id", userId).maybeSingle();
3358
- if (error)
3359
- throw mapError$1(error);
3360
- return data ? rowToProfile(data) : null;
3361
- }
3362
- async getProfiles(_ctx, userIds) {
3363
- if (userIds.length === 0)
3364
- return [];
3365
- const { data, error } = await this.client().from("user_profiles").select("user_id, display_name, starred_definitions, recent_runs").in("user_id", [...userIds]);
3366
- if (error)
3367
- throw mapError$1(error);
3368
- return (data ?? []).map(rowToProfile);
3369
- }
3370
- async updateProfile(ctx, userId, patch) {
3371
- assertCanAccess(ctx, userId);
3372
- const row = {};
3373
- if (patch.displayName !== void 0)
3374
- row.display_name = patch.displayName;
3375
- if (Object.keys(row).length === 0)
3376
- return "ok";
3377
- const { data, error } = await this.client().from("user_profiles").update(row).eq("user_id", userId).select("user_id");
3378
- if (error)
3379
- throw mapError$1(error);
3380
- return data && data.length > 0 ? "ok" : "not_found";
3381
- }
3382
- async starDefinition(ctx, userId, definitionId) {
3383
- assertCanAccess(ctx, userId);
3384
- const existing = await this.getProfile(ctx, userId);
3385
- if (!existing)
3386
- return "not_found";
3387
- if (existing.starredDefinitions.includes(definitionId))
3388
- return "ok";
3389
- const next = [...existing.starredDefinitions, definitionId];
3390
- const { data, error } = await this.client().from("user_profiles").update({ starred_definitions: next }).eq("user_id", userId).select("user_id");
3391
- if (error)
3392
- throw mapError$1(error);
3393
- return data && data.length > 0 ? "ok" : "not_found";
3394
- }
3395
- async unstarDefinition(ctx, userId, definitionId) {
3396
- assertCanAccess(ctx, userId);
3397
- const existing = await this.getProfile(ctx, userId);
3398
- if (!existing)
3399
- return "not_found";
3400
- if (!existing.starredDefinitions.includes(definitionId))
3401
- return "ok";
3402
- const next = existing.starredDefinitions.filter((id) => id !== definitionId);
3403
- const { data, error } = await this.client().from("user_profiles").update({ starred_definitions: next }).eq("user_id", userId).select("user_id");
3404
- if (error)
3405
- throw mapError$1(error);
3406
- return data && data.length > 0 ? "ok" : "not_found";
3407
- }
3408
- async recordRun(ctx, userId, run) {
3409
- assertCanAccess(ctx, userId);
3410
- const existing = await this.getProfile(ctx, userId);
3411
- if (!existing)
3412
- return "not_found";
3413
- const filtered = existing.recentRuns.filter((r) => r.definitionId !== run.definitionId);
3414
- const next = [run, ...filtered].slice(0, MAX_RECENT_RUNS);
3415
- const { data, error } = await this.client().from("user_profiles").update({ recent_runs: next }).eq("user_id", userId).select("user_id");
3416
- if (error)
3417
- throw mapError$1(error);
3418
- return data && data.length > 0 ? "ok" : "not_found";
3419
- }
3420
- }
3421
- function assertCanAccess(ctx, userId) {
3422
- if (ctx.system)
3423
- return;
3424
- if (ctx.userId === userId)
3425
- return;
3426
- if (hasPermission(ctx, "instance_admin"))
3427
- return;
3428
- throw new ProviderError("Forbidden: cannot access another user’s profile", 403);
3429
- }
3430
- function rowToProfile(row) {
3431
- return {
3432
- userId: row.user_id,
3433
- displayName: row.display_name ?? void 0,
3434
- starredDefinitions: row.starred_definitions ?? [],
3435
- recentRuns: row.recent_runs ?? []
3436
- };
3437
- }
3438
- function mapError$1(e) {
3439
- const pg = e;
3440
- if (pg?.code === "23505")
3441
- return new ProviderError(pg.message ?? "Duplicate record", 409);
3442
- if (pg?.code === "23503")
3443
- return new ProviderError(pg.message ?? "Foreign key violation", 409);
3444
- if (e instanceof Error)
3445
- return e;
3446
- if (e && typeof e === "object") {
3447
- const obj = e;
3448
- return new Error(obj.code ? `[${obj.code}] ${obj.message ?? ""}` : obj.message ?? String(e));
3449
- }
3450
- return new Error(String(e));
3451
- }
3452
- class SupabasePlatformPermissionStore {
3453
- clients;
3454
- constructor(clients) {
3455
- this.clients = clients;
3456
- }
3457
- client() {
3458
- return this.clients.serviceClient;
3459
- }
3460
- async getFor(ctx, userId) {
3461
- assertCanRead(ctx, userId);
3462
- const { data, error } = await this.client().from("user_profiles").select("platform_permissions").eq("user_id", userId).maybeSingle();
3463
- if (error)
3464
- throw mapError(error);
3465
- return filterValid(data?.platform_permissions ?? []);
3466
- }
3467
- async getForBatch(ctx, userIds) {
3468
- assertAdmin(ctx);
3469
- const out = /* @__PURE__ */ new Map();
3470
- if (userIds.length === 0)
3471
- return out;
3472
- const { data, error } = await this.client().from("user_profiles").select("user_id, platform_permissions").in("user_id", [...userIds]);
3473
- if (error)
3474
- throw mapError(error);
3475
- for (const row of data ?? []) {
3476
- out.set(row.user_id, filterValid(row.platform_permissions ?? []));
3477
- }
3478
- return out;
3479
- }
3480
- async set(ctx, userId, permissions) {
3481
- assertAdmin(ctx);
3482
- const { data: existing, error: fetchError } = await this.client().from("user_profiles").select("platform_permissions").eq("user_id", userId).maybeSingle();
3483
- if (fetchError)
3484
- throw mapError(fetchError);
3485
- if (!existing)
3486
- return "not_found";
3487
- const wasAdmin = (existing.platform_permissions ?? []).includes("instance_admin");
3488
- const willBeAdmin = permissions.includes("instance_admin");
3489
- if (wasAdmin && !willBeAdmin) {
3490
- const others = await this.countOtherEnabledAdmins(userId);
3491
- if (others === 0)
3492
- return "last_admin";
3493
- }
3494
- const { error } = await this.client().from("user_profiles").update({ platform_permissions: [...permissions] }).eq("user_id", userId);
3495
- if (error)
3496
- throw mapError(error);
3497
- return "ok";
3498
- }
3499
- async hasInstanceAdmin(_ctx) {
3500
- const { data, error } = await this.client().from("user_profiles").select("user_id").contains("platform_permissions", ["instance_admin"]);
3501
- if (error)
3502
- throw mapError(error);
3503
- const candidates = (data ?? []).map((r) => r.user_id);
3504
- if (candidates.length === 0)
3505
- return false;
3506
- for (const id of candidates) {
3507
- const { data: authData } = await this.clients.serviceClient.auth.admin.getUserById(id);
3508
- if (authData.user && authData.user.user_metadata?.disabled !== true)
3509
- return true;
3510
- }
3511
- return false;
3512
- }
3513
- async countInstanceAdminsExcluding(_ctx, excludeUserId) {
3514
- return this.countOtherEnabledAdmins(excludeUserId);
3515
- }
3516
- async countOtherEnabledAdmins(excludeUserId) {
3517
- const { data, error } = await this.client().from("user_profiles").select("user_id").contains("platform_permissions", ["instance_admin"]).neq("user_id", excludeUserId);
3518
- if (error)
3519
- throw mapError(error);
3520
- const candidates = (data ?? []).map((r) => r.user_id);
3521
- if (candidates.length === 0)
3522
- return 0;
3523
- let count = 0;
3524
- for (const id of candidates) {
3525
- const { data: authData } = await this.clients.serviceClient.auth.admin.getUserById(id);
3526
- if (authData.user && authData.user.user_metadata?.disabled !== true)
3527
- count += 1;
3528
- }
3529
- return count;
3530
- }
3531
- }
3532
- function filterValid(raw) {
3533
- return raw.filter((p) => PlatformPermissionSchema.safeParse(p).success);
3534
- }
3535
- function assertCanRead(ctx, userId) {
3536
- if (ctx.system)
3537
- return;
3538
- if (ctx.userId === userId)
3539
- return;
3540
- if (hasPermission(ctx, "instance_admin"))
3541
- return;
3542
- throw new ProviderError("Forbidden: cannot read another user’s permissions", 403);
3543
- }
3544
- function assertAdmin(ctx) {
3545
- if (ctx.system)
3546
- return;
3547
- if (hasPermission(ctx, "instance_admin"))
3548
- return;
3549
- throw new ProviderError("Forbidden: instance admin required", 403);
3550
- }
3551
- function mapError(e) {
3552
- const pg = e;
3553
- if (pg?.code === "23505")
3554
- return new ProviderError(pg.message ?? "Duplicate record", 409);
3555
- if (pg?.code === "23503")
3556
- return new ProviderError(pg.message ?? "Foreign key violation", 409);
3557
- if (e instanceof Error)
3558
- return e;
3559
- if (e && typeof e === "object") {
3560
- const obj = e;
3561
- return new Error(obj.code ? `[${obj.code}] ${obj.message ?? ""}` : obj.message ?? String(e));
3562
- }
3563
- return new Error(String(e));
3564
- }
3565
- const NOT_IMPLEMENTED_MSG = "Platform projects are not supported on this deployment yet.";
3566
- const notImplementedGrantStore = {
3567
- listByProject: async () => {
3568
- throw new ProviderError(NOT_IMPLEMENTED_MSG, 501);
3569
- },
3570
- create: async () => {
3571
- throw new ProviderError(NOT_IMPLEMENTED_MSG, 501);
3572
- },
3573
- delete: async () => {
3574
- throw new ProviderError(NOT_IMPLEMENTED_MSG, 501);
3575
- },
3576
- deleteByProject: async () => {
3577
- },
3578
- deleteByGranteeOrg: async () => {
3579
- }
3580
- };
3581
- class SupabaseDataProvider {
3582
- clients;
3583
- orgs;
3584
- projects;
3585
- definitions;
3586
- invites;
3587
- computeServer;
3588
- shareLinks;
3589
- userProfile;
3590
- permissions;
3591
- platformProjectGrants;
3592
- auditQuery;
3593
- constructor(clients, events) {
3594
- this.clients = clients;
3595
- this.orgs = new SupabaseOrgStore(clients, events);
3596
- this.projects = new SupabaseProjectStore(clients, events);
3597
- this.definitions = new SupabaseDefinitionStore(clients, events);
3598
- this.invites = new SupabaseInviteStore(clients, events);
3599
- this.computeServer = new SupabaseComputeServerStore(clients);
3600
- this.shareLinks = new SupabaseShareLinkStore(clients, events);
3601
- this.userProfile = new SupabaseUserProfileProvider(clients);
3602
- this.permissions = new SupabasePlatformPermissionStore(clients);
3603
- this.platformProjectGrants = notImplementedGrantStore;
3604
- this.auditQuery = new SupabaseAuditQuery(clients);
3605
- }
3606
- static fromEnv(env, events) {
3607
- const supabaseUrl = env.SUPABASE_URL;
3608
- const anonKey = env.SUPABASE_ANON_KEY;
3609
- const serviceRoleKey = env.SUPABASE_SERVICE_ROLE_KEY;
3610
- if (!supabaseUrl)
3611
- throw new Error("Missing required env var: SUPABASE_URL");
3612
- if (!anonKey)
3613
- throw new Error("Missing required env var: SUPABASE_ANON_KEY");
3614
- if (!serviceRoleKey)
3615
- throw new Error("Missing required env var: SUPABASE_SERVICE_ROLE_KEY");
3616
- const bundle = buildClientBundle({ supabaseUrl, anonKey, serviceRoleKey });
3617
- return new SupabaseDataProvider(bundle, events ?? new SupabaseEventSink(bundle));
3618
- }
3619
- static create(opts, events) {
3620
- const bundle = buildClientBundle(opts);
3621
- return new SupabaseDataProvider(bundle, events ?? new SupabaseEventSink(bundle));
3622
- }
3623
- /**
3624
- * Build from a pre-existing `ClientBundle`. Useful for tests or advanced
3625
- * cases that need to inject a custom event sink or share a bundle externally.
3626
- */
3627
- static fromBundle(bundle, events) {
3628
- return new SupabaseDataProvider(bundle, events ?? new SupabaseEventSink(bundle));
3629
- }
3630
- /**
3631
- * Expose the underlying bundle so other providers in the same package
3632
- * (storage, user profile, auth) can share one set of clients per process.
3633
- */
3634
- getClientBundle() {
3635
- return this.clients;
3636
- }
3637
- /**
3638
- * No-op: `public.user_profiles` is auto-seeded by the `handle_new_auth_user`
3639
- * trigger on every `auth.users` insert (see `0001_initial.sql`). The data
3640
- * layer always has a row for any authenticated user without per-request work.
3641
- */
3642
- async ensureUser() {
3643
- }
3644
- /**
3645
- * No-op: `public.user_profiles.user_id` references `auth.users(id)` with
3646
- * `on delete cascade`. Deleting the auth user removes the profile row
3647
- * automatically.
3648
- */
3649
- async onUserDeleted() {
3650
- }
3651
- }
3652
- class SupabaseAuthProvider {
3653
- name = "Supabase Auth";
3654
- passwordAuth;
3655
- oauth;
3656
- emailLink;
3657
- admin;
3658
- anon;
3659
- anonKey;
3660
- supabaseUrl;
3661
- constructor(config) {
3662
- this.supabaseUrl = config.supabaseUrl;
3663
- this.anonKey = config.anonKey;
3664
- this.admin = createClient(config.supabaseUrl, config.serviceRoleKey, {
3665
- auth: { persistSession: false, autoRefreshToken: false }
3666
- });
3667
- this.anon = createClient(config.supabaseUrl, config.anonKey, {
3668
- auth: { persistSession: false, autoRefreshToken: false }
3669
- });
3670
- this.passwordAuth = new SupabasePasswordAuth(this.admin, this.anon, (email, password) => this.signIn(email, password), config.enableSelfSignup ?? false, (user) => this.hydrate(user));
3671
- this.oauth = new SupabaseOAuthAuth(this.anon, (user) => this.hydrate(user), config.oauthProviders ?? []);
3672
- this.emailLink = new SupabaseEmailLinkAuth(this.anon, (user) => this.hydrate(user), config.allowEmailLinkSignup ?? true);
3673
- }
3674
- static fromEnv(env) {
3675
- const supabaseUrl = env.SUPABASE_URL;
3676
- const anonKey = env.SUPABASE_ANON_KEY;
3677
- const serviceRoleKey = env.SUPABASE_SERVICE_ROLE_KEY;
3678
- if (!supabaseUrl)
3679
- throw new Error("Missing required env var: SUPABASE_URL");
3680
- if (!anonKey)
3681
- throw new Error("Missing required env var: SUPABASE_ANON_KEY");
3682
- if (!serviceRoleKey)
3683
- throw new Error("Missing required env var: SUPABASE_SERVICE_ROLE_KEY");
3684
- const oauthProviders = (env.SUPABASE_OAUTH_PROVIDERS ?? "").split(",").map((p) => p.trim().toLowerCase()).filter((p) => p.length > 0);
3685
- return new SupabaseAuthProvider({
3686
- supabaseUrl,
3687
- anonKey,
3688
- serviceRoleKey,
3689
- enableSelfSignup: env.SUPABASE_ENABLE_SELF_SIGNUP === "true",
3690
- oauthProviders,
3691
- // Default true; set SUPABASE_ALLOW_EMAIL_LINK_SIGNUP=false to lock down
3692
- // to invite-only and reject magic-link signups for new addresses.
3693
- allowEmailLinkSignup: env.SUPABASE_ALLOW_EMAIL_LINK_SIGNUP !== "false"
3694
- });
3695
- }
3696
- async verifyToken(token) {
3697
- if (!token)
3698
- return null;
3699
- const { data, error } = await this.anon.auth.getUser(token);
3700
- if (error || !data.user)
3701
- return null;
3702
- if (data.user.user_metadata?.disabled === true)
3703
- return null;
3704
- return this.hydrate(data.user);
3705
- }
3706
- async getUser(id) {
3707
- const { data, error } = await this.admin.auth.admin.getUserById(id);
3708
- if (error || !data.user)
3709
- return null;
3710
- return this.hydrate(data.user);
3711
- }
3712
- async listUsers(opts) {
3713
- const perPage = opts?.limit ?? 50;
3714
- const page = opts?.cursor ? parseInt(opts.cursor, 10) : 1;
3715
- const { data, error } = await this.admin.auth.admin.listUsers({
3716
- page: Number.isFinite(page) && page >= 1 ? page : 1,
3717
- perPage
3718
- });
3719
- if (error)
3720
- throw error;
3721
- const users = data.users;
3722
- const hydrated = users.map((u) => this.hydrate(u));
3723
- const nextCursor = users.length >= perPage ? String(page + 1) : void 0;
3724
- return { items: hydrated, nextCursor };
3725
- }
3726
- async createUser(email) {
3727
- const { data, error } = await this.admin.auth.admin.createUser({
3728
- email,
3729
- email_confirm: true
3730
- });
3731
- if (error)
3732
- throw error;
3733
- if (!data.user)
3734
- throw new Error("createUser returned no user");
3735
- return this.hydrate(data.user);
3736
- }
3737
- async deleteUser(id) {
3738
- const { error } = await this.admin.auth.admin.deleteUser(id);
3739
- if (error) {
3740
- const e = error;
3741
- if (e.status === 404 || /not.?found/i.test(e.message ?? ""))
3742
- return "not_found";
3743
- throw error;
3744
- }
3745
- return "ok";
3746
- }
3747
- async disableUser(id) {
3748
- const { data: existing, error: fetchError } = await this.admin.auth.admin.getUserById(id);
3749
- if (fetchError || !existing.user)
3750
- return "not_found";
3751
- const mergedMetadata = {
3752
- ...existing.user.user_metadata ?? {},
3753
- disabled: true
3754
- };
3755
- const { error } = await this.admin.auth.admin.updateUserById(id, {
3756
- user_metadata: mergedMetadata
3757
- });
3758
- if (error) {
3759
- const e = error;
3760
- if (e.status === 404 || /not.?found/i.test(e.message ?? ""))
3761
- return "not_found";
3762
- throw error;
3763
- }
3764
- return "ok";
3765
- }
3766
- async touchLastLogin(id) {
3767
- const { data, error } = await this.admin.from("user_profiles").select("last_login_at").eq("user_id", id).maybeSingle();
3768
- if (error)
3769
- return;
3770
- if (data?.last_login_at) {
3771
- const prev = Date.parse(data.last_login_at);
3772
- if (Number.isFinite(prev) && Date.now() - prev < 6e4)
3773
- return;
3774
- }
3775
- await this.admin.from("user_profiles").update({ last_login_at: (/* @__PURE__ */ new Date()).toISOString() }).eq("user_id", id);
3776
- }
3777
- // OAuth lives on `this.oauth` (typed `IOAuthAuth`); see `SupabaseOAuthAuth`
3778
- // below. Mirrors the `passwordAuth` capability split.
3779
- // ============================================================================
3780
- // Internals
3781
- // ============================================================================
3782
- /**
3783
- * Sign in via GoTrue. Returns the access token string and the hydrated
3784
- * user. Called by `SupabasePasswordAuth.verifyLogin` — kept on the
3785
- * provider class so it has access to the hydrate helper without plumbing.
3786
- */
3787
- async signIn(email, password) {
3788
- const { data, error } = await this.anon.auth.signInWithPassword({ email, password });
3789
- if (error || !data.user || !data.session)
3790
- return null;
3791
- if (data.user.user_metadata?.disabled === true)
3792
- return null;
3793
- return { user: this.hydrate(data.user), sessionToken: data.session.access_token };
3794
- }
3795
- /**
3796
- * Map a GoTrue `User` to our identity-only `AuthUser`. Platform permissions
3797
- * live on `IPlatformPermissionStore` and profile fields (displayName,
3798
- * starred, recentRuns) on `IUserProfileStore` — neither is in AuthUser.
3799
- */
3800
- hydrate(user) {
3801
- return {
3802
- id: user.id,
3803
- email: user.email ?? void 0,
3804
- createdAt: user.created_at ?? void 0,
3805
- lastLoginAt: user.last_sign_in_at ?? void 0,
3806
- disabled: user.user_metadata?.disabled === true,
3807
- metadata: user.user_metadata
3808
- };
3809
- }
3810
- /**
3811
- * Expose the anon URL + key so other code (e.g. the same process's
3812
- * storage provider or per-request client factories) can build user-scoped
3813
- * clients without requiring a second config read.
3814
- */
3815
- getAnonClientConfig() {
3816
- return { supabaseUrl: this.supabaseUrl, anonKey: this.anonKey };
3817
- }
3818
- }
3819
- class SupabasePasswordAuth {
3820
- admin;
3821
- anon;
3822
- signIn;
3823
- enableSelfSignup;
3824
- hydrate;
3825
- constructor(admin, anon, signIn, enableSelfSignup, hydrate) {
3826
- this.admin = admin;
3827
- this.anon = anon;
3828
- this.signIn = signIn;
3829
- this.enableSelfSignup = enableSelfSignup;
3830
- this.hydrate = hydrate;
3831
- }
3832
- async verifyLogin(email, password) {
3833
- const result = await this.signIn(email, password);
3834
- if (!result)
3835
- return { kind: "failed", reason: "invalid_credentials" };
3836
- return { kind: "success", user: result.user, sessionToken: result.sessionToken };
3837
- }
3838
- async createUserWithPassword(email, password) {
3839
- const { data, error } = await this.admin.auth.admin.createUser({
3840
- email,
3841
- password,
3842
- email_confirm: true
3843
- });
3844
- if (error)
3845
- throw error;
3846
- if (!data.user)
3847
- throw new Error("createUserWithPassword returned no user");
3848
- return this.hydrate(data.user);
3849
- }
3850
- async registerUser(email, password) {
3851
- if (!this.enableSelfSignup)
3852
- return null;
3853
- const { data, error } = await this.anon.auth.signUp({ email, password });
3854
- if (error || !data.user)
3855
- return null;
3856
- return this.hydrate(data.user);
3857
- }
3858
- }
3859
- class SupabaseOAuthAuth {
3860
- anon;
3861
- hydrate;
3862
- providers;
3863
- constructor(anon, hydrate, providers2) {
3864
- this.anon = anon;
3865
- this.hydrate = hydrate;
3866
- this.providers = providers2;
3867
- }
3868
- listProviders() {
3869
- return this.providers;
3870
- }
3871
- async getOAuthAuthorizationUrl(provider, redirectTo) {
3872
- const { data, error } = await this.anon.auth.signInWithOAuth({
3873
- provider,
3874
- options: { redirectTo, skipBrowserRedirect: true }
3875
- });
3876
- if (error || !data.url)
3877
- throw error ?? new Error("signInWithOAuth returned no URL");
3878
- return data.url;
3879
- }
3880
- async exchangeOAuthCode(code) {
3881
- const { data, error } = await this.anon.auth.exchangeCodeForSession(code);
3882
- if (error || !data.user || !data.session)
3883
- return null;
3884
- if (data.user.user_metadata?.disabled === true)
3885
- return null;
3886
- return {
3887
- user: this.hydrate(data.user),
3888
- sessionToken: data.session.access_token,
3889
- refreshToken: data.session.refresh_token
3890
- };
3891
- }
3892
- async refreshSession(refreshToken) {
3893
- const { data, error } = await this.anon.auth.refreshSession({ refresh_token: refreshToken });
3894
- if (error || !data.session)
3895
- return null;
3896
- return {
3897
- sessionToken: data.session.access_token,
3898
- refreshToken: data.session.refresh_token
3899
- };
3900
- }
3901
- }
3902
- class SupabaseEmailLinkAuth {
3903
- anon;
3904
- hydrate;
3905
- allowSignup;
3906
- constructor(anon, hydrate, allowSignup) {
3907
- this.anon = anon;
3908
- this.hydrate = hydrate;
3909
- this.allowSignup = allowSignup;
3910
- }
3911
- async sendMagicLink(email, callbackUrl) {
3912
- const { error } = await this.anon.auth.signInWithOtp({
3913
- email,
3914
- options: {
3915
- emailRedirectTo: callbackUrl,
3916
- shouldCreateUser: this.allowSignup
3917
- }
3918
- });
3919
- if (!error)
3920
- return { ok: true };
3921
- const status = error.status;
3922
- const code = error.code;
3923
- const message = error.message ?? "";
3924
- if (status === 429 || /rate.?limit/i.test(message))
3925
- return { ok: false, reason: "rate_limited" };
3926
- if (code === "otp_disabled" || code === "signup_disabled" || /signup.*disabled/i.test(message)) {
3927
- return { ok: false, reason: "signup_disabled" };
3928
- }
3929
- if (code === "validation_failed" || /invalid.*email|email.*invalid/i.test(message)) {
3930
- return { ok: false, reason: "invalid_email" };
3931
- }
3932
- throw error;
3933
- }
3934
- async verifyMagicLink(rawCallbackUrl) {
3935
- const params = parseCallbackParams(rawCallbackUrl);
3936
- if (!params)
3937
- return null;
3938
- const { tokenHash, type } = params;
3939
- const { data, error } = await this.anon.auth.verifyOtp({
3940
- token_hash: tokenHash,
3941
- type
3942
- });
3943
- if (error || !data.user || !data.session)
3944
- return null;
3945
- if (data.user.user_metadata?.disabled === true)
3946
- return null;
3947
- return {
3948
- user: this.hydrate(data.user),
3949
- sessionToken: data.session.access_token,
3950
- refreshToken: data.session.refresh_token
3951
- };
3952
- }
3953
- }
3954
- function parseCallbackParams(raw) {
3955
- let search;
3956
- try {
3957
- search = new URL(raw).searchParams;
3958
- } catch {
3959
- search = new URLSearchParams(raw.startsWith("?") ? raw.slice(1) : raw);
3960
- }
3961
- const tokenHash = search.get("token_hash");
3962
- const type = search.get("type");
3963
- if (!tokenHash)
3964
- return null;
3965
- const allowed = /* @__PURE__ */ new Set(["magiclink", "email", "signup", "invite", "recovery"]);
3966
- if (!type || !allowed.has(type))
3967
- return null;
3968
- return {
3969
- tokenHash,
3970
- type
3971
- };
3972
- }
3973
- const empty = () => ({ users: [] });
3974
- const LAST_LOGIN_DEBOUNCE_MS = 6e4;
3975
- async function readFile(filePath) {
3976
- try {
3977
- const raw = await fs.readFile(filePath, "utf-8");
3978
- return JSON.parse(raw);
3979
- } catch (err) {
3980
- if (err.code === "ENOENT")
3981
- return empty();
3982
- throw err;
3983
- }
3984
- }
3985
- async function writeFile(filePath, data) {
3986
- await fs.mkdir(path.dirname(filePath), { recursive: true });
3987
- const tmp = `${filePath}.tmp`;
3988
- await fs.writeFile(tmp, JSON.stringify(data, null, " "), "utf-8");
3989
- await fs.rename(tmp, filePath);
3990
- }
3991
- function createAllowlistStore(filePath) {
3992
- const norm = (upn) => upn.trim().toLowerCase();
3993
- return {
3994
- async findByUpn(upn) {
3995
- const { users } = await readFile(filePath);
3996
- const key = norm(upn);
3997
- return users.find((u) => u.upn === key) ?? null;
3998
- },
3999
- async findByEmail(email) {
4000
- const { users } = await readFile(filePath);
4001
- const key = norm(email);
4002
- return users.find((u) => norm(u.email ?? "") === key || u.upn === key) ?? null;
4003
- },
4004
- async findById(id) {
4005
- const { users } = await readFile(filePath);
4006
- return users.find((u) => u.id === id) ?? null;
4007
- },
4008
- async listUsers() {
4009
- const { users } = await readFile(filePath);
4010
- return users;
4011
- },
4012
- async createUser(upn) {
4013
- const file = await readFile(filePath);
4014
- const key = norm(upn);
4015
- if (file.users.some((u) => u.upn === key)) {
4016
- throw new ProviderError(`User with UPN "${upn}" already exists`, 409);
4017
- }
4018
- const entry = {
4019
- id: randomUUID(),
4020
- upn: key,
4021
- createdAt: (/* @__PURE__ */ new Date()).toISOString()
4022
- };
4023
- file.users.push(entry);
4024
- await writeFile(filePath, file);
4025
- return entry;
4026
- },
4027
- async materializeFromHeaders(id, fields) {
4028
- const file = await readFile(filePath);
4029
- const user = file.users.find((u) => u.id === id);
4030
- if (!user)
4031
- return;
4032
- let dirty = false;
4033
- if (!user.email && fields.email) {
4034
- user.email = fields.email;
4035
- dirty = true;
4036
- }
4037
- if (!user.displayName && fields.displayName) {
4038
- user.displayName = fields.displayName;
4039
- dirty = true;
4040
- }
4041
- if (dirty)
4042
- await writeFile(filePath, file);
4043
- },
4044
- async rebindUpn(id, upn) {
4045
- const file = await readFile(filePath);
4046
- const key = norm(upn);
4047
- const user = file.users.find((u) => u.id === id);
4048
- if (!user || user.upn === key)
4049
- return;
4050
- if (file.users.some((u) => u.id !== id && u.upn === key))
4051
- return;
4052
- user.upn = key;
4053
- await writeFile(filePath, file);
4054
- },
4055
- async setDisabled(id, disabled) {
4056
- const file = await readFile(filePath);
4057
- const user = file.users.find((u) => u.id === id);
4058
- if (!user)
4059
- throw new ProviderError(`User "${id}" not found`, 404);
4060
- user.disabled = disabled;
4061
- await writeFile(filePath, file);
4062
- },
4063
- async touchLastLogin(id) {
4064
- const file = await readFile(filePath);
4065
- const user = file.users.find((u) => u.id === id);
4066
- if (!user)
4067
- return;
4068
- const now = Date.now();
4069
- if (user.lastLoginAt) {
4070
- const prev = Date.parse(user.lastLoginAt);
4071
- if (Number.isFinite(prev) && now - prev < LAST_LOGIN_DEBOUNCE_MS)
4072
- return;
4073
- }
4074
- user.lastLoginAt = new Date(now).toISOString();
4075
- await writeFile(filePath, file);
4076
- },
4077
- async deleteUser(id) {
4078
- const file = await readFile(filePath);
4079
- const before = file.users.length;
4080
- file.users = file.users.filter((u) => u.id !== id);
4081
- if (file.users.length === before)
4082
- throw new ProviderError(`User "${id}" not found`, 404);
4083
- await writeFile(filePath, file);
4084
- }
4085
- };
4086
- }
4087
- const DEFAULT_HEADERS = {
4088
- upn: "SELVA-UserPrincipalName",
4089
- email: "SELVA-Email",
4090
- displayName: "SELVA-DisplayName"
4091
- };
4092
- function toAuthUser(u) {
4093
- return {
4094
- id: u.id,
4095
- email: u.email,
4096
- metadata: { upn: u.upn, displayName: u.displayName },
4097
- createdAt: u.createdAt,
4098
- lastLoginAt: u.lastLoginAt,
4099
- disabled: u.disabled
4100
- };
4101
- }
4102
- class HeaderProxyAuth {
4103
- users;
4104
- headers;
4105
- bootstrapPolicy;
4106
- // One-shot diagnostic flag. Flipped the first time we see a request that
4107
- // carries none of the configured SELVA-* headers, so deploys with a
4108
- // misconfigured proxy get a single loud warning in the logs without
4109
- // spamming on every anonymous request. Reset is intentional — the
4110
- // process restarts and you see the warning again next deploy.
4111
- missingHeadersWarned = false;
4112
- constructor(users, headers, bootstrapPolicy) {
4113
- this.users = users;
4114
- this.headers = headers;
4115
- this.bootstrapPolicy = bootstrapPolicy;
4116
- }
4117
- setBootstrapPolicy(policy) {
4118
- this.bootstrapPolicy = policy ?? void 0;
4119
- }
4120
- /**
4121
- * Names of the configured identity headers, in priority order. Exposed so
4122
- * the hook layer can emit per-page diagnostics ("you hit /login without
4123
- * these headers") without having to know provider internals.
4124
- */
4125
- get configuredHeaderNames() {
4126
- return [this.headers.upn, this.headers.email, this.headers.displayName];
4127
- }
4128
- /** True iff none of the configured identity headers are present. */
4129
- hasNoIdentityHeaders(headers) {
4130
- return !headers.get(this.headers.upn) && !headers.get(this.headers.email) && !headers.get(this.headers.displayName);
4131
- }
4132
- async identifyFromHeaders(headers) {
4133
- const upn = headers.get(this.headers.upn);
4134
- if (!upn || !upn.trim()) {
4135
- if (!this.missingHeadersWarned && this.hasNoIdentityHeaders(headers)) {
4136
- this.missingHeadersWarned = true;
4137
- console.warn(`[HeaderAuth] No identity headers received on the first non-authed request. Expected one of: ${this.headers.upn}, ${this.headers.email}, ${this.headers.displayName}. If you reach the app through your forward-auth proxy, this means the proxy is not forwarding the configured headers — check your forward_auth / copy_headers config. If you're hitting the app directly (bypassing the proxy), bind the process to 127.0.0.1 and only reach it through the proxy. See @selvajs/header-auth-provider README.`);
4138
- }
4139
- return null;
4140
- }
4141
- const email = headers.get(this.headers.email)?.trim() || void 0;
4142
- const displayName = headers.get(this.headers.displayName)?.trim() || void 0;
4143
- let entry = await this.users.findByUpn(upn);
4144
- if (!entry && email) {
4145
- const byEmail = await this.users.findByEmail(email);
4146
- if (byEmail) {
4147
- entry = byEmail;
4148
- if (byEmail.upn !== upn.trim().toLowerCase()) {
4149
- await this.users.rebindUpn(byEmail.id, upn).catch(() => {
4150
- });
4151
- }
4152
- }
4153
- }
4154
- if (!entry && this.bootstrapPolicy) {
4155
- const allowed = await this.bootstrapPolicy({ upn, email });
4156
- if (allowed) {
4157
- try {
4158
- entry = await this.users.createUser(upn);
4159
- } catch {
4160
- entry = await this.users.findByUpn(upn);
4161
- }
4162
- }
4163
- }
4164
- if (!entry || entry.disabled) {
4165
- return null;
4166
- }
4167
- if (!entry.email && email || !entry.displayName && displayName) {
4168
- await this.users.materializeFromHeaders(entry.id, { email, displayName }).catch(() => {
4169
- });
4170
- if (email && !entry.email)
4171
- entry.email = email;
4172
- if (displayName && !entry.displayName)
4173
- entry.displayName = displayName;
4174
- }
4175
- await this.users.touchLastLogin(entry.id).catch(() => {
4176
- });
4177
- return toAuthUser(entry);
4178
- }
4179
- }
4180
- class HeaderAuthProvider {
4181
- users;
4182
- headers;
4183
- name = "Header (Forward Auth)";
4184
- proxyAuth;
4185
- constructor(config) {
4186
- this.users = createAllowlistStore(config.allowlistFilePath);
4187
- this.headers = { ...DEFAULT_HEADERS, ...config.headers };
4188
- this.proxyAuth = new HeaderProxyAuth(this.users, this.headers, config.bootstrapAllowlistPolicy);
4189
- }
4190
- /**
4191
- * Late-bind a bootstrap-allowlist policy. Useful when the policy needs
4192
- * runtime state the platform layer owns (e.g. `hasInstanceAdmin`) and
4193
- * therefore can't be wired up at provider construction time. Pass `null`
4194
- * to clear.
4195
- */
4196
- setBootstrapAllowlistPolicy(policy) {
4197
- this.proxyAuth.setBootstrapPolicy(policy);
4198
- }
4199
- static fromEnv(env) {
4200
- const dir = env.HEADER_AUTH_DATA_DIR ?? env.DATA_PATH;
4201
- if (!dir) {
4202
- throw new Error("Missing required env var: HEADER_AUTH_DATA_DIR (or DATA_PATH as fallback). This directory holds header-allowlist.json — the pre-provisioned UPN list.");
4203
- }
4204
- return new HeaderAuthProvider({
4205
- allowlistFilePath: path.join(dir, "header-allowlist.json"),
4206
- headers: {
4207
- upn: env.HEADER_AUTH_UPN_HEADER ?? DEFAULT_HEADERS.upn,
4208
- email: env.HEADER_AUTH_EMAIL_HEADER ?? DEFAULT_HEADERS.email,
4209
- displayName: env.HEADER_AUTH_DISPLAY_NAME_HEADER ?? DEFAULT_HEADERS.displayName
4210
- }
4211
- });
4212
- }
4213
- /**
4214
- * No tokens are issued by this provider — identity rides on every request
4215
- * via the trusted-proxy headers. Always returns null; the hook layer
4216
- * falls through to `proxyAuth.identifyFromHeaders`.
4217
- */
4218
- async verifyToken(_token) {
4219
- return null;
4220
- }
4221
- async getUser(id) {
4222
- const u = await this.users.findById(id);
4223
- return u ? toAuthUser(u) : null;
4224
- }
4225
- async listUsers(opts) {
4226
- const all = await this.users.listUsers();
4227
- const limit = Math.min(Math.max(1, opts?.limit ?? 25), 200);
4228
- const offset = opts?.cursor ? parseInt(opts.cursor, 10) || 0 : 0;
4229
- const slice = all.slice(offset, offset + limit).map(toAuthUser);
4230
- const nextOffset = offset + slice.length;
4231
- return {
4232
- items: slice,
4233
- nextCursor: nextOffset < all.length ? String(nextOffset) : void 0
4234
- };
4235
- }
4236
- /**
4237
- * Allowlist a UPN. Admin POST `/admin/api/users` with `{ email }`; the
4238
- * email IS the UPN for M365 / Entra deployments where they match. For
4239
- * other IdPs, document the UPN format in your README/onboarding.
4240
- */
4241
- async createUser(upn) {
4242
- return toAuthUser(await this.users.createUser(upn));
4243
- }
4244
- async deleteUser(id) {
4245
- const target = await this.users.findById(id);
4246
- if (!target)
4247
- return "not_found";
4248
- try {
4249
- await this.users.deleteUser(id);
4250
- return "ok";
4251
- } catch (err) {
4252
- if (err instanceof ProviderError && err.statusCode === 404)
4253
- return "not_found";
4254
- throw err;
4255
- }
4256
- }
4257
- async disableUser(id) {
4258
- const target = await this.users.findById(id);
4259
- if (!target)
4260
- return "not_found";
4261
- try {
4262
- await this.users.setDisabled(id, true);
4263
- return "ok";
4264
- } catch (err) {
4265
- if (err instanceof ProviderError && err.statusCode === 404)
4266
- return "not_found";
4267
- throw err;
4268
- }
4269
- }
4270
- async touchLastLogin(id) {
4271
- await this.users.touchLastLogin(id);
4272
- }
4273
- }
4274
- class DefinitionService {
4275
- constructor(data, storage) {
4276
- this.data = data;
4277
- this.storage = storage;
4278
- }
4279
- data;
4280
- storage;
4281
- async create(ctx, input, file) {
4282
- const now = (/* @__PURE__ */ new Date()).toISOString();
4283
- const actor = ctx.userId || input.ownerId;
4284
- const record = {
4285
- guid: input.guid,
4286
- projectId: input.projectId,
4287
- ownerId: input.ownerId,
4288
- createdBy: actor,
4289
- updatedBy: actor,
4290
- displayName: input.displayName,
4291
- description: input.description,
4292
- category: input.category,
4293
- tags: input.tags,
4294
- coverImage: input.coverImage,
4295
- computeServerId: input.computeServerId,
4296
- status: "pending",
4297
- solveCount: 0,
4298
- liveVersionId: null,
4299
- draftVersionId: null,
4300
- createdAt: now,
4301
- updatedAt: now,
4302
- deletedAt: null
4303
- };
4304
- await this.data.definitions.create(ctx, record);
4305
- const versionId = randomUUID();
4306
- const fileKey = definitionPaths.version(input.guid, 1, input.fileExt);
4307
- await this.storage.put(fileKey, file, "application/octet-stream");
4308
- const version = {
4309
- id: versionId,
4310
- definitionId: input.guid,
4311
- versionNumber: 1,
4312
- fileExt: input.fileExt,
4313
- fileKey,
4314
- originalFilename: input.originalFilename,
4315
- uploadedBy: actor,
4316
- uploadedAt: now
4317
- };
4318
- await this.data.definitions.createVersion(ctx, version);
4319
- await this.data.definitions.attachInitialVersion(ctx, input.guid, versionId);
4320
- return {
4321
- record: { ...record, status: "draft", liveVersionId: versionId, draftVersionId: versionId },
4322
- version
4323
- };
4324
- }
4325
- /**
4326
- * Upload a new version of an existing definition. Writes the blob, inserts
4327
- * the version row, and advances the draft pointer. `live` is unchanged —
4328
- * use `publish` to promote.
4329
- */
4330
- async uploadVersion(ctx, guid, file, ext, originalName, changeNote) {
4331
- const existing = await this.data.definitions.get(ctx, guid);
4332
- if (!existing) throw new ProviderError(`Definition not found: ${guid}`, 404);
4333
- const versions = await this.data.definitions.listVersions(ctx, guid, { limit: 1 });
4334
- const next = (versions.items[0]?.versionNumber ?? 0) + 1;
4335
- const versionId = randomUUID();
4336
- const fileKey = definitionPaths.version(guid, next, ext);
4337
- await this.storage.put(fileKey, file, "application/octet-stream");
4338
- const now = (/* @__PURE__ */ new Date()).toISOString();
4339
- const actor = ctx.userId || existing.ownerId;
4340
- const version = {
4341
- id: versionId,
4342
- definitionId: guid,
4343
- versionNumber: next,
4344
- fileExt: ext,
4345
- fileKey,
4346
- originalFilename: originalName,
4347
- uploadedBy: actor,
4348
- uploadedAt: now,
4349
- changeNote: changeNote?.trim() || void 0
4350
- };
4351
- await this.data.definitions.createVersion(ctx, version);
4352
- await this.data.definitions.setDraftVersion(ctx, guid, versionId);
4353
- return version;
4354
- }
4355
- /**
4356
- * Advance the live channel. If `versionId` is omitted, promotes the
4357
- * current draft. Pass an arbitrary version id to roll forward/back —
4358
- * spec §6 makes rollback a first-class operation.
4359
- */
4360
- async publish(ctx, guid, versionId) {
4361
- const existing = await this.data.definitions.get(ctx, guid);
4362
- if (!existing) throw new ProviderError(`Definition not found: ${guid}`, 404);
4363
- const target = versionId ?? existing.draftVersionId;
4364
- if (!target) throw new ProviderError("No version to publish", 400);
4365
- const version = await this.data.definitions.getVersion(ctx, target);
4366
- if (!version || version.definitionId !== guid) {
4367
- throw new ProviderError(`Version '${target}' not found for this definition`, 404);
4368
- }
4369
- await this.data.definitions.setLiveVersion(ctx, guid, target);
4370
- if (existing.status === "draft" || existing.status === "pending") {
4371
- await this.data.definitions.update(ctx, guid, { status: "published" });
4372
- }
4373
- return version;
4374
- }
4375
- async deleteVersion(ctx, guid, versionId) {
4376
- const version = await this.data.definitions.getVersion(ctx, versionId);
4377
- if (!version || version.definitionId !== guid) {
4378
- throw new ProviderError(`Version '${versionId}' not found for this definition`, 404);
4379
- }
4380
- await this.data.definitions.deleteVersion(ctx, versionId);
4381
- await this.storage.delete(version.fileKey);
4382
- }
4383
- async updateMeta(ctx, guid, patch) {
4384
- await this.data.definitions.update(ctx, guid, patch);
4385
- }
4386
- async saveCoverImage(ctx, guid, imageData) {
4387
- const path2 = definitionPaths.image(guid);
4388
- await this.storage.put(path2, imageData, "image/webp");
4389
- const url = this.storage.getPublicUrl(path2);
4390
- await this.data.definitions.update(ctx, guid, { coverImage: url });
4391
- return url;
4392
- }
4393
- async delete(ctx, guid) {
4394
- await this.data.definitions.delete(ctx, guid);
4395
- await this.storage.deletePrefix(definitionPaths.prefix(guid));
4396
- }
4397
- }
4398
- function envBool(e, key) {
4399
- const v = e[key]?.toLowerCase();
4400
- return v === "true" || v === "1" || v === "yes";
4401
- }
4402
- function pickAuth(e) {
4403
- const choice = (e.SELVA_AUTH_PROVIDER ?? "local").toLowerCase();
4404
- switch (choice) {
4405
- case "local":
4406
- return LocalAuthProvider.fromEnv(e);
4407
- case "supabase":
4408
- return SupabaseAuthProvider.fromEnv(e);
4409
- case "header":
4410
- return HeaderAuthProvider.fromEnv(e);
4411
- default:
4412
- throw new Error(
4413
- `Unknown SELVA_AUTH_PROVIDER="${choice}". Expected: local | supabase | header.`
4414
- );
4415
- }
4416
- }
4417
- function pickData(e) {
4418
- const choice = (e.SELVA_DATA_PROVIDER ?? "local").toLowerCase();
4419
- switch (choice) {
4420
- case "local":
4421
- return LocalDataProvider.fromEnv(e);
4422
- case "supabase":
4423
- return SupabaseDataProvider.fromEnv(e);
4424
- default:
4425
- throw new Error(`Unknown SELVA_DATA_PROVIDER="${choice}". Expected: local | supabase.`);
4426
- }
4427
- }
4428
- function pickStorage(e) {
4429
- const choice = (e.SELVA_STORAGE_PROVIDER ?? "local").toLowerCase();
4430
- switch (choice) {
4431
- case "local":
4432
- return LocalStorageProvider.fromEnv(e);
4433
- case "supabase":
4434
- return SupabaseStorageProvider.fromEnv(e);
4435
- default:
4436
- throw new Error(`Unknown SELVA_STORAGE_PROVIDER="${choice}". Expected: local | supabase.`);
4437
- }
4438
- }
4439
- function pickTenancy(e) {
4440
- const choice = (e.SELVA_TENANCY ?? "single").toLowerCase();
4441
- if (choice !== "single" && choice !== "multi") {
4442
- throw new Error(`Unknown SELVA_TENANCY="${choice}". Expected: single | multi.`);
4443
- }
4444
- return choice;
4445
- }
4446
- const defaultConfig = defineConfig((e) => ({
4447
- tenancy: pickTenancy(e),
4448
- flags: {
4449
- ALLOW_CROSS_ORG_PUBLIC: envBool(e, "SELVA_FLAG_ALLOW_CROSS_ORG_PUBLIC"),
4450
- ALLOW_ORG_COMPUTE_OVERRIDE: envBool(e, "SELVA_FLAG_ALLOW_ORG_COMPUTE_OVERRIDE"),
4451
- ALLOW_ORG_CREATION: envBool(e, "SELVA_FLAG_ALLOW_ORG_CREATION"),
4452
- ENABLE_PLATFORM_PROJECTS: envBool(e, "SELVA_FLAG_ENABLE_PLATFORM_PROJECTS"),
4453
- ENABLE_SHARING: envBool(e, "SELVA_FLAG_ENABLE_SHARING")
4454
- },
4455
- branding: {
4456
- name: e.SELVA_BRAND_NAME,
4457
- copyrightName: e.SELVA_BRAND_COPYRIGHT_NAME,
4458
- tagline: e.SELVA_BRAND_TAGLINE,
4459
- description: e.SELVA_BRAND_DESCRIPTION
4460
- },
4461
- auth: pickAuth(e),
4462
- data: pickData(e),
4463
- storage: pickStorage(e)
4464
- }));
4465
- async function loadRawConfig() {
4466
- const override = private_env.SELVA_CONFIG_PATH;
4467
- if (!override) {
4468
- return defaultConfig;
4469
- }
4470
- const abs = resolve(process.cwd(), override);
4471
- if (!existsSync(abs)) {
4472
- throw new Error(`SELVA_CONFIG_PATH=${override} resolved to ${abs} which does not exist.`);
4473
- }
4474
- const mod = await import(
4475
- /* @vite-ignore */
4476
- pathToFileURL(abs).href
4477
- );
4478
- return mod.default;
4479
- }
4480
- const _raw = await loadRawConfig();
4481
- const providers = typeof _raw === "function" ? _raw(private_env) : _raw;
4482
- const tenancy = providers.tenancy ?? "single";
4483
- console.log(
4484
- `[selva] providers wired: auth=${providers.auth.name} data=${providers.data.constructor.name} storage=${providers.storage.constructor.name} tenancy=${tenancy}` + (private_env.SELVA_CONFIG_PATH ? ` config=${private_env.SELVA_CONFIG_PATH}` : "")
4485
- );
4486
- const _brand = providers.branding ?? {};
4487
- const _name = _brand.name?.trim() || "Selva";
4488
- const branding = {
4489
- name: _name,
4490
- copyrightName: _brand.copyrightName?.trim() || _name,
4491
- tagline: _brand.tagline?.trim() || "Turn Grasshopper definitions into tools anyone can use.",
4492
- description: _brand.description?.trim() || `Build and deploy interactive web applications powered by Grasshopper definitions with ${_name}.`
4493
- };
4494
- providers.flags ?? {};
4495
- function flag(name) {
4496
- return isFlagEnabled(providers, name);
4497
- }
4498
- const definitionService = new DefinitionService(providers.data, providers.storage);
4499
- function getAuthProvider() {
4500
- return providers.auth;
4501
- }
4502
- function getStorageProvider() {
4503
- return providers.storage;
4504
- }
4505
- function getDataProvider() {
4506
- return providers.data;
4507
- }
4508
- function getOrganizationProvider() {
4509
- return providers.data.orgs;
4510
- }
4511
- function getProjectProvider() {
4512
- return providers.data.projects;
4513
- }
4514
- function getDefinitionMeta() {
4515
- return providers.data.definitions;
4516
- }
4517
- function getComputeServerConfigStore() {
4518
- return providers.data.computeServer;
4519
- }
4520
- function getUserProfileStore() {
4521
- return providers.data.userProfile;
4522
- }
4523
- function getInviteStore() {
4524
- return providers.data.invites;
4525
- }
4526
- function getPermissionStore() {
4527
- return providers.data.permissions;
4528
- }
4529
- function getPlatformProjectGrantStore() {
4530
- return providers.data.platformProjectGrants;
4531
- }
4532
- function getAuditQuery() {
4533
- return providers.data.auditQuery ?? null;
4534
- }
4535
-
4536
- export { LocalComputeServerStore as L, MAX_PAGE_LIMIT as M, ProviderError as P, definitionService as a, branding as b, getAuthProvider as c, definitionPaths as d, getComputeServerConfigStore as e, flag as f, getAuditQuery as g, getDataProvider as h, getDefinitionMeta as i, getInviteStore as j, getOrganizationProvider as k, getPermissionStore as l, getPlatformProjectGrantStore as m, getProjectProvider as n, getStorageProvider as o, getUserProfileStore as p, isOrgServer as q, isPlatformServer as r, providers as s, tenancy as t };
4537
- //# sourceMappingURL=providers.server-DOymvucH.js.map