@hot-updater/console 1.1.4 → 1.2.0-rc.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (273) hide show
  1. package/.output/nitro.json +1 -1
  2. package/.output/public/assets/-native-builds-search-C-TGpFAm.js +1 -0
  3. package/.output/public/assets/{ConsoleFeatureUnavailable-C0KfsKWL.js → ConsoleFeatureUnavailable-CUtcXuY2.js} +1 -1
  4. package/.output/public/assets/EventDetails-Dl2RvPAk.js +1 -0
  5. package/.output/public/assets/HashValueDisplay-6lNRxDJX.js +1 -0
  6. package/.output/public/assets/InsightsPageHeader-DHhqY3DT.js +1 -0
  7. package/.output/public/assets/NotFoundPage-DZ3DxyRA.js +1 -0
  8. package/.output/public/assets/PlatformIcon-BBWQlWm9.js +1 -0
  9. package/.output/public/assets/RolloutPercentageBadge-Cxogpi8F.js +1 -0
  10. package/.output/public/assets/StoreSubmission-JpngSvHS.js +1 -0
  11. package/.output/public/assets/alert-dialog-BqYScr9y.js +1 -0
  12. package/.output/public/assets/api-P2g8dCNg.js +1 -0
  13. package/.output/public/assets/api-keys-DWQC2q6y.js +1 -0
  14. package/.output/public/assets/api-keys-FueRkF9q.js +1 -0
  15. package/.output/public/assets/arrow-left-g9cKqXuC.js +1 -0
  16. package/.output/public/assets/arrow-right-CNII8TYn.js +1 -0
  17. package/.output/public/assets/arrow-up-right-DK8Zdg40.js +1 -0
  18. package/.output/public/assets/badge-DWFcDWho.js +1 -0
  19. package/.output/public/assets/check-CXVR3s3X.js +1 -0
  20. package/.output/public/assets/chevron-right-BoUXo82O.js +1 -0
  21. package/.output/public/assets/circle-off-C7Muo0ss.js +1 -0
  22. package/.output/public/assets/{clipboard-DTkrlIMn.js → clipboard-DQbOcrL7.js} +1 -1
  23. package/.output/public/assets/console-features-api-DEXSwFtc.js +1 -0
  24. package/.output/public/assets/copy-DsuLj3oj.js +1 -0
  25. package/.output/public/assets/dialog-CNUPxNxH.js +1 -0
  26. package/.output/public/assets/{dist-dDj-R6uh.js → dist-CPlO6ko9.js} +1 -1
  27. package/.output/public/assets/download-Cf24LBde.js +1 -0
  28. package/.output/public/assets/{empty-Bf4DanOL.js → empty-B3Uwdd6k.js} +1 -1
  29. package/.output/public/assets/{field-GxF9SyUo.js → field-D-2-mnNh.js} +1 -1
  30. package/.output/public/assets/history-DqHlgSuV.js +1 -0
  31. package/.output/public/assets/index-BWU6owTG.js +10 -0
  32. package/.output/public/assets/{input-group-B4nrqIh0.js → input-group-D3OUBk4n.js} +1 -1
  33. package/.output/public/assets/insights-B-0odqpt.js +42 -0
  34. package/.output/public/assets/insights-BSVGfxSL.js +1 -0
  35. package/.output/public/assets/insights-NK5B6ReS.js +2 -0
  36. package/.output/public/assets/insights-api-BVCXJsoV.js +1 -0
  37. package/.output/public/assets/insights-search-DghCbEnk.js +1 -0
  38. package/.output/public/assets/insights-usage-rpc-CKQH0pUS.js +1 -0
  39. package/.output/public/assets/insights_.distribution-CJvgwcVZ.js +2 -0
  40. package/.output/public/assets/insights_.distribution-DblZM0mO.js +1 -0
  41. package/.output/public/assets/insights_.distribution-dvk6vYDM.js +1 -0
  42. package/.output/public/assets/installations-B674P5Z5.js +2 -0
  43. package/.output/public/assets/installations-BWxczZ2t.js +1 -0
  44. package/.output/public/assets/installations-Dv4kWQYz.js +1 -0
  45. package/.output/public/assets/{key-round-B4fI1psK.js → key-round-DwNKkHhy.js} +1 -1
  46. package/.output/public/assets/link-DTEyW70e.js +2 -0
  47. package/.output/public/assets/{list-Dtj7TtzV.js → list--NIee1FZ.js} +1 -1
  48. package/.output/public/assets/native-builds-BOC71grI.js +1 -0
  49. package/.output/public/assets/native-builds-BswZazmc.js +1 -0
  50. package/.output/public/assets/native-builds-c4BpOLAe.js +2 -0
  51. package/.output/public/assets/native-builds_._buildId-D_Spjl10.js +1 -0
  52. package/.output/public/assets/native-builds_._buildId-DtoXD8rz.js +2 -0
  53. package/.output/public/assets/plus-BReVKct-.js +1 -0
  54. package/.output/public/assets/preload-helper-B44EvKhG.js +1 -0
  55. package/.output/public/assets/{refresh-cw-DjIKjmrS.js → refresh-cw-B9HHjLej.js} +1 -1
  56. package/.output/public/assets/relativeTime-YQt84dYr.js +1 -0
  57. package/.output/public/assets/remote-config-B7ujqhLa.js +6 -0
  58. package/.output/public/assets/remote-config-WjpozBG5.js +1 -0
  59. package/.output/public/assets/remote-config-gXeH6PBW.js +1 -0
  60. package/.output/public/assets/rotate-cw-Cv2aVbYr.js +1 -0
  61. package/.output/public/assets/routes-BDdBIxYS.js +1 -0
  62. package/.output/public/assets/routes-CCD33Azv.js +2 -0
  63. package/.output/public/assets/search-BCel4Oy6.js +1 -0
  64. package/.output/public/assets/select-CBIU0_M1.js +1 -0
  65. package/.output/public/assets/{sidebar-BqX460IW.js → sidebar-Di9SN47G.js} +1 -1
  66. package/.output/public/assets/smartphone-CMaSy_ir.js +1 -0
  67. package/.output/public/assets/styles-Ccxthuz1.css +2 -0
  68. package/.output/public/assets/switch-BpdiHL_t.js +1 -0
  69. package/.output/public/assets/{table-ek1DmRHq.js → table-Bpy3SvSo.js} +1 -1
  70. package/.output/public/assets/{tabs-CgEH_fMT.js → tabs-Xmt7tZeG.js} +1 -1
  71. package/.output/public/assets/{undo-2-DxXx9Zvr.js → undo-2-CUX96_BG.js} +1 -1
  72. package/.output/public/assets/useCompositeListItem-JmyDfo3-.js +1 -0
  73. package/.output/public/assets/useInfiniteQuery-DX4WpBRG.js +1 -0
  74. package/.output/public/assets/useMutation-DbYw7boA.js +1 -0
  75. package/.output/public/assets/uuidv7-zXMtwR9Q.js +1 -0
  76. package/.output/public/assets/{valueToPercent-B44vDssN.js → valueToPercent-BLwGy_xK.js} +1 -1
  77. package/.output/server/{__23tanstack-start-server-fn-resolver-KpQ5Z_24.mjs → __23tanstack-start-server-fn-resolver-CygMPYHZ.mjs} +64 -40
  78. package/.output/server/_chunks/ssr-renderer.mjs +2 -2
  79. package/.output/server/_libs/@tanstack/react-router+[...].mjs +1 -1
  80. package/.output/server/_libs/@tanstack/react-router-ssr-query+[...].mjs +1 -1
  81. package/.output/server/_libs/lucide-react.mjs +88 -1
  82. package/.output/server/_libs/uqr.mjs +858 -0
  83. package/.output/server/_ssr/-native-builds-search-CwNcoXf4.mjs +37 -0
  84. package/.output/server/_ssr/{BundleIdDisplay-CjSnY65J.mjs → BundleIdDisplay-DOPz4pUS.mjs} +2 -2
  85. package/.output/server/_ssr/{ConsoleFeatureUnavailable-CHxn9f-w.mjs → ConsoleFeatureUnavailable-Xb1JKqcc.mjs} +7 -7
  86. package/.output/server/_ssr/{EventDetails-l6dF54zp.mjs → EventDetails-D7MejFCN.mjs} +8 -8
  87. package/.output/server/_ssr/{HashValueDisplay-Zs7ABoOi.mjs → HashValueDisplay-Dd-wu5rY.mjs} +2 -2
  88. package/.output/server/_ssr/{InsightsPageHeader-ZlAlDxQy.mjs → InsightsPageHeader-CWf1n4Vt.mjs} +13 -11
  89. package/.output/server/_ssr/{NotFoundPage-u28ndvp1.mjs → NotFoundPage-C5rFdUpg.mjs} +2 -2
  90. package/.output/server/_ssr/PlatformIcon-CFLiTjh1.mjs +29 -0
  91. package/.output/server/_ssr/RolloutPercentageBadge-g0Bhfl3M.mjs +21 -0
  92. package/.output/server/_ssr/StoreSubmission-JZ2Zltak.mjs +139 -0
  93. package/.output/server/_ssr/{alert-dialog-B8AqlJwo.mjs → alert-dialog-CvNvTvIJ.mjs} +1 -1
  94. package/.output/server/_ssr/{api-C_0B7NXM.mjs → api-0vtwA5vY.mjs} +126 -7
  95. package/.output/server/_ssr/{api-keys-pRNvn2-9.mjs → api-keys-D5dyA4D1.mjs} +10 -10
  96. package/.output/server/_ssr/{api-keys-rpc-wecWs0nA.mjs → api-keys-rpc-BOIUHhDi.mjs} +5 -5
  97. package/.output/server/_ssr/{api-keys-CLH38u9B.mjs → api-keys-yFlQDwQF.mjs} +2 -2
  98. package/.output/server/_ssr/{api-rpc-DWN8eOHS.mjs → api-rpc-COeFOpYi.mjs} +79 -12
  99. package/.output/server/_ssr/{auth-UP0wXs4i.mjs → auth-Z-wLddzh.mjs} +1 -1
  100. package/.output/server/_ssr/{auth-rpc-CLRArbIl.mjs → auth-rpc-D1ss2GUI.mjs} +6 -6
  101. package/.output/server/_ssr/{auth.server-DR9zc0EU.mjs → auth.server-DYS1OJ6P.mjs} +771 -641
  102. package/.output/server/_ssr/{badge-BpT7r-ng.mjs → badge-CEdVRgyl.mjs} +1 -1
  103. package/.output/server/_ssr/{bundleActivity-0qFIcvqt.mjs → bundleActivity-MLrjNJCT.mjs} +1 -1
  104. package/.output/server/_ssr/{config-WVX4IxSR.mjs → config-CjIBFhJX.mjs} +1 -1
  105. package/.output/server/_ssr/config.server-NnMFjMFX.mjs +43 -0
  106. package/.output/server/_ssr/{console-access-aUpQs49I.mjs → console-access-33BNlH97.mjs} +3 -3
  107. package/.output/server/_ssr/{console-features-4xAGfZHw.mjs → console-features-BTV-XuhQ.mjs} +1 -1
  108. package/.output/server/_ssr/{console-features-api-DSSgCV3v.mjs → console-features-api-v1fSycue.mjs} +6 -6
  109. package/.output/server/_ssr/{console-features-rpc-D6kMlR2A.mjs → console-features-rpc-C7XNVqm0.mjs} +5 -5
  110. package/.output/server/_ssr/createCsrfMiddleware-BwHbC8n-.mjs +159 -0
  111. package/.output/server/_ssr/createMiddleware-C3ACsfuG.mjs +24 -0
  112. package/.output/server/_ssr/{createMiddleware-B1iPez7u.mjs → createServerFn-AQvBMBjJ.mjs} +2 -23
  113. package/.output/server/_ssr/{createServerRpc-BaDJLGBx.mjs → createServerRpc-BVvRVOz5.mjs} +2 -2
  114. package/.output/server/_ssr/{databaseConfig-C5SkAyUy.mjs → databaseConfig-B_Bg7qS5.mjs} +1 -1
  115. package/.output/server/_ssr/{databaseJsonValue-Csbuzc9Q.mjs → databaseJsonValue-kS7cvEtz.mjs} +1 -1
  116. package/.output/server/_ssr/{databaseRows-CPphvbag.mjs → databaseRows-B6H8Cmgq.mjs} +3 -3
  117. package/.output/server/_ssr/{dialog-B4ALf7NJ.mjs → dialog-C8CS8RMt.mjs} +1 -1
  118. package/.output/server/_ssr/{dist-CbQbBIw-.mjs → dist-TEpM_UAD.mjs} +125 -125
  119. package/.output/server/_ssr/{downloadBundle-94jPBGSO.mjs → downloadBundle-DCmr7vsj.mjs} +1 -1
  120. package/.output/server/_ssr/{empty-Bh1FEeYF.mjs → empty-CkdEAvCY.mjs} +2 -2
  121. package/.output/server/_ssr/{empty-plugin-adapters-CpCHi1TV.mjs → empty-plugin-adapters-zrZ0xs6n.mjs} +1 -1
  122. package/.output/server/_ssr/{failureReports-Bh22wois.mjs → failureReports-Cn_zU9S8.mjs} +3 -3
  123. package/.output/server/_ssr/{field-HKCaPH3e.mjs → field-CW08sZXd.mjs} +2 -2
  124. package/.output/server/_ssr/{getBundleChildren-DfxB2K8D.mjs → getBundleChildren-rtkEEJw5.mjs} +2 -2
  125. package/.output/server/_ssr/git-CTA8Aqr0.mjs +56 -0
  126. package/.output/server/_ssr/{input-group-xm3LzDuq.mjs → input-group-D-TpFPuG.mjs} +1 -1
  127. package/.output/server/_ssr/{insights-BKZpJ_K4.mjs → insights-CMyzPs8l.mjs} +28 -27
  128. package/.output/server/_ssr/{insights-CCyTACIw.mjs → insights-CYeBl8N9.mjs} +5 -5
  129. package/.output/server/_ssr/{insights-CNqWQLJR.mjs → insights-DAi9KknT.mjs} +2 -2
  130. package/.output/server/_ssr/{insights-api-DtRFz5X3.mjs → insights-api-BFARQ5ct.mjs} +6 -6
  131. package/.output/server/_ssr/{insights-errors-Iy-lBaM7.mjs → insights-errors-7BCwFybo.mjs} +2 -2
  132. package/.output/server/_ssr/{insights-failures-BJN3RfLu.mjs → insights-failures-B9VPkzZE.mjs} +2 -2
  133. package/.output/server/_ssr/{insights-failures-rpc-DLZ91uOG.mjs → insights-failures-rpc-Q4WNNJkU.mjs} +12 -12
  134. package/.output/server/_ssr/{insights-recovery-BUuQdlA3.mjs → insights-recovery-BtXVU3ro.mjs} +1 -1
  135. package/.output/server/_ssr/{insights-recovery-rpc-BQHUhPi7.mjs → insights-recovery-rpc-CY5RYJKa.mjs} +8 -8
  136. package/.output/server/_ssr/{insights-rpc-C6Vukyn7.mjs → insights-rpc-BO7_evvs.mjs} +5 -5
  137. package/.output/server/_ssr/{insights-search-CBYoxT7v.mjs → insights-search-DKfxgHD3.mjs} +5 -5
  138. package/.output/server/_ssr/{insights-usage-CHqvtehH.mjs → insights-usage-DiGnuxW8.mjs} +1 -1
  139. package/.output/server/_ssr/{insights-usage-rpc-BJ7a-xco.mjs → insights-usage-rpc-B4czku50.mjs} +8 -8
  140. package/.output/server/_ssr/{insights-usage-rpc-C-lNUIsD.mjs → insights-usage-rpc-CUCTFska.mjs} +5 -5
  141. package/.output/server/_ssr/{insightsUsage-COUG-_-U.mjs → insightsUsage-ClAmoUz8.mjs} +3 -3
  142. package/.output/server/_ssr/{insights_.distribution-DmLW8I8a.mjs → insights_.distribution-BDeUhZGj.mjs} +2 -2
  143. package/.output/server/_ssr/{insights_.distribution-CTwilMPm.mjs → insights_.distribution-BRrbZN1X.mjs} +5 -5
  144. package/.output/server/_ssr/{insights_.distribution-DztDyrBj.mjs → insights_.distribution-C2MXpzKd.mjs} +15 -14
  145. package/.output/server/_ssr/{installations-Bct7ag5y.mjs → installations-BVk7okiY.mjs} +4 -4
  146. package/.output/server/_ssr/{installations-B6MK5iA8.mjs → installations-BjLMgBoH.mjs} +2 -2
  147. package/.output/server/_ssr/{installations-_N4PtYFl.mjs → installations-DxGZEC5G.mjs} +12 -12
  148. package/.output/server/_ssr/{listReleases-BfUBlCHo.mjs → listReleases-D_GY00SQ.mjs} +1 -1
  149. package/.output/server/_ssr/native-builds-CSCgFB21.mjs +10 -0
  150. package/.output/server/_ssr/native-builds-CdlyAldW.mjs +569 -0
  151. package/.output/server/_ssr/native-builds-DhXL5zf_.mjs +137 -0
  152. package/.output/server/_ssr/native-builds_._buildId-CMp1h8dT.mjs +10 -0
  153. package/.output/server/_ssr/native-builds_._buildId-GHpGaYyE.mjs +813 -0
  154. package/.output/server/_ssr/nativeBuildQr-84cnFQPX.mjs +59 -0
  155. package/.output/server/_ssr/nativeBuilds-B_7BPjt_.mjs +133 -0
  156. package/.output/server/_ssr/{plugins-BaD1slHx.mjs → plugins-RIryUNWj.mjs} +6 -5
  157. package/.output/server/_ssr/qr-code-C7kNRIDX.mjs +22 -0
  158. package/.output/server/_ssr/{release-adoption-DuYJTGuX.mjs → release-adoption-DoAtNPED.mjs} +2 -2
  159. package/.output/server/_ssr/{release-adoption-rpc-CHl7G_Zy.mjs → release-adoption-rpc-BJXZvtoQ.mjs} +10 -10
  160. package/.output/server/_ssr/{releaseAdoption-B39cpvfo.mjs → releaseAdoption-a2byXMfz.mjs} +4 -4
  161. package/.output/server/_ssr/releaseCatalogCompiler-DLcean2k.mjs +364 -0
  162. package/.output/server/_ssr/{releaseManagement-DFMUnDF5.mjs → releaseManagement-DHUux2az.mjs} +1 -1
  163. package/.output/server/_ssr/{releaseReachability-bFsuElSS.mjs → releaseReachability-DZOK_dH-.mjs} +2 -2
  164. package/.output/server/_ssr/{remote-config-Mj05qVYZ.mjs → remote-config-DjsEl270.mjs} +20 -19
  165. package/.output/server/_ssr/{remote-config-10-obSZ0.mjs → remote-config-DlyyohL2.mjs} +2 -2
  166. package/.output/server/_ssr/{remote-config-Dj1eTYi4.mjs → remote-config-XdYuByHz.mjs} +2 -2
  167. package/.output/server/_ssr/{remote-config-rpc-lteqDSLn.mjs → remote-config-rpc-GMLPb-90.mjs} +6 -6
  168. package/.output/server/_ssr/request-guard-CPdRBuGW.mjs +108 -0
  169. package/.output/server/_ssr/{router-Dr4jjjhx.mjs → router-vpxd56RW.mjs} +317 -71
  170. package/.output/server/_ssr/{routes-BZbrY_qw.mjs → routes-DyEM4b3x.mjs} +14 -14
  171. package/.output/server/_ssr/{routes-B5KrCDwk.mjs → routes-dQe3XhiS.mjs} +99 -81
  172. package/.output/server/_ssr/{runtime.server-DsHqVqTr.mjs → runtime.server-BdMY1blX.mjs} +4 -4
  173. package/.output/server/_ssr/schema-ChlRtZIo.mjs +23 -0
  174. package/.output/server/_ssr/schema-migration-rpc-BfGzEK_o.mjs +65 -0
  175. package/.output/server/_ssr/{select-BtdGNSmp.mjs → select-DM1uwtk9.mjs} +3 -27
  176. package/.output/server/_ssr/{server-BxaHSwHh.mjs → server-BUUKNSPI.mjs} +7 -161
  177. package/.output/server/_ssr/{sidebar-CVsgosaD.mjs → sidebar-DB2YQlok.mjs} +4 -4
  178. package/.output/server/_ssr/ssr.mjs +1 -1
  179. package/.output/server/_ssr/start-BvDsQehg.mjs +49 -0
  180. package/.output/server/_ssr/{switch-BmARgkUP.mjs → switch-DLD58zLy.mjs} +2 -2
  181. package/.output/server/_ssr/{table-M5P3YUfY.mjs → table-P4TnAZhl.mjs} +1 -1
  182. package/.output/server/_ssr/{tabs-CrmfOlJj.mjs → tabs-B7ZeLicF.mjs} +2 -2
  183. package/.output/server/_ssr/{updateFailures-z1IQy_4q.mjs → updateFailures-n-tGv90S.mjs} +3 -3
  184. package/.output/server/_ssr/{uuidv7-C88s9jWF.mjs → uuidv7-BIF4nb_q.mjs} +2 -2
  185. package/.output/server/_ssr/{schema-BiAVyEj2.mjs → version-CQ98ZBpL-CWSkTT9J.mjs} +2 -22
  186. package/.output/server/_tanstack-start-manifest_v-C-KC63Zq.mjs +184 -0
  187. package/.output/server/index.mjs +432 -271
  188. package/lib/vite-internal.mjs +32 -1
  189. package/package.json +8 -7
  190. package/src/components/AppSidebar.tsx +12 -1
  191. package/src/components/ConsoleAccessPage.tsx +49 -3
  192. package/src/components/QrCode.tsx +35 -0
  193. package/src/components/SchemaMigrationRequired.tsx +139 -0
  194. package/src/components/features/insights/BuiltinBundle.tsx +5 -3
  195. package/src/components/features/native-builds/BuiltInBundleCard.tsx +163 -0
  196. package/src/components/features/native-builds/CommitLink.tsx +30 -0
  197. package/src/components/features/native-builds/CopyableText.tsx +48 -0
  198. package/src/components/features/native-builds/ImportBuild.tsx +91 -0
  199. package/src/components/features/native-builds/InstallCard.tsx +205 -0
  200. package/src/components/features/native-builds/NativeBuildDetailPage.tsx +175 -0
  201. package/src/components/features/native-builds/NativeBuildsPage.tsx +151 -0
  202. package/src/components/features/native-builds/NativeBuildsTable.tsx +426 -0
  203. package/src/components/features/native-builds/PatchesCard.tsx +222 -0
  204. package/src/components/features/native-builds/ReleaseNativeBuildLink.tsx +101 -0
  205. package/src/components/features/native-builds/ServedNowCard.tsx +214 -0
  206. package/src/components/features/native-builds/ShortHash.tsx +41 -0
  207. package/src/components/features/native-builds/StoreSubmission.tsx +73 -0
  208. package/src/components/features/releases/ReleaseEditorSheet.tsx +8 -0
  209. package/src/lib/api-rpc.ts +98 -0
  210. package/src/lib/api.ts +120 -0
  211. package/src/lib/native-builds.ts +162 -0
  212. package/src/lib/qr-code.ts +16 -0
  213. package/src/lib/schema-migration-api.ts +54 -0
  214. package/src/lib/schema-migration-rpc.ts +26 -0
  215. package/src/lib/schema-migration.ts +101 -0
  216. package/src/lib/server/config.server.ts +23 -14
  217. package/src/lib/server/console-runtime.server.ts +4 -6
  218. package/src/lib/server/local-console.ts +164 -0
  219. package/src/lib/server/nativeBuildQr.ts +73 -0
  220. package/src/lib/server/nativeBuilds.ts +288 -0
  221. package/src/lib/shell.ts +9 -0
  222. package/src/routeTree.gen.ts +88 -1
  223. package/src/router.tsx +11 -1
  224. package/src/routes/-native-builds-search.ts +51 -0
  225. package/src/routes/[_]hot-updater/native-builds/qr.ts +14 -0
  226. package/src/routes/__root.tsx +11 -1
  227. package/src/routes/api/native-builds/$buildId/download.ts +50 -0
  228. package/src/routes/native-builds.tsx +21 -0
  229. package/src/routes/native-builds_.$buildId.tsx +23 -0
  230. package/src/start.ts +33 -0
  231. package/src/virtual-modules.d.ts +18 -0
  232. package/src/vite-internal.ts +57 -1
  233. package/.output/public/assets/EventDetails-gbD_fCqc.js +0 -1
  234. package/.output/public/assets/HashValueDisplay-BGkDPaYi.js +0 -1
  235. package/.output/public/assets/InsightsPageHeader-BRw8XkJW.js +0 -1
  236. package/.output/public/assets/NotFoundPage-Cei6W2lm.js +0 -1
  237. package/.output/public/assets/alert-dialog-BtVg50WQ.js +0 -1
  238. package/.output/public/assets/api-DoicFJfd.js +0 -1
  239. package/.output/public/assets/api-keys-D81VHHNM.js +0 -1
  240. package/.output/public/assets/api-keys-Dia6i8K1.js +0 -1
  241. package/.output/public/assets/arrow-left-DsivSewE.js +0 -1
  242. package/.output/public/assets/arrow-up-right-B5aM0F7f.js +0 -1
  243. package/.output/public/assets/badge-Bqf3UDee.js +0 -1
  244. package/.output/public/assets/circle-off-BsbZQtsF.js +0 -1
  245. package/.output/public/assets/console-features-api-DPE4C06Y.js +0 -2
  246. package/.output/public/assets/dialog-CGKPxz3n.js +0 -1
  247. package/.output/public/assets/index-DrkdiRIn.js +0 -10
  248. package/.output/public/assets/insights-C-5t8wh2.js +0 -2
  249. package/.output/public/assets/insights-D_ngQdiz.js +0 -1
  250. package/.output/public/assets/insights-KigRBDgC.js +0 -42
  251. package/.output/public/assets/insights-api-1ZjVu3Sb.js +0 -1
  252. package/.output/public/assets/insights-search-aT8BVCci.js +0 -1
  253. package/.output/public/assets/insights-usage-rpc-DqTiXI1_.js +0 -1
  254. package/.output/public/assets/insights_.distribution-Bzl6RFBR.js +0 -2
  255. package/.output/public/assets/insights_.distribution-Cthgttqb.js +0 -1
  256. package/.output/public/assets/insights_.distribution-D2c2v1bu.js +0 -1
  257. package/.output/public/assets/installations-2Nx8Htf-.js +0 -1
  258. package/.output/public/assets/installations-BskJ1xQr.js +0 -2
  259. package/.output/public/assets/installations-K2iJ_r0h.js +0 -1
  260. package/.output/public/assets/remote-config-D9X3NiwV.js +0 -6
  261. package/.output/public/assets/remote-config-DzOOiBIO.js +0 -1
  262. package/.output/public/assets/remote-config-ikg7kak0.js +0 -1
  263. package/.output/public/assets/routes-9rb9P5Y7.js +0 -2
  264. package/.output/public/assets/routes-P7683vKQ.js +0 -1
  265. package/.output/public/assets/search-DuI1FBpg.js +0 -1
  266. package/.output/public/assets/select-M3H2gxCc.js +0 -1
  267. package/.output/public/assets/smartphone-CtsHuiIC.js +0 -1
  268. package/.output/public/assets/styles-CpiW_YdW.css +0 -2
  269. package/.output/public/assets/switch-By_vfm8I.js +0 -1
  270. package/.output/public/assets/useCompositeListItem-B-UkrDlu.js +0 -1
  271. package/.output/server/_ssr/config.server-DTdsG47T.mjs +0 -35
  272. package/.output/server/_ssr/start-B6ECIE_7.mjs +0 -4
  273. package/.output/server/_tanstack-start-manifest_v-_BY9hYTm.mjs +0 -136
package/src/lib/api.ts CHANGED
@@ -13,8 +13,13 @@ import {
13
13
  getBundleChildren,
14
14
  getChannels,
15
15
  getConfig,
16
+ getNativeBuildDetail,
17
+ getNativeBuildDownloadUrl,
18
+ getNativeBuildPatches,
19
+ getNativeBuilds,
16
20
  getRelease,
17
21
  getReleaseCatalogDiagnostics,
22
+ getReleaseNativeBuild,
18
23
  getReleases,
19
24
  preflightRelease as preflightReleaseApi,
20
25
  promoteRelease as promoteReleaseApi,
@@ -40,8 +45,45 @@ export const queryKeys = {
40
45
  ["bundle-children", "counts", ...bundleIds] as const,
41
46
  },
42
47
  bundle: (bundleId: string) => ["bundle", bundleId] as const,
48
+ nativeBuilds: {
49
+ all: ["native-builds"] as const,
50
+ list: (page: NativeBuildPage) => ["native-builds", page] as const,
51
+ },
52
+ nativeBuild: (id: string) => ["native-build", id] as const,
53
+ nativeBuildPatches: (minBundleId: string, page: KeysetPage) =>
54
+ ["native-build-patches", minBundleId, page] as const,
55
+ nativeBuildDownloadUrl: (id: string) =>
56
+ ["native-build-download-url", id] as const,
57
+ releaseNativeBuild: (release: ReleaseNativeBuildInput) =>
58
+ ["release-native-build", release] as const,
59
+ };
60
+
61
+ export type KeysetPage = {
62
+ /** Rows older than this key: the next page. */
63
+ before?: string;
64
+ /** Rows newer than this key: the previous page. */
65
+ after?: string;
66
+ };
67
+
68
+ export type NativeBuildPage = KeysetPage & {
69
+ /** Only the builds that embed this channel. */
70
+ channel?: string;
71
+ };
72
+
73
+ export type ReleaseNativeBuildInput = {
74
+ platform: "ios" | "android";
75
+ channel: string;
76
+ fingerprintHash: string | null;
77
+ targetAppVersion: string | null;
43
78
  };
44
79
 
80
+ /**
81
+ * How often an open install QR reads its download URL again. Storage gives
82
+ * no lifetime with the URL, and adapters let it be configured down to
83
+ * minutes, so the QR never shows one older than this.
84
+ */
85
+ const DOWNLOAD_URL_REFRESH_MS = 30_000;
86
+
45
87
  export type ReleaseFilters = {
46
88
  /** One of the filter sets the release indexes serve; none lists every release. */
47
89
  filter?: ReleaseFilter;
@@ -125,6 +167,84 @@ export function useBundleChildCountsQuery(bundleIds: string[]) {
125
167
  });
126
168
  }
127
169
 
170
+ /** One page of native builds, newest first, kept on screen while the next loads. */
171
+ export function useNativeBuildsQuery(page: NativeBuildPage) {
172
+ return useQuery({
173
+ queryKey: queryKeys.nativeBuilds.list(page),
174
+ queryFn: () => getNativeBuilds({ data: page }),
175
+ placeholderData: (previousData) => previousData,
176
+ staleTime: 60_000,
177
+ });
178
+ }
179
+
180
+ /**
181
+ * A native build's page in one round trip, or null for an unknown ID. The
182
+ * page reads it again when it opens, since its catalog and patches change
183
+ * with each deploy.
184
+ */
185
+ export function useNativeBuildDetailQuery(id: string) {
186
+ return useQuery({
187
+ queryKey: queryKeys.nativeBuild(id),
188
+ queryFn: () => getNativeBuildDetail({ data: { id } }),
189
+ enabled: id.length > 0,
190
+ });
191
+ }
192
+
193
+ /**
194
+ * A page of patches from a built-in bundle other than the newest, which the
195
+ * build's page already holds; kept on screen while the next one loads.
196
+ */
197
+ export function useNativeBuildPatchesQuery(
198
+ minBundleId: string,
199
+ page: KeysetPage,
200
+ enabled: boolean,
201
+ ) {
202
+ return useQuery({
203
+ queryKey: queryKeys.nativeBuildPatches(minBundleId, page),
204
+ queryFn: () => getNativeBuildPatches({ data: { minBundleId, ...page } }),
205
+ enabled: enabled && minBundleId.length > 0,
206
+ placeholderData: (previousData) => previousData,
207
+ });
208
+ }
209
+
210
+ /**
211
+ * The newest native build of a release's scope, or none: read only for a
212
+ * release one build can serve, by its fingerprint or one exact app version.
213
+ */
214
+ export function useReleaseNativeBuildQuery(
215
+ release: ReleaseNativeBuildInput | null,
216
+ ) {
217
+ return useQuery({
218
+ queryKey: queryKeys.releaseNativeBuild(
219
+ release ?? {
220
+ platform: "ios",
221
+ channel: "",
222
+ fingerprintHash: null,
223
+ targetAppVersion: null,
224
+ },
225
+ ),
226
+ queryFn: () => getReleaseNativeBuild({ data: release! }),
227
+ enabled: release !== null,
228
+ staleTime: 60_000,
229
+ });
230
+ }
231
+
232
+ /**
233
+ * The storage URL a phone downloads a build from, read while the install
234
+ * QR is open and again before it expires.
235
+ */
236
+ export function useNativeBuildDownloadUrlQuery(id: string, enabled: boolean) {
237
+ return useQuery({
238
+ queryKey: queryKeys.nativeBuildDownloadUrl(id),
239
+ queryFn: () => getNativeBuildDownloadUrl({ data: { id } }),
240
+ enabled,
241
+ staleTime: DOWNLOAD_URL_REFRESH_MS,
242
+ // A storage without download URLs has none to refresh.
243
+ refetchInterval: (query) =>
244
+ query.state.data?.url === null ? false : DOWNLOAD_URL_REFRESH_MS,
245
+ });
246
+ }
247
+
128
248
  // Mutation Hooks
129
249
  export function useCreateChannelMutation() {
130
250
  const queryClient = useQueryClient();
@@ -0,0 +1,162 @@
1
+ import type {
2
+ NativeBuildArtifactKind,
3
+ NativeBuildRow,
4
+ NativeBuildScope,
5
+ } from "@hot-updater/plugin-core";
6
+ import {
7
+ canonicalizeAppVersion,
8
+ createReleaseCatalogScopeKey,
9
+ decodeChannelKey,
10
+ encodeChannelKey,
11
+ } from "@hot-updater/protocol";
12
+
13
+ import { shellQuote } from "./shell";
14
+
15
+ /** How each artifact installs, as the Console's install dialog shows it. */
16
+ export const nativeBuildArtifacts: Record<
17
+ NativeBuildArtifactKind,
18
+ { readonly label: string; readonly installs: string }
19
+ > = {
20
+ apk: { label: "APK", installs: "Android device or emulator" },
21
+ aab: { label: "AAB", installs: "Google Play or bundletool" },
22
+ app: { label: "Simulator app", installs: "iOS Simulator" },
23
+ ipa: { label: "IPA", installs: "registered iOS devices" },
24
+ };
25
+
26
+ /** A platform's name as the console shows it. */
27
+ export const platformLabel = (platform: "ios" | "android") =>
28
+ platform === "ios" ? "iOS" : "Android";
29
+
30
+ /** The console route that redirects to a build's artifact in storage. */
31
+ export const nativeBuildDownloadPath = (id: string) =>
32
+ `/api/native-builds/${encodeURIComponent(id)}/download`;
33
+
34
+ /** The console page of one native build. */
35
+ export const nativeBuildDetailPath = (id: string) =>
36
+ `/native-builds/${encodeURIComponent(id)}`;
37
+
38
+ const CHANNEL_ID_PREFIX = "channel:";
39
+
40
+ /** A channel row's ID, `channel:` and its channel key. */
41
+ export const channelIdOf = (channel: string) =>
42
+ `${CHANNEL_ID_PREFIX}${encodeChannelKey(channel)}`;
43
+
44
+ /** The name of the channel a build embeds, decoded from its channel ID: no read. */
45
+ export const nativeBuildChannel = (build: Pick<NativeBuildRow, "channel_id">) =>
46
+ decodeChannelKey(build.channel_id.slice(CHANNEL_ID_PREFIX.length));
47
+
48
+ /** The scope a build was registered in, as `findNativeBuild` takes it. */
49
+ export const nativeBuildScope = (build: NativeBuildRow): NativeBuildScope =>
50
+ build.fingerprint_hash === null
51
+ ? {
52
+ platform: build.platform,
53
+ channel: nativeBuildChannel(build),
54
+ fingerprintHash: null,
55
+ appVersion: build.app_version ?? "",
56
+ }
57
+ : {
58
+ platform: build.platform,
59
+ channel: nativeBuildChannel(build),
60
+ fingerprintHash: build.fingerprint_hash,
61
+ appVersion: null,
62
+ };
63
+
64
+ /**
65
+ * The Release Catalog scope whose releases an install of the build is
66
+ * offered. A fingerprint build's scope key is that catalog's own key; an
67
+ * app-version build's adds its exact app version, which the catalog of
68
+ * every app version leaves out.
69
+ */
70
+ export const nativeBuildCatalogScopeKey = (build: NativeBuildRow): string => {
71
+ const channelKey = build.channel_id.slice(CHANNEL_ID_PREFIX.length);
72
+ return build.fingerprint_hash === null
73
+ ? createReleaseCatalogScopeKey({
74
+ channelKey,
75
+ platform: build.platform,
76
+ strategy: "APP_VERSION",
77
+ })
78
+ : createReleaseCatalogScopeKey({
79
+ channelKey,
80
+ fingerprintHash: build.fingerprint_hash,
81
+ platform: build.platform,
82
+ strategy: "FINGERPRINT",
83
+ });
84
+ };
85
+
86
+ /**
87
+ * The native build scope a release serves, or null when no one build has
88
+ * it: a release of an app version range, rather than one exact version,
89
+ * targets many builds.
90
+ */
91
+ export const releaseNativeBuildScope = (release: {
92
+ readonly platform: "ios" | "android";
93
+ readonly channel: string;
94
+ readonly fingerprintHash: string | null;
95
+ readonly targetAppVersion: string | null;
96
+ }): NativeBuildScope | null => {
97
+ if (release.fingerprintHash !== null) {
98
+ return {
99
+ platform: release.platform,
100
+ channel: release.channel,
101
+ fingerprintHash: release.fingerprintHash,
102
+ appVersion: null,
103
+ };
104
+ }
105
+ const target = release.targetAppVersion;
106
+ if (target === null || canonicalizeAppVersion(target) !== target) {
107
+ return null;
108
+ }
109
+ return {
110
+ platform: release.platform,
111
+ channel: release.channel,
112
+ fingerprintHash: null,
113
+ appVersion: target,
114
+ };
115
+ };
116
+
117
+ /**
118
+ * The artifact's file name, the last path segment of its storage URI, so a
119
+ * public URL's query or fragment stays out of it.
120
+ */
121
+ export const nativeBuildFileName = (build: NativeBuildRow): string => {
122
+ const path = build.artifact_storage_uri.split(/[?#]/, 1)[0] ?? "";
123
+ const segment = path.split("/").at(-1) ?? "";
124
+ try {
125
+ return decodeURIComponent(segment);
126
+ } catch {
127
+ return segment;
128
+ }
129
+ };
130
+
131
+ /** What the build compiled in: its app version, or its fingerprint. */
132
+ export const nativeBuildTarget = (build: NativeBuildRow) =>
133
+ build.app_version === null
134
+ ? { label: "Fingerprint", value: build.fingerprint_hash ?? "" }
135
+ : { label: "App version", value: build.app_version };
136
+
137
+ const UNITS = ["B", "KB", "MB", "GB"] as const;
138
+
139
+ /** A byte count in the largest unit that keeps it at or above 1. */
140
+ export const formatByteSize = (bytes: number): string => {
141
+ let value = bytes;
142
+ let unit = 0;
143
+ while (value >= 1024 && unit < UNITS.length - 1) {
144
+ value /= 1024;
145
+ unit += 1;
146
+ }
147
+ return `${unit === 0 ? value : value.toFixed(1)} ${UNITS[unit]}`;
148
+ };
149
+
150
+ /**
151
+ * The commands that install a simulator build: unzip the download, then
152
+ * install the `.app` on the booted simulator.
153
+ */
154
+ export const simulatorInstallCommand = (build: NativeBuildRow) => {
155
+ const archive = nativeBuildFileName(build);
156
+ const app = archive.replace(/\.zip$/, "");
157
+ return `unzip -o ${shellQuote(archive)} && xcrun simctl install booted ${shellQuote(app)}`;
158
+ };
159
+
160
+ /** The command that installs a downloaded APK on an Android device or emulator. */
161
+ export const apkInstallCommand = (build: NativeBuildRow) =>
162
+ `adb install -r ${shellQuote(nativeBuildFileName(build))}`;
@@ -0,0 +1,16 @@
1
+ import { encode } from "uqr";
2
+
3
+ /**
4
+ * A QR code of `value` as one SVG path of unit squares, with the standard
5
+ * four-module quiet zone: `size` is the side of its viewBox.
6
+ */
7
+ export const qrCodePath = (value: string): { size: number; path: string } => {
8
+ const { data, size } = encode(value, { ecc: "M", border: 4 });
9
+ let path = "";
10
+ data.forEach((row, y) =>
11
+ row.forEach((dark, x) => {
12
+ if (dark) path += `M${x} ${y}h1v1h-1z`;
13
+ }),
14
+ );
15
+ return { size, path };
16
+ };
@@ -0,0 +1,54 @@
1
+ import { queryOptions, useQuery, useQueryClient } from "@tanstack/react-query";
2
+ import { useCallback, useSyncExternalStore } from "react";
3
+
4
+ import { getSchemaMigrationRpc } from "./schema-migration-rpc";
5
+
6
+ export const schemaMigrationQueryKey = ["schema-migration"] as const;
7
+
8
+ export const schemaMigrationQueryOptions = () =>
9
+ queryOptions({
10
+ queryKey: schemaMigrationQueryKey,
11
+ queryFn: () => getSchemaMigrationRpc(),
12
+ retry: false,
13
+ });
14
+
15
+ const isSchemaQuery = (queryKey: readonly unknown[]) =>
16
+ queryKey[0] === schemaMigrationQueryKey[0];
17
+
18
+ /**
19
+ * The schema fence's refusal of the console's database, asked for once any
20
+ * page's read fails, so a healthy console reads nothing more. `retry` asks
21
+ * again, and once the fence passes, reads the failed pages again.
22
+ */
23
+ export const useSchemaMigration = () => {
24
+ const queryClient = useQueryClient();
25
+ const cache = queryClient.getQueryCache();
26
+ const failing = useSyncExternalStore(
27
+ (onChange) => cache.subscribe(onChange),
28
+ () =>
29
+ cache
30
+ .getAll()
31
+ .some(
32
+ ({ queryKey, state }) =>
33
+ !isSchemaQuery(queryKey) && state.fetchFailureCount > 0,
34
+ ),
35
+ () => false,
36
+ );
37
+ const { data } = useQuery({
38
+ ...schemaMigrationQueryOptions(),
39
+ enabled: failing,
40
+ });
41
+ const retry = useCallback(async () => {
42
+ const status = await queryClient.fetchQuery({
43
+ ...schemaMigrationQueryOptions(),
44
+ staleTime: 0,
45
+ });
46
+ if (status !== null) return;
47
+ await queryClient.resetQueries({
48
+ predicate: ({ queryKey, state }) =>
49
+ !isSchemaQuery(queryKey) &&
50
+ (state.fetchFailureCount > 0 || state.status === "error"),
51
+ });
52
+ }, [queryClient]);
53
+ return { status: data ?? null, retry };
54
+ };
@@ -0,0 +1,26 @@
1
+ import { createServerFn } from "@tanstack/react-start";
2
+
3
+ import { consoleAccess } from "./console-access";
4
+ import {
5
+ type SchemaMigrationStatus,
6
+ schemaMigrationOf,
7
+ } from "./schema-migration";
8
+
9
+ /**
10
+ * Whether the schema fence refuses the console's database, and what it
11
+ * found: one read through core, which the console makes only after a page's
12
+ * read failed. Null when the read passes or fails for another reason, which
13
+ * the page reports itself.
14
+ */
15
+ export const getSchemaMigrationRpc = createServerFn({ method: "GET" })
16
+ .middleware([consoleAccess])
17
+ .handler(async (): Promise<SchemaMigrationStatus | null> => {
18
+ const { prepareConfig } = await import("./server/config.server");
19
+ const { config, core } = await prepareConfig();
20
+ try {
21
+ await core.listChannels();
22
+ return null;
23
+ } catch (error) {
24
+ return schemaMigrationOf(error, config.plugins);
25
+ }
26
+ });
@@ -0,0 +1,101 @@
1
+ /** A schema setting the fence found missing or different. */
2
+ export interface SchemaSetting {
3
+ readonly key: string;
4
+ readonly expected: string;
5
+ readonly found: string | null;
6
+ }
7
+
8
+ /**
9
+ * The database needs migrations before the console can read it: what the
10
+ * schema fence reported, as plain data. TanStack Start sends a thrown error
11
+ * as its message alone, so the console asks for this separately.
12
+ */
13
+ export interface SchemaMigrationStatus {
14
+ readonly message: string;
15
+ readonly settings: readonly SchemaSetting[];
16
+ /** The plugins whose tables a migration has yet to create or change. */
17
+ readonly plugins: readonly string[];
18
+ /**
19
+ * Whether a migration moves it forward: every setting is missing or older.
20
+ * False for a database a newer release migrated, a different storage
21
+ * layout, or a v0 database, which doctor reports and nothing moves.
22
+ */
23
+ readonly migratable: boolean;
24
+ }
25
+
26
+ /** Compares dotted numeric versions, such as "1" and "1.2.0"; NaN when either is not one. */
27
+ const compareVersions = (left: string, right: string): number => {
28
+ const parse = (version: string) => version.split(".").map(Number);
29
+ const [a, b] = [parse(left), parse(right)];
30
+ if ([...a, ...b].some(Number.isNaN)) return Number.NaN;
31
+ for (let index = 0; index < Math.max(a.length, b.length); index += 1) {
32
+ const difference = (a[index] ?? 0) - (b[index] ?? 0);
33
+ if (difference !== 0) return difference;
34
+ }
35
+ return 0;
36
+ };
37
+
38
+ /** The brand Hot Updater's own plugin factories set, read as the server reads it. */
39
+ const OFFICIAL = Symbol.for("@hot-updater/server/official-plugin");
40
+
41
+ /**
42
+ * Whether a migration moves a setting forward: a missing one, or an older
43
+ * version of core's or of one of Hot Updater's own plugins. Another plugin's
44
+ * changed tables need its own migration.
45
+ */
46
+ const migrates = (
47
+ { key, expected, found }: SchemaSetting,
48
+ official: ReadonlySet<string>,
49
+ ) =>
50
+ found === null ||
51
+ ((key === "schema.core" || official.has(key)) &&
52
+ compareVersions(found, expected) < 0);
53
+
54
+ /**
55
+ * The fence's refusal in `error`, recognized by name: plugin-core may be
56
+ * another copy than the console's. Null for any other error.
57
+ */
58
+ export const schemaMigrationOf = (
59
+ error: unknown,
60
+ /** The plugins the console's config lists. */
61
+ plugins: readonly unknown[] = [],
62
+ ): SchemaMigrationStatus | null => {
63
+ if (
64
+ !(error instanceof Error) ||
65
+ error.name !== "HotUpdaterSchemaMigrationRequiredError"
66
+ ) {
67
+ return null;
68
+ }
69
+ const official = new Set(
70
+ plugins.flatMap((plugin) =>
71
+ typeof plugin === "object" &&
72
+ plugin !== null &&
73
+ Reflect.get(plugin, OFFICIAL) === true
74
+ ? [`schema.${String(Reflect.get(plugin, "id"))}`]
75
+ : [],
76
+ ),
77
+ );
78
+ const {
79
+ settings = [],
80
+ plugins: refused = [],
81
+ currentVersion,
82
+ } = error as Error & {
83
+ readonly settings?: readonly SchemaSetting[];
84
+ readonly plugins?: readonly string[];
85
+ /** A v0 database's schema version. */
86
+ readonly currentVersion?: string;
87
+ };
88
+ return {
89
+ message: error.message,
90
+ settings: settings.map(({ key, expected, found }) => ({
91
+ key,
92
+ expected,
93
+ found,
94
+ })),
95
+ plugins: [...refused],
96
+ migratable:
97
+ currentVersion === undefined &&
98
+ settings.length > 0 &&
99
+ settings.every((setting) => migrates(setting, official)),
100
+ };
101
+ };
@@ -23,23 +23,32 @@ const loadCachedConfig = async (request: Request) => {
23
23
  return configPromise;
24
24
  };
25
25
 
26
+ /**
27
+ * The console's config, core, and features, without the access check: for
28
+ * routes that take no session, such as a channel link's QR code. Everything
29
+ * else goes through {@link prepareConfig}.
30
+ */
31
+ export const loadConsole = async (request: Request = getRequest()) => {
32
+ const config = await loadCachedConfig(request);
33
+
34
+ // Bundles, releases, catalogs, and channels: core assembled as the
35
+ // server's, on the server's own path, or a self-hosted server's admin API.
36
+ core ??= config.core;
37
+
38
+ // The console's features: those of the plugins its config lists.
39
+ if (!runtime) {
40
+ const { createConsoleRuntime } = await import("./runtime.server");
41
+ runtime = createConsoleRuntime(config);
42
+ }
43
+
44
+ // Each bundle file is read and deleted with its protocol's storage.
45
+ return { config, core, runtime, storage: config.storage };
46
+ };
47
+
26
48
  export const prepareConfig = async (request: Request = getRequest()) => {
27
49
  try {
28
50
  await requireConsoleAccess(request);
29
- const config = await loadCachedConfig(request);
30
-
31
- // Bundles, releases, catalogs, and channels: core assembled as the
32
- // server's, on the server's own path, or a self-hosted server's admin API.
33
- core ??= config.core;
34
-
35
- // The console's features: those of the plugins its config lists.
36
- if (!runtime) {
37
- const { createConsoleRuntime } = await import("./runtime.server");
38
- runtime = createConsoleRuntime(config);
39
- }
40
-
41
- // Each bundle file is read and deleted with its protocol's storage.
42
- return { config, core, runtime, storage: config.storage };
51
+ return await loadConsole(request);
43
52
  } catch (error) {
44
53
  if (
45
54
  !(
@@ -72,10 +72,8 @@ export const resolveConsoleConfig = async (
72
72
 
73
73
  const config = typeof source === "function" ? await source(request) : source;
74
74
  const { database, storage, plugins = [] } = config;
75
- const gitUrl =
76
- config.console?.gitUrl === undefined
77
- ? {}
78
- : { gitUrl: config.console.gitUrl };
75
+ const { gitUrl } = config.console ?? {};
76
+ const consoleOptions = gitUrl === undefined ? {} : { gitUrl };
79
77
  // A self-hosted server runs the plugins itself: core is its admin API.
80
78
  // The plugins are still checked as the server checks them, on a database
81
79
  // nothing reads, so one the server would refuse is refused here too.
@@ -86,7 +84,7 @@ export const resolveConsoleConfig = async (
86
84
  plugins,
87
85
  );
88
86
  return {
89
- ...gitUrl,
87
+ ...consoleOptions,
90
88
  database,
91
89
  core: database.core,
92
90
  storage,
@@ -95,7 +93,7 @@ export const resolveConsoleConfig = async (
95
93
  }
96
94
  const server = assemble(database, storage, plugins);
97
95
  return {
98
- ...gitUrl,
96
+ ...consoleOptions,
99
97
  database,
100
98
  core: server.core,
101
99
  storage,