@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
@@ -13,10 +13,14 @@ import { Route as IndexRouteImport } from './routes/index'
13
13
  import { Route as ApiKeysRouteImport } from './routes/api-keys'
14
14
  import { Route as InsightsRouteImport } from './routes/insights'
15
15
  import { Route as InstallationsRouteImport } from './routes/installations'
16
+ import { Route as NativeBuildsRouteImport } from './routes/native-builds'
16
17
  import { Route as RemoteConfigRouteImport } from './routes/remote-config'
17
18
  import { Route as InsightsDistributionRouteImport } from './routes/insights_.distribution'
19
+ import { Route as NativeBuildsBuildIdRouteImport } from './routes/native-builds_.$buildId'
20
+ import { Route as HotUpdaterNativeBuildsQrRouteImport } from './routes/[_]hot-updater/native-builds/qr'
18
21
  import { Route as ApiAuthSplatRouteImport } from './routes/api/auth/$'
19
22
  import { Route as ApiBundlesBundleIdDownloadRouteImport } from './routes/api/bundles/$bundleId/download'
23
+ import { Route as ApiNativeBuildsBuildIdDownloadRouteImport } from './routes/api/native-builds/$buildId/download'
20
24
 
21
25
  const IndexRoute = IndexRouteImport.update({
22
26
  id: '/',
@@ -38,6 +42,11 @@ const InstallationsRoute = InstallationsRouteImport.update({
38
42
  path: '/installations',
39
43
  getParentRoute: () => rootRouteImport,
40
44
  } as any)
45
+ const NativeBuildsRoute = NativeBuildsRouteImport.update({
46
+ id: '/native-builds',
47
+ path: '/native-builds',
48
+ getParentRoute: () => rootRouteImport,
49
+ } as any)
41
50
  const RemoteConfigRoute = RemoteConfigRouteImport.update({
42
51
  id: '/remote-config',
43
52
  path: '/remote-config',
@@ -48,6 +57,17 @@ const InsightsDistributionRoute = InsightsDistributionRouteImport.update({
48
57
  path: '/insights/distribution',
49
58
  getParentRoute: () => rootRouteImport,
50
59
  } as any)
60
+ const NativeBuildsBuildIdRoute = NativeBuildsBuildIdRouteImport.update({
61
+ id: '/native-builds_/$buildId',
62
+ path: '/native-builds/$buildId',
63
+ getParentRoute: () => rootRouteImport,
64
+ } as any)
65
+ const HotUpdaterNativeBuildsQrRoute =
66
+ HotUpdaterNativeBuildsQrRouteImport.update({
67
+ id: '/_hot-updater/native-builds/qr',
68
+ path: '/_hot-updater/native-builds/qr',
69
+ getParentRoute: () => rootRouteImport,
70
+ } as any)
51
71
  const ApiAuthSplatRoute = ApiAuthSplatRouteImport.update({
52
72
  id: '/api/auth/$',
53
73
  path: '/api/auth/$',
@@ -59,26 +79,40 @@ const ApiBundlesBundleIdDownloadRoute =
59
79
  path: '/api/bundles/$bundleId/download',
60
80
  getParentRoute: () => rootRouteImport,
61
81
  } as any)
82
+ const ApiNativeBuildsBuildIdDownloadRoute =
83
+ ApiNativeBuildsBuildIdDownloadRouteImport.update({
84
+ id: '/api/native-builds/$buildId/download',
85
+ path: '/api/native-builds/$buildId/download',
86
+ getParentRoute: () => rootRouteImport,
87
+ } as any)
62
88
 
63
89
  export interface FileRoutesByFullPath {
64
90
  '/': typeof IndexRoute
65
91
  '/api-keys': typeof ApiKeysRoute
66
92
  '/insights': typeof InsightsRoute
67
93
  '/installations': typeof InstallationsRoute
94
+ '/native-builds': typeof NativeBuildsRoute
68
95
  '/remote-config': typeof RemoteConfigRoute
69
96
  '/insights/distribution': typeof InsightsDistributionRoute
97
+ '/native-builds/$buildId': typeof NativeBuildsBuildIdRoute
98
+ '/_hot-updater/native-builds/qr': typeof HotUpdaterNativeBuildsQrRoute
70
99
  '/api/auth/$': typeof ApiAuthSplatRoute
71
100
  '/api/bundles/$bundleId/download': typeof ApiBundlesBundleIdDownloadRoute
101
+ '/api/native-builds/$buildId/download': typeof ApiNativeBuildsBuildIdDownloadRoute
72
102
  }
73
103
  export interface FileRoutesByTo {
74
104
  '/': typeof IndexRoute
75
105
  '/api-keys': typeof ApiKeysRoute
76
106
  '/insights': typeof InsightsRoute
77
107
  '/installations': typeof InstallationsRoute
108
+ '/native-builds': typeof NativeBuildsRoute
78
109
  '/remote-config': typeof RemoteConfigRoute
79
110
  '/insights/distribution': typeof InsightsDistributionRoute
111
+ '/native-builds/$buildId': typeof NativeBuildsBuildIdRoute
112
+ '/_hot-updater/native-builds/qr': typeof HotUpdaterNativeBuildsQrRoute
80
113
  '/api/auth/$': typeof ApiAuthSplatRoute
81
114
  '/api/bundles/$bundleId/download': typeof ApiBundlesBundleIdDownloadRoute
115
+ '/api/native-builds/$buildId/download': typeof ApiNativeBuildsBuildIdDownloadRoute
82
116
  }
83
117
  export interface FileRoutesById {
84
118
  __root__: typeof rootRouteImport
@@ -86,10 +120,14 @@ export interface FileRoutesById {
86
120
  '/api-keys': typeof ApiKeysRoute
87
121
  '/insights': typeof InsightsRoute
88
122
  '/installations': typeof InstallationsRoute
123
+ '/native-builds': typeof NativeBuildsRoute
89
124
  '/remote-config': typeof RemoteConfigRoute
90
125
  '/insights_/distribution': typeof InsightsDistributionRoute
126
+ '/native-builds_/$buildId': typeof NativeBuildsBuildIdRoute
127
+ '/_hot-updater/native-builds/qr': typeof HotUpdaterNativeBuildsQrRoute
91
128
  '/api/auth/$': typeof ApiAuthSplatRoute
92
129
  '/api/bundles/$bundleId/download': typeof ApiBundlesBundleIdDownloadRoute
130
+ '/api/native-builds/$buildId/download': typeof ApiNativeBuildsBuildIdDownloadRoute
93
131
  }
94
132
  export interface FileRouteTypes {
95
133
  fileRoutesByFullPath: FileRoutesByFullPath
@@ -98,30 +136,42 @@ export interface FileRouteTypes {
98
136
  | '/api-keys'
99
137
  | '/insights'
100
138
  | '/installations'
139
+ | '/native-builds'
101
140
  | '/remote-config'
102
141
  | '/insights/distribution'
142
+ | '/native-builds/$buildId'
143
+ | '/_hot-updater/native-builds/qr'
103
144
  | '/api/auth/$'
104
145
  | '/api/bundles/$bundleId/download'
146
+ | '/api/native-builds/$buildId/download'
105
147
  fileRoutesByTo: FileRoutesByTo
106
148
  to:
107
149
  | '/'
108
150
  | '/api-keys'
109
151
  | '/insights'
110
152
  | '/installations'
153
+ | '/native-builds'
111
154
  | '/remote-config'
112
155
  | '/insights/distribution'
156
+ | '/native-builds/$buildId'
157
+ | '/_hot-updater/native-builds/qr'
113
158
  | '/api/auth/$'
114
159
  | '/api/bundles/$bundleId/download'
160
+ | '/api/native-builds/$buildId/download'
115
161
  id:
116
162
  | '__root__'
117
163
  | '/'
118
164
  | '/api-keys'
119
165
  | '/insights'
120
166
  | '/installations'
167
+ | '/native-builds'
121
168
  | '/remote-config'
122
169
  | '/insights_/distribution'
170
+ | '/native-builds_/$buildId'
171
+ | '/_hot-updater/native-builds/qr'
123
172
  | '/api/auth/$'
124
173
  | '/api/bundles/$bundleId/download'
174
+ | '/api/native-builds/$buildId/download'
125
175
  fileRoutesById: FileRoutesById
126
176
  }
127
177
  export interface RootRouteChildren {
@@ -129,10 +179,14 @@ export interface RootRouteChildren {
129
179
  ApiKeysRoute: typeof ApiKeysRoute
130
180
  InsightsRoute: typeof InsightsRoute
131
181
  InstallationsRoute: typeof InstallationsRoute
182
+ NativeBuildsRoute: typeof NativeBuildsRoute
132
183
  RemoteConfigRoute: typeof RemoteConfigRoute
133
184
  InsightsDistributionRoute: typeof InsightsDistributionRoute
185
+ NativeBuildsBuildIdRoute: typeof NativeBuildsBuildIdRoute
186
+ HotUpdaterNativeBuildsQrRoute: typeof HotUpdaterNativeBuildsQrRoute
134
187
  ApiAuthSplatRoute: typeof ApiAuthSplatRoute
135
188
  ApiBundlesBundleIdDownloadRoute: typeof ApiBundlesBundleIdDownloadRoute
189
+ ApiNativeBuildsBuildIdDownloadRoute: typeof ApiNativeBuildsBuildIdDownloadRoute
136
190
  }
137
191
 
138
192
  declare module '@tanstack/react-router' {
@@ -165,6 +219,13 @@ declare module '@tanstack/react-router' {
165
219
  preLoaderRoute: typeof InstallationsRouteImport
166
220
  parentRoute: typeof rootRouteImport
167
221
  }
222
+ '/native-builds': {
223
+ id: '/native-builds'
224
+ path: '/native-builds'
225
+ fullPath: '/native-builds'
226
+ preLoaderRoute: typeof NativeBuildsRouteImport
227
+ parentRoute: typeof rootRouteImport
228
+ }
168
229
  '/remote-config': {
169
230
  id: '/remote-config'
170
231
  path: '/remote-config'
@@ -179,6 +240,20 @@ declare module '@tanstack/react-router' {
179
240
  preLoaderRoute: typeof InsightsDistributionRouteImport
180
241
  parentRoute: typeof rootRouteImport
181
242
  }
243
+ '/native-builds_/$buildId': {
244
+ id: '/native-builds_/$buildId'
245
+ path: '/native-builds/$buildId'
246
+ fullPath: '/native-builds/$buildId'
247
+ preLoaderRoute: typeof NativeBuildsBuildIdRouteImport
248
+ parentRoute: typeof rootRouteImport
249
+ }
250
+ '/_hot-updater/native-builds/qr': {
251
+ id: '/_hot-updater/native-builds/qr'
252
+ path: '/_hot-updater/native-builds/qr'
253
+ fullPath: '/_hot-updater/native-builds/qr'
254
+ preLoaderRoute: typeof HotUpdaterNativeBuildsQrRouteImport
255
+ parentRoute: typeof rootRouteImport
256
+ }
182
257
  '/api/auth/$': {
183
258
  id: '/api/auth/$'
184
259
  path: '/api/auth/$'
@@ -193,6 +268,13 @@ declare module '@tanstack/react-router' {
193
268
  preLoaderRoute: typeof ApiBundlesBundleIdDownloadRouteImport
194
269
  parentRoute: typeof rootRouteImport
195
270
  }
271
+ '/api/native-builds/$buildId/download': {
272
+ id: '/api/native-builds/$buildId/download'
273
+ path: '/api/native-builds/$buildId/download'
274
+ fullPath: '/api/native-builds/$buildId/download'
275
+ preLoaderRoute: typeof ApiNativeBuildsBuildIdDownloadRouteImport
276
+ parentRoute: typeof rootRouteImport
277
+ }
196
278
  }
197
279
  }
198
280
 
@@ -201,20 +283,25 @@ const rootRouteChildren: RootRouteChildren = {
201
283
  ApiKeysRoute: ApiKeysRoute,
202
284
  InsightsRoute: InsightsRoute,
203
285
  InstallationsRoute: InstallationsRoute,
286
+ NativeBuildsRoute: NativeBuildsRoute,
204
287
  RemoteConfigRoute: RemoteConfigRoute,
205
288
  InsightsDistributionRoute: InsightsDistributionRoute,
289
+ NativeBuildsBuildIdRoute: NativeBuildsBuildIdRoute,
290
+ HotUpdaterNativeBuildsQrRoute: HotUpdaterNativeBuildsQrRoute,
206
291
  ApiAuthSplatRoute: ApiAuthSplatRoute,
207
292
  ApiBundlesBundleIdDownloadRoute: ApiBundlesBundleIdDownloadRoute,
293
+ ApiNativeBuildsBuildIdDownloadRoute: ApiNativeBuildsBuildIdDownloadRoute,
208
294
  }
209
295
  export const routeTree = rootRouteImport
210
296
  ._addFileChildren(rootRouteChildren)
211
297
  ._addFileTypes<FileRouteTypes>()
212
298
 
213
299
  import type { getRouter } from './router.tsx'
214
- import type { createStart } from '@tanstack/react-start'
300
+ import type { startInstance } from './start.ts'
215
301
  declare module '@tanstack/react-start' {
216
302
  interface Register {
217
303
  ssr: true
218
304
  router: Awaited<ReturnType<typeof getRouter>>
305
+ config: Awaited<ReturnType<typeof startInstance.getOptions>>
219
306
  }
220
307
  }
package/src/router.tsx CHANGED
@@ -4,11 +4,21 @@ import { setupRouterSsrQueryIntegration } from "@tanstack/react-router-ssr-query
4
4
  // Import the route tree selected by the local or hosted Vite integration.
5
5
  import { routeTree } from "virtual:hot-updater-console/route-tree";
6
6
 
7
+ import { schemaMigrationQueryKey } from "./lib/schema-migration-api";
7
8
  import { routeScrollRestorationKey } from "./lib/scroll-restoration";
8
9
 
9
10
  // Create a new router instance
10
11
  export const getRouter = () => {
11
- const queryClient = new QueryClient();
12
+ const queryClient: QueryClient = new QueryClient({
13
+ defaultOptions: {
14
+ queries: {
15
+ // A database that needs migrations stays refused until someone runs
16
+ // them; the console's notice retries when asked.
17
+ retry: (failures) =>
18
+ failures < 3 && !queryClient.getQueryData(schemaMigrationQueryKey),
19
+ },
20
+ },
21
+ });
12
22
  const router = createRouter({
13
23
  routeTree,
14
24
  context: { queryClient },
@@ -0,0 +1,51 @@
1
+ import { assertCanonicalChannelName } from "@hot-updater/protocol";
2
+
3
+ import type { NativeBuildDetailSearch } from "@/components/features/native-builds/NativeBuildDetailPage";
4
+ import type { NativeBuildPage } from "@/lib/api";
5
+
6
+ const text = (value: unknown) =>
7
+ typeof value === "string" && value.length > 0 ? value : undefined;
8
+
9
+ /** A channel name a build can embed, or undefined. */
10
+ const channelName = (value: unknown) => {
11
+ const channel = text(value);
12
+ if (channel === undefined) return undefined;
13
+ try {
14
+ assertCanonicalChannelName(channel);
15
+ return channel;
16
+ } catch {
17
+ return undefined;
18
+ }
19
+ };
20
+
21
+ const defined = <T extends object>(values: T): T =>
22
+ Object.fromEntries(
23
+ Object.entries(values).filter(([, value]) => value !== undefined),
24
+ ) as T;
25
+
26
+ /**
27
+ * The native build list's URL: a channel the builds embed, and one keyset
28
+ * page. A page has one direction, so `before` wins over `after`.
29
+ */
30
+ export const validateNativeBuildsSearch = (
31
+ search: Record<string, unknown>,
32
+ ): NativeBuildPage => {
33
+ const before = text(search.before);
34
+ return defined({
35
+ channel: channelName(search.channel),
36
+ before,
37
+ after: before === undefined ? text(search.after) : undefined,
38
+ });
39
+ };
40
+
41
+ /** A native build page's URL: one page of the patches from it. */
42
+ export const validateNativeBuildDetailSearch = (
43
+ search: Record<string, unknown>,
44
+ ): NativeBuildDetailSearch => {
45
+ const patchesBefore = text(search.patchesBefore);
46
+ return defined({
47
+ patchesBefore,
48
+ patchesAfter:
49
+ patchesBefore === undefined ? text(search.patchesAfter) : undefined,
50
+ });
51
+ };
@@ -0,0 +1,14 @@
1
+ import { createFileRoute } from "@tanstack/react-router";
2
+
3
+ // A native build's download QR code takes no session and reads nothing:
4
+ // see nativeBuildQr.ts.
5
+ const handle = async ({ request }: { readonly request: Request }) => {
6
+ const { serveNativeBuildQr } = await import("@/lib/server/nativeBuildQr");
7
+ return serveNativeBuildQr(request);
8
+ };
9
+
10
+ export const Route = createFileRoute("/_hot-updater/native-builds/qr")({
11
+ server: {
12
+ handlers: { ANY: handle },
13
+ },
14
+ });
@@ -10,6 +10,7 @@ import { useEffect, useState } from "react";
10
10
  import { AppSidebar } from "@/components/AppSidebar";
11
11
  import { ConsoleAccessPage } from "@/components/ConsoleAccessPage";
12
12
  import { NotFoundPage } from "@/components/NotFoundPage";
13
+ import { SchemaMigrationRequired } from "@/components/SchemaMigrationRequired";
13
14
  import { ThemeProvider } from "@/components/ThemeProvider";
14
15
  import { SidebarInset, SidebarProvider } from "@/components/ui/sidebar";
15
16
  import { Toaster } from "@/components/ui/sonner";
@@ -19,6 +20,7 @@ import {
19
20
  getConsoleAuthProvidersRpc,
20
21
  } from "@/lib/auth-rpc";
21
22
  import { consoleFeaturesQueryOptions } from "@/lib/console-features-api";
23
+ import { useSchemaMigration } from "@/lib/schema-migration-api";
22
24
 
23
25
  import appCss from "../styles.css?url";
24
26
 
@@ -150,6 +152,7 @@ function RootLayout() {
150
152
  }
151
153
 
152
154
  function AuthorizedConsole({ canSignOut }: { canSignOut: boolean }) {
155
+ const schema = useSchemaMigration();
153
156
  useEffect(() => {
154
157
  if (
155
158
  import.meta.env.DEV &&
@@ -163,7 +166,14 @@ function AuthorizedConsole({ canSignOut }: { canSignOut: boolean }) {
163
166
  <SidebarProvider>
164
167
  <AppSidebar canSignOut={canSignOut} />
165
168
  <SidebarInset className="min-h-0 min-w-0 overflow-hidden">
166
- <Outlet />
169
+ {schema.status ? (
170
+ <SchemaMigrationRequired
171
+ status={schema.status}
172
+ onRetry={schema.retry}
173
+ />
174
+ ) : (
175
+ <Outlet />
176
+ )}
167
177
  </SidebarInset>
168
178
  </SidebarProvider>
169
179
  );
@@ -0,0 +1,50 @@
1
+ import { createFileRoute } from "@tanstack/react-router";
2
+
3
+ /**
4
+ * Whether a request is a browser opening the URL as a page, as a phone does
5
+ * after scanning a QR code, rather than a script fetching it.
6
+ */
7
+ const isNavigation = (request: Request) =>
8
+ request.headers.get("sec-fetch-mode") === "navigate" ||
9
+ (request.headers.get("accept") ?? "").includes("text/html");
10
+
11
+ export const Route = createFileRoute("/api/native-builds/$buildId/download")({
12
+ server: {
13
+ handlers: {
14
+ GET: async ({ params, request }) => {
15
+ const { prepareConfig } = await import("@/lib/server/config.server");
16
+ const { downloadNativeBuild } =
17
+ await import("@/lib/server/nativeBuilds");
18
+ let deps: Awaited<ReturnType<typeof prepareConfig>>;
19
+ try {
20
+ deps = await prepareConfig(request);
21
+ } catch (error) {
22
+ // A browser without a session opens the build's page instead,
23
+ // where the console signs it in and returns to this download
24
+ // (`returnTo`, relative to that page). Both paths are relative,
25
+ // so they stay under the console's own path, wherever that is
26
+ // mounted; sign-in takes `returnTo` only on the console's origin.
27
+ if (
28
+ error instanceof Response &&
29
+ error.status === 401 &&
30
+ isNavigation(request)
31
+ ) {
32
+ const buildId = encodeURIComponent(params.buildId);
33
+ const returnTo = encodeURIComponent(
34
+ `../api/native-builds/${buildId}/download`,
35
+ );
36
+ return new Response(null, {
37
+ headers: {
38
+ "cache-control": "no-store",
39
+ location: `../../../native-builds/${buildId}?returnTo=${returnTo}`,
40
+ },
41
+ status: 302,
42
+ });
43
+ }
44
+ throw error;
45
+ }
46
+ return downloadNativeBuild(params.buildId, deps);
47
+ },
48
+ },
49
+ },
50
+ });
@@ -0,0 +1,21 @@
1
+ import { createFileRoute } from "@tanstack/react-router";
2
+
3
+ import { NativeBuildsPage } from "@/components/features/native-builds/NativeBuildsPage";
4
+
5
+ import { validateNativeBuildsSearch } from "./-native-builds-search";
6
+
7
+ export const Route = createFileRoute("/native-builds")({
8
+ component: NativeBuildsRoute,
9
+ validateSearch: validateNativeBuildsSearch,
10
+ });
11
+
12
+ function NativeBuildsRoute() {
13
+ const search = Route.useSearch();
14
+ const navigate = Route.useNavigate();
15
+ return (
16
+ <NativeBuildsPage
17
+ onSearchChange={(next) => void navigate({ search: next })}
18
+ search={search}
19
+ />
20
+ );
21
+ }
@@ -0,0 +1,23 @@
1
+ import { createFileRoute } from "@tanstack/react-router";
2
+
3
+ import { NativeBuildDetailPage } from "@/components/features/native-builds/NativeBuildDetailPage";
4
+
5
+ import { validateNativeBuildDetailSearch } from "./-native-builds-search";
6
+
7
+ export const Route = createFileRoute("/native-builds_/$buildId")({
8
+ component: NativeBuildDetailRoute,
9
+ validateSearch: validateNativeBuildDetailSearch,
10
+ });
11
+
12
+ function NativeBuildDetailRoute() {
13
+ const { buildId } = Route.useParams();
14
+ const search = Route.useSearch();
15
+ const navigate = Route.useNavigate();
16
+ return (
17
+ <NativeBuildDetailPage
18
+ buildId={buildId}
19
+ onSearchChange={(next) => void navigate({ search: next, replace: true })}
20
+ search={search}
21
+ />
22
+ );
23
+ }
package/src/start.ts ADDED
@@ -0,0 +1,33 @@
1
+ import {
2
+ createCsrfMiddleware,
3
+ createMiddleware,
4
+ createStart,
5
+ } from "@tanstack/react-start";
6
+
7
+ /**
8
+ * Server functions answer only their own console's pages: a request
9
+ * another site sends, such as a form that posts to one, gets 403. TanStack
10
+ * Start adds this check itself only while no `start.ts` exists, so it is
11
+ * listed here, and `start.spec.ts` keeps it listed.
12
+ */
13
+ const sameOriginServerFunctions = createCsrfMiddleware({
14
+ filter: (context) => context.handlerType === "serverFn",
15
+ });
16
+
17
+ /**
18
+ * The local console's lock, before any page, server function, or route:
19
+ * this machine's `Host` only, changes from its own pages only, and the
20
+ * run's session for every page, server function, and route. A hosted
21
+ * console has none: its sign-in guards it.
22
+ */
23
+ const localConsoleGuard = createMiddleware().server(
24
+ async ({ request, next }) => {
25
+ const { default: guard } =
26
+ await import("virtual:hot-updater-console/request-guard");
27
+ return (await guard?.(request)) ?? next();
28
+ },
29
+ );
30
+
31
+ export const startInstance = createStart(() => ({
32
+ requestMiddleware: [sameOriginServerFunctions, localConsoleGuard],
33
+ }));
@@ -19,3 +19,21 @@ declare module "virtual:hot-updater-console/package-router" {
19
19
  declare module "virtual:hot-updater-console/route-tree" {
20
20
  export { routeTree } from "./routeTree.gen";
21
21
  }
22
+
23
+ declare module "virtual:hot-updater-console/request-guard" {
24
+ /**
25
+ * The local console's request guard: a refusal or redirect to answer
26
+ * with, or undefined to let the request through. A hosted console has
27
+ * none.
28
+ */
29
+ const guard:
30
+ | ((
31
+ request: Request,
32
+ ) => Response | undefined | Promise<Response | undefined>)
33
+ | undefined;
34
+ export default guard;
35
+ }
36
+
37
+ declare module "virtual:hot-updater-console/package-start" {
38
+ export { startInstance } from "./start";
39
+ }
@@ -14,14 +14,23 @@ const virtualConfigModuleId = "virtual:hot-updater-console/config";
14
14
  const virtualPackageRouterModuleId =
15
15
  "virtual:hot-updater-console/package-router";
16
16
  const virtualRouteTreeModuleId = "virtual:hot-updater-console/route-tree";
17
+ const virtualPackageStartModuleId = "virtual:hot-updater-console/package-start";
18
+ const virtualRequestGuardModuleId = "virtual:hot-updater-console/request-guard";
17
19
 
18
20
  const resolvedVirtualAuthModuleId = `\0${virtualAuthModuleId}`;
19
21
  const resolvedVirtualConfigModuleId = `\0${virtualConfigModuleId}`;
20
22
  const resolvedVirtualPackageRouterModuleId = `\0${virtualPackageRouterModuleId}`;
23
+ const resolvedVirtualPackageStartModuleId = `\0${virtualPackageStartModuleId}`;
24
+ const resolvedVirtualRequestGuardModuleId = `\0${virtualRequestGuardModuleId}`;
21
25
 
22
26
  const packageRoot = path.resolve(import.meta.dirname, "..");
23
27
  const packagePublicDirectory = path.join(packageRoot, "public");
24
28
  const packageRouterFile = path.join(packageRoot, "src/router.tsx");
29
+ const packageStartFile = path.join(packageRoot, "src/start.ts");
30
+ const localConsoleGuardFile = path.join(
31
+ packageRoot,
32
+ "src/lib/server/local-console.ts",
33
+ );
25
34
  const packageRoutesDirectory = path.join(packageRoot, "src/routes");
26
35
  const packageSourceDirectory = path.join(packageRoot, "src");
27
36
  const localRouteTreeFile = path.join(
@@ -80,6 +89,15 @@ const createConsoleModulesPlugin = (mode: ConsoleModuleMode): Plugin => {
80
89
  "",
81
90
  ].join("\n"),
82
91
  );
92
+ // The package's request middleware, same-origin server functions
93
+ // included, which TanStack Start reads from the source directory.
94
+ writeFileIfChanged(
95
+ path.join(cacheDirectory, "start.ts"),
96
+ [
97
+ `export { startInstance } from ${JSON.stringify(virtualPackageStartModuleId)};`,
98
+ "",
99
+ ].join("\n"),
100
+ );
83
101
  }
84
102
 
85
103
  return {
@@ -116,6 +134,12 @@ const createConsoleModulesPlugin = (mode: ConsoleModuleMode): Plugin => {
116
134
  if (id === virtualPackageRouterModuleId) {
117
135
  return resolvedVirtualPackageRouterModuleId;
118
136
  }
137
+ if (id === virtualPackageStartModuleId) {
138
+ return resolvedVirtualPackageStartModuleId;
139
+ }
140
+ if (id === virtualRequestGuardModuleId) {
141
+ return resolvedVirtualRequestGuardModuleId;
142
+ }
119
143
  if (id === virtualRouteTreeModuleId) {
120
144
  return generatedRouteTreeFile;
121
145
  }
@@ -126,6 +150,36 @@ const createConsoleModulesPlugin = (mode: ConsoleModuleMode): Plugin => {
126
150
  return `export { getRouter } from ${JSON.stringify(toImportPath(packageRouterFile))};`;
127
151
  }
128
152
 
153
+ if (id === resolvedVirtualPackageStartModuleId) {
154
+ return `export { startInstance } from ${JSON.stringify(toImportPath(packageStartFile))};`;
155
+ }
156
+
157
+ if (id === resolvedVirtualRequestGuardModuleId) {
158
+ if (mode.type === "hosted") {
159
+ // Its sign-in guards a hosted console.
160
+ return "export default undefined;";
161
+ }
162
+ // `hot-updater console` passes the run's session. Vite's dev server
163
+ // checks the Host header itself, and a dev console makes its own
164
+ // session and prints the link.
165
+ return [
166
+ `import { guardLocalConsoleRequest, LOCAL_CONSOLE_SESSION_ENV, LOCAL_CONSOLE_SESSION_PARAM } from ${JSON.stringify(toImportPath(localConsoleGuardFile))};`,
167
+ "let session = process.env[LOCAL_CONSOLE_SESSION_ENV] || undefined;",
168
+ "if (session === undefined && import.meta.env.DEV) {",
169
+ " const bytes = crypto.getRandomValues(new Uint8Array(32));",
170
+ ' session = btoa(String.fromCharCode(...bytes)).replaceAll("+", "-").replaceAll("/", "_").replaceAll("=", "");',
171
+ " console.info(`Open the console at /?${LOCAL_CONSOLE_SESSION_PARAM}=${session}`);",
172
+ "}",
173
+ "const port = process.env.NITRO_PORT || process.env.PORT || undefined;",
174
+ "export default (request) =>",
175
+ " guardLocalConsoleRequest(request, {",
176
+ " session,",
177
+ " port: import.meta.env.DEV ? undefined : port,",
178
+ " checkHost: !import.meta.env.DEV,",
179
+ " });",
180
+ ].join("\n");
181
+ }
182
+
129
183
  if (id === resolvedVirtualConfigModuleId) {
130
184
  if (mode.type === "local") {
131
185
  // hot-updater.config.ts's database, storage, and plugins, as the
@@ -148,7 +202,9 @@ const createConsoleModulesPlugin = (mode: ConsoleModuleMode): Plugin => {
148
202
  " database: config.database,",
149
203
  " storage: config.storage,",
150
204
  " plugins: config.plugins,",
151
- " console: { gitUrl: config.console.gitUrl },",
205
+ " console: {",
206
+ " gitUrl: config.console.gitUrl,",
207
+ " },",
152
208
  " };",
153
209
  "};",
154
210
  ].join("\n");
@@ -1 +0,0 @@
1
- import{Fn as e,Ur as t,_ as n,ar as r,b as i,ei as a,g as o,ri as s,v as c,x as l,y as u}from"./sidebar-BqX460IW.js";import{o as d}from"./useCompositeListItem-B-UkrDlu.js";import{f}from"./insights-api-1ZjVu3Sb.js";import{p,t as m}from"./badge-Bqf3UDee.js";import{r as h,t as g}from"./HashValueDisplay-BGkDPaYi.js";import{s as _}from"./input-group-B4nrqIh0.js";import{t as v}from"./smartphone-CtsHuiIC.js";import{n as y}from"./dist-dDj-R6uh.js";import{i as b,o as x,r as S,t as C}from"./empty-Bf4DanOL.js";import{n as w,r as T}from"./InsightsPageHeader-BRw8XkJW.js";var E=r(`activity`,[[`path`,{d:`M22 12h-2.48a2 2 0 0 0-1.93 1.46l-2.35 8.36a.25.25 0 0 1-.48 0L9.24 2.18a.25.25 0 0 0-.48 0l-2.35 8.36A2 2 0 0 1 4.49 12H2`,key:`169zse`}]]),D=r(`arrow-right-left`,[[`path`,{d:`m16 3 4 4-4 4`,key:`1x1c3m`}],[`path`,{d:`M20 7H4`,key:`zbl0bi`}],[`path`,{d:`m8 21-4-4 4-4`,key:`h9nckh`}],[`path`,{d:`M4 17h16`,key:`g4d7ey`}]]),O=r(`circle-alert`,[[`circle`,{cx:`12`,cy:`12`,r:`10`,key:`1mglay`}],[`line`,{x1:`12`,x2:`12`,y1:`8`,y2:`12`,key:`1pkeuh`}],[`line`,{x1:`12`,x2:`12.01`,y1:`16`,y2:`16`,key:`4dfq90`}]]),k=r(`copy`,[[`rect`,{width:`14`,height:`14`,x:`8`,y:`8`,rx:`2`,ry:`2`,key:`17jyea`}],[`path`,{d:`M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2`,key:`zix9uf`}]]),A=r(`sparkles`,[[`path`,{d:`M11.017 2.814a1 1 0 0 1 1.966 0l1.051 5.558a2 2 0 0 0 1.594 1.594l5.558 1.051a1 1 0 0 1 0 1.966l-5.558 1.051a2 2 0 0 0-1.594 1.594l-1.051 5.558a1 1 0 0 1-1.966 0l-1.051-5.558a2 2 0 0 0-1.594-1.594l-5.558-1.051a1 1 0 0 1 0-1.966l5.558-1.051a2 2 0 0 0 1.594-1.594z`,key:`1s2grr`}],[`path`,{d:`M20 2v4`,key:`1rf3ol`}],[`path`,{d:`M22 4h-4`,key:`gwowj6`}],[`circle`,{cx:`4`,cy:`20`,r:`2`,key:`6kqj1y`}]]),j=s(a(),1),M=t(),N={UPDATE_DOWNLOADED:{label:`Downloaded`,description:`Downloaded. It launches when the app restarts.`,variant:`default`,icon:h},UPDATE_APPLIED:{label:`Launched`,description:`The app restarted into the downloaded bundle.`,variant:`success`,icon:p},RECOVERED:{label:`Crashed`,description:`Crashed on the bundle and rolled back.`,variant:`warning`,icon:_},UPDATE_FAILED:{label:`Update failed`,description:`An update check, download, or install failed.`,variant:`destructive`,icon:O},UNCHANGED:{label:`Launch`,description:`The app launched; the report changed nothing.`,variant:`secondary`,icon:E}},P=e=>{let{kinds:t=[],previous:n}=e.change??{};return t.includes(`first_seen`)?{label:`First seen`,description:`The installation's first report to this server.`,variant:`secondary`,icon:A}:t.includes(`app_version`)||t.includes(`native_build`)?{label:`App updated`,description:n&&n.appVersion!==e.appVersion?`From app ${n.appVersion} to ${e.appVersion}.`:`A new build of the same app version.`,variant:`secondary`,icon:v}:t.includes(`bundle`)?{label:`Launched`,description:`Seen running this bundle; the report of the restart into it never arrived.`,variant:`success`,icon:p}:t.includes(`release`)?{label:`Release adopted`,description:`The bundle it runs now ships under another release.`,variant:`secondary`,icon:D}:t.includes(`channel`)?{label:`Channel changed`,description:n?`From ${n.channel} to ${e.channel}.`:`It reports on another channel.`,variant:`secondary`,icon:D}:N.UNCHANGED},F=e=>e.type===`UNCHANGED`&&e.change?P({change:e.change,appVersion:e.appVersion??``,channel:e.channel??``}):N[e.type];function I(){let[e,t]=(0,j.useState)(`UTC`);return(0,j.useEffect)(()=>{t(Intl.DateTimeFormat().resolvedOptions().timeZone)},[]),new Intl.DateTimeFormat(`en`,{timeZone:e,timeZoneName:`shortOffset`,year:`numeric`,month:`2-digit`,day:`2-digit`,hour:`2-digit`,minute:`2-digit`,second:`2-digit`,hourCycle:`h23`})}function L(e,t){let n=Object.fromEntries(t.formatToParts(new Date(e)).map(({type:e,value:t})=>[e,t])),r=n.timeZoneName===`GMT`?`GMT+0`:n.timeZoneName;return`${n.year}/${n.month}/${n.day} ${n.hour}:${n.minute}:${n.second} ${r}`}function R({value:e,formatter:t,touch:n=!1}){let r=new Date(e),i=L(e,t);return(0,M.jsxs)(`details`,{className:`group/time`,children:[(0,M.jsx)(`summary`,{className:`cursor-pointer list-none rounded-md outline-none focus-visible:ring-2 focus-visible:ring-ring/30 [&::-webkit-details-marker]:hidden ${n?`flex min-h-11 items-center`:``}`,children:(0,M.jsxs)(`span`,{className:`flex items-center gap-1`,children:[(0,M.jsx)(`time`,{dateTime:r.toISOString(),className:`whitespace-nowrap`,children:i}),(0,M.jsx)(d,{"aria-hidden":`true`,className:`size-3 text-muted-foreground group-open/time:rotate-180`})]})}),(0,M.jsx)(`p`,{className:`mt-2 text-muted-foreground`,children:r.toISOString().replace(`T`,` `).replace(`Z`,` UTC`)})]})}var z={patch:`A patch delivered it.`,manifest:`Only the changed files were downloaded.`,archive:`The full archive was downloaded.`},B=e=>{if(e.late)return`Counted nothing: the installation had already downloaded or run this bundle.`;if(e.impliedDownload)return`Its download report never arrived; the download counted with it.`;if(e.type===`UPDATE_FAILED`&&e.failure)return f(e.failure);if(e.type===`UPDATE_DOWNLOADED`&&e.delivery){let t=z[e.delivery]??null;return e.patchFallback?`The patch failed. ${t??``}`.trim():t}return null};function V({response:t}){let n=async()=>{try{await navigator.clipboard.writeText(t.body),y.success(`Response body copied`)}catch{y.error(`Could not copy the response body`)}};return(0,M.jsxs)(`section`,{"aria-label":`Response body`,className:`flex min-w-0 flex-col gap-3`,children:[(0,M.jsxs)(`div`,{className:`flex flex-wrap items-center justify-between gap-3`,children:[(0,M.jsx)(`h3`,{className:`text-sm font-medium`,children:`Response body`}),(0,M.jsxs)(e,{variant:`outline`,className:`min-h-11`,disabled:t.body===null||t.body===``,onClick:()=>void n(),children:[(0,M.jsx)(k,{"aria-hidden":`true`,"data-icon":`inline-start`}),` Copy body`]})]}),t.bodyTruncated?(0,M.jsx)(`p`,{className:`text-xs text-muted-foreground`,children:`Truncated to the 4 KiB reporting limit. Copy includes only the stored text.`}):null,t.body?(0,M.jsx)(`pre`,{className:`rounded-md border bg-muted/30 p-4 font-mono text-xs leading-relaxed whitespace-pre-wrap wrap-anywhere`,children:t.body}):(0,M.jsx)(C,{children:(0,M.jsxs)(b,{children:[(0,M.jsx)(x,{children:t.body===null?`Response body unavailable`:`Empty response body`}),(0,M.jsx)(S,{children:t.body===null?`The client received the HTTP status but could not read the body.`:t.status===304?`The server returned no body. The client can reuse its cached catalog.`:`The server returned no text in this response.`})]})})]})}function H({event:t}){let r=t.httpResponse,a=I(),s=r.status===304?`Not modified`:r.status>=500?`Server error`:r.status>=400?`Request error`:r.status>=300?`Redirect`:`Success`,d=r.resource===`catalog`?`Catalog`:`Artifact`,f=[[`App`,t.platform&&`${t.platform===`ios`?`iOS`:`Android`} ${t.appVersion}`],[`Channel`,t.channel],[`SDK`,t.sdkVersion],[`Installation`,t.installId]].filter(([,e])=>e!=null);return(0,M.jsxs)(o,{children:[(0,M.jsxs)(l,{"aria-label":`View ${d.toLowerCase()} response: HTTP ${r.status}`,render:(0,M.jsx)(e,{variant:`ghost`,className:`-ml-2 h-auto min-h-11 justify-start`}),children:[(0,M.jsxs)(m,{variant:r.status>=400?`destructive`:`secondary`,children:[`HTTP `,r.status]}),(0,M.jsxs)(`span`,{children:[d,` response`]})]}),(0,M.jsxs)(n,{className:`data-[side=right]:w-full data-[side=right]:sm:max-w-2xl`,children:[(0,M.jsxs)(u,{className:`border-b pr-14`,children:[(0,M.jsx)(i,{children:`HTTP response`}),(0,M.jsxs)(c,{children:[d,` · HTTP `,r.status,` · `,s,`. Most recent response available when this report was created.`]})]}),(0,M.jsxs)(`div`,{className:`flex min-h-0 flex-1 flex-col gap-6 overflow-y-auto p-6`,children:[(0,M.jsxs)(`section`,{"aria-label":`Request`,className:`flex min-w-0 flex-col gap-2`,children:[(0,M.jsx)(`h3`,{className:`text-sm font-medium`,children:`Request`}),(0,M.jsxs)(`p`,{className:`font-mono text-xs leading-relaxed whitespace-pre-wrap wrap-anywhere`,children:[`GET `,r.path]}),r.receivedAtMs==null?null:(0,M.jsxs)(`div`,{className:`text-xs text-muted-foreground`,children:[`Response received`,` `,(0,M.jsx)(R,{value:r.receivedAtMs,formatter:a})]})]}),(0,M.jsx)(V,{response:r}),f.length?(0,M.jsxs)(`section`,{"aria-label":`Response context`,className:`flex flex-col gap-3`,children:[(0,M.jsx)(`h3`,{className:`text-sm font-medium`,children:`Response context`}),(0,M.jsx)(`dl`,{className:`grid grid-cols-2 gap-x-6 gap-y-4`,children:f.map(([e,t])=>(0,M.jsxs)(`div`,{className:`min-w-0`,children:[(0,M.jsx)(`dt`,{className:`text-xs text-muted-foreground`,children:e}),(0,M.jsx)(`dd`,{className:`mt-1 text-sm wrap-anywhere`,children:t})]},e))})]}):null]})]})]})}function U({event:e}){let t=F(e),n=t.icon,r=B(e);return(0,M.jsxs)(`div`,{className:`flex min-w-0 flex-col items-start gap-2`,children:[(0,M.jsxs)(m,{variant:t.variant,className:`gap-1 whitespace-nowrap [&_svg]:size-3`,children:[(0,M.jsx)(n,{"aria-hidden":`true`}),t.label]}),(0,M.jsx)(`p`,{className:`max-w-56 whitespace-pre-wrap wrap-anywhere text-xs text-muted-foreground`,children:e.type===`UPDATE_FAILED`&&r?r:t.description}),e.httpResponse?(0,M.jsx)(H,{event:e}):null,e.type===`UPDATE_FAILED`&&e.failure?.errorStack?(0,M.jsxs)(`details`,{className:`w-full max-w-56 text-xs`,children:[(0,M.jsx)(`summary`,{className:`cursor-pointer text-muted-foreground`,children:`Stack trace`}),(0,M.jsx)(`pre`,{className:`mt-2 max-h-64 overflow-auto whitespace-pre-wrap wrap-anywhere font-mono`,children:e.failure.errorStack})]}):null,e.type!==`UPDATE_FAILED`&&r?(0,M.jsx)(`p`,{className:`max-w-56 whitespace-normal text-xs text-muted-foreground`,children:r}):null]})}function W({event:e,touch:t=!1}){let n=e.type===`UPDATE_DOWNLOADED`,r=e.type===`UPDATE_FAILED`,i=!r||e.failure?.stage!==`check`,a=e.type===`UNCHANGED`&&e.change?.kinds.includes(`bundle`)===!0&&e.change.previous!==void 0,o=a?e.change.previous.bundleId:e.fromBundleId,s=n||r||a||e.type===`UPDATE_APPLIED`||e.type===`RECOVERED`;return(0,M.jsxs)(`dl`,{className:`grid grid-cols-[auto_minmax(0,1fr)] items-center gap-x-2 gap-y-2`,children:[o&&s?(0,M.jsxs)(M.Fragment,{children:[(0,M.jsx)(`dt`,{className:`text-muted-foreground`,children:n||r?`Running`:`From`}),(0,M.jsxs)(`dd`,{className:`flex min-w-0 flex-wrap items-center gap-2`,children:[(0,M.jsx)(g,{value:o,buttonClassName:t?`min-h-11 px-3`:void 0}),T(o,a?e.change.previous.minBundleId:e.minBundleId)?(0,M.jsx)(w,{}):null]})]}):null,i?(0,M.jsxs)(M.Fragment,{children:[(0,M.jsx)(`dt`,{className:`text-muted-foreground`,children:n?`Pending`:r?`Target`:s?`To`:`Current`}),(0,M.jsxs)(`dd`,{className:`flex min-w-0 flex-wrap items-center gap-2`,children:[(0,M.jsx)(g,{value:e.toBundleId,buttonClassName:t?`min-h-11 px-3`:void 0}),T(e.toBundleId,e.minBundleId)?(0,M.jsx)(w,{}):null]})]}):null]})}export{H as a,V as i,R as n,I as o,U as r,k as s,W as t};
@@ -1 +0,0 @@
1
- import{Ln as e,Ur as t,ar as n,it as r,nt as i,tt as a}from"./sidebar-BqX460IW.js";import{n as o}from"./dist-dDj-R6uh.js";var s=n(`download`,[[`path`,{d:`M12 15V3`,key:`m9g1x1`}],[`path`,{d:`M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4`,key:`ih7n3h`}],[`path`,{d:`m7 10 5 5 5-5`,key:`brsn70`}]]),c=t(),l=(e,t=12)=>e.length>t?`${e.slice(0,Math.max(1,t-4))}…${e.slice(-4)}`:e;function u({value:t,maxLength:n=12,className:s,buttonClassName:u}){let d=t.length>n,f=l(t,n),p=async()=>{try{await navigator.clipboard.writeText(t),o.success(`Copied to clipboard`,{description:t})}catch{o.error(`Failed to copy value`)}},m=e=>{e.preventDefault(),e.stopPropagation(),p()},h=e=>{(e.key===`Enter`||e.key===` `)&&(e.preventDefault(),e.stopPropagation(),p())},g=(0,c.jsx)(`span`,{translate:`no`,className:e(`font-mono text-xs tabular-nums whitespace-nowrap`,s),children:f});return(0,c.jsxs)(a,{children:[(0,c.jsx)(r,{render:(0,c.jsx)(`button`,{type:`button`,"aria-label":`Copy full value: ${t}`,translate:`no`,className:e(`ring-ring/30 bg-muted/40 border-border/70 inline-flex min-w-0 max-w-full cursor-pointer items-center rounded-md border px-1.5 py-0.5 align-top shadow-xs outline-none transition-[background-color,border-color,transform,box-shadow]`,`hover:bg-muted/70 active:scale-[0.98] active:bg-muted/85 focus-visible:ring-[2px]`,`touch-manipulation select-none motion-reduce:transition-none motion-reduce:active:scale-100`,!d&&`cursor-copy`,u),onClick:m,onKeyDown:h}),children:g}),(0,c.jsx)(i,{hidden:!d,children:(0,c.jsx)(`p`,{translate:`no`,className:`break-all font-mono text-xs tabular-nums`,children:t})})]})}export{l as n,s as r,u as t};
@@ -1 +0,0 @@
1
- import{In as e,Ln as t,Ur as n,p as r}from"./sidebar-BqX460IW.js";import{i,l as a,s as o}from"./console-features-api-DPE4C06Y.js";import{b as s,x as c}from"./insights-api-1ZjVu3Sb.js";import{a as l,f as u,i as d,n as f,t as p}from"./badge-Bqf3UDee.js";import{t as m}from"./list-Dtj7TtzV.js";import{i as h,r as g,t as _}from"./tabs-CgEH_fMT.js";var v=n();function y({error:e,fallbackTitle:t}){return o(e)?(0,v.jsxs)(f,{children:[(0,v.jsx)(s,{"aria-hidden":`true`}),(0,v.jsx)(l,{children:`Insights not installed`}),(0,v.jsx)(d,{children:e.message})]}):(0,v.jsxs)(f,{variant:`destructive`,children:[(0,v.jsx)(u,{"aria-hidden":`true`}),(0,v.jsx)(l,{children:t}),(0,v.jsx)(d,{children:`Refresh to try again. If this keeps happening, check your Insights provider connection.`})]})}var b={"24h":{label:`DAU`,period:`24 hours`,interval:`hour`},"7d":{label:`WAU`,period:`7 days`,interval:`6 hours`},"30d":{label:`MAU`,period:`30 days`,interval:`day`},"12m":{label:`YAU`,period:`12 months`,interval:`week`}};function x({label:e,onPeriodChange:t,period:n,periods:r}){return(0,v.jsx)(_,{value:n,onValueChange:e=>{let n=r.find(t=>t.value===e);n&&t(n.value)},children:(0,v.jsx)(g,{"aria-label":e,className:`min-h-11 sm:min-h-9`,children:r.map(({value:e,name:t})=>(0,v.jsx)(h,{value:e,"aria-label":t,className:`min-w-12 px-3`,children:e},e))})})}var S=[`24h`,`7d`,`30d`].map(e=>({value:e,name:b[e].period})),C=Object.keys(b).map(e=>({value:e,name:b[e].period}));function w({window:e,onWindowChange:t}){return(0,v.jsx)(x,{label:`Reporting period`,onPeriodChange:t,period:e,periods:S})}function T({window:e,onWindowChange:t,twelveMonths:n=!0}){return(0,v.jsx)(x,{label:`Reporting period`,onPeriodChange:t,period:e,periods:C.filter(({value:e})=>n||e!==`12m`)})}var E=/^(?:[0-9a-f]{8}-[0-9a-f]{4}-7000-8000-000000000000|00000000-0000-0000-0000-000000000000)$/iu,D=(e,t)=>e!=null&&(e===t||E.test(e));function O(){return(0,v.jsx)(p,{className:`shrink-0 font-sans font-normal`,title:`The bundle the native build shipped`,variant:`secondary`,children:`Built-in bundle`})}function k({view:n,overviewSearch:o}){let s=i(`insightsAnalytics`);return(0,v.jsxs)(`header`,{className:`sticky top-0 z-10 flex shrink-0 flex-wrap items-center gap-3 border-b bg-background px-3 py-3 sm:bg-card/70 sm:px-4 sm:backdrop-blur-sm`,children:[(0,v.jsx)(r,{className:`-ml-1 size-11 lg:size-7`}),(0,v.jsxs)(`div`,{className:`flex items-center gap-1.5`,children:[(0,v.jsx)(c,{"aria-hidden":`true`,className:`size-3.5 text-muted-foreground`}),(0,v.jsx)(`h1`,{className:`text-sm font-medium`,children:`Insights`})]}),(0,v.jsxs)(`nav`,{"aria-label":`Insights views`,className:`ml-auto flex gap-2`,children:[s?(0,v.jsx)(a,{"aria-current":n===`overview`?`page`:void 0,className:t(e({className:`h-11 px-3 lg:h-8 lg:px-2.5`,size:`lg`,variant:n===`overview`?`secondary`:`ghost`})),search:o,to:`/insights`,children:`Overview`}):null,(0,v.jsxs)(a,{"aria-current":n===`events`?`page`:void 0,className:t(e({className:`h-11 px-3 lg:h-8 lg:px-2.5`,size:`lg`,variant:n===`events`?`secondary`:`ghost`})),to:`/installations`,children:[(0,v.jsx)(m,{"aria-hidden":`true`,"data-icon":`inline-start`}),`All events`]})]})]})}export{x as a,y as c,w as i,O as n,T as o,D as r,b as s,k as t};
@@ -1 +0,0 @@
1
- import{In as e,Ur as t}from"./sidebar-BqX460IW.js";import{l as n}from"./console-features-api-DPE4C06Y.js";var r=t(),i={afterReleaseId:void 0,beforeReleaseId:void 0,bundleId:void 0,channelId:void 0,enabled:void 0,platform:void 0,releaseId:void 0,scopeKey:void 0};function a(){return(0,r.jsx)(`div`,{className:`flex min-h-svh flex-1 items-center justify-center px-6 py-10`,children:(0,r.jsxs)(`section`,{className:`flex max-w-md flex-col items-center text-center`,children:[(0,r.jsx)(`h1`,{className:`text-2xl font-semibold tracking-tight text-foreground`,children:`Page not found`}),(0,r.jsx)(n,{className:e({className:`mt-6`,size:`lg`}),to:`/`,search:i,children:`Go to home`})]})})}export{a as t};