@byline/host-tanstack-start 3.21.0 → 4.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (236) hide show
  1. package/dist/admin-shell/admin-activity/list.js +15 -5
  2. package/dist/admin-shell/admin-roles/delete.js +2 -1
  3. package/dist/admin-shell/admin-roles/list.js +2 -1
  4. package/dist/admin-shell/admin-users/delete.js +2 -1
  5. package/dist/admin-shell/admin-users/list.js +4 -7
  6. package/dist/admin-shell/chrome/admin-app-bar.js +2 -1
  7. package/dist/admin-shell/chrome/admin-menu-drawer.js +9 -8
  8. package/dist/admin-shell/chrome/admin-menu-provider.js +2 -1
  9. package/dist/admin-shell/chrome/dashboard.js +4 -3
  10. package/dist/admin-shell/chrome/sign-in-page.d.ts +2 -2
  11. package/dist/admin-shell/chrome/sign-in-page.js +2 -2
  12. package/dist/admin-shell/collections/create.js +4 -3
  13. package/dist/admin-shell/collections/document-history.js +6 -1
  14. package/dist/admin-shell/collections/edit.js +18 -14
  15. package/dist/admin-shell/collections/history.js +5 -4
  16. package/dist/admin-shell/collections/list.js +8 -7
  17. package/dist/admin-shell/collections/restore-version-modal.js +2 -1
  18. package/dist/admin-shell/collections/tree-list.js +53 -17
  19. package/dist/admin-shell/collections/view-menu.js +9 -8
  20. package/dist/i18n/resolve-locale.js +1 -1
  21. package/dist/index.d.ts +5 -6
  22. package/dist/integrations/abilities.js +8 -7
  23. package/dist/integrations/host-bridge.d.ts +13 -0
  24. package/dist/integrations/host-bridge.js +22 -0
  25. package/dist/integrations/serve-uploads.d.ts +1 -0
  26. package/dist/integrations/serve-uploads.js +1 -0
  27. package/dist/integrations/start-errors.js +2 -1
  28. package/dist/routes/admin-path.d.ts +22 -0
  29. package/dist/routes/admin-path.js +35 -0
  30. package/dist/routes/create-admin-account-route.js +3 -2
  31. package/dist/routes/create-admin-activity-route.js +3 -2
  32. package/dist/routes/create-admin-dashboard-route.js +2 -1
  33. package/dist/routes/create-admin-layout-route.d.ts +1 -1
  34. package/dist/routes/create-admin-layout-route.js +3 -1
  35. package/dist/routes/create-admin-permissions-route.js +3 -2
  36. package/dist/routes/create-admin-role-edit-route.js +4 -3
  37. package/dist/routes/create-admin-roles-list-route.js +3 -2
  38. package/dist/routes/create-admin-user-edit-route.js +4 -3
  39. package/dist/routes/create-admin-users-list-route.js +3 -2
  40. package/dist/routes/create-collection-api-route.js +5 -4
  41. package/dist/routes/create-collection-create-route.js +4 -3
  42. package/dist/routes/create-collection-edit-route.js +4 -3
  43. package/dist/routes/create-collection-history-route.js +5 -4
  44. package/dist/routes/create-collection-list-route.js +3 -2
  45. package/dist/routes/create-sign-in-route.js +3 -2
  46. package/dist/routes/index.d.ts +3 -0
  47. package/dist/routes/index.js +2 -0
  48. package/dist/routes/sign-in-path.d.ts +13 -0
  49. package/dist/routes/sign-in-path.js +19 -0
  50. package/dist/server-fns/admin-account/change-password.js +1 -1
  51. package/dist/server-fns/admin-account/get.js +1 -1
  52. package/dist/server-fns/admin-account/update.js +1 -1
  53. package/dist/server-fns/admin-activity/get.js +1 -1
  54. package/dist/server-fns/admin-permissions/get-role-abilities.js +1 -1
  55. package/dist/server-fns/admin-permissions/list-registered.js +1 -1
  56. package/dist/server-fns/admin-permissions/set-role-abilities.js +1 -1
  57. package/dist/server-fns/admin-permissions/who-has.js +1 -1
  58. package/dist/server-fns/admin-roles/create.js +1 -1
  59. package/dist/server-fns/admin-roles/delete.js +1 -1
  60. package/dist/server-fns/admin-roles/get.js +1 -1
  61. package/dist/server-fns/admin-roles/list.js +1 -1
  62. package/dist/server-fns/admin-roles/reorder.js +1 -1
  63. package/dist/server-fns/admin-roles/update.js +1 -1
  64. package/dist/server-fns/admin-users/create.js +1 -1
  65. package/dist/server-fns/admin-users/delete.js +1 -1
  66. package/dist/server-fns/admin-users/disable.js +1 -1
  67. package/dist/server-fns/admin-users/enable.js +1 -1
  68. package/dist/server-fns/admin-users/get-user-roles.js +1 -1
  69. package/dist/server-fns/admin-users/get.js +1 -1
  70. package/dist/server-fns/admin-users/list.js +1 -1
  71. package/dist/server-fns/admin-users/set-password.js +1 -1
  72. package/dist/server-fns/admin-users/set-user-roles.js +1 -1
  73. package/dist/server-fns/admin-users/update.js +1 -1
  74. package/dist/server-fns/ai/execute.js +1 -1
  75. package/dist/server-fns/auth/current-user.js +1 -1
  76. package/dist/server-fns/auth/sign-in.js +1 -1
  77. package/dist/server-fns/auth/sign-out.js +1 -2
  78. package/dist/server-fns/collections/audit.js +1 -1
  79. package/dist/server-fns/collections/copy-to-locale.js +1 -1
  80. package/dist/server-fns/collections/create.js +1 -1
  81. package/dist/server-fns/collections/delete-locale.js +1 -1
  82. package/dist/server-fns/collections/delete-outcome.d.ts +30 -0
  83. package/dist/server-fns/collections/delete-outcome.js +34 -0
  84. package/dist/server-fns/collections/delete.d.ts +1 -4
  85. package/dist/server-fns/collections/delete.js +3 -5
  86. package/dist/server-fns/collections/duplicate.js +1 -1
  87. package/dist/server-fns/collections/get.js +1 -1
  88. package/dist/server-fns/collections/history.js +1 -1
  89. package/dist/server-fns/collections/index.d.ts +1 -0
  90. package/dist/server-fns/collections/index.js +1 -0
  91. package/dist/server-fns/collections/list.js +1 -1
  92. package/dist/server-fns/collections/reindex.js +1 -1
  93. package/dist/server-fns/collections/reorder.js +1 -1
  94. package/dist/server-fns/collections/restore-version.js +1 -1
  95. package/dist/server-fns/collections/stats.js +1 -1
  96. package/dist/server-fns/collections/status.js +1 -1
  97. package/dist/server-fns/collections/tree-mutation.d.ts +46 -0
  98. package/dist/server-fns/collections/tree-mutation.js +109 -0
  99. package/dist/server-fns/collections/tree-read.d.ts +6 -0
  100. package/dist/server-fns/collections/tree-read.js +15 -0
  101. package/dist/server-fns/collections/tree.d.ts +5 -4
  102. package/dist/server-fns/collections/tree.js +16 -13
  103. package/dist/server-fns/collections/update.js +3 -2
  104. package/dist/server-fns/collections/upload.js +1 -1
  105. package/dist/server-fns/i18n/set-locale.js +1 -1
  106. package/dist/server-fns/preview/disable.js +1 -1
  107. package/dist/server-fns/preview/enable.js +1 -2
  108. package/dist/server-fns/preview/state.js +1 -1
  109. package/dist/vite/client-hook-boundary.d.ts +19 -0
  110. package/dist/vite/client-hook-boundary.js +20 -0
  111. package/dist/{integrations/byline-public-client.d.ts → vite/index.d.ts} +1 -2
  112. package/dist/vite/index.js +1 -0
  113. package/package.json +15 -14
  114. package/src/admin-shell/admin-activity/list.tsx +13 -3
  115. package/src/admin-shell/admin-roles/delete.tsx +2 -1
  116. package/src/admin-shell/admin-roles/list.tsx +2 -1
  117. package/src/admin-shell/admin-users/delete.tsx +3 -2
  118. package/src/admin-shell/admin-users/list.tsx +9 -8
  119. package/src/admin-shell/chrome/admin-app-bar.tsx +2 -1
  120. package/src/admin-shell/chrome/admin-menu-drawer.tsx +13 -8
  121. package/src/admin-shell/chrome/admin-menu-provider.tsx +2 -1
  122. package/src/admin-shell/chrome/dashboard.tsx +4 -3
  123. package/src/admin-shell/chrome/sign-in-page.tsx +3 -3
  124. package/src/admin-shell/collections/create.tsx +4 -3
  125. package/src/admin-shell/collections/document-history.tsx +5 -0
  126. package/src/admin-shell/collections/edit.tsx +20 -13
  127. package/src/admin-shell/collections/history.tsx +6 -5
  128. package/src/admin-shell/collections/list.tsx +8 -7
  129. package/src/admin-shell/collections/restore-version-modal.tsx +2 -1
  130. package/src/admin-shell/collections/tree-list.tsx +78 -22
  131. package/src/admin-shell/collections/view-menu.tsx +9 -8
  132. package/src/i18n/resolve-locale.ts +1 -1
  133. package/src/index.ts +5 -6
  134. package/src/integrations/abilities.tsx +14 -4
  135. package/src/integrations/host-bridge.ts +56 -0
  136. package/src/integrations/serve-uploads.ts +6 -0
  137. package/src/integrations/start-errors.test.node.ts +22 -0
  138. package/src/integrations/start-errors.ts +1 -0
  139. package/src/routes/admin-path.test.node.ts +129 -0
  140. package/src/routes/admin-path.ts +66 -0
  141. package/src/routes/auth-routes.test.node.ts +39 -0
  142. package/src/routes/create-admin-account-route.tsx +3 -2
  143. package/src/routes/create-admin-activity-route.tsx +3 -2
  144. package/src/routes/create-admin-dashboard-route.tsx +2 -1
  145. package/src/routes/create-admin-layout-route.tsx +4 -4
  146. package/src/routes/create-admin-permissions-route.tsx +3 -2
  147. package/src/routes/create-admin-role-edit-route.tsx +7 -3
  148. package/src/routes/create-admin-roles-list-route.tsx +3 -2
  149. package/src/routes/create-admin-user-edit-route.tsx +7 -3
  150. package/src/routes/create-admin-users-list-route.tsx +3 -2
  151. package/src/routes/create-collection-api-route.tsx +8 -4
  152. package/src/routes/create-collection-create-route.tsx +7 -3
  153. package/src/routes/create-collection-edit-route.tsx +7 -3
  154. package/src/routes/create-collection-history-route.tsx +8 -4
  155. package/src/routes/create-collection-list-route.tsx +3 -2
  156. package/src/routes/create-sign-in-route.tsx +9 -3
  157. package/src/routes/index.ts +11 -0
  158. package/src/routes/sign-in-path.test.node.ts +79 -0
  159. package/src/routes/sign-in-path.ts +36 -0
  160. package/src/server-fns/admin-account/change-password.ts +1 -1
  161. package/src/server-fns/admin-account/get.ts +1 -1
  162. package/src/server-fns/admin-account/update.ts +1 -1
  163. package/src/server-fns/admin-activity/get.ts +1 -1
  164. package/src/server-fns/admin-permissions/get-role-abilities.ts +1 -1
  165. package/src/server-fns/admin-permissions/list-registered.ts +1 -1
  166. package/src/server-fns/admin-permissions/set-role-abilities.ts +1 -1
  167. package/src/server-fns/admin-permissions/who-has.ts +1 -1
  168. package/src/server-fns/admin-roles/create.ts +1 -1
  169. package/src/server-fns/admin-roles/delete.ts +1 -1
  170. package/src/server-fns/admin-roles/get.ts +1 -1
  171. package/src/server-fns/admin-roles/list.ts +1 -1
  172. package/src/server-fns/admin-roles/reorder.ts +1 -1
  173. package/src/server-fns/admin-roles/update.ts +1 -1
  174. package/src/server-fns/admin-users/create.ts +1 -1
  175. package/src/server-fns/admin-users/delete.ts +1 -1
  176. package/src/server-fns/admin-users/disable.ts +1 -1
  177. package/src/server-fns/admin-users/enable.ts +1 -1
  178. package/src/server-fns/admin-users/get-user-roles.ts +1 -1
  179. package/src/server-fns/admin-users/get.ts +1 -1
  180. package/src/server-fns/admin-users/list.ts +1 -1
  181. package/src/server-fns/admin-users/set-password.ts +1 -1
  182. package/src/server-fns/admin-users/set-user-roles.ts +1 -1
  183. package/src/server-fns/admin-users/update.ts +1 -1
  184. package/src/server-fns/ai/execute.ts +1 -2
  185. package/src/server-fns/auth/current-user.ts +1 -1
  186. package/src/server-fns/auth/sign-in.ts +1 -1
  187. package/src/server-fns/auth/sign-out.ts +5 -3
  188. package/src/server-fns/collections/audit.ts +1 -1
  189. package/src/server-fns/collections/copy-to-locale.ts +1 -1
  190. package/src/server-fns/collections/create.ts +1 -1
  191. package/src/server-fns/collections/delete-locale.ts +1 -1
  192. package/src/server-fns/collections/delete-outcome.test.node.ts +72 -0
  193. package/src/server-fns/collections/delete-outcome.ts +80 -0
  194. package/src/server-fns/collections/delete.ts +3 -2
  195. package/src/server-fns/collections/duplicate.ts +1 -1
  196. package/src/server-fns/collections/get.ts +3 -1
  197. package/src/server-fns/collections/history.ts +1 -1
  198. package/src/server-fns/collections/index.ts +1 -0
  199. package/src/server-fns/collections/list.ts +1 -1
  200. package/src/server-fns/collections/reindex.ts +1 -1
  201. package/src/server-fns/collections/reorder.ts +1 -1
  202. package/src/server-fns/collections/restore-version.ts +1 -1
  203. package/src/server-fns/collections/stats.ts +2 -1
  204. package/src/server-fns/collections/status.ts +1 -1
  205. package/src/server-fns/collections/tree-mutation.test.node.ts +225 -0
  206. package/src/server-fns/collections/tree-mutation.ts +165 -0
  207. package/src/server-fns/collections/tree-read.test.node.ts +46 -0
  208. package/src/server-fns/collections/tree-read.ts +26 -0
  209. package/src/server-fns/collections/tree.ts +27 -11
  210. package/src/server-fns/collections/update.ts +4 -1
  211. package/src/server-fns/collections/upload.ts +1 -1
  212. package/src/server-fns/i18n/set-locale.ts +1 -1
  213. package/src/server-fns/preview/disable.ts +1 -1
  214. package/src/server-fns/preview/enable.ts +1 -2
  215. package/src/server-fns/preview/state.ts +1 -1
  216. package/src/vite/client-hook-boundary.test.node.ts +50 -0
  217. package/src/vite/client-hook-boundary.ts +45 -0
  218. package/src/vite/index.ts +9 -0
  219. package/dist/auth/auth-context.d.ts +0 -37
  220. package/dist/auth/auth-context.js +0 -57
  221. package/dist/auth/auth-cookies.d.ts +0 -34
  222. package/dist/auth/auth-cookies.js +0 -46
  223. package/dist/auth/preview-cookies.d.ts +0 -19
  224. package/dist/auth/preview-cookies.js +0 -26
  225. package/dist/integrations/byline-client.d.ts +0 -24
  226. package/dist/integrations/byline-client.js +0 -25
  227. package/dist/integrations/byline-public-client.js +0 -15
  228. package/dist/integrations/byline-viewer-client.d.ts +0 -20
  229. package/dist/integrations/byline-viewer-client.js +0 -39
  230. package/src/auth/auth-context.test.node.ts +0 -215
  231. package/src/auth/auth-context.ts +0 -124
  232. package/src/auth/auth-cookies.ts +0 -113
  233. package/src/auth/preview-cookies.ts +0 -73
  234. package/src/integrations/byline-client.ts +0 -66
  235. package/src/integrations/byline-public-client.ts +0 -53
  236. package/src/integrations/byline-viewer-client.ts +0 -99
@@ -1,7 +1,7 @@
1
1
  import { createServerFn } from "@tanstack/react-start";
2
+ import { getAdminRequestContext } from "@byline/client/server";
2
3
  import { ERR_NOT_FOUND, getLogger, getServerConfig } from "@byline/core";
3
4
  import { createDocument } from "@byline/core/services";
4
- import { getAdminRequestContext } from "../../auth/auth-context.js";
5
5
  import { ensureCollection } from "../../integrations/api-utils.js";
6
6
  const createCollectionDocument = createServerFn({
7
7
  method: 'POST'
@@ -1,7 +1,7 @@
1
1
  import { createServerFn } from "@tanstack/react-start";
2
+ import { getAdminRequestContext } from "@byline/client/server";
2
3
  import { ERR_NOT_FOUND, getLogger, getServerConfig } from "@byline/core";
3
4
  import { deleteLocale } from "@byline/core/services";
4
- import { getAdminRequestContext } from "../../auth/auth-context.js";
5
5
  import { ensureCollection } from "../../integrations/api-utils.js";
6
6
  const deleteDocumentLocale = createServerFn({
7
7
  method: 'POST'
@@ -0,0 +1,30 @@
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
+ import type { DeleteDocumentResult, DeleteDocumentSideEffectCode, DeleteDocumentSideEffectPhase } from '@byline/core';
9
+ export type DeleteDocumentPublicSideEffectPhase = DeleteDocumentSideEffectPhase | 'unknown';
10
+ export type DeleteDocumentPublicSideEffectCode = DeleteDocumentSideEffectCode;
11
+ export interface DeleteDocumentPublicSideEffectFailure {
12
+ phase: DeleteDocumentPublicSideEffectPhase;
13
+ code: DeleteDocumentPublicSideEffectCode;
14
+ }
15
+ export type DeleteDocumentResponse = {
16
+ status: 'ok';
17
+ deletedVersionCount: number;
18
+ outcome: 'committed';
19
+ sideEffectFailures: [];
20
+ } | {
21
+ status: 'ok';
22
+ deletedVersionCount: number;
23
+ outcome: 'committed-with-side-effect-failures';
24
+ sideEffectFailures: [
25
+ DeleteDocumentPublicSideEffectFailure,
26
+ ...DeleteDocumentPublicSideEffectFailure[]
27
+ ];
28
+ };
29
+ export declare function toDeleteDocumentResponse(result: DeleteDocumentResult): DeleteDocumentResponse;
30
+ export declare function hasDeleteSideEffectFailures(result: Pick<DeleteDocumentResult, 'outcome'>): boolean;
@@ -0,0 +1,34 @@
1
+ import { ErrorCodes } from "@byline/core";
2
+ function sanitizePhase(phase) {
3
+ if ('storageCleanup' === phase || 'afterTreeChange' === phase || 'afterDelete' === phase) return phase;
4
+ return 'unknown';
5
+ }
6
+ function sanitizeCode(code) {
7
+ return code === ErrorCodes.STORAGE ? ErrorCodes.STORAGE : ErrorCodes.UNHANDLED;
8
+ }
9
+ function sanitizeFailure({ phase, code }) {
10
+ return {
11
+ phase: sanitizePhase(phase),
12
+ code: sanitizeCode(code)
13
+ };
14
+ }
15
+ function toDeleteDocumentResponse(result) {
16
+ if ('committed' === result.outcome) return {
17
+ status: 'ok',
18
+ ...result
19
+ };
20
+ const [firstFailure, ...remainingFailures] = result.sideEffectFailures;
21
+ return {
22
+ status: 'ok',
23
+ deletedVersionCount: result.deletedVersionCount,
24
+ outcome: result.outcome,
25
+ sideEffectFailures: [
26
+ sanitizeFailure(firstFailure),
27
+ ...remainingFailures.map(sanitizeFailure)
28
+ ]
29
+ };
30
+ }
31
+ function hasDeleteSideEffectFailures(result) {
32
+ return 'committed-with-side-effect-failures' === result.outcome;
33
+ }
34
+ export { hasDeleteSideEffectFailures, toDeleteDocumentResponse };
@@ -11,7 +11,4 @@ export declare const deleteDocument: import("@tanstack/react-start").RequiredFet
11
11
  }) => {
12
12
  collection: string;
13
13
  id: string;
14
- }, Promise<{
15
- status: 'ok';
16
- deletedVersionCount: number;
17
- }>>;
14
+ }, Promise<import("./delete-outcome.js").DeleteDocumentResponse>>;
@@ -1,8 +1,9 @@
1
1
  import { createServerFn } from "@tanstack/react-start";
2
+ import { getAdminRequestContext } from "@byline/client/server";
2
3
  import { ERR_NOT_FOUND, getLogger, getServerConfig, getUploadFields } from "@byline/core";
3
4
  import { deleteDocument } from "@byline/core/services";
4
- import { getAdminRequestContext } from "../../auth/auth-context.js";
5
5
  import { ensureCollection } from "../../integrations/api-utils.js";
6
+ import { toDeleteDocumentResponse } from "./delete-outcome.js";
6
7
  const delete_deleteDocument = createServerFn({
7
8
  method: 'POST'
8
9
  }).validator((input)=>input).handler(async ({ data: input })=>{
@@ -36,9 +37,6 @@ const delete_deleteDocument = createServerFn({
36
37
  const result = await deleteDocument(ctx, {
37
38
  documentId: id
38
39
  });
39
- return {
40
- status: 'ok',
41
- deletedVersionCount: result.deletedVersionCount
42
- };
40
+ return toDeleteDocumentResponse(result);
43
41
  });
44
42
  export { delete_deleteDocument as deleteDocument };
@@ -1,7 +1,7 @@
1
1
  import { createServerFn } from "@tanstack/react-start";
2
+ import { getAdminRequestContext } from "@byline/client/server";
2
3
  import { ERR_NOT_FOUND, getLogger, getServerConfig } from "@byline/core";
3
4
  import { duplicateDocument } from "@byline/core/services";
4
- import { getAdminRequestContext } from "../../auth/auth-context.js";
5
5
  import { ensureCollection } from "../../integrations/api-utils.js";
6
6
  const duplicateCollectionDocument = createServerFn({
7
7
  method: 'POST'
@@ -1,7 +1,7 @@
1
1
  import { createServerFn } from "@tanstack/react-start";
2
+ import { getAdminBylineClient } from "@byline/client/server";
2
3
  import { BylineError, ERR_NOT_FOUND, ErrorCodes, buildRelationSummaryPopulateMap, getCollectionAdminConfig, getCollectionDefinition, getCollectionSchemasForPath, getLogger, getServerConfig } from "@byline/core";
3
4
  import { ensureCollection } from "../../integrations/api-utils.js";
4
- import { getAdminBylineClient } from "../../integrations/byline-client.js";
5
5
  import { serialise } from "./utils.js";
6
6
  const getDocumentFn = createServerFn({
7
7
  method: 'GET'
@@ -1,7 +1,7 @@
1
1
  import { createServerFn } from "@tanstack/react-start";
2
+ import { getAdminBylineClient } from "@byline/client/server";
2
3
  import { ERR_NOT_FOUND, getCollectionSchemasForPath, getLogger } from "@byline/core";
3
4
  import { ensureCollection } from "../../integrations/api-utils.js";
4
- import { getAdminBylineClient } from "../../integrations/byline-client.js";
5
5
  import { resolveActorLabels } from "./actors.js";
6
6
  import { serialise } from "./utils.js";
7
7
  const getCollectionDocumentHistory = createServerFn({
@@ -9,6 +9,7 @@ export * from './copy-to-locale';
9
9
  export * from './create';
10
10
  export * from './delete';
11
11
  export * from './delete-locale';
12
+ export * from './delete-outcome';
12
13
  export * from './duplicate';
13
14
  export * from './get';
14
15
  export * from './history';
@@ -3,6 +3,7 @@ export * from "./copy-to-locale.js";
3
3
  export * from "./create.js";
4
4
  export * from "./delete.js";
5
5
  export * from "./delete-locale.js";
6
+ export * from "./delete-outcome.js";
6
7
  export * from "./duplicate.js";
7
8
  export * from "./get.js";
8
9
  export * from "./history.js";
@@ -1,7 +1,7 @@
1
1
  import { createServerFn } from "@tanstack/react-start";
2
+ import { getAdminBylineClient } from "@byline/client/server";
2
3
  import { ERR_NOT_FOUND, buildRelationSummaryPopulateMap, getCollectionAdminConfig, getCollectionDefinition, getCollectionSchemasForPath, getLogger, getServerConfig } from "@byline/core";
3
4
  import { ensureCollection } from "../../integrations/api-utils.js";
4
- import { getAdminBylineClient } from "../../integrations/byline-client.js";
5
5
  import { serialise } from "./utils.js";
6
6
  const getCollectionDocuments = createServerFn({
7
7
  method: 'GET'
@@ -1,7 +1,7 @@
1
1
  import { createServerFn } from "@tanstack/react-start";
2
+ import { getAdminBylineClient } from "@byline/client/server";
2
3
  import { ERR_NOT_FOUND, getLogger } from "@byline/core";
3
4
  import { ensureCollection } from "../../integrations/api-utils.js";
4
- import { getAdminBylineClient } from "../../integrations/byline-client.js";
5
5
  const reindexCollection = createServerFn({
6
6
  method: 'POST'
7
7
  }).validator((input)=>input).handler(async ({ data })=>{
@@ -1,6 +1,6 @@
1
1
  import { createServerFn } from "@tanstack/react-start";
2
+ import { getAdminRequestContext } from "@byline/client/server";
2
3
  import { ERR_NOT_FOUND, ERR_VALIDATION, assertActorCanPerform, generateKeyBetween, generateNKeysBetween, getLogger, getServerConfig } from "@byline/core";
3
- import { getAdminRequestContext } from "../../auth/auth-context.js";
4
4
  import { ensureCollection } from "../../integrations/api-utils.js";
5
5
  const reorderCollectionDocument = createServerFn({
6
6
  method: 'POST'
@@ -1,7 +1,7 @@
1
1
  import { createServerFn } from "@tanstack/react-start";
2
+ import { getAdminRequestContext } from "@byline/client/server";
2
3
  import { ERR_NOT_FOUND, getLogger, getServerConfig } from "@byline/core";
3
4
  import { restoreDocumentVersion } from "@byline/core/services";
4
- import { getAdminRequestContext } from "../../auth/auth-context.js";
5
5
  import { ensureCollection } from "../../integrations/api-utils.js";
6
6
  const restore_version_restoreDocumentVersion = createServerFn({
7
7
  method: 'POST'
@@ -1,6 +1,6 @@
1
1
  import { createServerFn } from "@tanstack/react-start";
2
+ import { getAdminBylineClient } from "@byline/client/server";
2
3
  import { ensureCollection } from "../../integrations/api-utils.js";
3
- import { getAdminBylineClient } from "../../integrations/byline-client.js";
4
4
  const getCollectionStatsFn = createServerFn({
5
5
  method: 'GET'
6
6
  }).validator((input)=>input).handler(async ({ data })=>{
@@ -1,7 +1,7 @@
1
1
  import { createServerFn } from "@tanstack/react-start";
2
+ import { getAdminRequestContext } from "@byline/client/server";
2
3
  import { ERR_NOT_FOUND, getLogger, getServerConfig } from "@byline/core";
3
4
  import { changeDocumentStatus, unpublishDocument } from "@byline/core/services";
4
- import { getAdminRequestContext } from "../../auth/auth-context.js";
5
5
  import { ensureCollection } from "../../integrations/api-utils.js";
6
6
  const updateDocumentStatus = createServerFn({
7
7
  method: 'POST'
@@ -0,0 +1,46 @@
1
+ import type { CollectionHandle, PlaceTreeNodeOptions, RemoveFromTreeOptions } from '@byline/client';
2
+ /** Prefer the code; the marker survives transports that reconstruct a code-less Error. */
3
+ export declare function isTreeMutationConflict(error: unknown): boolean;
4
+ /** Detect when tree/audit committed even if transport reconstruction dropped the code. */
5
+ export declare function isCommittedTreeHookFailure(error: unknown): boolean;
6
+ export type AdminTreeMoveOutcome = {
7
+ status: 'ok';
8
+ } | {
9
+ status: 'suppressed';
10
+ } | {
11
+ status: 'mutation-failed';
12
+ error: unknown;
13
+ refreshError?: unknown;
14
+ } | {
15
+ status: 'committed-hook-failed';
16
+ error: unknown;
17
+ refreshError?: unknown;
18
+ } | {
19
+ status: 'refresh-failed';
20
+ error: unknown;
21
+ };
22
+ export interface AdminTreeMoveUiEffects {
23
+ rollback: boolean;
24
+ preserveOptimistic: boolean;
25
+ structuralFailure: 'conflict' | 'generic' | null;
26
+ committedHookWarning: boolean;
27
+ refreshWarning: boolean;
28
+ }
29
+ /** Pure UI policy for every mutation/refresh outcome. */
30
+ export declare function getAdminTreeMoveUiEffects(outcome: AdminTreeMoveOutcome): AdminTreeMoveUiEffects;
31
+ /** Preserve a committed optimistic move until a later loader returns new row data. */
32
+ export declare function shouldSyncAdminTreeRows(rows: unknown, preservedRows: unknown, isMoving: boolean): boolean;
33
+ /** Keep mutation and canonical-refresh failures distinct for optimistic tree UIs. */
34
+ export declare function executeAdminTreeMove(mutate: () => Promise<unknown>, refresh: () => Promise<unknown>): Promise<AdminTreeMoveOutcome>;
35
+ export interface AdminTreeMoveController {
36
+ isMoving(): boolean;
37
+ execute(mutate: () => Promise<unknown>, refresh: () => Promise<unknown>): Promise<AdminTreeMoveOutcome>;
38
+ }
39
+ /** Single-flight controller shared by pointer and keyboard tree moves. */
40
+ export declare function createAdminTreeMoveController(): AdminTreeMoveController;
41
+ /** Admin retries reconcile post-commit tree hooks unless explicitly disabled. */
42
+ export declare function placeAdminTreeNode(handle: Pick<CollectionHandle, 'placeTreeNode'>, documentId: string, options: PlaceTreeNodeOptions): Promise<{
43
+ orderKey: string;
44
+ }>;
45
+ /** Admin retries reconcile post-commit tree hooks unless explicitly disabled. */
46
+ export declare function removeAdminTreeNode(handle: Pick<CollectionHandle, 'removeFromTree'>, documentId: string, options?: RemoveFromTreeOptions): Promise<void>;
@@ -0,0 +1,109 @@
1
+ import { ErrorCodes, TREE_HOOK_COMMITTED_MARKER, TREE_PLACEMENT_STALE_MARKER } from "@byline/core";
2
+ function hasErrorCode(error, code) {
3
+ return 'object' == typeof error && null != error && 'code' in error && error.code === code;
4
+ }
5
+ function hasMessageMarker(error, marker) {
6
+ return error instanceof Error && error.message.startsWith(marker);
7
+ }
8
+ function isTreeMutationConflict(error) {
9
+ if (hasErrorCode(error, ErrorCodes.CONFLICT)) return true;
10
+ return hasMessageMarker(error, TREE_PLACEMENT_STALE_MARKER);
11
+ }
12
+ function isCommittedTreeHookFailure(error) {
13
+ if (hasErrorCode(error, ErrorCodes.TREE_HOOK_COMMITTED)) return true;
14
+ return hasMessageMarker(error, TREE_HOOK_COMMITTED_MARKER);
15
+ }
16
+ function getAdminTreeMoveUiEffects(outcome) {
17
+ if ('mutation-failed' === outcome.status) return {
18
+ rollback: true,
19
+ preserveOptimistic: false,
20
+ structuralFailure: isTreeMutationConflict(outcome.error) ? 'conflict' : 'generic',
21
+ committedHookWarning: false,
22
+ refreshWarning: null != outcome.refreshError
23
+ };
24
+ if ('committed-hook-failed' === outcome.status) return {
25
+ rollback: false,
26
+ preserveOptimistic: null != outcome.refreshError,
27
+ structuralFailure: null,
28
+ committedHookWarning: true,
29
+ refreshWarning: null != outcome.refreshError
30
+ };
31
+ if ('refresh-failed' === outcome.status) return {
32
+ rollback: false,
33
+ preserveOptimistic: true,
34
+ structuralFailure: null,
35
+ committedHookWarning: false,
36
+ refreshWarning: true
37
+ };
38
+ return {
39
+ rollback: 'suppressed' === outcome.status,
40
+ preserveOptimistic: false,
41
+ structuralFailure: null,
42
+ committedHookWarning: false,
43
+ refreshWarning: false
44
+ };
45
+ }
46
+ function shouldSyncAdminTreeRows(rows, preservedRows, isMoving) {
47
+ return !isMoving && rows !== preservedRows;
48
+ }
49
+ async function executeAdminTreeMove(mutate, refresh) {
50
+ try {
51
+ await mutate();
52
+ } catch (error) {
53
+ const status = isCommittedTreeHookFailure(error) ? 'committed-hook-failed' : 'mutation-failed';
54
+ try {
55
+ await refresh();
56
+ return {
57
+ status,
58
+ error
59
+ };
60
+ } catch (refreshError) {
61
+ return {
62
+ status,
63
+ error,
64
+ refreshError
65
+ };
66
+ }
67
+ }
68
+ try {
69
+ await refresh();
70
+ return {
71
+ status: 'ok'
72
+ };
73
+ } catch (error) {
74
+ return {
75
+ status: 'refresh-failed',
76
+ error
77
+ };
78
+ }
79
+ }
80
+ function createAdminTreeMoveController() {
81
+ let moving = false;
82
+ return {
83
+ isMoving: ()=>moving,
84
+ execute: async (mutate, refresh)=>{
85
+ if (moving) return {
86
+ status: 'suppressed'
87
+ };
88
+ moving = true;
89
+ try {
90
+ return await executeAdminTreeMove(mutate, refresh);
91
+ } finally{
92
+ moving = false;
93
+ }
94
+ }
95
+ };
96
+ }
97
+ function placeAdminTreeNode(handle, documentId, options) {
98
+ return handle.placeTreeNode(documentId, {
99
+ ...options,
100
+ reconcile: options.reconcile ?? true
101
+ });
102
+ }
103
+ function removeAdminTreeNode(handle, documentId, options = {}) {
104
+ return handle.removeFromTree(documentId, {
105
+ ...options,
106
+ reconcile: options.reconcile ?? true
107
+ });
108
+ }
109
+ export { createAdminTreeMoveController, executeAdminTreeMove, getAdminTreeMoveUiEffects, isCommittedTreeHookFailure, isTreeMutationConflict, placeAdminTreeNode, removeAdminTreeNode, shouldSyncAdminTreeRows };
@@ -0,0 +1,6 @@
1
+ import type { ClientDocument, CollectionHandle, TreeParentResult } from '@byline/client';
2
+ import type { ReadContext } from '@byline/core';
3
+ /** Admin tree placement reads must include drafts. */
4
+ export declare function getAdminTreeParent(handle: Pick<CollectionHandle, 'getTreeParent'>, documentId: string): Promise<TreeParentResult>;
5
+ /** Find unplaced nodes through the same row scope as the structural tree read. */
6
+ export declare function getAdminUnplacedTreeDocuments(handle: Pick<CollectionHandle, 'find'>, placed: ReadonlySet<string>, readContext: ReadContext, locale?: string): Promise<ClientDocument[]>;
@@ -0,0 +1,15 @@
1
+ function getAdminTreeParent(handle, documentId) {
2
+ return handle.getTreeParent(documentId, {
3
+ status: 'any'
4
+ });
5
+ }
6
+ async function getAdminUnplacedTreeDocuments(handle, placed, readContext, locale) {
7
+ const all = await handle.find({
8
+ status: 'any',
9
+ locale,
10
+ pageSize: 1000,
11
+ _readContext: readContext
12
+ });
13
+ return all.docs.filter((doc)=>!placed.has(doc.id));
14
+ }
15
+ export { getAdminTreeParent, getAdminUnplacedTreeDocuments };
@@ -11,12 +11,14 @@ export declare const placeTreeNode: import("@tanstack/react-start").RequiredFetc
11
11
  parentDocumentId: string | null;
12
12
  beforeDocumentId?: string | null;
13
13
  afterDocumentId?: string | null;
14
+ reconcile?: boolean;
14
15
  }) => {
15
16
  collection: string;
16
17
  documentId: string;
17
18
  parentDocumentId: string | null;
18
19
  beforeDocumentId?: string | null;
19
20
  afterDocumentId?: string | null;
21
+ reconcile?: boolean;
20
22
  }, Promise<{
21
23
  status: 'ok';
22
24
  orderKey: string;
@@ -24,9 +26,11 @@ export declare const placeTreeNode: import("@tanstack/react-start").RequiredFetc
24
26
  export declare const removeFromTree: import("@tanstack/react-start").RequiredFetcher<undefined, (input: {
25
27
  collection: string;
26
28
  documentId: string;
29
+ reconcile?: boolean;
27
30
  }) => {
28
31
  collection: string;
29
32
  documentId: string;
33
+ reconcile?: boolean;
30
34
  }, Promise<{
31
35
  status: 'ok';
32
36
  }>>;
@@ -47,10 +51,7 @@ export declare const getTreeParent: import("@tanstack/react-start").RequiredFetc
47
51
  }) => {
48
52
  collection: string;
49
53
  documentId: string;
50
- }, Promise<{
51
- placed: boolean;
52
- parentDocumentId: string | null;
53
- }>>;
54
+ }, Promise<import("@byline/client").TreeParentResult>>;
54
55
  export interface CollectionTreeRow {
55
56
  id: string;
56
57
  /** Parent document id, or `null` for a root or unplaced node. Drives the
@@ -1,7 +1,9 @@
1
1
  import { createServerFn } from "@tanstack/react-start";
2
- import { ERR_NOT_FOUND, getLogger } from "@byline/core";
2
+ import { getAdminBylineClient } from "@byline/client/server";
3
+ import { ERR_NOT_FOUND, createReadContext, getLogger } from "@byline/core";
3
4
  import { ensureCollection } from "../../integrations/api-utils.js";
4
- import { getAdminBylineClient } from "../../integrations/byline-client.js";
5
+ import { placeAdminTreeNode, removeAdminTreeNode } from "./tree-mutation.js";
6
+ import { getAdminTreeParent, getAdminUnplacedTreeDocuments } from "./tree-read.js";
5
7
  const placeTreeNode = createServerFn({
6
8
  method: 'POST'
7
9
  }).validator((input)=>input).handler(async ({ data })=>{
@@ -14,10 +16,11 @@ const placeTreeNode = createServerFn({
14
16
  }
15
17
  }).log(getLogger());
16
18
  const handle = getAdminBylineClient().collection(path);
17
- const result = await handle.placeTreeNode(documentId, {
19
+ const result = await placeAdminTreeNode(handle, documentId, {
18
20
  parentDocumentId: data.parentDocumentId,
19
21
  beforeDocumentId: data.beforeDocumentId ?? null,
20
- afterDocumentId: data.afterDocumentId ?? null
22
+ afterDocumentId: data.afterDocumentId ?? null,
23
+ reconcile: data.reconcile
21
24
  });
22
25
  return {
23
26
  status: 'ok',
@@ -35,7 +38,9 @@ const removeFromTree = createServerFn({
35
38
  collectionPath: path
36
39
  }
37
40
  }).log(getLogger());
38
- await getAdminBylineClient().collection(path).removeFromTree(documentId);
41
+ await removeAdminTreeNode(getAdminBylineClient().collection(path), documentId, {
42
+ reconcile: data.reconcile
43
+ });
39
44
  return {
40
45
  status: 'ok'
41
46
  };
@@ -76,7 +81,7 @@ const getTreeParent = createServerFn({
76
81
  collectionPath: path
77
82
  }
78
83
  }).log(getLogger());
79
- return getAdminBylineClient().collection(path).getTreeParent(documentId);
84
+ return getAdminTreeParent(getAdminBylineClient().collection(path), documentId);
80
85
  });
81
86
  const getCollectionTree = createServerFn({
82
87
  method: 'GET'
@@ -90,9 +95,11 @@ const getCollectionTree = createServerFn({
90
95
  }
91
96
  }).log(getLogger());
92
97
  const handle = getAdminBylineClient().collection(path);
98
+ const readContext = createReadContext();
93
99
  const forest = await handle.getSubtree({
94
100
  status: 'any',
95
- locale: data.locale
101
+ locale: data.locale,
102
+ _readContext: readContext
96
103
  });
97
104
  const rows = [];
98
105
  const placed = new Set();
@@ -115,12 +122,8 @@ const getCollectionTree = createServerFn({
115
122
  }
116
123
  };
117
124
  walk(forest, 0, null);
118
- const all = await handle.find({
119
- status: 'any',
120
- pageSize: 1000,
121
- _bypassBeforeRead: true
122
- });
123
- for (const doc of all.docs)if (!placed.has(doc.id)) rows.push({
125
+ const unplaced = await getAdminUnplacedTreeDocuments(handle, placed, readContext, data.locale);
126
+ for (const doc of unplaced)rows.push({
124
127
  id: doc.id,
125
128
  parentId: null,
126
129
  depth: 0,
@@ -1,7 +1,7 @@
1
1
  import { createServerFn } from "@tanstack/react-start";
2
+ import { getAdminRequestContext } from "@byline/client/server";
2
3
  import { ERR_NOT_FOUND, getLogger, getServerConfig } from "@byline/core";
3
4
  import { updateDocumentSystemFields, updateDocumentWithPatches } from "@byline/core/services";
4
- import { getAdminRequestContext } from "../../auth/auth-context.js";
5
5
  import { ensureCollection } from "../../integrations/api-utils.js";
6
6
  const updateCollectionDocumentWithPatches = createServerFn({
7
7
  method: 'POST'
@@ -65,7 +65,8 @@ const updateCollectionDocumentSystemFields = createServerFn({
65
65
  documentId: id,
66
66
  locale: locale ?? serverConfig.i18n.content.defaultLocale,
67
67
  path: explicitPath,
68
- availableLocales
68
+ availableLocales,
69
+ reconcile: true
69
70
  });
70
71
  return {
71
72
  status: 'ok'
@@ -1,9 +1,9 @@
1
1
  import { createServerFn } from "@tanstack/react-start";
2
+ import { getAdminRequestContext } from "@byline/client/server";
2
3
  import { ERR_NOT_FOUND, ERR_VALIDATION, getServerConfig, getUploadFields } from "@byline/core";
3
4
  import { extractImageMeta, generateImageVariants, isBypassMimeType } from "@byline/core/image";
4
5
  import { getLogger, withLogContext } from "@byline/core/logger";
5
6
  import { uploadField } from "@byline/core/services";
6
- import { getAdminRequestContext } from "../../auth/auth-context.js";
7
7
  import { ensureCollection } from "../../integrations/api-utils.js";
8
8
  function parseUploadFormData(data) {
9
9
  if (!(data instanceof FormData)) throw new Error('Expected FormData upload payload.');
@@ -1,7 +1,7 @@
1
1
  import { createServerFn } from "@tanstack/react-start";
2
2
  import { setPreferredLocaleCommand } from "@byline/admin/admin-account";
3
3
  import { AuthError, AuthErrorCodes } from "@byline/auth";
4
- import { getAdminRequestContext } from "../../auth/auth-context.js";
4
+ import { getAdminRequestContext } from "@byline/client/server";
5
5
  import { clearAdminLocaleCookie, setAdminLocaleCookie } from "../../i18n/locale-cookie.js";
6
6
  import { bylineCore } from "../../integrations/byline-core.js";
7
7
  const setInterfaceLocaleFn = createServerFn({
@@ -1,5 +1,5 @@
1
1
  import { createServerFn } from "@tanstack/react-start";
2
- import { clearPreviewCookie } from "../../auth/preview-cookies.js";
2
+ import { clearPreviewCookie } from "@byline/client/server";
3
3
  const disablePreviewModeFn = createServerFn({
4
4
  method: 'POST'
5
5
  }).handler(async ()=>{
@@ -1,6 +1,5 @@
1
1
  import { createServerFn } from "@tanstack/react-start";
2
- import { getAdminRequestContext } from "../../auth/auth-context.js";
3
- import { setPreviewCookie } from "../../auth/preview-cookies.js";
2
+ import { getAdminRequestContext, setPreviewCookie } from "@byline/client/server";
4
3
  const enablePreviewModeFn = createServerFn({
5
4
  method: 'POST'
6
5
  }).handler(async ()=>{
@@ -1,5 +1,5 @@
1
1
  import { createServerFn } from "@tanstack/react-start";
2
- import { readPreviewCookie } from "../../auth/preview-cookies.js";
2
+ import { readPreviewCookie } from "@byline/client/server";
3
3
  const getPreviewStateFn = createServerFn({
4
4
  method: 'GET'
5
5
  }).handler(async ()=>({
@@ -0,0 +1,19 @@
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
+ * Production client-bundle guard for server-only Byline lifecycle modules.
10
+ *
11
+ * Collection schemas are isomorphic, but registered lifecycle hooks may
12
+ * import Node APIs, caches, storage SDKs, and other server-only dependencies.
13
+ * This Vite plugin inspects emitted client chunks and fails the build if a
14
+ * hook implementation, server hook registry, or shared lifecycle helper
15
+ * becomes reachable from the browser bundle.
16
+ */
17
+ import type { Plugin } from 'vite';
18
+ export declare function findServerHookModules(moduleIds: Iterable<string>): string[];
19
+ export declare function bylineClientHookBoundary(): Plugin;
@@ -0,0 +1,20 @@
1
+ const SERVER_HOOK_MODULE = /\/byline\/collections\/(?:.+\/)?(?:hooks|[^/]+-hooks|[^/]+-lifecycle-hooks|[^/]+-side-effects)\.[cm]?[jt]sx?$/;
2
+ function findServerHookModules(moduleIds) {
3
+ return [
4
+ ...moduleIds
5
+ ].filter((moduleId)=>{
6
+ const normalized = moduleId.replaceAll('\\', '/').split('?', 1)[0];
7
+ return SERVER_HOOK_MODULE.test(normalized);
8
+ });
9
+ }
10
+ function bylineClientHookBoundary() {
11
+ return {
12
+ name: 'byline:client-hook-boundary',
13
+ generateBundle (_options, bundle) {
14
+ if (this.environment?.name !== 'client') return;
15
+ const leaked = findServerHookModules(Object.values(bundle).flatMap((output)=>'chunk' === output.type ? Object.keys(output.modules) : []));
16
+ if (leaked.length > 0) this.error(`server lifecycle modules entered the client bundle:\n${leaked.join('\n')}`);
17
+ }
18
+ };
19
+ }
20
+ export { bylineClientHookBoundary, findServerHookModules };
@@ -5,5 +5,4 @@
5
5
  *
6
6
  * Copyright (c) Infonomic Company Limited
7
7
  */
8
- import { type BylineClient } from '@byline/client';
9
- export declare function getPublicBylineClient(): BylineClient;
8
+ export { bylineClientHookBoundary } from './client-hook-boundary.js';
@@ -0,0 +1 @@
1
+ export { bylineClientHookBoundary } from "./client-hook-boundary.js";