@byline/host-tanstack-start 0.9.3

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 (511) hide show
  1. package/LICENSE +373 -0
  2. package/README.md +48 -0
  3. package/dist/admin-shell/admin-roles/container.d.ts +34 -0
  4. package/dist/admin-shell/admin-roles/container.d.ts.map +1 -0
  5. package/dist/admin-shell/admin-roles/container.js +259 -0
  6. package/dist/admin-shell/admin-roles/container.module.js +17 -0
  7. package/dist/admin-shell/admin-roles/container_module.css +93 -0
  8. package/dist/admin-shell/admin-roles/delete.d.ts +9 -0
  9. package/dist/admin-shell/admin-roles/delete.d.ts.map +1 -0
  10. package/dist/admin-shell/admin-roles/delete.js +107 -0
  11. package/dist/admin-shell/admin-roles/delete.module.js +10 -0
  12. package/dist/admin-shell/admin-roles/delete_module.css +35 -0
  13. package/dist/admin-shell/admin-roles/list.d.ts +25 -0
  14. package/dist/admin-shell/admin-roles/list.d.ts.map +1 -0
  15. package/dist/admin-shell/admin-roles/list.js +292 -0
  16. package/dist/admin-shell/admin-roles/list.module.js +24 -0
  17. package/dist/admin-shell/admin-roles/list_module.css +113 -0
  18. package/dist/admin-shell/admin-users/container.d.ts +18 -0
  19. package/dist/admin-shell/admin-users/container.d.ts.map +1 -0
  20. package/dist/admin-shell/admin-users/container.js +418 -0
  21. package/dist/admin-shell/admin-users/container.module.js +22 -0
  22. package/dist/admin-shell/admin-users/container_module.css +136 -0
  23. package/dist/admin-shell/admin-users/delete.d.ts +9 -0
  24. package/dist/admin-shell/admin-users/delete.d.ts.map +1 -0
  25. package/dist/admin-shell/admin-users/delete.js +115 -0
  26. package/dist/admin-shell/admin-users/delete.module.js +10 -0
  27. package/dist/admin-shell/admin-users/delete_module.css +35 -0
  28. package/dist/admin-shell/admin-users/list.d.ts +13 -0
  29. package/dist/admin-shell/admin-users/list.d.ts.map +1 -0
  30. package/dist/admin-shell/admin-users/list.js +328 -0
  31. package/dist/admin-shell/admin-users/list.module.js +22 -0
  32. package/dist/admin-shell/admin-users/list_module.css +112 -0
  33. package/dist/admin-shell/chrome/admin-app-bar.d.ts +7 -0
  34. package/dist/admin-shell/chrome/admin-app-bar.d.ts.map +1 -0
  35. package/dist/admin-shell/chrome/admin-app-bar.js +71 -0
  36. package/dist/admin-shell/chrome/admin-app-bar.module.js +9 -0
  37. package/dist/admin-shell/chrome/admin-app-bar_module.css +54 -0
  38. package/dist/admin-shell/chrome/admin-layout.module.js +5 -0
  39. package/dist/admin-shell/chrome/admin-layout_module.css +8 -0
  40. package/dist/admin-shell/chrome/branding.d.ts +9 -0
  41. package/dist/admin-shell/chrome/branding.d.ts.map +1 -0
  42. package/dist/admin-shell/chrome/branding.js +17 -0
  43. package/dist/admin-shell/chrome/branding.module.js +6 -0
  44. package/dist/admin-shell/chrome/branding_module.css +11 -0
  45. package/dist/admin-shell/chrome/breadcrumbs/@types.d.ts +6 -0
  46. package/dist/admin-shell/chrome/breadcrumbs/@types.d.ts.map +1 -0
  47. package/dist/admin-shell/chrome/breadcrumbs/@types.js +1 -0
  48. package/dist/admin-shell/chrome/breadcrumbs/breadcrumbs-client.d.ts +7 -0
  49. package/dist/admin-shell/chrome/breadcrumbs/breadcrumbs-client.d.ts.map +1 -0
  50. package/dist/admin-shell/chrome/breadcrumbs/breadcrumbs-client.js +20 -0
  51. package/dist/admin-shell/chrome/breadcrumbs/breadcrumbs-provider.d.ts +24 -0
  52. package/dist/admin-shell/chrome/breadcrumbs/breadcrumbs-provider.d.ts.map +1 -0
  53. package/dist/admin-shell/chrome/breadcrumbs/breadcrumbs-provider.js +23 -0
  54. package/dist/admin-shell/chrome/breadcrumbs/breadcrumbs.d.ts +15 -0
  55. package/dist/admin-shell/chrome/breadcrumbs/breadcrumbs.d.ts.map +1 -0
  56. package/dist/admin-shell/chrome/breadcrumbs/breadcrumbs.js +77 -0
  57. package/dist/admin-shell/chrome/breadcrumbs/breadcrumbs.module.js +12 -0
  58. package/dist/admin-shell/chrome/breadcrumbs/breadcrumbs_module.css +81 -0
  59. package/dist/admin-shell/chrome/byline-logo.d.ts +12 -0
  60. package/dist/admin-shell/chrome/byline-logo.d.ts.map +1 -0
  61. package/dist/admin-shell/chrome/byline-logo.js +178 -0
  62. package/dist/admin-shell/chrome/content.d.ts +24 -0
  63. package/dist/admin-shell/chrome/content.d.ts.map +1 -0
  64. package/dist/admin-shell/chrome/content.js +31 -0
  65. package/dist/admin-shell/chrome/content.module.js +5 -0
  66. package/dist/admin-shell/chrome/content_module.css +10 -0
  67. package/dist/admin-shell/chrome/dashboard.d.ts +14 -0
  68. package/dist/admin-shell/chrome/dashboard.d.ts.map +1 -0
  69. package/dist/admin-shell/chrome/dashboard.js +129 -0
  70. package/dist/admin-shell/chrome/dashboard.module.js +19 -0
  71. package/dist/admin-shell/chrome/dashboard_module.css +175 -0
  72. package/dist/admin-shell/chrome/drawer-toggle.d.ts +9 -0
  73. package/dist/admin-shell/chrome/drawer-toggle.d.ts.map +1 -0
  74. package/dist/admin-shell/chrome/drawer-toggle.js +57 -0
  75. package/dist/admin-shell/chrome/drawer-toggle.module.js +8 -0
  76. package/dist/admin-shell/chrome/drawer-toggle_module.css +21 -0
  77. package/dist/admin-shell/chrome/hamburger.d.ts +10 -0
  78. package/dist/admin-shell/chrome/hamburger.d.ts.map +1 -0
  79. package/dist/admin-shell/chrome/hamburger.js +30 -0
  80. package/dist/admin-shell/chrome/hamburger.module.js +5 -0
  81. package/dist/admin-shell/chrome/hamburger_module.css +7 -0
  82. package/dist/admin-shell/chrome/loose-router.d.ts +33 -0
  83. package/dist/admin-shell/chrome/loose-router.d.ts.map +1 -0
  84. package/dist/admin-shell/chrome/loose-router.js +6 -0
  85. package/dist/admin-shell/chrome/menu-drawer.d.ts +10 -0
  86. package/dist/admin-shell/chrome/menu-drawer.d.ts.map +1 -0
  87. package/dist/admin-shell/chrome/menu-drawer.js +141 -0
  88. package/dist/admin-shell/chrome/menu-drawer.module.js +12 -0
  89. package/dist/admin-shell/chrome/menu-drawer_module.css +137 -0
  90. package/dist/admin-shell/chrome/menu-provider.d.ts +21 -0
  91. package/dist/admin-shell/chrome/menu-provider.d.ts.map +1 -0
  92. package/dist/admin-shell/chrome/menu-provider.js +54 -0
  93. package/dist/admin-shell/chrome/preview-toggle.d.ts +13 -0
  94. package/dist/admin-shell/chrome/preview-toggle.d.ts.map +1 -0
  95. package/dist/admin-shell/chrome/preview-toggle.js +75 -0
  96. package/dist/admin-shell/chrome/route-error.d.ts +22 -0
  97. package/dist/admin-shell/chrome/route-error.d.ts.map +1 -0
  98. package/dist/admin-shell/chrome/route-error.js +119 -0
  99. package/dist/admin-shell/chrome/route-error.module.js +14 -0
  100. package/dist/admin-shell/chrome/route-error_module.css +94 -0
  101. package/dist/admin-shell/chrome/router-pager.d.ts +19 -0
  102. package/dist/admin-shell/chrome/router-pager.d.ts.map +1 -0
  103. package/dist/admin-shell/chrome/router-pager.js +91 -0
  104. package/dist/admin-shell/chrome/sign-in-page.d.ts +19 -0
  105. package/dist/admin-shell/chrome/sign-in-page.d.ts.map +1 -0
  106. package/dist/admin-shell/chrome/sign-in-page.js +20 -0
  107. package/dist/admin-shell/chrome/sign-in-page.module.js +6 -0
  108. package/dist/admin-shell/chrome/sign-in-page_module.css +22 -0
  109. package/dist/admin-shell/chrome/sort-icons.d.ts +10 -0
  110. package/dist/admin-shell/chrome/sort-icons.d.ts.map +1 -0
  111. package/dist/admin-shell/chrome/sort-icons.js +103 -0
  112. package/dist/admin-shell/chrome/th-sortable.d.ts +23 -0
  113. package/dist/admin-shell/chrome/th-sortable.d.ts.map +1 -0
  114. package/dist/admin-shell/chrome/th-sortable.js +75 -0
  115. package/dist/admin-shell/chrome/th-sortable.module.js +10 -0
  116. package/dist/admin-shell/chrome/th-sortable_module.css +37 -0
  117. package/dist/admin-shell/chrome/use-media-query.d.ts +9 -0
  118. package/dist/admin-shell/chrome/use-media-query.d.ts.map +1 -0
  119. package/dist/admin-shell/chrome/use-media-query.js +20 -0
  120. package/dist/admin-shell/chrome/utils.d.ts +12 -0
  121. package/dist/admin-shell/chrome/utils.d.ts.map +1 -0
  122. package/dist/admin-shell/chrome/utils.js +8 -0
  123. package/dist/admin-shell/collections/api.d.ts +28 -0
  124. package/dist/admin-shell/collections/api.d.ts.map +1 -0
  125. package/dist/admin-shell/collections/api.js +51 -0
  126. package/dist/admin-shell/collections/api.module.js +9 -0
  127. package/dist/admin-shell/collections/api_module.css +42 -0
  128. package/dist/admin-shell/collections/create.d.ts +14 -0
  129. package/dist/admin-shell/collections/create.d.ts.map +1 -0
  130. package/dist/admin-shell/collections/create.js +77 -0
  131. package/dist/admin-shell/collections/edit.d.ts +19 -0
  132. package/dist/admin-shell/collections/edit.d.ts.map +1 -0
  133. package/dist/admin-shell/collections/edit.js +279 -0
  134. package/dist/admin-shell/collections/history.d.ts +20 -0
  135. package/dist/admin-shell/collections/history.d.ts.map +1 -0
  136. package/dist/admin-shell/collections/history.js +252 -0
  137. package/dist/admin-shell/collections/history.module.js +18 -0
  138. package/dist/admin-shell/collections/history_module.css +121 -0
  139. package/dist/admin-shell/collections/list.d.ts +16 -0
  140. package/dist/admin-shell/collections/list.d.ts.map +1 -0
  141. package/dist/admin-shell/collections/list.js +253 -0
  142. package/dist/admin-shell/collections/list.module.js +16 -0
  143. package/dist/admin-shell/collections/list_module.css +88 -0
  144. package/dist/admin-shell/collections/preview-link.d.ts +32 -0
  145. package/dist/admin-shell/collections/preview-link.d.ts.map +1 -0
  146. package/dist/admin-shell/collections/preview-link.js +54 -0
  147. package/dist/admin-shell/collections/tanstack-navigation-guard.d.ts +16 -0
  148. package/dist/admin-shell/collections/tanstack-navigation-guard.d.ts.map +1 -0
  149. package/dist/admin-shell/collections/tanstack-navigation-guard.js +19 -0
  150. package/dist/admin-shell/collections/view-menu.d.ts +58 -0
  151. package/dist/admin-shell/collections/view-menu.d.ts.map +1 -0
  152. package/dist/admin-shell/collections/view-menu.js +203 -0
  153. package/dist/admin-shell/collections/view-menu.module.js +11 -0
  154. package/dist/admin-shell/collections/view-menu_module.css +43 -0
  155. package/dist/auth/auth-context.d.ts +38 -0
  156. package/dist/auth/auth-context.d.ts.map +1 -0
  157. package/dist/auth/auth-context.js +57 -0
  158. package/dist/auth/auth-cookies.d.ts +35 -0
  159. package/dist/auth/auth-cookies.d.ts.map +1 -0
  160. package/dist/auth/auth-cookies.js +46 -0
  161. package/dist/auth/preview-cookies.d.ts +20 -0
  162. package/dist/auth/preview-cookies.d.ts.map +1 -0
  163. package/dist/auth/preview-cookies.js +26 -0
  164. package/dist/index.d.ts +43 -0
  165. package/dist/index.d.ts.map +1 -0
  166. package/dist/index.js +1 -0
  167. package/dist/integrations/abilities.d.ts +67 -0
  168. package/dist/integrations/abilities.d.ts.map +1 -0
  169. package/dist/integrations/abilities.js +25 -0
  170. package/dist/integrations/api-utils.d.ts +34 -0
  171. package/dist/integrations/api-utils.d.ts.map +1 -0
  172. package/dist/integrations/api-utils.js +22 -0
  173. package/dist/integrations/byline-admin-services.d.ts +25 -0
  174. package/dist/integrations/byline-admin-services.d.ts.map +1 -0
  175. package/dist/integrations/byline-admin-services.js +26 -0
  176. package/dist/integrations/byline-client.d.ts +22 -0
  177. package/dist/integrations/byline-client.d.ts.map +1 -0
  178. package/dist/integrations/byline-client.js +13 -0
  179. package/dist/integrations/byline-core.d.ts +28 -0
  180. package/dist/integrations/byline-core.d.ts.map +1 -0
  181. package/dist/integrations/byline-core.js +5 -0
  182. package/dist/integrations/byline-field-services.d.ts +19 -0
  183. package/dist/integrations/byline-field-services.d.ts.map +1 -0
  184. package/dist/integrations/byline-field-services.js +14 -0
  185. package/dist/integrations/byline-public-client.d.ts +10 -0
  186. package/dist/integrations/byline-public-client.d.ts.map +1 -0
  187. package/dist/integrations/byline-public-client.js +15 -0
  188. package/dist/integrations/byline-viewer-client.d.ts +21 -0
  189. package/dist/integrations/byline-viewer-client.d.ts.map +1 -0
  190. package/dist/integrations/byline-viewer-client.js +39 -0
  191. package/dist/integrations/start-errors.d.ts +23 -0
  192. package/dist/integrations/start-errors.d.ts.map +1 -0
  193. package/dist/integrations/start-errors.js +32 -0
  194. package/dist/routes/create-admin-account-route.d.ts +9 -0
  195. package/dist/routes/create-admin-account-route.d.ts.map +1 -0
  196. package/dist/routes/create-admin-account-route.js +68 -0
  197. package/dist/routes/create-admin-dashboard-route.d.ts +9 -0
  198. package/dist/routes/create-admin-dashboard-route.d.ts.map +1 -0
  199. package/dist/routes/create-admin-dashboard-route.js +44 -0
  200. package/dist/routes/create-admin-layout-route.d.ts +14 -0
  201. package/dist/routes/create-admin-layout-route.d.ts.map +1 -0
  202. package/dist/routes/create-admin-layout-route.js +64 -0
  203. package/dist/routes/create-admin-permissions-route.d.ts +9 -0
  204. package/dist/routes/create-admin-permissions-route.d.ts.map +1 -0
  205. package/dist/routes/create-admin-permissions-route.js +39 -0
  206. package/dist/routes/create-admin-role-edit-route.d.ts +9 -0
  207. package/dist/routes/create-admin-role-edit-route.d.ts.map +1 -0
  208. package/dist/routes/create-admin-role-edit-route.js +79 -0
  209. package/dist/routes/create-admin-roles-list-route.d.ts +9 -0
  210. package/dist/routes/create-admin-roles-list-route.d.ts.map +1 -0
  211. package/dist/routes/create-admin-roles-list-route.js +39 -0
  212. package/dist/routes/create-admin-user-edit-route.d.ts +9 -0
  213. package/dist/routes/create-admin-user-edit-route.d.ts.map +1 -0
  214. package/dist/routes/create-admin-user-edit-route.js +86 -0
  215. package/dist/routes/create-admin-users-list-route.d.ts +9 -0
  216. package/dist/routes/create-admin-users-list-route.d.ts.map +1 -0
  217. package/dist/routes/create-admin-users-list-route.js +71 -0
  218. package/dist/routes/create-collection-api-route.d.ts +15 -0
  219. package/dist/routes/create-collection-api-route.d.ts.map +1 -0
  220. package/dist/routes/create-collection-api-route.js +71 -0
  221. package/dist/routes/create-collection-create-route.d.ts +9 -0
  222. package/dist/routes/create-collection-create-route.d.ts.map +1 -0
  223. package/dist/routes/create-collection-create-route.js +53 -0
  224. package/dist/routes/create-collection-edit-route.d.ts +15 -0
  225. package/dist/routes/create-collection-edit-route.d.ts.map +1 -0
  226. package/dist/routes/create-collection-edit-route.js +65 -0
  227. package/dist/routes/create-collection-history-route.d.ts +15 -0
  228. package/dist/routes/create-collection-history-route.d.ts.map +1 -0
  229. package/dist/routes/create-collection-history-route.js +94 -0
  230. package/dist/routes/create-collection-list-route.d.ts +9 -0
  231. package/dist/routes/create-collection-list-route.d.ts.map +1 -0
  232. package/dist/routes/create-collection-list-route.js +130 -0
  233. package/dist/routes/create-sign-in-route.d.ts +9 -0
  234. package/dist/routes/create-sign-in-route.d.ts.map +1 -0
  235. package/dist/routes/create-sign-in-route.js +21 -0
  236. package/dist/routes/index.d.ts +35 -0
  237. package/dist/routes/index.d.ts.map +1 -0
  238. package/dist/routes/index.js +14 -0
  239. package/dist/server-fns/admin-account/change-password.d.ts +30 -0
  240. package/dist/server-fns/admin-account/change-password.d.ts.map +1 -0
  241. package/dist/server-fns/admin-account/change-password.js +13 -0
  242. package/dist/server-fns/admin-account/get.d.ts +31 -0
  243. package/dist/server-fns/admin-account/get.d.ts.map +1 -0
  244. package/dist/server-fns/admin-account/get.js +13 -0
  245. package/dist/server-fns/admin-account/index.d.ts +22 -0
  246. package/dist/server-fns/admin-account/index.d.ts.map +1 -0
  247. package/dist/server-fns/admin-account/index.js +3 -0
  248. package/dist/server-fns/admin-account/update.d.ts +34 -0
  249. package/dist/server-fns/admin-account/update.d.ts.map +1 -0
  250. package/dist/server-fns/admin-account/update.js +13 -0
  251. package/dist/server-fns/admin-permissions/get-role-abilities.d.ts +16 -0
  252. package/dist/server-fns/admin-permissions/get-role-abilities.d.ts.map +1 -0
  253. package/dist/server-fns/admin-permissions/get-role-abilities.js +14 -0
  254. package/dist/server-fns/admin-permissions/index.d.ts +25 -0
  255. package/dist/server-fns/admin-permissions/index.d.ts.map +1 -0
  256. package/dist/server-fns/admin-permissions/index.js +4 -0
  257. package/dist/server-fns/admin-permissions/list-registered.d.ts +33 -0
  258. package/dist/server-fns/admin-permissions/list-registered.d.ts.map +1 -0
  259. package/dist/server-fns/admin-permissions/list-registered.js +14 -0
  260. package/dist/server-fns/admin-permissions/set-role-abilities.d.ts +16 -0
  261. package/dist/server-fns/admin-permissions/set-role-abilities.d.ts.map +1 -0
  262. package/dist/server-fns/admin-permissions/set-role-abilities.js +14 -0
  263. package/dist/server-fns/admin-permissions/who-has.d.ts +26 -0
  264. package/dist/server-fns/admin-permissions/who-has.d.ts.map +1 -0
  265. package/dist/server-fns/admin-permissions/who-has.js +14 -0
  266. package/dist/server-fns/admin-roles/create.d.ts +24 -0
  267. package/dist/server-fns/admin-roles/create.d.ts.map +1 -0
  268. package/dist/server-fns/admin-roles/create.js +13 -0
  269. package/dist/server-fns/admin-roles/delete.d.ts +17 -0
  270. package/dist/server-fns/admin-roles/delete.d.ts.map +1 -0
  271. package/dist/server-fns/admin-roles/delete.js +13 -0
  272. package/dist/server-fns/admin-roles/get.d.ts +22 -0
  273. package/dist/server-fns/admin-roles/get.d.ts.map +1 -0
  274. package/dist/server-fns/admin-roles/get.js +13 -0
  275. package/dist/server-fns/admin-roles/index.d.ts +23 -0
  276. package/dist/server-fns/admin-roles/index.d.ts.map +1 -0
  277. package/dist/server-fns/admin-roles/index.js +6 -0
  278. package/dist/server-fns/admin-roles/list.d.ts +26 -0
  279. package/dist/server-fns/admin-roles/list.d.ts.map +1 -0
  280. package/dist/server-fns/admin-roles/list.js +13 -0
  281. package/dist/server-fns/admin-roles/reorder.d.ts +15 -0
  282. package/dist/server-fns/admin-roles/reorder.d.ts.map +1 -0
  283. package/dist/server-fns/admin-roles/reorder.js +13 -0
  284. package/dist/server-fns/admin-roles/update.d.ts +27 -0
  285. package/dist/server-fns/admin-roles/update.d.ts.map +1 -0
  286. package/dist/server-fns/admin-roles/update.js +13 -0
  287. package/dist/server-fns/admin-users/create.d.ts +35 -0
  288. package/dist/server-fns/admin-users/create.d.ts.map +1 -0
  289. package/dist/server-fns/admin-users/create.js +13 -0
  290. package/dist/server-fns/admin-users/delete.d.ts +17 -0
  291. package/dist/server-fns/admin-users/delete.d.ts.map +1 -0
  292. package/dist/server-fns/admin-users/delete.js +13 -0
  293. package/dist/server-fns/admin-users/disable.d.ts +15 -0
  294. package/dist/server-fns/admin-users/disable.d.ts.map +1 -0
  295. package/dist/server-fns/admin-users/disable.js +13 -0
  296. package/dist/server-fns/admin-users/enable.d.ts +15 -0
  297. package/dist/server-fns/admin-users/enable.d.ts.map +1 -0
  298. package/dist/server-fns/admin-users/enable.js +13 -0
  299. package/dist/server-fns/admin-users/get-user-roles.d.ts +25 -0
  300. package/dist/server-fns/admin-users/get-user-roles.d.ts.map +1 -0
  301. package/dist/server-fns/admin-users/get-user-roles.js +13 -0
  302. package/dist/server-fns/admin-users/get.d.ts +29 -0
  303. package/dist/server-fns/admin-users/get.d.ts.map +1 -0
  304. package/dist/server-fns/admin-users/get.js +13 -0
  305. package/dist/server-fns/admin-users/index.d.ts +28 -0
  306. package/dist/server-fns/admin-users/index.d.ts.map +1 -0
  307. package/dist/server-fns/admin-users/index.js +10 -0
  308. package/dist/server-fns/admin-users/list.d.ts +51 -0
  309. package/dist/server-fns/admin-users/list.d.ts.map +1 -0
  310. package/dist/server-fns/admin-users/list.js +13 -0
  311. package/dist/server-fns/admin-users/set-password.d.ts +30 -0
  312. package/dist/server-fns/admin-users/set-password.d.ts.map +1 -0
  313. package/dist/server-fns/admin-users/set-password.js +13 -0
  314. package/dist/server-fns/admin-users/set-user-roles.d.ts +25 -0
  315. package/dist/server-fns/admin-users/set-user-roles.d.ts.map +1 -0
  316. package/dist/server-fns/admin-users/set-user-roles.js +13 -0
  317. package/dist/server-fns/admin-users/update.d.ts +37 -0
  318. package/dist/server-fns/admin-users/update.d.ts.map +1 -0
  319. package/dist/server-fns/admin-users/update.js +13 -0
  320. package/dist/server-fns/auth/current-user.d.ts +38 -0
  321. package/dist/server-fns/auth/current-user.d.ts.map +1 -0
  322. package/dist/server-fns/auth/current-user.js +52 -0
  323. package/dist/server-fns/auth/index.d.ts +11 -0
  324. package/dist/server-fns/auth/index.d.ts.map +1 -0
  325. package/dist/server-fns/auth/index.js +3 -0
  326. package/dist/server-fns/auth/sign-in.d.ts +19 -0
  327. package/dist/server-fns/auth/sign-in.d.ts.map +1 -0
  328. package/dist/server-fns/auth/sign-in.js +31 -0
  329. package/dist/server-fns/auth/sign-out.d.ts +11 -0
  330. package/dist/server-fns/auth/sign-out.d.ts.map +1 -0
  331. package/dist/server-fns/auth/sign-out.js +17 -0
  332. package/dist/server-fns/collections/create.d.ts +21 -0
  333. package/dist/server-fns/collections/create.d.ts.map +1 -0
  334. package/dist/server-fns/collections/create.js +40 -0
  335. package/dist/server-fns/collections/delete.d.ts +18 -0
  336. package/dist/server-fns/collections/delete.d.ts.map +1 -0
  337. package/dist/server-fns/collections/delete.js +44 -0
  338. package/dist/server-fns/collections/get.d.ts +26 -0
  339. package/dist/server-fns/collections/get.d.ts.map +1 -0
  340. package/dist/server-fns/collections/get.js +133 -0
  341. package/dist/server-fns/collections/history.d.ts +43 -0
  342. package/dist/server-fns/collections/history.d.ts.map +1 -0
  343. package/dist/server-fns/collections/history.js +29 -0
  344. package/dist/server-fns/collections/index.d.ts +16 -0
  345. package/dist/server-fns/collections/index.d.ts.map +1 -0
  346. package/dist/server-fns/collections/index.js +9 -0
  347. package/dist/server-fns/collections/list.d.ts +54 -0
  348. package/dist/server-fns/collections/list.d.ts.map +1 -0
  349. package/dist/server-fns/collections/list.js +65 -0
  350. package/dist/server-fns/collections/stats.d.ts +17 -0
  351. package/dist/server-fns/collections/stats.d.ts.map +1 -0
  352. package/dist/server-fns/collections/stats.js +28 -0
  353. package/dist/server-fns/collections/status.d.ts +31 -0
  354. package/dist/server-fns/collections/status.d.ts.map +1 -0
  355. package/dist/server-fns/collections/status.js +79 -0
  356. package/dist/server-fns/collections/update.d.ts +26 -0
  357. package/dist/server-fns/collections/update.d.ts.map +1 -0
  358. package/dist/server-fns/collections/update.js +41 -0
  359. package/dist/server-fns/collections/upload.d.ts +57 -0
  360. package/dist/server-fns/collections/upload.d.ts.map +1 -0
  361. package/dist/server-fns/collections/upload.js +132 -0
  362. package/dist/server-fns/collections/utils.d.ts +15 -0
  363. package/dist/server-fns/collections/utils.d.ts.map +1 -0
  364. package/dist/server-fns/collections/utils.js +4 -0
  365. package/dist/server-fns/preview/disable.d.ts +12 -0
  366. package/dist/server-fns/preview/disable.d.ts.map +1 -0
  367. package/dist/server-fns/preview/disable.js +12 -0
  368. package/dist/server-fns/preview/enable.d.ts +12 -0
  369. package/dist/server-fns/preview/enable.d.ts.map +1 -0
  370. package/dist/server-fns/preview/enable.js +14 -0
  371. package/dist/server-fns/preview/index.d.ts +11 -0
  372. package/dist/server-fns/preview/index.d.ts.map +1 -0
  373. package/dist/server-fns/preview/index.js +3 -0
  374. package/dist/server-fns/preview/state.d.ts +11 -0
  375. package/dist/server-fns/preview/state.d.ts.map +1 -0
  376. package/dist/server-fns/preview/state.js +8 -0
  377. package/package.json +164 -0
  378. package/src/admin-shell/admin-roles/container.module.css +132 -0
  379. package/src/admin-shell/admin-roles/container.tsx +209 -0
  380. package/src/admin-shell/admin-roles/delete.module.css +52 -0
  381. package/src/admin-shell/admin-roles/delete.tsx +117 -0
  382. package/src/admin-shell/admin-roles/list.module.css +158 -0
  383. package/src/admin-shell/admin-roles/list.tsx +308 -0
  384. package/src/admin-shell/admin-users/container.module.css +199 -0
  385. package/src/admin-shell/admin-users/container.tsx +344 -0
  386. package/src/admin-shell/admin-users/delete.module.css +52 -0
  387. package/src/admin-shell/admin-users/delete.tsx +129 -0
  388. package/src/admin-shell/admin-users/list.module.css +164 -0
  389. package/src/admin-shell/admin-users/list.tsx +314 -0
  390. package/src/admin-shell/chrome/admin-app-bar.module.css +72 -0
  391. package/src/admin-shell/chrome/admin-app-bar.tsx +74 -0
  392. package/src/admin-shell/chrome/admin-layout.module.css +16 -0
  393. package/src/admin-shell/chrome/branding.module.css +20 -0
  394. package/src/admin-shell/chrome/branding.tsx +23 -0
  395. package/src/admin-shell/chrome/breadcrumbs/@types.ts +5 -0
  396. package/src/admin-shell/chrome/breadcrumbs/breadcrumbs-client.tsx +30 -0
  397. package/src/admin-shell/chrome/breadcrumbs/breadcrumbs-provider.tsx +48 -0
  398. package/src/admin-shell/chrome/breadcrumbs/breadcrumbs.module.css +93 -0
  399. package/src/admin-shell/chrome/breadcrumbs/breadcrumbs.tsx +96 -0
  400. package/src/admin-shell/chrome/byline-logo.tsx +151 -0
  401. package/src/admin-shell/chrome/content.module.css +16 -0
  402. package/src/admin-shell/chrome/content.tsx +60 -0
  403. package/src/admin-shell/chrome/dashboard.module.css +245 -0
  404. package/src/admin-shell/chrome/dashboard.tsx +128 -0
  405. package/src/admin-shell/chrome/drawer-toggle.module.css +30 -0
  406. package/src/admin-shell/chrome/drawer-toggle.tsx +62 -0
  407. package/src/admin-shell/chrome/hamburger.module.css +16 -0
  408. package/src/admin-shell/chrome/hamburger.tsx +56 -0
  409. package/src/admin-shell/chrome/loose-router.ts +47 -0
  410. package/src/admin-shell/chrome/menu-drawer.module.css +196 -0
  411. package/src/admin-shell/chrome/menu-drawer.tsx +155 -0
  412. package/src/admin-shell/chrome/menu-provider.tsx +95 -0
  413. package/src/admin-shell/chrome/preview-toggle.tsx +107 -0
  414. package/src/admin-shell/chrome/route-error.module.css +114 -0
  415. package/src/admin-shell/chrome/route-error.tsx +125 -0
  416. package/src/admin-shell/chrome/router-pager.tsx +179 -0
  417. package/src/admin-shell/chrome/sign-in-page.module.css +32 -0
  418. package/src/admin-shell/chrome/sign-in-page.tsx +35 -0
  419. package/src/admin-shell/chrome/sort-icons.tsx +127 -0
  420. package/src/admin-shell/chrome/th-sortable.module.css +51 -0
  421. package/src/admin-shell/chrome/th-sortable.tsx +114 -0
  422. package/src/admin-shell/chrome/use-media-query.ts +28 -0
  423. package/src/admin-shell/chrome/utils.ts +20 -0
  424. package/src/admin-shell/collections/api.module.css +62 -0
  425. package/src/admin-shell/collections/api.tsx +70 -0
  426. package/src/admin-shell/collections/create.tsx +108 -0
  427. package/src/admin-shell/collections/edit.tsx +319 -0
  428. package/src/admin-shell/collections/history.module.css +156 -0
  429. package/src/admin-shell/collections/history.tsx +352 -0
  430. package/src/admin-shell/collections/list.module.css +124 -0
  431. package/src/admin-shell/collections/list.tsx +313 -0
  432. package/src/admin-shell/collections/preview-link.tsx +138 -0
  433. package/src/admin-shell/collections/tanstack-navigation-guard.ts +43 -0
  434. package/src/admin-shell/collections/view-menu.module.css +60 -0
  435. package/src/admin-shell/collections/view-menu.tsx +238 -0
  436. package/src/auth/auth-context.test.node.ts +200 -0
  437. package/src/auth/auth-context.ts +119 -0
  438. package/src/auth/auth-cookies.ts +113 -0
  439. package/src/auth/preview-cookies.ts +73 -0
  440. package/src/declarations.d.ts +4 -0
  441. package/src/index.ts +44 -0
  442. package/src/integrations/abilities.tsx +90 -0
  443. package/src/integrations/api-utils.ts +66 -0
  444. package/src/integrations/byline-admin-services.ts +86 -0
  445. package/src/integrations/byline-client.ts +40 -0
  446. package/src/integrations/byline-core.ts +32 -0
  447. package/src/integrations/byline-field-services.ts +35 -0
  448. package/src/integrations/byline-public-client.ts +53 -0
  449. package/src/integrations/byline-viewer-client.ts +99 -0
  450. package/src/integrations/start-errors.ts +86 -0
  451. package/src/routes/create-admin-account-route.tsx +65 -0
  452. package/src/routes/create-admin-dashboard-route.tsx +52 -0
  453. package/src/routes/create-admin-layout-route.tsx +89 -0
  454. package/src/routes/create-admin-permissions-route.tsx +43 -0
  455. package/src/routes/create-admin-role-edit-route.tsx +88 -0
  456. package/src/routes/create-admin-roles-list-route.tsx +39 -0
  457. package/src/routes/create-admin-user-edit-route.tsx +105 -0
  458. package/src/routes/create-admin-users-list-route.tsx +84 -0
  459. package/src/routes/create-collection-api-route.tsx +111 -0
  460. package/src/routes/create-collection-create-route.tsx +66 -0
  461. package/src/routes/create-collection-edit-route.tsx +102 -0
  462. package/src/routes/create-collection-history-route.tsx +130 -0
  463. package/src/routes/create-collection-list-route.tsx +175 -0
  464. package/src/routes/create-sign-in-route.tsx +39 -0
  465. package/src/routes/index.ts +36 -0
  466. package/src/server-fns/admin-account/change-password.ts +27 -0
  467. package/src/server-fns/admin-account/get.ts +27 -0
  468. package/src/server-fns/admin-account/index.ts +28 -0
  469. package/src/server-fns/admin-account/update.ts +31 -0
  470. package/src/server-fns/admin-permissions/get-role-abilities.ts +27 -0
  471. package/src/server-fns/admin-permissions/index.ts +36 -0
  472. package/src/server-fns/admin-permissions/list-registered.ts +36 -0
  473. package/src/server-fns/admin-permissions/set-role-abilities.ts +32 -0
  474. package/src/server-fns/admin-permissions/who-has.ts +24 -0
  475. package/src/server-fns/admin-roles/create.ts +28 -0
  476. package/src/server-fns/admin-roles/delete.ts +25 -0
  477. package/src/server-fns/admin-roles/get.ts +21 -0
  478. package/src/server-fns/admin-roles/index.ts +25 -0
  479. package/src/server-fns/admin-roles/list.ts +27 -0
  480. package/src/server-fns/admin-roles/reorder.ts +21 -0
  481. package/src/server-fns/admin-roles/update.ts +31 -0
  482. package/src/server-fns/admin-users/create.ts +32 -0
  483. package/src/server-fns/admin-users/delete.ts +21 -0
  484. package/src/server-fns/admin-users/disable.ts +24 -0
  485. package/src/server-fns/admin-users/enable.ts +24 -0
  486. package/src/server-fns/admin-users/get-user-roles.ts +21 -0
  487. package/src/server-fns/admin-users/get.ts +21 -0
  488. package/src/server-fns/admin-users/index.ts +35 -0
  489. package/src/server-fns/admin-users/list.ts +40 -0
  490. package/src/server-fns/admin-users/set-password.ts +27 -0
  491. package/src/server-fns/admin-users/set-user-roles.ts +26 -0
  492. package/src/server-fns/admin-users/update.ts +34 -0
  493. package/src/server-fns/auth/current-user.ts +117 -0
  494. package/src/server-fns/auth/index.ts +15 -0
  495. package/src/server-fns/auth/sign-in.ts +71 -0
  496. package/src/server-fns/auth/sign-out.ts +42 -0
  497. package/src/server-fns/collections/create.ts +58 -0
  498. package/src/server-fns/collections/delete.ts +62 -0
  499. package/src/server-fns/collections/get.ts +233 -0
  500. package/src/server-fns/collections/history.ts +73 -0
  501. package/src/server-fns/collections/index.ts +16 -0
  502. package/src/server-fns/collections/list.ts +121 -0
  503. package/src/server-fns/collections/stats.ts +52 -0
  504. package/src/server-fns/collections/status.ts +102 -0
  505. package/src/server-fns/collections/update.ts +67 -0
  506. package/src/server-fns/collections/upload.ts +274 -0
  507. package/src/server-fns/collections/utils.ts +17 -0
  508. package/src/server-fns/preview/disable.ts +24 -0
  509. package/src/server-fns/preview/enable.ts +27 -0
  510. package/src/server-fns/preview/index.ts +11 -0
  511. package/src/server-fns/preview/state.ts +30 -0
@@ -0,0 +1,238 @@
1
+ /**
2
+ * This Source Code is subject to the terms of the Mozilla Public
3
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
4
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
5
+ *
6
+ * Copyright (c) Infonomic Company Limited
7
+ */
8
+
9
+ import { useEffect } from 'react'
10
+
11
+ import type { CollectionAdminConfig, PreviewDocument } from '@byline/core'
12
+ import { Button, HistoryIcon, IconButton, Label, Select } from '@infonomic/uikit/react'
13
+ import cx from 'classnames'
14
+
15
+ import { useNavigate } from '../chrome/loose-router.js'
16
+ import { PreviewLink } from './preview-link.js'
17
+ import styles from './view-menu.module.css'
18
+
19
+ export type ViewMenuPaths = 'edit' | 'history' | 'api'
20
+
21
+ export interface ContentLocaleOption {
22
+ code: string
23
+ label: string
24
+ }
25
+
26
+ /**
27
+ * Shared mini-navigation bar for document-level views (Edit, History, API).
28
+ * Renders a locale selector, the History icon button, Edit button, and API
29
+ * button with appropriate variant styling based on the currently active view.
30
+ * Changing the locale triggers a navigate to the current view's route so the
31
+ * loader re-fetches with the new locale — all three views react automatically.
32
+ *
33
+ * On the API route, an additional Depth selector appears — it drives the
34
+ * `populateDocuments` call inside the api loader and lets editors see
35
+ * what a client library `find({ populate: true, depth: N })` call would
36
+ * return. Capped at 3 in the UI to avoid runaway fan-out.
37
+ *
38
+ * `contentLocales` and `defaultContentLocale` are passed in from the host
39
+ * route shell (which reads them from the host's i18n config) so this
40
+ * component stays free of host-specific imports.
41
+ */
42
+ export const ViewMenu = ({
43
+ collection,
44
+ documentId,
45
+ activeView,
46
+ locale,
47
+ depth,
48
+ contentLocales,
49
+ defaultContentLocale,
50
+ adminConfig,
51
+ doc,
52
+ }: {
53
+ /** Collection path (e.g. "docs", "news"). */
54
+ collection: string
55
+ /** The document ID to navigate to. */
56
+ documentId: string
57
+ /** Which view is currently active — used to style the active button. */
58
+ activeView?: ViewMenuPaths
59
+ /** Current content locale. undefined means "All" (full multi-locale shape). */
60
+ locale?: string
61
+ /** Populate depth (api route only). undefined → 0 (no populate). */
62
+ depth?: number
63
+ /** Content locales the host advertises in language switchers. */
64
+ contentLocales: ReadonlyArray<ContentLocaleOption>
65
+ /** Fallback content locale used when the URL has none. */
66
+ defaultContentLocale: string
67
+ /**
68
+ * Admin config for the collection. When present and `adminConfig.preview`
69
+ * is configured (or the default URL convention applies), a `<PreviewLink>`
70
+ * external-link icon is rendered next to the History button.
71
+ */
72
+ adminConfig?: CollectionAdminConfig
73
+ /**
74
+ * The currently-loaded document. Required for the preview link's
75
+ * URL resolution; omit this prop to suppress the preview affordance
76
+ * entirely (e.g. on the create route, where no doc exists yet).
77
+ */
78
+ doc?: PreviewDocument
79
+ }) => {
80
+ const navigate = useNavigate()
81
+
82
+ // Edit view must never use 'all' locale — strip it from the URL and fall
83
+ // back to the default locale if it somehow arrives via navigation.
84
+ useEffect(() => {
85
+ if (activeView === 'edit' && locale === 'all') {
86
+ navigate({
87
+ to: '/admin/collections/$collection/$id' as never,
88
+ params: { collection, id: documentId },
89
+ search: (prev: Record<string, unknown>) => ({
90
+ ...prev,
91
+ locale: defaultContentLocale,
92
+ }),
93
+ })
94
+ }
95
+ }, [activeView, locale, collection, documentId, defaultContentLocale, navigate])
96
+
97
+ const handleLocaleChange = (value: string | null) => {
98
+ if (value == null) return
99
+ // Always put locale explicitly in the URL — 'all' is stored as 'all',
100
+ // never as undefined, so the loader knows the intent unambiguously.
101
+ const search = (prev: Record<string, unknown>) => ({ ...prev, locale: value })
102
+ if (activeView === 'api') {
103
+ navigate({
104
+ to: '/admin/collections/$collection/$id/api' as never,
105
+ params: { collection, id: documentId },
106
+ search: search as never,
107
+ })
108
+ } else if (activeView === 'history') {
109
+ navigate({
110
+ to: '/admin/collections/$collection/$id/history' as never,
111
+ params: { collection, id: documentId },
112
+ search: search as never,
113
+ })
114
+ } else {
115
+ navigate({
116
+ to: '/admin/collections/$collection/$id' as never,
117
+ params: { collection, id: documentId },
118
+ search: search as never,
119
+ })
120
+ }
121
+ }
122
+
123
+ const handleDepthChange = (value: string | null) => {
124
+ if (value == null || activeView !== 'api') return
125
+ const n = Number.parseInt(value, 10)
126
+ const nextDepth = Number.isFinite(n) ? Math.max(0, Math.min(3, n)) : 0
127
+ navigate({
128
+ to: '/admin/collections/$collection/$id/api' as never,
129
+ params: { collection, id: documentId },
130
+ // Store 0 as undefined so the URL stays clean when the user picks
131
+ // "no populate" — avoids `?depth=0` in bookmarks / share links.
132
+ search: ((prev: Record<string, unknown>) => ({
133
+ ...prev,
134
+ depth: nextDepth === 0 ? undefined : nextDepth,
135
+ })) as never,
136
+ })
137
+ }
138
+
139
+ return (
140
+ <div className={cx('byline-view-menu', styles.root)}>
141
+ <Label
142
+ className={cx('muted byline-view-menu-label', styles.label)}
143
+ id="contentLocaleLabel"
144
+ htmlFor="contentLocale"
145
+ label="Content Locale:"
146
+ />
147
+ <Select<string>
148
+ name="contentLocale"
149
+ id="contentLocale"
150
+ className={cx('byline-view-menu-locale-select', styles.localeSelect)}
151
+ size="xs"
152
+ variant="outlined"
153
+ value={locale ?? defaultContentLocale}
154
+ items={[
155
+ ...(activeView !== 'edit' ? [{ value: 'all', label: 'All' }] : []),
156
+ ...contentLocales.map((loc) => ({ value: loc.code, label: loc.label })),
157
+ ]}
158
+ onValueChange={handleLocaleChange}
159
+ />
160
+ {activeView === 'api' && (
161
+ <>
162
+ <Label
163
+ className={cx('muted byline-view-menu-label', styles.label)}
164
+ id="populateDepthLabel"
165
+ htmlFor="populateDepth"
166
+ label="Depth:"
167
+ />
168
+ <Select<string>
169
+ name="populateDepth"
170
+ id="populateDepth"
171
+ className={cx('byline-view-menu-depth-select', styles.depthSelect)}
172
+ size="xs"
173
+ variant="outlined"
174
+ value={String(depth ?? 0)}
175
+ items={[
176
+ { value: '0', label: '0' },
177
+ { value: '1', label: '1' },
178
+ { value: '2', label: '2' },
179
+ { value: '3', label: '3' },
180
+ ]}
181
+ onValueChange={handleDepthChange}
182
+ />
183
+ </>
184
+ )}
185
+ {doc && (
186
+ <PreviewLink
187
+ collectionPath={collection}
188
+ doc={doc}
189
+ adminConfig={adminConfig}
190
+ locale={locale}
191
+ className={cx('byline-view-menu-icon-button', styles.iconButton)}
192
+ />
193
+ )}
194
+ <IconButton
195
+ className={cx('byline-view-menu-icon-button', styles.iconButton)}
196
+ size="xs"
197
+ variant={activeView === 'history' ? 'filled' : 'text'}
198
+ onClick={() =>
199
+ navigate({
200
+ to: '/admin/collections/$collection/$id/history' as never,
201
+ params: { collection, id: documentId },
202
+ search: locale ? { locale } : {},
203
+ })
204
+ }
205
+ >
206
+ <HistoryIcon className={cx('byline-view-menu-icon-button-icon', styles.iconButtonIcon)} />
207
+ </IconButton>
208
+ <Button
209
+ size="xs"
210
+ variant={activeView === 'edit' ? 'filled' : 'outlined'}
211
+ className={cx('byline-view-menu-button', styles.button)}
212
+ onClick={() =>
213
+ navigate({
214
+ to: '/admin/collections/$collection/$id' as never,
215
+ params: { collection, id: documentId },
216
+ search: locale ? { locale } : {},
217
+ })
218
+ }
219
+ >
220
+ Edit
221
+ </Button>
222
+ <Button
223
+ size="xs"
224
+ variant={activeView === 'api' ? 'filled' : 'outlined'}
225
+ className={cx('byline-view-menu-button', styles.button)}
226
+ onClick={() =>
227
+ navigate({
228
+ to: '/admin/collections/$collection/$id/api' as never,
229
+ params: { collection, id: documentId },
230
+ search: locale ? { locale } : {},
231
+ })
232
+ }
233
+ >
234
+ API
235
+ </Button>
236
+ </div>
237
+ )
238
+ }
@@ -0,0 +1,200 @@
1
+ /**
2
+ * This Source Code is subject to the terms of the Mozilla Public
3
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
4
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
5
+ *
6
+ * Copyright (c) Infonomic Company Limited
7
+ */
8
+
9
+ /**
10
+ * Unit coverage for the admin request-context resolver. Mocks the
11
+ * TanStack Start cookie helpers and the `bylineCore.sessionProvider` so
12
+ * the branches can be exercised without a live Postgres or JWT
13
+ * machinery.
14
+ */
15
+
16
+ import { AdminAuth, AuthError, AuthErrorCodes } from '@byline/auth'
17
+ import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
18
+
19
+ // ---------------------------------------------------------------------------
20
+ // Mocks — must be declared before the module under test is imported.
21
+ // `vi.mock` is hoisted to the top of the file, so the fakes themselves
22
+ // have to go through `vi.hoisted` to be available when the factory runs.
23
+ // ---------------------------------------------------------------------------
24
+
25
+ const mocks = vi.hoisted(() => ({
26
+ verifyAccessToken: vi.fn(),
27
+ refreshSession: vi.fn(),
28
+ getCookie: vi.fn(),
29
+ setCookie: vi.fn(),
30
+ getRequestHeader: vi.fn(),
31
+ }))
32
+
33
+ vi.mock('@byline/core', async () => {
34
+ const actual = await vi.importActual<typeof import('@byline/core')>('@byline/core')
35
+ return {
36
+ ...actual,
37
+ getServerConfig: () => ({
38
+ sessionProvider: {
39
+ verifyAccessToken: mocks.verifyAccessToken,
40
+ refreshSession: mocks.refreshSession,
41
+ },
42
+ }),
43
+ }
44
+ })
45
+
46
+ vi.mock('@tanstack/react-start/server', () => ({
47
+ getCookie: mocks.getCookie,
48
+ setCookie: mocks.setCookie,
49
+ getRequestHeader: mocks.getRequestHeader,
50
+ }))
51
+
52
+ const { verifyAccessToken, refreshSession, getCookie, setCookie } = mocks
53
+
54
+ // Import AFTER mocks are declared.
55
+ import { getAdminRequestContext } from './auth-context.js'
56
+
57
+ // ---------------------------------------------------------------------------
58
+
59
+ function cookiesReturn(values: Record<string, string | undefined>) {
60
+ getCookie.mockImplementation((name: string) => values[name])
61
+ }
62
+
63
+ function stubActor() {
64
+ return new AdminAuth({
65
+ id: 'admin-1',
66
+ abilities: ['collections.pages.read'],
67
+ })
68
+ }
69
+
70
+ describe('getAdminRequestContext', () => {
71
+ beforeEach(() => {
72
+ vi.clearAllMocks()
73
+ })
74
+
75
+ afterEach(() => {
76
+ vi.clearAllMocks()
77
+ })
78
+
79
+ it('returns the actor directly when the access token verifies', async () => {
80
+ cookiesReturn({
81
+ byline_access_token: 'valid-access',
82
+ byline_refresh_token: 'some-refresh',
83
+ })
84
+ const actor = stubActor()
85
+ verifyAccessToken.mockResolvedValueOnce({ actor })
86
+
87
+ const ctx = await getAdminRequestContext()
88
+
89
+ expect(ctx.actor).toBe(actor)
90
+ expect(ctx.readMode).toBe('any')
91
+ expect(refreshSession).not.toHaveBeenCalled()
92
+ expect(setCookie).not.toHaveBeenCalled()
93
+ })
94
+
95
+ it('refreshes when the access token fails verification', async () => {
96
+ cookiesReturn({
97
+ byline_access_token: 'stale-access',
98
+ byline_refresh_token: 'valid-refresh',
99
+ })
100
+ const actor = stubActor()
101
+ verifyAccessToken.mockRejectedValueOnce(new Error('expired')).mockResolvedValueOnce({ actor })
102
+ refreshSession.mockResolvedValueOnce({
103
+ accessToken: 'fresh-access',
104
+ refreshToken: 'fresh-refresh',
105
+ accessTokenExpiresAt: new Date(Date.now() + 15 * 60_000),
106
+ refreshTokenExpiresAt: new Date(Date.now() + 30 * 24 * 60 * 60_000),
107
+ })
108
+
109
+ const ctx = await getAdminRequestContext()
110
+
111
+ expect(ctx.actor).toBe(actor)
112
+ expect(refreshSession).toHaveBeenCalledWith({ refreshToken: 'valid-refresh' })
113
+ // Both access + refresh cookies should have been written with maxAge > 0.
114
+ expect(setCookie).toHaveBeenCalledTimes(2)
115
+ const accessCall = setCookie.mock.calls.find((c) => c[0] === 'byline_access_token')
116
+ expect(accessCall?.[1]).toBe('fresh-access')
117
+ expect(accessCall?.[2]?.maxAge).toBeGreaterThan(0)
118
+ })
119
+
120
+ it('refreshes when the access cookie is missing but a refresh cookie exists', async () => {
121
+ cookiesReturn({ byline_refresh_token: 'only-refresh' })
122
+ const actor = stubActor()
123
+ refreshSession.mockResolvedValueOnce({
124
+ accessToken: 'fresh-access',
125
+ refreshToken: 'fresh-refresh',
126
+ accessTokenExpiresAt: new Date(Date.now() + 15 * 60_000),
127
+ refreshTokenExpiresAt: new Date(Date.now() + 30 * 24 * 60 * 60_000),
128
+ })
129
+ verifyAccessToken.mockResolvedValueOnce({ actor })
130
+
131
+ const ctx = await getAdminRequestContext()
132
+
133
+ expect(ctx.actor).toBe(actor)
134
+ // The access-token path was skipped (no cookie) so verifyAccessToken ran
135
+ // only for the freshly-issued token.
136
+ expect(verifyAccessToken).toHaveBeenCalledTimes(1)
137
+ expect(verifyAccessToken).toHaveBeenCalledWith('fresh-access')
138
+ })
139
+
140
+ it('throws ERR_UNAUTHENTICATED and clears cookies when no session exists', async () => {
141
+ cookiesReturn({})
142
+
143
+ try {
144
+ await getAdminRequestContext()
145
+ expect.fail('expected ERR_UNAUTHENTICATED')
146
+ } catch (err) {
147
+ expect(err).toBeInstanceOf(AuthError)
148
+ expect((err as AuthError).code).toBe(AuthErrorCodes.UNAUTHENTICATED)
149
+ }
150
+ // Cookie clear = setCookie with empty value and maxAge 0 for both names.
151
+ const clears = setCookie.mock.calls.filter((c) => c[2]?.maxAge === 0)
152
+ const clearedNames = new Set(clears.map((c) => c[0]))
153
+ expect(clearedNames.has('byline_access_token')).toBe(true)
154
+ expect(clearedNames.has('byline_refresh_token')).toBe(true)
155
+ })
156
+
157
+ it('clears cookies and throws when refresh itself fails', async () => {
158
+ cookiesReturn({
159
+ byline_access_token: 'stale',
160
+ byline_refresh_token: 'bad-refresh',
161
+ })
162
+ verifyAccessToken.mockRejectedValueOnce(new Error('expired'))
163
+ refreshSession.mockRejectedValueOnce(new Error('revoked'))
164
+
165
+ try {
166
+ await getAdminRequestContext()
167
+ expect.fail('expected ERR_UNAUTHENTICATED')
168
+ } catch (err) {
169
+ expect(err).toBeInstanceOf(AuthError)
170
+ expect((err as AuthError).code).toBe(AuthErrorCodes.UNAUTHENTICATED)
171
+ }
172
+ const clears = setCookie.mock.calls.filter((c) => c[2]?.maxAge === 0)
173
+ expect(clears.length).toBe(2)
174
+ })
175
+
176
+ it('clears cookies and throws when the refreshed access token fails to verify', async () => {
177
+ cookiesReturn({
178
+ byline_access_token: 'stale',
179
+ byline_refresh_token: 'valid',
180
+ })
181
+ verifyAccessToken
182
+ .mockRejectedValueOnce(new Error('expired'))
183
+ .mockRejectedValueOnce(new Error('still bad'))
184
+ refreshSession.mockResolvedValueOnce({
185
+ accessToken: 'fresh-but-somehow-bad',
186
+ refreshToken: 'fresh-refresh',
187
+ accessTokenExpiresAt: new Date(Date.now() + 15 * 60_000),
188
+ refreshTokenExpiresAt: new Date(Date.now() + 30 * 24 * 60 * 60_000),
189
+ })
190
+
191
+ try {
192
+ await getAdminRequestContext()
193
+ expect.fail('expected ERR_UNAUTHENTICATED')
194
+ } catch (err) {
195
+ expect((err as AuthError).code).toBe(AuthErrorCodes.UNAUTHENTICATED)
196
+ }
197
+ const clears = setCookie.mock.calls.filter((c) => c[2]?.maxAge === 0)
198
+ expect(clears.length).toBe(2)
199
+ })
200
+ })
@@ -0,0 +1,119 @@
1
+ /**
2
+ * This Source Code is subject to the terms of the Mozilla Public
3
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
4
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
5
+ *
6
+ * Copyright (c) Infonomic Company Limited
7
+ */
8
+
9
+ /**
10
+ * Request-scoped auth context for admin server functions.
11
+ *
12
+ * Reads the session cookies, verifies the access token, transparently
13
+ * refreshes when needed, and returns a `RequestContext` carrying the
14
+ * authenticated `AdminAuth`. Every admin server fn calls this as its
15
+ * first step — it is the single point where the admin transport boundary
16
+ * meets the actor/ability machinery.
17
+ *
18
+ * Flow, in order:
19
+ *
20
+ * 1. Read the access cookie.
21
+ * 2. If present, try `sessionProvider.verifyAccessToken`. On success,
22
+ * return the context — no DB write, no cookie churn.
23
+ * 3. On verify failure (or missing access cookie), read the refresh
24
+ * cookie. If present, call `sessionProvider.refreshSession` — this
25
+ * rotates the refresh token atomically and issues a new access
26
+ * token. Write both fresh cookies to the response.
27
+ * 4. Verify the new access token (populate the actor) and return the
28
+ * context.
29
+ * 5. Any failure along the way clears both cookies so the browser
30
+ * stops sending a session the server has already rejected, and
31
+ * throws `ERR_UNAUTHENTICATED`.
32
+ *
33
+ * Burns a refresh-token rotation only when the access token actually
34
+ * fails verification — not on every request. The "one session" UX is
35
+ * the consequence of this helper working invisibly behind each call.
36
+ */
37
+
38
+ import { ERR_UNAUTHENTICATED, type RequestContext } from '@byline/auth'
39
+ import { getServerConfig } from '@byline/core'
40
+ import { v7 as uuidv7 } from 'uuid'
41
+
42
+ import {
43
+ clearSessionCookies,
44
+ readAccessTokenCookie,
45
+ readRefreshTokenCookie,
46
+ setSessionCookies,
47
+ } from './auth-cookies.js'
48
+
49
+ function requireSessionProvider() {
50
+ const provider = getServerConfig().sessionProvider
51
+ if (!provider) {
52
+ throw new Error(
53
+ 'No sessionProvider configured on ServerConfig. ' +
54
+ 'Construct a JwtSessionProvider in your server config and pass it to initBylineCore().'
55
+ )
56
+ }
57
+ return provider
58
+ }
59
+
60
+ export async function getAdminRequestContext(): Promise<RequestContext> {
61
+ const provider = requireSessionProvider()
62
+
63
+ const accessToken = readAccessTokenCookie()
64
+
65
+ // Happy path: valid access token.
66
+ if (accessToken) {
67
+ try {
68
+ const { actor } = await provider.verifyAccessToken(accessToken)
69
+ return {
70
+ actor,
71
+ requestId: uuidv7(),
72
+ readMode: 'any',
73
+ }
74
+ } catch {
75
+ // Fall through to refresh — we'll burn a rotation only when the
76
+ // access token genuinely can't verify.
77
+ }
78
+ }
79
+
80
+ // Refresh path: swap the refresh cookie for a fresh token pair.
81
+ const refreshToken = readRefreshTokenCookie()
82
+ if (!refreshToken) {
83
+ // No session at all — clear anything stale and reject.
84
+ clearSessionCookies()
85
+ throw ERR_UNAUTHENTICATED({ message: 'no admin session' })
86
+ }
87
+
88
+ let refreshed: Awaited<ReturnType<typeof provider.refreshSession>>
89
+ try {
90
+ refreshed = await provider.refreshSession({ refreshToken })
91
+ } catch (err) {
92
+ clearSessionCookies()
93
+ throw ERR_UNAUTHENTICATED({
94
+ message: 'admin session could not be refreshed',
95
+ cause: err,
96
+ })
97
+ }
98
+
99
+ // Write the new cookies so subsequent requests skip the refresh path.
100
+ setSessionCookies(refreshed)
101
+
102
+ // Verify the freshly-minted access token to extract the actor.
103
+ let verified: Awaited<ReturnType<typeof provider.verifyAccessToken>>
104
+ try {
105
+ verified = await provider.verifyAccessToken(refreshed.accessToken)
106
+ } catch (err) {
107
+ clearSessionCookies()
108
+ throw ERR_UNAUTHENTICATED({
109
+ message: 'refreshed access token did not verify',
110
+ cause: err,
111
+ })
112
+ }
113
+
114
+ return {
115
+ actor: verified.actor,
116
+ requestId: uuidv7(),
117
+ readMode: 'any',
118
+ }
119
+ }
@@ -0,0 +1,113 @@
1
+ /**
2
+ * This Source Code is subject to the terms of the Mozilla Public
3
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
4
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
5
+ *
6
+ * Copyright (c) Infonomic Company Limited
7
+ */
8
+
9
+ /**
10
+ * Cookie helpers for admin session management.
11
+ *
12
+ * Two separate httpOnly cookies, one for each token half:
13
+ *
14
+ * - `byline_access_token` — short-lived JWT; sent on every request.
15
+ * - `byline_refresh_token` — long-lived opaque string; sent back only
16
+ * when the access cookie is missing or
17
+ * expired, to mint a new access token.
18
+ *
19
+ * Presenting "one session" to the user is a function of the middleware —
20
+ * `getAdminRequestContext()` transparently refreshes the access cookie
21
+ * using the refresh cookie, so the UI layer doesn't have to care.
22
+ *
23
+ * All cookies set here use:
24
+ * - `httpOnly: true` — inaccessible to JavaScript (XSS-hardened).
25
+ * - `sameSite: 'lax'` — sent on top-level navigations but not
26
+ * cross-origin subrequests (reasonable default
27
+ * for an admin SSR app).
28
+ * - `secure: true` in production — https-only; dev keeps it off so
29
+ * cookies work on http://localhost.
30
+ * - `path: '/'` — available everywhere in the app.
31
+ */
32
+
33
+ import { getCookie, setCookie } from '@tanstack/react-start/server'
34
+
35
+ export const ACCESS_TOKEN_COOKIE = 'byline_access_token'
36
+ export const REFRESH_TOKEN_COOKIE = 'byline_refresh_token'
37
+
38
+ const IS_PROD = process.env.NODE_ENV === 'production'
39
+
40
+ /** Read the access-token cookie. Returns undefined when not present. */
41
+ export function readAccessTokenCookie(): string | undefined {
42
+ return getCookie(ACCESS_TOKEN_COOKIE)
43
+ }
44
+
45
+ /** Read the refresh-token cookie. Returns undefined when not present. */
46
+ export function readRefreshTokenCookie(): string | undefined {
47
+ return getCookie(REFRESH_TOKEN_COOKIE)
48
+ }
49
+
50
+ export interface SessionCookieTokens {
51
+ accessToken: string
52
+ refreshToken: string
53
+ accessTokenExpiresAt: Date
54
+ refreshTokenExpiresAt: Date
55
+ }
56
+
57
+ /**
58
+ * Write both access and refresh cookies. Called after sign-in and after
59
+ * every transparent refresh in `getAdminRequestContext()`.
60
+ *
61
+ * `maxAge` is derived from each token's own expiry claim so the browser
62
+ * drops the cookies at the same moment the server would reject them —
63
+ * saves round trips when the refresh token has fully expired.
64
+ */
65
+ export function setSessionCookies(tokens: SessionCookieTokens): void {
66
+ const now = Date.now()
67
+ const accessMaxAgeSeconds = Math.max(
68
+ 0,
69
+ Math.floor((tokens.accessTokenExpiresAt.getTime() - now) / 1000)
70
+ )
71
+ const refreshMaxAgeSeconds = Math.max(
72
+ 0,
73
+ Math.floor((tokens.refreshTokenExpiresAt.getTime() - now) / 1000)
74
+ )
75
+
76
+ setCookie(ACCESS_TOKEN_COOKIE, tokens.accessToken, {
77
+ httpOnly: true,
78
+ sameSite: 'lax',
79
+ secure: IS_PROD,
80
+ path: '/',
81
+ maxAge: accessMaxAgeSeconds,
82
+ })
83
+
84
+ setCookie(REFRESH_TOKEN_COOKIE, tokens.refreshToken, {
85
+ httpOnly: true,
86
+ sameSite: 'lax',
87
+ secure: IS_PROD,
88
+ path: '/',
89
+ maxAge: refreshMaxAgeSeconds,
90
+ })
91
+ }
92
+
93
+ /**
94
+ * Clear both session cookies. Called on sign-out and on any auth failure
95
+ * during `getAdminRequestContext()` (ensures the browser does not keep
96
+ * trying a token that the server has already rejected).
97
+ */
98
+ export function clearSessionCookies(): void {
99
+ setCookie(ACCESS_TOKEN_COOKIE, '', {
100
+ httpOnly: true,
101
+ sameSite: 'lax',
102
+ secure: IS_PROD,
103
+ path: '/',
104
+ maxAge: 0,
105
+ })
106
+ setCookie(REFRESH_TOKEN_COOKIE, '', {
107
+ httpOnly: true,
108
+ sameSite: 'lax',
109
+ secure: IS_PROD,
110
+ path: '/',
111
+ maxAge: 0,
112
+ })
113
+ }