@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.
- package/dist/admin-shell/admin-activity/list.js +15 -5
- package/dist/admin-shell/admin-roles/delete.js +2 -1
- package/dist/admin-shell/admin-roles/list.js +2 -1
- package/dist/admin-shell/admin-users/delete.js +2 -1
- package/dist/admin-shell/admin-users/list.js +4 -7
- package/dist/admin-shell/chrome/admin-app-bar.js +2 -1
- package/dist/admin-shell/chrome/admin-menu-drawer.js +9 -8
- package/dist/admin-shell/chrome/admin-menu-provider.js +2 -1
- package/dist/admin-shell/chrome/dashboard.js +4 -3
- package/dist/admin-shell/chrome/sign-in-page.d.ts +2 -2
- package/dist/admin-shell/chrome/sign-in-page.js +2 -2
- package/dist/admin-shell/collections/create.js +4 -3
- package/dist/admin-shell/collections/document-history.js +6 -1
- package/dist/admin-shell/collections/edit.js +18 -14
- package/dist/admin-shell/collections/history.js +5 -4
- package/dist/admin-shell/collections/list.js +8 -7
- package/dist/admin-shell/collections/restore-version-modal.js +2 -1
- package/dist/admin-shell/collections/tree-list.js +53 -17
- package/dist/admin-shell/collections/view-menu.js +9 -8
- package/dist/i18n/resolve-locale.js +1 -1
- package/dist/index.d.ts +5 -6
- package/dist/integrations/abilities.js +8 -7
- package/dist/integrations/host-bridge.d.ts +13 -0
- package/dist/integrations/host-bridge.js +22 -0
- package/dist/integrations/serve-uploads.d.ts +1 -0
- package/dist/integrations/serve-uploads.js +1 -0
- package/dist/integrations/start-errors.js +2 -1
- package/dist/routes/admin-path.d.ts +22 -0
- package/dist/routes/admin-path.js +35 -0
- package/dist/routes/create-admin-account-route.js +3 -2
- package/dist/routes/create-admin-activity-route.js +3 -2
- package/dist/routes/create-admin-dashboard-route.js +2 -1
- package/dist/routes/create-admin-layout-route.d.ts +1 -1
- package/dist/routes/create-admin-layout-route.js +3 -1
- package/dist/routes/create-admin-permissions-route.js +3 -2
- package/dist/routes/create-admin-role-edit-route.js +4 -3
- package/dist/routes/create-admin-roles-list-route.js +3 -2
- package/dist/routes/create-admin-user-edit-route.js +4 -3
- package/dist/routes/create-admin-users-list-route.js +3 -2
- package/dist/routes/create-collection-api-route.js +5 -4
- package/dist/routes/create-collection-create-route.js +4 -3
- package/dist/routes/create-collection-edit-route.js +4 -3
- package/dist/routes/create-collection-history-route.js +5 -4
- package/dist/routes/create-collection-list-route.js +3 -2
- package/dist/routes/create-sign-in-route.js +3 -2
- package/dist/routes/index.d.ts +3 -0
- package/dist/routes/index.js +2 -0
- package/dist/routes/sign-in-path.d.ts +13 -0
- package/dist/routes/sign-in-path.js +19 -0
- package/dist/server-fns/admin-account/change-password.js +1 -1
- package/dist/server-fns/admin-account/get.js +1 -1
- package/dist/server-fns/admin-account/update.js +1 -1
- package/dist/server-fns/admin-activity/get.js +1 -1
- package/dist/server-fns/admin-permissions/get-role-abilities.js +1 -1
- package/dist/server-fns/admin-permissions/list-registered.js +1 -1
- package/dist/server-fns/admin-permissions/set-role-abilities.js +1 -1
- package/dist/server-fns/admin-permissions/who-has.js +1 -1
- package/dist/server-fns/admin-roles/create.js +1 -1
- package/dist/server-fns/admin-roles/delete.js +1 -1
- package/dist/server-fns/admin-roles/get.js +1 -1
- package/dist/server-fns/admin-roles/list.js +1 -1
- package/dist/server-fns/admin-roles/reorder.js +1 -1
- package/dist/server-fns/admin-roles/update.js +1 -1
- package/dist/server-fns/admin-users/create.js +1 -1
- package/dist/server-fns/admin-users/delete.js +1 -1
- package/dist/server-fns/admin-users/disable.js +1 -1
- package/dist/server-fns/admin-users/enable.js +1 -1
- package/dist/server-fns/admin-users/get-user-roles.js +1 -1
- package/dist/server-fns/admin-users/get.js +1 -1
- package/dist/server-fns/admin-users/list.js +1 -1
- package/dist/server-fns/admin-users/set-password.js +1 -1
- package/dist/server-fns/admin-users/set-user-roles.js +1 -1
- package/dist/server-fns/admin-users/update.js +1 -1
- package/dist/server-fns/ai/execute.js +1 -1
- package/dist/server-fns/auth/current-user.js +1 -1
- package/dist/server-fns/auth/sign-in.js +1 -1
- package/dist/server-fns/auth/sign-out.js +1 -2
- package/dist/server-fns/collections/audit.js +1 -1
- package/dist/server-fns/collections/copy-to-locale.js +1 -1
- package/dist/server-fns/collections/create.js +1 -1
- package/dist/server-fns/collections/delete-locale.js +1 -1
- package/dist/server-fns/collections/delete-outcome.d.ts +30 -0
- package/dist/server-fns/collections/delete-outcome.js +34 -0
- package/dist/server-fns/collections/delete.d.ts +1 -4
- package/dist/server-fns/collections/delete.js +3 -5
- package/dist/server-fns/collections/duplicate.js +1 -1
- package/dist/server-fns/collections/get.js +1 -1
- package/dist/server-fns/collections/history.js +1 -1
- package/dist/server-fns/collections/index.d.ts +1 -0
- package/dist/server-fns/collections/index.js +1 -0
- package/dist/server-fns/collections/list.js +1 -1
- package/dist/server-fns/collections/reindex.js +1 -1
- package/dist/server-fns/collections/reorder.js +1 -1
- package/dist/server-fns/collections/restore-version.js +1 -1
- package/dist/server-fns/collections/stats.js +1 -1
- package/dist/server-fns/collections/status.js +1 -1
- package/dist/server-fns/collections/tree-mutation.d.ts +46 -0
- package/dist/server-fns/collections/tree-mutation.js +109 -0
- package/dist/server-fns/collections/tree-read.d.ts +6 -0
- package/dist/server-fns/collections/tree-read.js +15 -0
- package/dist/server-fns/collections/tree.d.ts +5 -4
- package/dist/server-fns/collections/tree.js +16 -13
- package/dist/server-fns/collections/update.js +3 -2
- package/dist/server-fns/collections/upload.js +1 -1
- package/dist/server-fns/i18n/set-locale.js +1 -1
- package/dist/server-fns/preview/disable.js +1 -1
- package/dist/server-fns/preview/enable.js +1 -2
- package/dist/server-fns/preview/state.js +1 -1
- package/dist/vite/client-hook-boundary.d.ts +19 -0
- package/dist/vite/client-hook-boundary.js +20 -0
- package/dist/{integrations/byline-public-client.d.ts → vite/index.d.ts} +1 -2
- package/dist/vite/index.js +1 -0
- package/package.json +15 -14
- package/src/admin-shell/admin-activity/list.tsx +13 -3
- package/src/admin-shell/admin-roles/delete.tsx +2 -1
- package/src/admin-shell/admin-roles/list.tsx +2 -1
- package/src/admin-shell/admin-users/delete.tsx +3 -2
- package/src/admin-shell/admin-users/list.tsx +9 -8
- package/src/admin-shell/chrome/admin-app-bar.tsx +2 -1
- package/src/admin-shell/chrome/admin-menu-drawer.tsx +13 -8
- package/src/admin-shell/chrome/admin-menu-provider.tsx +2 -1
- package/src/admin-shell/chrome/dashboard.tsx +4 -3
- package/src/admin-shell/chrome/sign-in-page.tsx +3 -3
- package/src/admin-shell/collections/create.tsx +4 -3
- package/src/admin-shell/collections/document-history.tsx +5 -0
- package/src/admin-shell/collections/edit.tsx +20 -13
- package/src/admin-shell/collections/history.tsx +6 -5
- package/src/admin-shell/collections/list.tsx +8 -7
- package/src/admin-shell/collections/restore-version-modal.tsx +2 -1
- package/src/admin-shell/collections/tree-list.tsx +78 -22
- package/src/admin-shell/collections/view-menu.tsx +9 -8
- package/src/i18n/resolve-locale.ts +1 -1
- package/src/index.ts +5 -6
- package/src/integrations/abilities.tsx +14 -4
- package/src/integrations/host-bridge.ts +56 -0
- package/src/integrations/serve-uploads.ts +6 -0
- package/src/integrations/start-errors.test.node.ts +22 -0
- package/src/integrations/start-errors.ts +1 -0
- package/src/routes/admin-path.test.node.ts +129 -0
- package/src/routes/admin-path.ts +66 -0
- package/src/routes/auth-routes.test.node.ts +39 -0
- package/src/routes/create-admin-account-route.tsx +3 -2
- package/src/routes/create-admin-activity-route.tsx +3 -2
- package/src/routes/create-admin-dashboard-route.tsx +2 -1
- package/src/routes/create-admin-layout-route.tsx +4 -4
- package/src/routes/create-admin-permissions-route.tsx +3 -2
- package/src/routes/create-admin-role-edit-route.tsx +7 -3
- package/src/routes/create-admin-roles-list-route.tsx +3 -2
- package/src/routes/create-admin-user-edit-route.tsx +7 -3
- package/src/routes/create-admin-users-list-route.tsx +3 -2
- package/src/routes/create-collection-api-route.tsx +8 -4
- package/src/routes/create-collection-create-route.tsx +7 -3
- package/src/routes/create-collection-edit-route.tsx +7 -3
- package/src/routes/create-collection-history-route.tsx +8 -4
- package/src/routes/create-collection-list-route.tsx +3 -2
- package/src/routes/create-sign-in-route.tsx +9 -3
- package/src/routes/index.ts +11 -0
- package/src/routes/sign-in-path.test.node.ts +79 -0
- package/src/routes/sign-in-path.ts +36 -0
- package/src/server-fns/admin-account/change-password.ts +1 -1
- package/src/server-fns/admin-account/get.ts +1 -1
- package/src/server-fns/admin-account/update.ts +1 -1
- package/src/server-fns/admin-activity/get.ts +1 -1
- package/src/server-fns/admin-permissions/get-role-abilities.ts +1 -1
- package/src/server-fns/admin-permissions/list-registered.ts +1 -1
- package/src/server-fns/admin-permissions/set-role-abilities.ts +1 -1
- package/src/server-fns/admin-permissions/who-has.ts +1 -1
- package/src/server-fns/admin-roles/create.ts +1 -1
- package/src/server-fns/admin-roles/delete.ts +1 -1
- package/src/server-fns/admin-roles/get.ts +1 -1
- package/src/server-fns/admin-roles/list.ts +1 -1
- package/src/server-fns/admin-roles/reorder.ts +1 -1
- package/src/server-fns/admin-roles/update.ts +1 -1
- package/src/server-fns/admin-users/create.ts +1 -1
- package/src/server-fns/admin-users/delete.ts +1 -1
- package/src/server-fns/admin-users/disable.ts +1 -1
- package/src/server-fns/admin-users/enable.ts +1 -1
- package/src/server-fns/admin-users/get-user-roles.ts +1 -1
- package/src/server-fns/admin-users/get.ts +1 -1
- package/src/server-fns/admin-users/list.ts +1 -1
- package/src/server-fns/admin-users/set-password.ts +1 -1
- package/src/server-fns/admin-users/set-user-roles.ts +1 -1
- package/src/server-fns/admin-users/update.ts +1 -1
- package/src/server-fns/ai/execute.ts +1 -2
- package/src/server-fns/auth/current-user.ts +1 -1
- package/src/server-fns/auth/sign-in.ts +1 -1
- package/src/server-fns/auth/sign-out.ts +5 -3
- package/src/server-fns/collections/audit.ts +1 -1
- package/src/server-fns/collections/copy-to-locale.ts +1 -1
- package/src/server-fns/collections/create.ts +1 -1
- package/src/server-fns/collections/delete-locale.ts +1 -1
- package/src/server-fns/collections/delete-outcome.test.node.ts +72 -0
- package/src/server-fns/collections/delete-outcome.ts +80 -0
- package/src/server-fns/collections/delete.ts +3 -2
- package/src/server-fns/collections/duplicate.ts +1 -1
- package/src/server-fns/collections/get.ts +3 -1
- package/src/server-fns/collections/history.ts +1 -1
- package/src/server-fns/collections/index.ts +1 -0
- package/src/server-fns/collections/list.ts +1 -1
- package/src/server-fns/collections/reindex.ts +1 -1
- package/src/server-fns/collections/reorder.ts +1 -1
- package/src/server-fns/collections/restore-version.ts +1 -1
- package/src/server-fns/collections/stats.ts +2 -1
- package/src/server-fns/collections/status.ts +1 -1
- package/src/server-fns/collections/tree-mutation.test.node.ts +225 -0
- package/src/server-fns/collections/tree-mutation.ts +165 -0
- package/src/server-fns/collections/tree-read.test.node.ts +46 -0
- package/src/server-fns/collections/tree-read.ts +26 -0
- package/src/server-fns/collections/tree.ts +27 -11
- package/src/server-fns/collections/update.ts +4 -1
- package/src/server-fns/collections/upload.ts +1 -1
- package/src/server-fns/i18n/set-locale.ts +1 -1
- package/src/server-fns/preview/disable.ts +1 -1
- package/src/server-fns/preview/enable.ts +1 -2
- package/src/server-fns/preview/state.ts +1 -1
- package/src/vite/client-hook-boundary.test.node.ts +50 -0
- package/src/vite/client-hook-boundary.ts +45 -0
- package/src/vite/index.ts +9 -0
- package/dist/auth/auth-context.d.ts +0 -37
- package/dist/auth/auth-context.js +0 -57
- package/dist/auth/auth-cookies.d.ts +0 -34
- package/dist/auth/auth-cookies.js +0 -46
- package/dist/auth/preview-cookies.d.ts +0 -19
- package/dist/auth/preview-cookies.js +0 -26
- package/dist/integrations/byline-client.d.ts +0 -24
- package/dist/integrations/byline-client.js +0 -25
- package/dist/integrations/byline-public-client.js +0 -15
- package/dist/integrations/byline-viewer-client.d.ts +0 -20
- package/dist/integrations/byline-viewer-client.js +0 -39
- package/src/auth/auth-context.test.node.ts +0 -215
- package/src/auth/auth-context.ts +0 -124
- package/src/auth/auth-cookies.ts +0 -113
- package/src/auth/preview-cookies.ts +0 -73
- package/src/integrations/byline-client.ts +0 -66
- package/src/integrations/byline-public-client.ts +0 -53
- 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({
|
|
@@ -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 {
|
|
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 {
|
|
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
|
|
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)
|
|
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)
|
|
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
|
|
119
|
-
|
|
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 "
|
|
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 "
|
|
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 "
|
|
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 "
|
|
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 };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { bylineClientHookBoundary } from "./client-hook-boundary.js";
|