@btst/stack 2.3.0 → 2.5.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/packages/stack/src/client/components/compose.cjs +1 -2
- package/dist/packages/stack/src/client/components/compose.mjs +1 -2
- package/dist/packages/stack/src/plugins/ai-chat/api/page-tools.cjs +71 -0
- package/dist/packages/stack/src/plugins/ai-chat/api/page-tools.mjs +68 -0
- package/dist/packages/stack/src/plugins/ai-chat/api/plugin.cjs +87 -54
- package/dist/packages/stack/src/plugins/ai-chat/api/plugin.mjs +87 -54
- package/dist/packages/stack/src/plugins/ai-chat/client/components/chat-input.cjs +2 -2
- package/dist/packages/stack/src/plugins/ai-chat/client/components/chat-input.mjs +2 -2
- package/dist/packages/stack/src/plugins/ai-chat/client/components/chat-interface.cjs +89 -22
- package/dist/packages/stack/src/plugins/ai-chat/client/components/chat-interface.mjs +90 -23
- package/dist/packages/stack/src/plugins/ai-chat/client/components/chat-layout.cjs +110 -33
- package/dist/packages/stack/src/plugins/ai-chat/client/components/chat-layout.mjs +112 -35
- package/dist/packages/stack/src/plugins/ai-chat/client/components/chat-sidebar.cjs +1 -1
- package/dist/packages/stack/src/plugins/ai-chat/client/components/chat-sidebar.mjs +1 -1
- package/dist/packages/stack/src/plugins/ai-chat/client/plugin.cjs +14 -21
- package/dist/packages/stack/src/plugins/ai-chat/client/plugin.mjs +15 -22
- package/dist/packages/stack/src/plugins/ai-chat/schemas.cjs +17 -1
- package/dist/packages/stack/src/plugins/ai-chat/schemas.mjs +17 -1
- package/dist/packages/stack/src/plugins/blog/api/plugin.cjs +28 -45
- package/dist/packages/stack/src/plugins/blog/api/plugin.mjs +22 -39
- package/dist/packages/stack/src/plugins/blog/client/components/forms/post-forms.cjs +15 -2
- package/dist/packages/stack/src/plugins/blog/client/components/forms/post-forms.mjs +16 -3
- package/dist/packages/stack/src/plugins/blog/client/components/pages/edit-post-page.internal.cjs +24 -1
- package/dist/packages/stack/src/plugins/blog/client/components/pages/edit-post-page.internal.mjs +24 -1
- package/dist/packages/stack/src/plugins/blog/client/components/pages/fill-blog-form-handler.cjs +26 -0
- package/dist/packages/stack/src/plugins/blog/client/components/pages/fill-blog-form-handler.mjs +24 -0
- package/dist/packages/stack/src/plugins/blog/client/components/pages/new-post-page.internal.cjs +30 -1
- package/dist/packages/stack/src/plugins/blog/client/components/pages/new-post-page.internal.mjs +30 -1
- package/dist/packages/stack/src/plugins/blog/client/components/pages/post-page.internal.cjs +18 -0
- package/dist/packages/stack/src/plugins/blog/client/components/pages/post-page.internal.mjs +18 -0
- package/dist/packages/stack/src/plugins/blog/client/plugin.cjs +23 -27
- package/dist/packages/stack/src/plugins/blog/client/plugin.mjs +24 -28
- package/dist/packages/stack/src/plugins/cms/api/mutations.cjs +48 -0
- package/dist/packages/stack/src/plugins/cms/api/mutations.mjs +46 -0
- package/dist/packages/stack/src/plugins/cms/api/plugin.cjs +21 -18
- package/dist/packages/stack/src/plugins/cms/api/plugin.mjs +21 -18
- package/dist/packages/stack/src/plugins/cms/client/plugin.cjs +11 -15
- package/dist/packages/stack/src/plugins/cms/client/plugin.mjs +12 -16
- package/dist/packages/stack/src/plugins/form-builder/api/plugin.cjs +58 -62
- package/dist/packages/stack/src/plugins/form-builder/api/plugin.mjs +58 -62
- package/dist/packages/stack/src/plugins/form-builder/client/plugin.cjs +12 -12
- package/dist/packages/stack/src/plugins/form-builder/client/plugin.mjs +13 -13
- package/dist/packages/stack/src/plugins/kanban/api/mutations.cjs +91 -0
- package/dist/packages/stack/src/plugins/kanban/api/mutations.mjs +87 -0
- package/dist/packages/stack/src/plugins/kanban/api/plugin.cjs +92 -118
- package/dist/packages/stack/src/plugins/kanban/api/plugin.mjs +89 -115
- package/dist/packages/stack/src/plugins/kanban/client/hooks/kanban-hooks.cjs +7 -3
- package/dist/packages/stack/src/plugins/kanban/client/hooks/kanban-hooks.mjs +7 -3
- package/dist/packages/stack/src/plugins/kanban/client/plugin.cjs +22 -29
- package/dist/packages/stack/src/plugins/kanban/client/plugin.mjs +23 -30
- package/dist/packages/stack/src/plugins/ui-builder/client/components/pages/page-builder-page.internal.cjs +89 -0
- package/dist/packages/stack/src/plugins/ui-builder/client/components/pages/page-builder-page.internal.mjs +89 -0
- package/dist/packages/stack/src/plugins/ui-builder/client/plugin.cjs +8 -8
- package/dist/packages/stack/src/plugins/ui-builder/client/plugin.mjs +9 -9
- package/dist/packages/stack/src/plugins/utils.cjs +42 -0
- package/dist/packages/stack/src/plugins/utils.mjs +41 -1
- package/dist/plugins/ai-chat/api/index.d.cts +1 -1
- package/dist/plugins/ai-chat/api/index.d.mts +1 -1
- package/dist/plugins/ai-chat/api/index.d.ts +1 -1
- package/dist/plugins/ai-chat/client/components/index.d.cts +1 -1
- package/dist/plugins/ai-chat/client/components/index.d.mts +1 -1
- package/dist/plugins/ai-chat/client/components/index.d.ts +1 -1
- package/dist/plugins/ai-chat/client/context/page-ai-context.cjs +92 -0
- package/dist/plugins/ai-chat/client/context/page-ai-context.d.cts +84 -0
- package/dist/plugins/ai-chat/client/context/page-ai-context.d.mts +84 -0
- package/dist/plugins/ai-chat/client/context/page-ai-context.d.ts +84 -0
- package/dist/plugins/ai-chat/client/context/page-ai-context.mjs +88 -0
- package/dist/plugins/ai-chat/client/hooks/index.d.cts +1 -1
- package/dist/plugins/ai-chat/client/hooks/index.d.mts +1 -1
- package/dist/plugins/ai-chat/client/hooks/index.d.ts +1 -1
- package/dist/plugins/ai-chat/client/index.d.cts +10 -10
- package/dist/plugins/ai-chat/client/index.d.mts +10 -10
- package/dist/plugins/ai-chat/client/index.d.ts +10 -10
- package/dist/plugins/ai-chat/query-keys.d.cts +1 -1
- package/dist/plugins/ai-chat/query-keys.d.mts +1 -1
- package/dist/plugins/ai-chat/query-keys.d.ts +1 -1
- package/dist/plugins/blog/api/index.d.cts +2 -2
- package/dist/plugins/blog/api/index.d.mts +2 -2
- package/dist/plugins/blog/api/index.d.ts +2 -2
- package/dist/plugins/blog/client/hooks/index.d.cts +2 -2
- package/dist/plugins/blog/client/hooks/index.d.mts +2 -2
- package/dist/plugins/blog/client/hooks/index.d.ts +2 -2
- package/dist/plugins/blog/client/index.d.cts +13 -13
- package/dist/plugins/blog/client/index.d.mts +13 -13
- package/dist/plugins/blog/client/index.d.ts +13 -13
- package/dist/plugins/blog/query-keys.d.cts +2 -2
- package/dist/plugins/blog/query-keys.d.mts +2 -2
- package/dist/plugins/blog/query-keys.d.ts +2 -2
- package/dist/plugins/client/index.cjs +1 -0
- package/dist/plugins/client/index.d.cts +8 -1
- package/dist/plugins/client/index.d.mts +8 -1
- package/dist/plugins/client/index.d.ts +8 -1
- package/dist/plugins/client/index.mjs +1 -1
- package/dist/plugins/cms/api/index.cjs +2 -0
- package/dist/plugins/cms/api/index.d.cts +2 -2
- package/dist/plugins/cms/api/index.d.mts +2 -2
- package/dist/plugins/cms/api/index.d.ts +2 -2
- package/dist/plugins/cms/api/index.mjs +1 -0
- package/dist/plugins/cms/client/hooks/index.d.cts +1 -1
- package/dist/plugins/cms/client/hooks/index.d.mts +1 -1
- package/dist/plugins/cms/client/hooks/index.d.ts +1 -1
- package/dist/plugins/cms/client/index.d.cts +6 -6
- package/dist/plugins/cms/client/index.d.mts +6 -6
- package/dist/plugins/cms/client/index.d.ts +6 -6
- package/dist/plugins/cms/query-keys.d.cts +2 -2
- package/dist/plugins/cms/query-keys.d.mts +2 -2
- package/dist/plugins/cms/query-keys.d.ts +2 -2
- package/dist/plugins/form-builder/api/index.d.cts +2 -2
- package/dist/plugins/form-builder/api/index.d.mts +2 -2
- package/dist/plugins/form-builder/api/index.d.ts +2 -2
- package/dist/plugins/form-builder/client/components/index.d.cts +1 -1
- package/dist/plugins/form-builder/client/components/index.d.mts +1 -1
- package/dist/plugins/form-builder/client/components/index.d.ts +1 -1
- package/dist/plugins/form-builder/client/hooks/index.d.cts +1 -1
- package/dist/plugins/form-builder/client/hooks/index.d.mts +1 -1
- package/dist/plugins/form-builder/client/hooks/index.d.ts +1 -1
- package/dist/plugins/form-builder/client/index.d.cts +6 -6
- package/dist/plugins/form-builder/client/index.d.mts +6 -6
- package/dist/plugins/form-builder/client/index.d.ts +6 -6
- package/dist/plugins/form-builder/query-keys.d.cts +2 -2
- package/dist/plugins/form-builder/query-keys.d.mts +2 -2
- package/dist/plugins/form-builder/query-keys.d.ts +2 -2
- package/dist/plugins/kanban/api/index.cjs +4 -0
- package/dist/plugins/kanban/api/index.d.cts +1 -1
- package/dist/plugins/kanban/api/index.d.mts +1 -1
- package/dist/plugins/kanban/api/index.d.ts +1 -1
- package/dist/plugins/kanban/api/index.mjs +1 -0
- package/dist/plugins/kanban/client/index.d.cts +12 -12
- package/dist/plugins/kanban/client/index.d.mts +12 -12
- package/dist/plugins/kanban/client/index.d.ts +12 -12
- package/dist/plugins/kanban/query-keys.d.cts +1 -1
- package/dist/plugins/kanban/query-keys.d.mts +1 -1
- package/dist/plugins/kanban/query-keys.d.ts +1 -1
- package/dist/plugins/ui-builder/client/hooks/index.d.cts +1 -1
- package/dist/plugins/ui-builder/client/hooks/index.d.mts +1 -1
- package/dist/plugins/ui-builder/client/hooks/index.d.ts +1 -1
- package/dist/plugins/ui-builder/client/index.d.cts +3 -3
- package/dist/plugins/ui-builder/client/index.d.mts +3 -3
- package/dist/plugins/ui-builder/client/index.d.ts +3 -3
- package/dist/plugins/ui-builder/index.d.cts +2 -2
- package/dist/plugins/ui-builder/index.d.mts +2 -2
- package/dist/plugins/ui-builder/index.d.ts +2 -2
- package/dist/shared/{stack.C-WUPMT6.d.cts → stack.B2xZTSiO.d.cts} +4 -4
- package/dist/shared/{stack.B1EeBt1b.d.ts → stack.B58oHdqm.d.mts} +33 -3
- package/dist/shared/{stack.CVDTkMoO.d.mts → stack.B8QD11QU.d.cts} +7 -7
- package/dist/shared/{stack.CVDTkMoO.d.cts → stack.B8QD11QU.d.mts} +7 -7
- package/dist/shared/{stack.CVDTkMoO.d.ts → stack.B8QD11QU.d.ts} +7 -7
- package/dist/shared/{stack.CIP6QS9l.d.ts → stack.BDVEpue1.d.ts} +1 -1
- package/dist/shared/{stack.C5dtIncc.d.mts → stack.BTvbxZvw.d.cts} +1 -1
- package/dist/shared/{stack.DaOcgmrM.d.ts → stack.BV9hnvu4.d.cts} +31 -7
- package/dist/shared/{stack.DaOcgmrM.d.cts → stack.BV9hnvu4.d.mts} +31 -7
- package/dist/shared/{stack.DaOcgmrM.d.mts → stack.BV9hnvu4.d.ts} +31 -7
- package/dist/shared/{stack.DdI5W6MB.d.mts → stack.BozPgbrZ.d.cts} +19 -19
- package/dist/shared/{stack.DdI5W6MB.d.ts → stack.BozPgbrZ.d.mts} +19 -19
- package/dist/shared/{stack.DdI5W6MB.d.cts → stack.BozPgbrZ.d.ts} +19 -19
- package/dist/shared/{stack.CP68pFEH.d.mts → stack.C9Mg2Q46.d.cts} +33 -3
- package/dist/shared/{stack.BeSm90va.d.ts → stack.CTDVxbrA.d.ts} +72 -14
- package/dist/shared/{stack.C-Ptrz8s.d.ts → stack.Cj_zKww4.d.ts} +4 -4
- package/dist/shared/{stack.TIBF2AOx.d.ts → stack.CxaFNQCV.d.mts} +89 -34
- package/dist/shared/{stack.CMh_EdxW.d.cts → stack.D-b5zbPm.d.cts} +72 -14
- package/dist/shared/{stack.Dw0Ly2TM.d.cts → stack.DTtmJPQO.d.mts} +1 -1
- package/dist/shared/{stack.BKfolAyK.d.ts → stack.DXnclTG7.d.ts} +11 -11
- package/dist/shared/{stack.snB1EDP7.d.cts → stack.DaZM10cp.d.cts} +11 -11
- package/dist/shared/{stack.Dg09R0oB.d.mts → stack.FVWf2JhZ.d.mts} +72 -14
- package/dist/shared/{stack.BIXEI6v_.d.mts → stack.cfCkioTe.d.mts} +11 -11
- package/dist/shared/{stack.6fUOjLs9.d.mts → stack.dH7u-TJH.d.mts} +4 -4
- package/dist/shared/{stack.BpolpQpf.d.cts → stack.j75TpKh2.d.ts} +89 -34
- package/dist/shared/{stack.rTy7-wQU.d.mts → stack.n1_i1p2B.d.cts} +89 -34
- package/dist/shared/{stack.IdtKDRka.d.cts → stack.sO33ZDhK.d.ts} +33 -3
- package/package.json +14 -1
- package/src/client/components/compose.tsx +7 -4
- package/src/plugins/ai-chat/api/page-tools.ts +111 -0
- package/src/plugins/ai-chat/api/plugin.ts +228 -72
- package/src/plugins/ai-chat/client/components/chat-input.tsx +2 -2
- package/src/plugins/ai-chat/client/components/chat-interface.tsx +154 -58
- package/src/plugins/ai-chat/client/components/chat-layout.tsx +166 -32
- package/src/plugins/ai-chat/client/components/chat-sidebar.tsx +1 -1
- package/src/plugins/ai-chat/client/context/page-ai-context.tsx +240 -0
- package/src/plugins/ai-chat/client/plugin.tsx +23 -31
- package/src/plugins/ai-chat/schemas.ts +16 -0
- package/src/plugins/blog/api/plugin.ts +31 -47
- package/src/plugins/blog/client/components/forms/post-forms.tsx +29 -2
- package/src/plugins/blog/client/components/pages/edit-post-page.internal.tsx +28 -0
- package/src/plugins/blog/client/components/pages/fill-blog-form-handler.ts +38 -0
- package/src/plugins/blog/client/components/pages/new-post-page.internal.tsx +33 -1
- package/src/plugins/blog/client/components/pages/post-page.internal.tsx +20 -0
- package/src/plugins/blog/client/plugin.tsx +36 -39
- package/src/plugins/client/index.ts +5 -1
- package/src/plugins/cms/api/index.ts +4 -0
- package/src/plugins/cms/api/mutations.ts +84 -0
- package/src/plugins/cms/api/plugin.ts +23 -17
- package/src/plugins/cms/client/plugin.tsx +18 -21
- package/src/plugins/cms/types.ts +7 -7
- package/src/plugins/form-builder/api/plugin.ts +64 -64
- package/src/plugins/form-builder/client/plugin.tsx +19 -18
- package/src/plugins/form-builder/types.ts +19 -24
- package/src/plugins/kanban/api/index.ts +6 -0
- package/src/plugins/kanban/api/mutations.ts +169 -0
- package/src/plugins/kanban/api/plugin.ts +123 -136
- package/src/plugins/kanban/client/hooks/kanban-hooks.tsx +4 -0
- package/src/plugins/kanban/client/plugin.tsx +35 -41
- package/src/plugins/ui-builder/client/components/pages/page-builder-page.internal.tsx +132 -0
- package/src/plugins/ui-builder/client/plugin.tsx +11 -10
- package/src/plugins/ui-builder/types.ts +4 -4
- package/src/plugins/utils.ts +92 -1
- package/dist/shared/{stack.CBON0dWL.d.mts → stack.BQmuNl5p.d.cts} +2 -2
- package/dist/shared/{stack.CBON0dWL.d.ts → stack.BQmuNl5p.d.mts} +2 -2
- package/dist/shared/{stack.CBON0dWL.d.cts → stack.BQmuNl5p.d.ts} +2 -2
|
@@ -35,7 +35,8 @@ function useBoards(params) {
|
|
|
35
35
|
const queries = plugins_kanban_queryKeys.createKanbanQueryKeys(client, headers);
|
|
36
36
|
return reactQuery.useQuery({
|
|
37
37
|
...queries.boards.list(params),
|
|
38
|
-
staleTime: 3e4
|
|
38
|
+
staleTime: 3e4,
|
|
39
|
+
refetchOnWindowFocus: true
|
|
39
40
|
});
|
|
40
41
|
}
|
|
41
42
|
function useSuspenseBoards(params) {
|
|
@@ -43,7 +44,8 @@ function useSuspenseBoards(params) {
|
|
|
43
44
|
const queries = plugins_kanban_queryKeys.createKanbanQueryKeys(client, headers);
|
|
44
45
|
const result = reactQuery.useSuspenseQuery({
|
|
45
46
|
...queries.boards.list(params),
|
|
46
|
-
staleTime: 3e4
|
|
47
|
+
staleTime: 3e4,
|
|
48
|
+
refetchOnWindowFocus: true
|
|
47
49
|
});
|
|
48
50
|
if (result.error && !result.isFetching) {
|
|
49
51
|
throw result.error;
|
|
@@ -56,6 +58,7 @@ function useBoard(boardId) {
|
|
|
56
58
|
return reactQuery.useQuery({
|
|
57
59
|
...queries.boards.detail(boardId),
|
|
58
60
|
staleTime: 3e4,
|
|
61
|
+
refetchOnWindowFocus: true,
|
|
59
62
|
enabled: !!boardId
|
|
60
63
|
});
|
|
61
64
|
}
|
|
@@ -64,7 +67,8 @@ function useSuspenseBoard(boardId) {
|
|
|
64
67
|
const queries = plugins_kanban_queryKeys.createKanbanQueryKeys(client, headers);
|
|
65
68
|
const result = reactQuery.useSuspenseQuery({
|
|
66
69
|
...queries.boards.detail(boardId),
|
|
67
|
-
staleTime: 3e4
|
|
70
|
+
staleTime: 3e4,
|
|
71
|
+
refetchOnWindowFocus: true
|
|
68
72
|
});
|
|
69
73
|
if (result.error && !result.isFetching) {
|
|
70
74
|
throw result.error;
|
|
@@ -33,7 +33,8 @@ function useBoards(params) {
|
|
|
33
33
|
const queries = createKanbanQueryKeys(client, headers);
|
|
34
34
|
return useQuery({
|
|
35
35
|
...queries.boards.list(params),
|
|
36
|
-
staleTime: 3e4
|
|
36
|
+
staleTime: 3e4,
|
|
37
|
+
refetchOnWindowFocus: true
|
|
37
38
|
});
|
|
38
39
|
}
|
|
39
40
|
function useSuspenseBoards(params) {
|
|
@@ -41,7 +42,8 @@ function useSuspenseBoards(params) {
|
|
|
41
42
|
const queries = createKanbanQueryKeys(client, headers);
|
|
42
43
|
const result = useSuspenseQuery({
|
|
43
44
|
...queries.boards.list(params),
|
|
44
|
-
staleTime: 3e4
|
|
45
|
+
staleTime: 3e4,
|
|
46
|
+
refetchOnWindowFocus: true
|
|
45
47
|
});
|
|
46
48
|
if (result.error && !result.isFetching) {
|
|
47
49
|
throw result.error;
|
|
@@ -54,6 +56,7 @@ function useBoard(boardId) {
|
|
|
54
56
|
return useQuery({
|
|
55
57
|
...queries.boards.detail(boardId),
|
|
56
58
|
staleTime: 3e4,
|
|
59
|
+
refetchOnWindowFocus: true,
|
|
57
60
|
enabled: !!boardId
|
|
58
61
|
});
|
|
59
62
|
}
|
|
@@ -62,7 +65,8 @@ function useSuspenseBoard(boardId) {
|
|
|
62
65
|
const queries = createKanbanQueryKeys(client, headers);
|
|
63
66
|
const result = useSuspenseQuery({
|
|
64
67
|
...queries.boards.detail(boardId),
|
|
65
|
-
staleTime: 3e4
|
|
68
|
+
staleTime: 3e4,
|
|
69
|
+
refetchOnWindowFocus: true
|
|
66
70
|
});
|
|
67
71
|
if (result.error && !result.isFetching) {
|
|
68
72
|
throw result.error;
|
|
@@ -21,10 +21,10 @@ function createBoardsLoader(config) {
|
|
|
21
21
|
};
|
|
22
22
|
try {
|
|
23
23
|
if (hooks?.beforeLoadBoards) {
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
24
|
+
await client.runClientHookWithShim(
|
|
25
|
+
() => hooks.beforeLoadBoards(context),
|
|
26
|
+
"Load prevented by beforeLoadBoards hook"
|
|
27
|
+
);
|
|
28
28
|
}
|
|
29
29
|
const client$1 = client.createApiClient({
|
|
30
30
|
baseURL: apiBaseURL,
|
|
@@ -37,13 +37,10 @@ function createBoardsLoader(config) {
|
|
|
37
37
|
const boards = queryClient.getQueryData(
|
|
38
38
|
listQuery.queryKey
|
|
39
39
|
);
|
|
40
|
-
|
|
41
|
-
boards || null,
|
|
42
|
-
|
|
40
|
+
await client.runClientHookWithShim(
|
|
41
|
+
() => hooks.afterLoadBoards(boards || null, context),
|
|
42
|
+
"Load prevented by afterLoadBoards hook"
|
|
43
43
|
);
|
|
44
|
-
if (canContinue === false) {
|
|
45
|
-
throw new Error("Load prevented by afterLoadBoards hook");
|
|
46
|
-
}
|
|
47
44
|
}
|
|
48
45
|
const queryState = queryClient.getQueryState(listQuery.queryKey);
|
|
49
46
|
if (queryState?.error && hooks?.onLoadError) {
|
|
@@ -77,10 +74,10 @@ function createBoardLoader(boardId, config) {
|
|
|
77
74
|
};
|
|
78
75
|
try {
|
|
79
76
|
if (hooks?.beforeLoadBoard) {
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
77
|
+
await client.runClientHookWithShim(
|
|
78
|
+
() => hooks.beforeLoadBoard(boardId, context),
|
|
79
|
+
"Load prevented by beforeLoadBoard hook"
|
|
80
|
+
);
|
|
84
81
|
}
|
|
85
82
|
const client$1 = client.createApiClient({
|
|
86
83
|
baseURL: apiBaseURL,
|
|
@@ -93,14 +90,10 @@ function createBoardLoader(boardId, config) {
|
|
|
93
90
|
const board = queryClient.getQueryData(
|
|
94
91
|
boardQuery.queryKey
|
|
95
92
|
);
|
|
96
|
-
|
|
97
|
-
board || null,
|
|
98
|
-
|
|
99
|
-
context
|
|
93
|
+
await client.runClientHookWithShim(
|
|
94
|
+
() => hooks.afterLoadBoard(board || null, boardId, context),
|
|
95
|
+
"Load prevented by afterLoadBoard hook"
|
|
100
96
|
);
|
|
101
|
-
if (canContinue === false) {
|
|
102
|
-
throw new Error("Load prevented by afterLoadBoard hook");
|
|
103
|
-
}
|
|
104
97
|
}
|
|
105
98
|
const queryState = queryClient.getQueryState(boardQuery.queryKey);
|
|
106
99
|
if (queryState?.error && hooks?.onLoadError) {
|
|
@@ -133,16 +126,16 @@ function createNewBoardLoader(config) {
|
|
|
133
126
|
};
|
|
134
127
|
try {
|
|
135
128
|
if (hooks?.beforeLoadNewBoard) {
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
129
|
+
await client.runClientHookWithShim(
|
|
130
|
+
() => hooks.beforeLoadNewBoard(context),
|
|
131
|
+
"Load prevented by beforeLoadNewBoard hook"
|
|
132
|
+
);
|
|
140
133
|
}
|
|
141
134
|
if (hooks?.afterLoadNewBoard) {
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
135
|
+
await client.runClientHookWithShim(
|
|
136
|
+
() => hooks.afterLoadNewBoard(context),
|
|
137
|
+
"Load prevented by afterLoadNewBoard hook"
|
|
138
|
+
);
|
|
146
139
|
}
|
|
147
140
|
} catch (error) {
|
|
148
141
|
if (hooks?.onLoadError) {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { jsx } from 'react/jsx-runtime';
|
|
2
|
-
import { defineClientPlugin, createApiClient, isConnectionError } from '@btst/stack/plugins/client';
|
|
2
|
+
import { defineClientPlugin, createApiClient, runClientHookWithShim, isConnectionError } from '@btst/stack/plugins/client';
|
|
3
3
|
import { createRoute } from '@btst/yar';
|
|
4
4
|
import { createKanbanQueryKeys } from '../../../../../../plugins/kanban/query-keys.mjs';
|
|
5
5
|
import { BoardsListPageComponent } from './components/pages/boards-list-page.mjs';
|
|
@@ -19,10 +19,10 @@ function createBoardsLoader(config) {
|
|
|
19
19
|
};
|
|
20
20
|
try {
|
|
21
21
|
if (hooks?.beforeLoadBoards) {
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
22
|
+
await runClientHookWithShim(
|
|
23
|
+
() => hooks.beforeLoadBoards(context),
|
|
24
|
+
"Load prevented by beforeLoadBoards hook"
|
|
25
|
+
);
|
|
26
26
|
}
|
|
27
27
|
const client = createApiClient({
|
|
28
28
|
baseURL: apiBaseURL,
|
|
@@ -35,13 +35,10 @@ function createBoardsLoader(config) {
|
|
|
35
35
|
const boards = queryClient.getQueryData(
|
|
36
36
|
listQuery.queryKey
|
|
37
37
|
);
|
|
38
|
-
|
|
39
|
-
boards || null,
|
|
40
|
-
|
|
38
|
+
await runClientHookWithShim(
|
|
39
|
+
() => hooks.afterLoadBoards(boards || null, context),
|
|
40
|
+
"Load prevented by afterLoadBoards hook"
|
|
41
41
|
);
|
|
42
|
-
if (canContinue === false) {
|
|
43
|
-
throw new Error("Load prevented by afterLoadBoards hook");
|
|
44
|
-
}
|
|
45
42
|
}
|
|
46
43
|
const queryState = queryClient.getQueryState(listQuery.queryKey);
|
|
47
44
|
if (queryState?.error && hooks?.onLoadError) {
|
|
@@ -75,10 +72,10 @@ function createBoardLoader(boardId, config) {
|
|
|
75
72
|
};
|
|
76
73
|
try {
|
|
77
74
|
if (hooks?.beforeLoadBoard) {
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
75
|
+
await runClientHookWithShim(
|
|
76
|
+
() => hooks.beforeLoadBoard(boardId, context),
|
|
77
|
+
"Load prevented by beforeLoadBoard hook"
|
|
78
|
+
);
|
|
82
79
|
}
|
|
83
80
|
const client = createApiClient({
|
|
84
81
|
baseURL: apiBaseURL,
|
|
@@ -91,14 +88,10 @@ function createBoardLoader(boardId, config) {
|
|
|
91
88
|
const board = queryClient.getQueryData(
|
|
92
89
|
boardQuery.queryKey
|
|
93
90
|
);
|
|
94
|
-
|
|
95
|
-
board || null,
|
|
96
|
-
|
|
97
|
-
context
|
|
91
|
+
await runClientHookWithShim(
|
|
92
|
+
() => hooks.afterLoadBoard(board || null, boardId, context),
|
|
93
|
+
"Load prevented by afterLoadBoard hook"
|
|
98
94
|
);
|
|
99
|
-
if (canContinue === false) {
|
|
100
|
-
throw new Error("Load prevented by afterLoadBoard hook");
|
|
101
|
-
}
|
|
102
95
|
}
|
|
103
96
|
const queryState = queryClient.getQueryState(boardQuery.queryKey);
|
|
104
97
|
if (queryState?.error && hooks?.onLoadError) {
|
|
@@ -131,16 +124,16 @@ function createNewBoardLoader(config) {
|
|
|
131
124
|
};
|
|
132
125
|
try {
|
|
133
126
|
if (hooks?.beforeLoadNewBoard) {
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
127
|
+
await runClientHookWithShim(
|
|
128
|
+
() => hooks.beforeLoadNewBoard(context),
|
|
129
|
+
"Load prevented by beforeLoadNewBoard hook"
|
|
130
|
+
);
|
|
138
131
|
}
|
|
139
132
|
if (hooks?.afterLoadNewBoard) {
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
133
|
+
await runClientHookWithShim(
|
|
134
|
+
() => hooks.afterLoadNewBoard(context),
|
|
135
|
+
"Load prevented by afterLoadNewBoard hook"
|
|
136
|
+
);
|
|
144
137
|
}
|
|
145
138
|
} catch (error) {
|
|
146
139
|
if (hooks?.onLoadError) {
|
|
@@ -12,10 +12,73 @@ const label = require('../../../../../../../ui/src/components/label.cjs');
|
|
|
12
12
|
const LucideIcons = require('lucide-react');
|
|
13
13
|
const sonner = require('sonner');
|
|
14
14
|
const index$1 = require('../../../../../../../ui/src/components/ui-builder/index.cjs');
|
|
15
|
+
const layerStore = require('../../../../../../../ui/src/lib/ui-builder/store/layer-store.cjs');
|
|
16
|
+
const context$1 = require('@btst/stack/plugins/ai-chat/client/context');
|
|
15
17
|
const uiBuilderHooks = require('../../hooks/ui-builder-hooks.cjs');
|
|
16
18
|
const index = require('../../localization/index.cjs');
|
|
17
19
|
const registry = require('../../registry.cjs');
|
|
18
20
|
|
|
21
|
+
function buildRegistryDescription(registry) {
|
|
22
|
+
const lines = [];
|
|
23
|
+
for (const [name, entry] of Object.entries(registry)) {
|
|
24
|
+
let propsLine = "";
|
|
25
|
+
try {
|
|
26
|
+
const shape = entry.schema?.shape;
|
|
27
|
+
if (shape) {
|
|
28
|
+
const fields = Object.keys(shape).join(", ");
|
|
29
|
+
propsLine = ` \u2014 props: ${fields}`;
|
|
30
|
+
}
|
|
31
|
+
} catch {
|
|
32
|
+
}
|
|
33
|
+
lines.push(`- ${name}${propsLine}`);
|
|
34
|
+
}
|
|
35
|
+
return lines.join("\n");
|
|
36
|
+
}
|
|
37
|
+
function buildPageDescription(id, slug, layers, registry) {
|
|
38
|
+
const header = id ? `UI Builder \u2014 editing page (slug: "${slug}")` : "UI Builder \u2014 creating new page";
|
|
39
|
+
const layersJson = JSON.stringify(layers, null, 2);
|
|
40
|
+
const registryDesc = buildRegistryDescription(registry);
|
|
41
|
+
const layerFormat = `Each layer: { id: string, type: string, name: string, props: Record<string,any>, children?: ComponentLayer[] | string }`;
|
|
42
|
+
const full = [
|
|
43
|
+
header,
|
|
44
|
+
"",
|
|
45
|
+
`## Current Layers (${layers.length})`,
|
|
46
|
+
layersJson,
|
|
47
|
+
"",
|
|
48
|
+
`## Available Component Types`,
|
|
49
|
+
registryDesc,
|
|
50
|
+
"",
|
|
51
|
+
`## ComponentLayer format`,
|
|
52
|
+
layerFormat
|
|
53
|
+
].join("\n");
|
|
54
|
+
if (full.length <= 16e3) return full;
|
|
55
|
+
const overhead = [
|
|
56
|
+
header,
|
|
57
|
+
"",
|
|
58
|
+
`## Current Layers (${layers.length})`,
|
|
59
|
+
"",
|
|
60
|
+
"",
|
|
61
|
+
`## Available Component Types`,
|
|
62
|
+
registryDesc,
|
|
63
|
+
"",
|
|
64
|
+
`## ComponentLayer format`,
|
|
65
|
+
layerFormat
|
|
66
|
+
].join("\n").length + 30;
|
|
67
|
+
const budget = Math.max(0, 16e3 - overhead);
|
|
68
|
+
const truncatedLayers = layersJson.length > budget ? layersJson.slice(0, budget) + "\n...(truncated)" : layersJson;
|
|
69
|
+
return [
|
|
70
|
+
header,
|
|
71
|
+
"",
|
|
72
|
+
`## Current Layers (${layers.length})`,
|
|
73
|
+
truncatedLayers,
|
|
74
|
+
"",
|
|
75
|
+
`## Available Component Types`,
|
|
76
|
+
registryDesc,
|
|
77
|
+
"",
|
|
78
|
+
`## ComponentLayer format`,
|
|
79
|
+
layerFormat
|
|
80
|
+
].join("\n");
|
|
81
|
+
}
|
|
19
82
|
function slugify(str) {
|
|
20
83
|
return str.toLowerCase().trim().replace(/[^\w\s-]/g, "").replace(/[\s_-]+/g, "-").replace(/^-+|-+$/g, "");
|
|
21
84
|
}
|
|
@@ -72,6 +135,32 @@ function PageBuilderPageContent({
|
|
|
72
135
|
const [layers, setLayers] = React.useState(existingLayers);
|
|
73
136
|
const [variables, setVariables] = React.useState(existingVariables);
|
|
74
137
|
const [autoSlug, setAutoSlug] = React.useState(!id);
|
|
138
|
+
context$1.useRegisterPageAIContext({
|
|
139
|
+
routeName: id ? "ui-builder-edit-page" : "ui-builder-new-page",
|
|
140
|
+
pageDescription: buildPageDescription(id, slug, layers, componentRegistry),
|
|
141
|
+
suggestions: [
|
|
142
|
+
"Add a hero section",
|
|
143
|
+
"Add a 3-column feature grid",
|
|
144
|
+
"Make the layout full-width",
|
|
145
|
+
"Add a card with a title, description, and button",
|
|
146
|
+
"Replace the layout with a centered single-column design"
|
|
147
|
+
],
|
|
148
|
+
clientTools: {
|
|
149
|
+
updatePageLayers: async ({ layers: newLayers }) => {
|
|
150
|
+
const store = layerStore.useLayerStore.getState();
|
|
151
|
+
store.initialize(
|
|
152
|
+
newLayers,
|
|
153
|
+
store.selectedPageId || newLayers[0]?.id,
|
|
154
|
+
void 0,
|
|
155
|
+
store.variables
|
|
156
|
+
);
|
|
157
|
+
return {
|
|
158
|
+
success: true,
|
|
159
|
+
message: `Applied ${newLayers.length} layer(s) to the page`
|
|
160
|
+
};
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
});
|
|
75
164
|
const handleLayersChange = React.useCallback(
|
|
76
165
|
(newLayers) => {
|
|
77
166
|
setLayers(newLayers);
|
|
@@ -10,10 +10,73 @@ import { Label } from '../../../../../../../ui/src/components/label.mjs';
|
|
|
10
10
|
import { ArrowLeft, Settings2, Save } from 'lucide-react';
|
|
11
11
|
import { toast } from 'sonner';
|
|
12
12
|
import UIBuilder from '../../../../../../../ui/src/components/ui-builder/index.mjs';
|
|
13
|
+
import { useLayerStore } from '../../../../../../../ui/src/lib/ui-builder/store/layer-store.mjs';
|
|
14
|
+
import { useRegisterPageAIContext } from '@btst/stack/plugins/ai-chat/client/context';
|
|
13
15
|
import { useSuspenseUIBuilderPage, useCreateUIBuilderPage, useUpdateUIBuilderPage } from '../../hooks/ui-builder-hooks.mjs';
|
|
14
16
|
import { uiBuilderLocalization } from '../../localization/index.mjs';
|
|
15
17
|
import { defaultComponentRegistry } from '../../registry.mjs';
|
|
16
18
|
|
|
19
|
+
function buildRegistryDescription(registry) {
|
|
20
|
+
const lines = [];
|
|
21
|
+
for (const [name, entry] of Object.entries(registry)) {
|
|
22
|
+
let propsLine = "";
|
|
23
|
+
try {
|
|
24
|
+
const shape = entry.schema?.shape;
|
|
25
|
+
if (shape) {
|
|
26
|
+
const fields = Object.keys(shape).join(", ");
|
|
27
|
+
propsLine = ` \u2014 props: ${fields}`;
|
|
28
|
+
}
|
|
29
|
+
} catch {
|
|
30
|
+
}
|
|
31
|
+
lines.push(`- ${name}${propsLine}`);
|
|
32
|
+
}
|
|
33
|
+
return lines.join("\n");
|
|
34
|
+
}
|
|
35
|
+
function buildPageDescription(id, slug, layers, registry) {
|
|
36
|
+
const header = id ? `UI Builder \u2014 editing page (slug: "${slug}")` : "UI Builder \u2014 creating new page";
|
|
37
|
+
const layersJson = JSON.stringify(layers, null, 2);
|
|
38
|
+
const registryDesc = buildRegistryDescription(registry);
|
|
39
|
+
const layerFormat = `Each layer: { id: string, type: string, name: string, props: Record<string,any>, children?: ComponentLayer[] | string }`;
|
|
40
|
+
const full = [
|
|
41
|
+
header,
|
|
42
|
+
"",
|
|
43
|
+
`## Current Layers (${layers.length})`,
|
|
44
|
+
layersJson,
|
|
45
|
+
"",
|
|
46
|
+
`## Available Component Types`,
|
|
47
|
+
registryDesc,
|
|
48
|
+
"",
|
|
49
|
+
`## ComponentLayer format`,
|
|
50
|
+
layerFormat
|
|
51
|
+
].join("\n");
|
|
52
|
+
if (full.length <= 16e3) return full;
|
|
53
|
+
const overhead = [
|
|
54
|
+
header,
|
|
55
|
+
"",
|
|
56
|
+
`## Current Layers (${layers.length})`,
|
|
57
|
+
"",
|
|
58
|
+
"",
|
|
59
|
+
`## Available Component Types`,
|
|
60
|
+
registryDesc,
|
|
61
|
+
"",
|
|
62
|
+
`## ComponentLayer format`,
|
|
63
|
+
layerFormat
|
|
64
|
+
].join("\n").length + 30;
|
|
65
|
+
const budget = Math.max(0, 16e3 - overhead);
|
|
66
|
+
const truncatedLayers = layersJson.length > budget ? layersJson.slice(0, budget) + "\n...(truncated)" : layersJson;
|
|
67
|
+
return [
|
|
68
|
+
header,
|
|
69
|
+
"",
|
|
70
|
+
`## Current Layers (${layers.length})`,
|
|
71
|
+
truncatedLayers,
|
|
72
|
+
"",
|
|
73
|
+
`## Available Component Types`,
|
|
74
|
+
registryDesc,
|
|
75
|
+
"",
|
|
76
|
+
`## ComponentLayer format`,
|
|
77
|
+
layerFormat
|
|
78
|
+
].join("\n");
|
|
79
|
+
}
|
|
17
80
|
function slugify(str) {
|
|
18
81
|
return str.toLowerCase().trim().replace(/[^\w\s-]/g, "").replace(/[\s_-]+/g, "-").replace(/^-+|-+$/g, "");
|
|
19
82
|
}
|
|
@@ -70,6 +133,32 @@ function PageBuilderPageContent({
|
|
|
70
133
|
const [layers, setLayers] = useState(existingLayers);
|
|
71
134
|
const [variables, setVariables] = useState(existingVariables);
|
|
72
135
|
const [autoSlug, setAutoSlug] = useState(!id);
|
|
136
|
+
useRegisterPageAIContext({
|
|
137
|
+
routeName: id ? "ui-builder-edit-page" : "ui-builder-new-page",
|
|
138
|
+
pageDescription: buildPageDescription(id, slug, layers, componentRegistry),
|
|
139
|
+
suggestions: [
|
|
140
|
+
"Add a hero section",
|
|
141
|
+
"Add a 3-column feature grid",
|
|
142
|
+
"Make the layout full-width",
|
|
143
|
+
"Add a card with a title, description, and button",
|
|
144
|
+
"Replace the layout with a centered single-column design"
|
|
145
|
+
],
|
|
146
|
+
clientTools: {
|
|
147
|
+
updatePageLayers: async ({ layers: newLayers }) => {
|
|
148
|
+
const store = useLayerStore.getState();
|
|
149
|
+
store.initialize(
|
|
150
|
+
newLayers,
|
|
151
|
+
store.selectedPageId || newLayers[0]?.id,
|
|
152
|
+
void 0,
|
|
153
|
+
store.variables
|
|
154
|
+
);
|
|
155
|
+
return {
|
|
156
|
+
success: true,
|
|
157
|
+
message: `Applied ${newLayers.length} layer(s) to the page`
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
});
|
|
73
162
|
const handleLayersChange = useCallback(
|
|
74
163
|
(newLayers) => {
|
|
75
164
|
setLayers(newLayers);
|
|
@@ -31,10 +31,10 @@ function createPageListLoader(config) {
|
|
|
31
31
|
};
|
|
32
32
|
try {
|
|
33
33
|
if (hooks?.beforeLoadPageList) {
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
34
|
+
await client.runClientHookWithShim(
|
|
35
|
+
() => hooks.beforeLoadPageList(context),
|
|
36
|
+
"Load prevented by beforeLoadPageList hook"
|
|
37
|
+
);
|
|
38
38
|
}
|
|
39
39
|
const client$1 = client.createApiClient({
|
|
40
40
|
baseURL: apiBaseURL,
|
|
@@ -97,10 +97,10 @@ function createPageBuilderLoader(id, config) {
|
|
|
97
97
|
};
|
|
98
98
|
try {
|
|
99
99
|
if (hooks?.beforeLoadPageBuilder) {
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
100
|
+
await client.runClientHookWithShim(
|
|
101
|
+
() => hooks.beforeLoadPageBuilder(id, context),
|
|
102
|
+
"Load prevented by beforeLoadPageBuilder hook"
|
|
103
|
+
);
|
|
104
104
|
}
|
|
105
105
|
const client$1 = client.createApiClient({
|
|
106
106
|
baseURL: apiBaseURL,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { jsx } from 'react/jsx-runtime';
|
|
2
2
|
import { lazy } from 'react';
|
|
3
|
-
import { defineClientPlugin, createApiClient } from '@btst/stack/plugins/client';
|
|
3
|
+
import { defineClientPlugin, createApiClient, runClientHookWithShim } from '@btst/stack/plugins/client';
|
|
4
4
|
import { createRoute } from '@btst/yar';
|
|
5
5
|
import { createCMSQueryKeys } from '../../../../../../plugins/cms/query-keys.mjs';
|
|
6
6
|
import { UI_BUILDER_TYPE_SLUG } from '../schemas.mjs';
|
|
@@ -29,10 +29,10 @@ function createPageListLoader(config) {
|
|
|
29
29
|
};
|
|
30
30
|
try {
|
|
31
31
|
if (hooks?.beforeLoadPageList) {
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
32
|
+
await runClientHookWithShim(
|
|
33
|
+
() => hooks.beforeLoadPageList(context),
|
|
34
|
+
"Load prevented by beforeLoadPageList hook"
|
|
35
|
+
);
|
|
36
36
|
}
|
|
37
37
|
const client = createApiClient({
|
|
38
38
|
baseURL: apiBaseURL,
|
|
@@ -95,10 +95,10 @@ function createPageBuilderLoader(id, config) {
|
|
|
95
95
|
};
|
|
96
96
|
try {
|
|
97
97
|
if (hooks?.beforeLoadPageBuilder) {
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
98
|
+
await runClientHookWithShim(
|
|
99
|
+
() => hooks.beforeLoadPageBuilder(id, context),
|
|
100
|
+
"Load prevented by beforeLoadPageBuilder hook"
|
|
101
|
+
);
|
|
102
102
|
}
|
|
103
103
|
const client = createApiClient({
|
|
104
104
|
baseURL: apiBaseURL,
|
|
@@ -2,6 +2,46 @@
|
|
|
2
2
|
|
|
3
3
|
const client = require('better-call/client');
|
|
4
4
|
|
|
5
|
+
async function runHookWithShim(hookFn, createError, defaultMessage, errorStatus = 403) {
|
|
6
|
+
let result;
|
|
7
|
+
try {
|
|
8
|
+
result = await hookFn();
|
|
9
|
+
} catch (e) {
|
|
10
|
+
throw createError(errorStatus, {
|
|
11
|
+
message: e instanceof Error ? e.message : defaultMessage
|
|
12
|
+
});
|
|
13
|
+
}
|
|
14
|
+
if (typeof result === "boolean") {
|
|
15
|
+
if (process.env.NODE_ENV !== "production") {
|
|
16
|
+
console.warn(
|
|
17
|
+
`[btst] A lifecycle hook returned a boolean (${result}). Boolean returns are deprecated \u2014 throw an Error to deny access instead. IMPORTANT: any code path in this hook that falls through to undefined now ALLOWS access (previously denied). Update the hook to throw new Error("Unauthorized") to deny.`
|
|
18
|
+
);
|
|
19
|
+
}
|
|
20
|
+
if (!result) {
|
|
21
|
+
throw createError(errorStatus, { message: defaultMessage });
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
return result;
|
|
25
|
+
}
|
|
26
|
+
async function runClientHookWithShim(hookFn, defaultMessage) {
|
|
27
|
+
let result;
|
|
28
|
+
try {
|
|
29
|
+
result = await hookFn();
|
|
30
|
+
} catch (e) {
|
|
31
|
+
throw e instanceof Error ? e : new Error(defaultMessage);
|
|
32
|
+
}
|
|
33
|
+
if (typeof result === "boolean") {
|
|
34
|
+
if (process.env.NODE_ENV !== "production") {
|
|
35
|
+
console.warn(
|
|
36
|
+
`[btst] A lifecycle hook returned a boolean (${result}). Boolean returns are deprecated \u2014 throw an Error to deny access instead. IMPORTANT: any code path in this hook that falls through to undefined now ALLOWS access (previously denied). Update the hook to throw new Error("Unauthorized") to deny.`
|
|
37
|
+
);
|
|
38
|
+
}
|
|
39
|
+
if (!result) {
|
|
40
|
+
throw new Error(defaultMessage);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
return result;
|
|
44
|
+
}
|
|
5
45
|
function isConnectionError(err) {
|
|
6
46
|
if (!(err instanceof Error)) return false;
|
|
7
47
|
const code = err.cause?.code ?? err.code;
|
|
@@ -20,3 +60,5 @@ function createApiClient(options) {
|
|
|
20
60
|
|
|
21
61
|
exports.createApiClient = createApiClient;
|
|
22
62
|
exports.isConnectionError = isConnectionError;
|
|
63
|
+
exports.runClientHookWithShim = runClientHookWithShim;
|
|
64
|
+
exports.runHookWithShim = runHookWithShim;
|
|
@@ -1,5 +1,45 @@
|
|
|
1
1
|
import { createClient } from 'better-call/client';
|
|
2
2
|
|
|
3
|
+
async function runHookWithShim(hookFn, createError, defaultMessage, errorStatus = 403) {
|
|
4
|
+
let result;
|
|
5
|
+
try {
|
|
6
|
+
result = await hookFn();
|
|
7
|
+
} catch (e) {
|
|
8
|
+
throw createError(errorStatus, {
|
|
9
|
+
message: e instanceof Error ? e.message : defaultMessage
|
|
10
|
+
});
|
|
11
|
+
}
|
|
12
|
+
if (typeof result === "boolean") {
|
|
13
|
+
if (process.env.NODE_ENV !== "production") {
|
|
14
|
+
console.warn(
|
|
15
|
+
`[btst] A lifecycle hook returned a boolean (${result}). Boolean returns are deprecated \u2014 throw an Error to deny access instead. IMPORTANT: any code path in this hook that falls through to undefined now ALLOWS access (previously denied). Update the hook to throw new Error("Unauthorized") to deny.`
|
|
16
|
+
);
|
|
17
|
+
}
|
|
18
|
+
if (!result) {
|
|
19
|
+
throw createError(errorStatus, { message: defaultMessage });
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
return result;
|
|
23
|
+
}
|
|
24
|
+
async function runClientHookWithShim(hookFn, defaultMessage) {
|
|
25
|
+
let result;
|
|
26
|
+
try {
|
|
27
|
+
result = await hookFn();
|
|
28
|
+
} catch (e) {
|
|
29
|
+
throw e instanceof Error ? e : new Error(defaultMessage);
|
|
30
|
+
}
|
|
31
|
+
if (typeof result === "boolean") {
|
|
32
|
+
if (process.env.NODE_ENV !== "production") {
|
|
33
|
+
console.warn(
|
|
34
|
+
`[btst] A lifecycle hook returned a boolean (${result}). Boolean returns are deprecated \u2014 throw an Error to deny access instead. IMPORTANT: any code path in this hook that falls through to undefined now ALLOWS access (previously denied). Update the hook to throw new Error("Unauthorized") to deny.`
|
|
35
|
+
);
|
|
36
|
+
}
|
|
37
|
+
if (!result) {
|
|
38
|
+
throw new Error(defaultMessage);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
return result;
|
|
42
|
+
}
|
|
3
43
|
function isConnectionError(err) {
|
|
4
44
|
if (!(err instanceof Error)) return false;
|
|
5
45
|
const code = err.cause?.code ?? err.code;
|
|
@@ -16,4 +56,4 @@ function createApiClient(options) {
|
|
|
16
56
|
});
|
|
17
57
|
}
|
|
18
58
|
|
|
19
|
-
export { createApiClient, isConnectionError };
|
|
59
|
+
export { createApiClient, isConnectionError, runClientHookWithShim, runHookWithShim };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { e as AiChatApiRouter, b as AiChatBackendConfig, A as AiChatBackendHooks, a as AiChatMode, C as ChatApiContext, d as aiChatBackendPlugin, c as createAiChatQueryKeys } from '../../../shared/stack.
|
|
1
|
+
export { e as AiChatApiRouter, b as AiChatBackendConfig, A as AiChatBackendHooks, a as AiChatMode, C as ChatApiContext, d as aiChatBackendPlugin, c as createAiChatQueryKeys } from '../../../shared/stack.D-b5zbPm.cjs';
|
|
2
2
|
import { Adapter } from '@btst/db';
|
|
3
3
|
import { C as Conversation, M as Message } from '../../../shared/stack.Be1QIHEn.cjs';
|
|
4
4
|
import '@tanstack/react-query';
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { e as AiChatApiRouter, b as AiChatBackendConfig, A as AiChatBackendHooks, a as AiChatMode, C as ChatApiContext, d as aiChatBackendPlugin, c as createAiChatQueryKeys } from '../../../shared/stack.
|
|
1
|
+
export { e as AiChatApiRouter, b as AiChatBackendConfig, A as AiChatBackendHooks, a as AiChatMode, C as ChatApiContext, d as aiChatBackendPlugin, c as createAiChatQueryKeys } from '../../../shared/stack.FVWf2JhZ.mjs';
|
|
2
2
|
import { Adapter } from '@btst/db';
|
|
3
3
|
import { C as Conversation, M as Message } from '../../../shared/stack.Be1QIHEn.mjs';
|
|
4
4
|
import '@tanstack/react-query';
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { e as AiChatApiRouter, b as AiChatBackendConfig, A as AiChatBackendHooks, a as AiChatMode, C as ChatApiContext, d as aiChatBackendPlugin, c as createAiChatQueryKeys } from '../../../shared/stack.
|
|
1
|
+
export { e as AiChatApiRouter, b as AiChatBackendConfig, A as AiChatBackendHooks, a as AiChatMode, C as ChatApiContext, d as aiChatBackendPlugin, c as createAiChatQueryKeys } from '../../../shared/stack.CTDVxbrA.js';
|
|
2
2
|
import { Adapter } from '@btst/db';
|
|
3
3
|
import { C as Conversation, M as Message } from '../../../shared/stack.Be1QIHEn.js';
|
|
4
4
|
import '@tanstack/react-query';
|