@btst/stack 2.2.0 → 2.4.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 +54 -7
- package/dist/packages/stack/src/plugins/ai-chat/api/plugin.mjs +54 -7
- 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/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 +52 -1
- package/dist/packages/stack/src/plugins/blog/api/plugin.mjs +52 -1
- package/dist/packages/stack/src/plugins/blog/api/query-key-defs.cjs +18 -0
- package/dist/packages/stack/src/plugins/blog/api/query-key-defs.mjs +15 -0
- package/dist/packages/stack/src/plugins/blog/api/serializers.cjs +21 -0
- package/dist/packages/stack/src/plugins/blog/api/serializers.mjs +18 -0
- 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 +15 -0
- package/dist/packages/stack/src/plugins/blog/client/plugin.mjs +16 -1
- package/dist/packages/stack/src/plugins/cms/api/getters.cjs +10 -0
- package/dist/packages/stack/src/plugins/cms/api/getters.mjs +10 -1
- 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 +75 -0
- package/dist/packages/stack/src/plugins/cms/api/plugin.mjs +76 -1
- package/dist/packages/stack/src/plugins/cms/api/query-key-defs.cjs +29 -0
- package/dist/packages/stack/src/plugins/cms/api/query-key-defs.mjs +26 -0
- package/dist/packages/stack/src/plugins/cms/client/plugin.cjs +15 -0
- package/dist/packages/stack/src/plugins/cms/client/plugin.mjs +16 -1
- package/dist/packages/stack/src/plugins/form-builder/api/getters.cjs +9 -0
- package/dist/packages/stack/src/plugins/form-builder/api/getters.mjs +9 -1
- package/dist/packages/stack/src/plugins/form-builder/api/plugin.cjs +62 -1
- package/dist/packages/stack/src/plugins/form-builder/api/plugin.mjs +63 -2
- package/dist/packages/stack/src/plugins/form-builder/api/query-key-defs.cjs +37 -0
- package/dist/packages/stack/src/plugins/form-builder/api/query-key-defs.mjs +33 -0
- package/dist/packages/stack/src/plugins/form-builder/client/plugin.cjs +15 -0
- package/dist/packages/stack/src/plugins/form-builder/client/plugin.mjs +16 -1
- 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 +34 -1
- package/dist/packages/stack/src/plugins/kanban/api/plugin.mjs +34 -1
- package/dist/packages/stack/src/plugins/kanban/api/query-key-defs.cjs +26 -0
- package/dist/packages/stack/src/plugins/kanban/api/query-key-defs.mjs +23 -0
- package/dist/packages/stack/src/plugins/kanban/api/serializers.cjs +30 -0
- package/dist/packages/stack/src/plugins/kanban/api/serializers.mjs +26 -0
- 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 +10 -0
- package/dist/packages/stack/src/plugins/kanban/client/plugin.mjs +11 -1
- 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/utils.cjs +6 -0
- package/dist/packages/stack/src/plugins/utils.mjs +6 -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 +2 -2
- package/dist/plugins/ai-chat/client/index.d.mts +2 -2
- package/dist/plugins/ai-chat/client/index.d.ts +2 -2
- 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.cjs +5 -0
- package/dist/plugins/blog/api/index.d.cts +19 -4
- package/dist/plugins/blog/api/index.d.mts +19 -4
- package/dist/plugins/blog/api/index.d.ts +19 -4
- package/dist/plugins/blog/api/index.mjs +2 -0
- package/dist/plugins/blog/client/hooks/index.d.cts +3 -3
- package/dist/plugins/blog/client/hooks/index.d.mts +3 -3
- package/dist/plugins/blog/client/hooks/index.d.ts +3 -3
- package/dist/plugins/blog/client/index.d.cts +1 -1
- package/dist/plugins/blog/client/index.d.mts +1 -1
- package/dist/plugins/blog/client/index.d.ts +1 -1
- package/dist/plugins/blog/query-keys.cjs +6 -5
- package/dist/plugins/blog/query-keys.d.cts +8 -387
- package/dist/plugins/blog/query-keys.d.mts +8 -387
- package/dist/plugins/blog/query-keys.d.ts +8 -387
- package/dist/plugins/blog/query-keys.mjs +6 -5
- 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 +8 -0
- package/dist/plugins/cms/api/index.d.cts +7 -219
- package/dist/plugins/cms/api/index.d.mts +7 -219
- package/dist/plugins/cms/api/index.d.ts +7 -219
- package/dist/plugins/cms/api/index.mjs +3 -1
- 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/query-keys.cjs +2 -1
- package/dist/plugins/cms/query-keys.d.cts +5 -9
- package/dist/plugins/cms/query-keys.d.mts +5 -9
- package/dist/plugins/cms/query-keys.d.ts +5 -9
- package/dist/plugins/cms/query-keys.mjs +2 -1
- package/dist/plugins/form-builder/api/index.cjs +6 -0
- package/dist/plugins/form-builder/api/index.d.cts +7 -211
- package/dist/plugins/form-builder/api/index.d.mts +7 -211
- package/dist/plugins/form-builder/api/index.d.ts +7 -211
- package/dist/plugins/form-builder/api/index.mjs +2 -1
- 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/query-keys.cjs +3 -2
- package/dist/plugins/form-builder/query-keys.d.cts +6 -6
- package/dist/plugins/form-builder/query-keys.d.mts +6 -6
- package/dist/plugins/form-builder/query-keys.d.ts +6 -6
- package/dist/plugins/form-builder/query-keys.mjs +3 -2
- package/dist/plugins/kanban/api/index.cjs +10 -0
- package/dist/plugins/kanban/api/index.d.cts +17 -392
- package/dist/plugins/kanban/api/index.d.mts +17 -392
- package/dist/plugins/kanban/api/index.d.ts +17 -392
- package/dist/plugins/kanban/api/index.mjs +3 -0
- package/dist/plugins/kanban/client/components/index.d.cts +1 -1
- package/dist/plugins/kanban/client/components/index.d.mts +1 -1
- package/dist/plugins/kanban/client/components/index.d.ts +1 -1
- package/dist/plugins/kanban/client/hooks/index.d.cts +1 -1
- package/dist/plugins/kanban/client/hooks/index.d.mts +1 -1
- package/dist/plugins/kanban/client/hooks/index.d.ts +1 -1
- package/dist/plugins/kanban/client/index.d.cts +1 -1
- package/dist/plugins/kanban/client/index.d.mts +1 -1
- package/dist/plugins/kanban/client/index.d.ts +1 -1
- package/dist/plugins/kanban/query-keys.cjs +2 -9
- package/dist/plugins/kanban/query-keys.d.cts +4 -16
- package/dist/plugins/kanban/query-keys.d.mts +4 -16
- package/dist/plugins/kanban/query-keys.d.ts +4 -16
- package/dist/plugins/kanban/query-keys.mjs +2 -9
- package/dist/plugins/ui-builder/index.d.cts +1 -1
- package/dist/plugins/ui-builder/index.d.mts +1 -1
- package/dist/plugins/ui-builder/index.d.ts +1 -1
- package/dist/shared/stack.B7ONvlD_.d.mts +293 -0
- package/dist/shared/{stack.BeSm90va.d.ts → stack.BEn34wW6.d.ts} +60 -2
- package/dist/shared/stack.BUkC2EsZ.d.cts +327 -0
- 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.BepFXT3w.d.mts +500 -0
- package/dist/shared/stack.CL8ts1Mu.d.ts +419 -0
- package/dist/shared/{stack.CXjzTMsb.d.cts → stack.CVDTkMoO.d.cts} +7 -1
- package/dist/shared/{stack.CXjzTMsb.d.mts → stack.CVDTkMoO.d.mts} +7 -1
- package/dist/shared/{stack.CXjzTMsb.d.ts → stack.CVDTkMoO.d.ts} +7 -1
- package/dist/shared/stack.CczspVn2.d.mts +327 -0
- package/dist/shared/stack.CgWzG5jH.d.ts +500 -0
- package/dist/shared/stack.D3GB6wKv.d.cts +500 -0
- package/dist/shared/stack.DASmUVjX.d.ts +327 -0
- package/dist/shared/{stack.QD1y_7NY.d.cts → stack.DJaKVY7v.d.cts} +1 -1
- package/dist/shared/{stack.QD1y_7NY.d.mts → stack.DJaKVY7v.d.mts} +1 -1
- package/dist/shared/{stack.QD1y_7NY.d.ts → stack.DJaKVY7v.d.ts} +1 -1
- package/dist/shared/{stack.Dg09R0oB.d.mts → stack.DTDxgFj8.d.mts} +60 -2
- package/dist/shared/{stack.CMh_EdxW.d.cts → stack.DWoCZff7.d.cts} +60 -2
- package/dist/shared/{stack.CIrIsc-A.d.cts → stack.DdI5W6MB.d.cts} +7 -1
- package/dist/shared/{stack.CIrIsc-A.d.mts → stack.DdI5W6MB.d.mts} +7 -1
- package/dist/shared/{stack.CIrIsc-A.d.ts → stack.DdI5W6MB.d.ts} +7 -1
- package/dist/shared/stack.Dk5r4W1F.d.mts +419 -0
- package/dist/shared/stack.Kq2-QzOC.d.ts +293 -0
- package/dist/shared/stack.heOA9gzA.d.cts +419 -0
- package/dist/shared/stack.kcdnD4gA.d.cts +293 -0
- package/package.json +16 -3
- 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 +180 -9
- 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/schemas.ts +16 -0
- package/src/plugins/blog/api/index.ts +2 -0
- package/src/plugins/blog/api/plugin.ts +85 -0
- package/src/plugins/blog/api/query-key-defs.ts +46 -0
- package/src/plugins/blog/api/serializers.ts +27 -0
- 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 +19 -0
- package/src/plugins/blog/query-keys.ts +5 -7
- package/src/plugins/client/index.ts +1 -1
- package/src/plugins/cms/api/getters.ts +24 -0
- package/src/plugins/cms/api/index.ts +14 -1
- package/src/plugins/cms/api/mutations.ts +84 -0
- package/src/plugins/cms/api/plugin.ts +114 -0
- package/src/plugins/cms/api/query-key-defs.ts +53 -0
- package/src/plugins/cms/api/serializers.ts +12 -0
- package/src/plugins/cms/client/plugin.tsx +19 -0
- package/src/plugins/cms/query-keys.ts +2 -1
- package/src/plugins/form-builder/api/getters.ts +23 -0
- package/src/plugins/form-builder/api/index.ts +15 -2
- package/src/plugins/form-builder/api/plugin.ts +91 -0
- package/src/plugins/form-builder/api/query-key-defs.ts +79 -0
- package/src/plugins/form-builder/api/serializers.ts +12 -0
- package/src/plugins/form-builder/client/plugin.tsx +19 -0
- package/src/plugins/form-builder/query-keys.ts +6 -2
- package/src/plugins/kanban/api/index.ts +9 -0
- package/src/plugins/kanban/api/mutations.ts +169 -0
- package/src/plugins/kanban/api/plugin.ts +61 -0
- package/src/plugins/kanban/api/query-key-defs.ts +54 -0
- package/src/plugins/kanban/api/serializers.ts +49 -0
- package/src/plugins/kanban/client/hooks/kanban-hooks.tsx +4 -0
- package/src/plugins/kanban/client/plugin.tsx +13 -0
- package/src/plugins/kanban/query-keys.ts +2 -9
- package/src/plugins/ui-builder/client/components/pages/page-builder-page.internal.tsx +132 -0
- package/src/plugins/utils.ts +19 -0
- package/dist/shared/{stack.BkYlUT_8.d.cts → stack.BQmuNl5p.d.cts} +6 -6
- package/dist/shared/{stack.BkYlUT_8.d.mts → stack.BQmuNl5p.d.mts} +6 -6
- package/dist/shared/{stack.BkYlUT_8.d.ts → stack.BQmuNl5p.d.ts} +6 -6
|
@@ -0,0 +1,293 @@
|
|
|
1
|
+
import * as _btst_stack_plugins_api from '@btst/stack/plugins/api';
|
|
2
|
+
import * as better_call from 'better-call';
|
|
3
|
+
import { S as SerializedForm, b as SerializedFormSubmissionWithData, F as Form, d as FormSubmission, a as SerializedFormSubmission, e as FormSubmissionWithForm, f as FormBuilderBackendConfig } from './stack.DdI5W6MB.cjs';
|
|
4
|
+
import { z } from 'zod';
|
|
5
|
+
import { Adapter } from '@btst/db';
|
|
6
|
+
import { QueryClient } from '@tanstack/react-query';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Serialize a Form for SSR/SSG use (convert dates to strings).
|
|
10
|
+
*/
|
|
11
|
+
declare function serializeForm(form: Form): SerializedForm;
|
|
12
|
+
/**
|
|
13
|
+
* Serialize a FormSubmission for SSR/SSG use (convert dates to strings).
|
|
14
|
+
*/
|
|
15
|
+
declare function serializeFormSubmission(submission: FormSubmission): SerializedFormSubmission;
|
|
16
|
+
/**
|
|
17
|
+
* Serialize a FormSubmission with parsed data and joined Form.
|
|
18
|
+
* If `submission.data` is corrupted JSON, `parsedData` is set to `null` rather
|
|
19
|
+
* than throwing, so one bad row cannot crash the entire list or SSG build.
|
|
20
|
+
*/
|
|
21
|
+
declare function serializeFormSubmissionWithData(submission: FormSubmissionWithForm): SerializedFormSubmissionWithData;
|
|
22
|
+
/**
|
|
23
|
+
* Retrieve all forms with optional status filter and pagination.
|
|
24
|
+
* Pure DB function — no hooks, no HTTP context. Safe for SSG and server-side use.
|
|
25
|
+
*
|
|
26
|
+
* @remarks **Security:** Authorization hooks (e.g. `onBeforeListForms`) are NOT
|
|
27
|
+
* called. The caller is responsible for any access-control checks before
|
|
28
|
+
* invoking this function.
|
|
29
|
+
*
|
|
30
|
+
* @param adapter - The database adapter
|
|
31
|
+
* @param params - Optional filter/pagination parameters
|
|
32
|
+
*/
|
|
33
|
+
declare function getAllForms(adapter: Adapter, params?: {
|
|
34
|
+
status?: string;
|
|
35
|
+
limit?: number;
|
|
36
|
+
offset?: number;
|
|
37
|
+
}): Promise<{
|
|
38
|
+
items: SerializedForm[];
|
|
39
|
+
total: number;
|
|
40
|
+
limit?: number;
|
|
41
|
+
offset?: number;
|
|
42
|
+
}>;
|
|
43
|
+
/**
|
|
44
|
+
* Retrieve a single form by its ID (UUID).
|
|
45
|
+
* Returns null if the form is not found.
|
|
46
|
+
* Pure DB function — no hooks, no HTTP context. Safe for SSG and server-side use.
|
|
47
|
+
*
|
|
48
|
+
* @remarks **Security:** Authorization hooks are NOT called. The caller is
|
|
49
|
+
* responsible for any access-control checks before invoking this function.
|
|
50
|
+
*
|
|
51
|
+
* @param adapter - The database adapter
|
|
52
|
+
* @param id - The form UUID
|
|
53
|
+
*/
|
|
54
|
+
declare function getFormById(adapter: Adapter, id: string): Promise<SerializedForm | null>;
|
|
55
|
+
/**
|
|
56
|
+
* Retrieve a single form by its slug.
|
|
57
|
+
* Returns null if the form is not found.
|
|
58
|
+
* Pure DB function — no hooks, no HTTP context. Safe for SSG and server-side use.
|
|
59
|
+
*
|
|
60
|
+
* @remarks **Security:** Authorization hooks are NOT called. The caller is
|
|
61
|
+
* responsible for any access-control checks before invoking this function.
|
|
62
|
+
*
|
|
63
|
+
* @param adapter - The database adapter
|
|
64
|
+
* @param slug - The form slug
|
|
65
|
+
*/
|
|
66
|
+
declare function getFormBySlug(adapter: Adapter, slug: string): Promise<SerializedForm | null>;
|
|
67
|
+
/**
|
|
68
|
+
* Retrieve submissions for a form by form ID, with optional pagination.
|
|
69
|
+
* Returns an empty result if the form does not exist.
|
|
70
|
+
* Pure DB function — no hooks, no HTTP context. Safe for server-side use.
|
|
71
|
+
*
|
|
72
|
+
* @remarks **Security:** Authorization hooks are NOT called. The caller is
|
|
73
|
+
* responsible for any access-control checks before invoking this function.
|
|
74
|
+
*
|
|
75
|
+
* @param adapter - The database adapter
|
|
76
|
+
* @param formId - The form ID
|
|
77
|
+
* @param params - Optional pagination parameters
|
|
78
|
+
*/
|
|
79
|
+
declare function getFormSubmissions(adapter: Adapter, formId: string, params?: {
|
|
80
|
+
limit?: number;
|
|
81
|
+
offset?: number;
|
|
82
|
+
}): Promise<{
|
|
83
|
+
items: SerializedFormSubmissionWithData[];
|
|
84
|
+
total: number;
|
|
85
|
+
limit?: number;
|
|
86
|
+
offset?: number;
|
|
87
|
+
}>;
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Route keys for the Form Builder plugin — matches the keys returned by
|
|
91
|
+
* `stackClient.router.getRoute(path).routeKey`.
|
|
92
|
+
*/
|
|
93
|
+
type FormBuilderRouteKey = "formList" | "newForm" | "editForm" | "submissions";
|
|
94
|
+
interface FormBuilderPrefetchForRoute {
|
|
95
|
+
(key: "formList" | "newForm", qc: QueryClient): Promise<void>;
|
|
96
|
+
(key: "editForm" | "submissions", qc: QueryClient, params: {
|
|
97
|
+
id: string;
|
|
98
|
+
}): Promise<void>;
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Form Builder backend plugin
|
|
102
|
+
* Provides API endpoints for managing forms and form submissions
|
|
103
|
+
*
|
|
104
|
+
* @param config - Configuration with optional hooks
|
|
105
|
+
*/
|
|
106
|
+
declare const formBuilderBackendPlugin: (config?: FormBuilderBackendConfig) => _btst_stack_plugins_api.BackendPlugin<{
|
|
107
|
+
listForms: better_call.StrictEndpoint<"/forms", {
|
|
108
|
+
method: "GET";
|
|
109
|
+
query: z.ZodObject<{
|
|
110
|
+
status: z.ZodOptional<z.ZodEnum<{
|
|
111
|
+
active: "active";
|
|
112
|
+
inactive: "inactive";
|
|
113
|
+
archived: "archived";
|
|
114
|
+
}>>;
|
|
115
|
+
limit: z.ZodDefault<z.ZodOptional<z.ZodCoercedNumber<unknown>>>;
|
|
116
|
+
offset: z.ZodDefault<z.ZodOptional<z.ZodCoercedNumber<unknown>>>;
|
|
117
|
+
}, z.core.$strip>;
|
|
118
|
+
}, {
|
|
119
|
+
items: SerializedForm[];
|
|
120
|
+
total: number;
|
|
121
|
+
limit?: number;
|
|
122
|
+
offset?: number;
|
|
123
|
+
}>;
|
|
124
|
+
getFormBySlug: better_call.StrictEndpoint<"/forms/:slug", {
|
|
125
|
+
method: "GET";
|
|
126
|
+
params: z.ZodObject<{
|
|
127
|
+
slug: z.ZodString;
|
|
128
|
+
}, z.core.$strip>;
|
|
129
|
+
}, SerializedForm>;
|
|
130
|
+
getFormById: better_call.StrictEndpoint<"/forms/id/:id", {
|
|
131
|
+
method: "GET";
|
|
132
|
+
params: z.ZodObject<{
|
|
133
|
+
id: z.ZodString;
|
|
134
|
+
}, z.core.$strip>;
|
|
135
|
+
}, SerializedForm>;
|
|
136
|
+
createForm: better_call.StrictEndpoint<"/forms", {
|
|
137
|
+
method: "POST";
|
|
138
|
+
body: z.ZodObject<{
|
|
139
|
+
name: z.ZodString;
|
|
140
|
+
slug: z.ZodString;
|
|
141
|
+
description: z.ZodOptional<z.ZodString>;
|
|
142
|
+
schema: z.ZodString;
|
|
143
|
+
successMessage: z.ZodOptional<z.ZodString>;
|
|
144
|
+
redirectUrl: z.ZodUnion<[z.ZodOptional<z.ZodString>, z.ZodLiteral<"">]>;
|
|
145
|
+
status: z.ZodDefault<z.ZodOptional<z.ZodEnum<{
|
|
146
|
+
active: "active";
|
|
147
|
+
inactive: "inactive";
|
|
148
|
+
archived: "archived";
|
|
149
|
+
}>>>;
|
|
150
|
+
}, z.core.$strip>;
|
|
151
|
+
}, SerializedForm>;
|
|
152
|
+
updateForm: better_call.StrictEndpoint<"/forms/:id", {
|
|
153
|
+
method: "PUT";
|
|
154
|
+
params: z.ZodObject<{
|
|
155
|
+
id: z.ZodString;
|
|
156
|
+
}, z.core.$strip>;
|
|
157
|
+
body: z.ZodObject<{
|
|
158
|
+
name: z.ZodOptional<z.ZodString>;
|
|
159
|
+
slug: z.ZodOptional<z.ZodString>;
|
|
160
|
+
description: z.ZodOptional<z.ZodString>;
|
|
161
|
+
schema: z.ZodOptional<z.ZodString>;
|
|
162
|
+
successMessage: z.ZodOptional<z.ZodString>;
|
|
163
|
+
redirectUrl: z.ZodUnion<[z.ZodOptional<z.ZodString>, z.ZodLiteral<"">]>;
|
|
164
|
+
status: z.ZodOptional<z.ZodEnum<{
|
|
165
|
+
active: "active";
|
|
166
|
+
inactive: "inactive";
|
|
167
|
+
archived: "archived";
|
|
168
|
+
}>>;
|
|
169
|
+
}, z.core.$strip>;
|
|
170
|
+
}, SerializedForm>;
|
|
171
|
+
deleteForm: better_call.StrictEndpoint<"/forms/:id", {
|
|
172
|
+
method: "DELETE";
|
|
173
|
+
params: z.ZodObject<{
|
|
174
|
+
id: z.ZodString;
|
|
175
|
+
}, z.core.$strip>;
|
|
176
|
+
}, {
|
|
177
|
+
success: boolean;
|
|
178
|
+
}>;
|
|
179
|
+
submitForm: better_call.StrictEndpoint<"/forms/:slug/submit", {
|
|
180
|
+
method: "POST";
|
|
181
|
+
params: z.ZodObject<{
|
|
182
|
+
slug: z.ZodString;
|
|
183
|
+
}, z.core.$strip>;
|
|
184
|
+
body: z.ZodObject<{
|
|
185
|
+
data: z.ZodObject<{}, z.core.$loose>;
|
|
186
|
+
}, z.core.$strip>;
|
|
187
|
+
}, {
|
|
188
|
+
form: {
|
|
189
|
+
successMessage: string | undefined;
|
|
190
|
+
redirectUrl: string | undefined;
|
|
191
|
+
};
|
|
192
|
+
submittedAt: string;
|
|
193
|
+
id: string;
|
|
194
|
+
data: string;
|
|
195
|
+
formId: string;
|
|
196
|
+
submittedBy?: string | undefined;
|
|
197
|
+
ipAddress?: string | undefined;
|
|
198
|
+
userAgent?: string | undefined;
|
|
199
|
+
}>;
|
|
200
|
+
listSubmissions: better_call.StrictEndpoint<"/forms/:formId/submissions", {
|
|
201
|
+
method: "GET";
|
|
202
|
+
params: z.ZodObject<{
|
|
203
|
+
formId: z.ZodString;
|
|
204
|
+
}, z.core.$strip>;
|
|
205
|
+
query: z.ZodObject<{
|
|
206
|
+
limit: z.ZodDefault<z.ZodOptional<z.ZodCoercedNumber<unknown>>>;
|
|
207
|
+
offset: z.ZodDefault<z.ZodOptional<z.ZodCoercedNumber<unknown>>>;
|
|
208
|
+
}, z.core.$strip>;
|
|
209
|
+
}, {
|
|
210
|
+
items: SerializedFormSubmissionWithData[];
|
|
211
|
+
total: number;
|
|
212
|
+
limit?: number;
|
|
213
|
+
offset?: number;
|
|
214
|
+
}>;
|
|
215
|
+
getSubmission: better_call.StrictEndpoint<"/forms/:formId/submissions/:subId", {
|
|
216
|
+
method: "GET";
|
|
217
|
+
params: z.ZodObject<{
|
|
218
|
+
formId: z.ZodString;
|
|
219
|
+
subId: z.ZodString;
|
|
220
|
+
}, z.core.$strip>;
|
|
221
|
+
}, SerializedFormSubmissionWithData<Record<string, unknown>>>;
|
|
222
|
+
deleteSubmission: better_call.StrictEndpoint<"/forms/:formId/submissions/:subId", {
|
|
223
|
+
method: "DELETE";
|
|
224
|
+
params: z.ZodObject<{
|
|
225
|
+
formId: z.ZodString;
|
|
226
|
+
subId: z.ZodString;
|
|
227
|
+
}, z.core.$strip>;
|
|
228
|
+
}, {
|
|
229
|
+
success: boolean;
|
|
230
|
+
}>;
|
|
231
|
+
}, {
|
|
232
|
+
getAllForms: (params?: Parameters<typeof getAllForms>[1]) => Promise<{
|
|
233
|
+
items: SerializedForm[];
|
|
234
|
+
total: number;
|
|
235
|
+
limit?: number;
|
|
236
|
+
offset?: number;
|
|
237
|
+
}>;
|
|
238
|
+
getFormById: (id: string) => Promise<SerializedForm | null>;
|
|
239
|
+
getFormBySlug: (slug: string) => Promise<SerializedForm | null>;
|
|
240
|
+
getFormSubmissions: (formId: string, params?: Parameters<typeof getFormSubmissions>[2]) => Promise<{
|
|
241
|
+
items: SerializedFormSubmissionWithData[];
|
|
242
|
+
total: number;
|
|
243
|
+
limit?: number;
|
|
244
|
+
offset?: number;
|
|
245
|
+
}>;
|
|
246
|
+
prefetchForRoute: FormBuilderPrefetchForRoute;
|
|
247
|
+
}>;
|
|
248
|
+
type FormBuilderApiRouter = ReturnType<ReturnType<typeof formBuilderBackendPlugin>["routes"]>;
|
|
249
|
+
|
|
250
|
+
/**
|
|
251
|
+
* Internal query key constants for the Form Builder plugin.
|
|
252
|
+
* Shared between query-keys.ts (HTTP path) and prefetchForRoute (DB path)
|
|
253
|
+
* to prevent key drift between SSR loaders and SSG prefetching.
|
|
254
|
+
*/
|
|
255
|
+
interface FormsListDiscriminator {
|
|
256
|
+
status?: "active" | "inactive" | "archived";
|
|
257
|
+
limit: number;
|
|
258
|
+
offset: number;
|
|
259
|
+
}
|
|
260
|
+
interface SubmissionsListDiscriminator {
|
|
261
|
+
formId: string;
|
|
262
|
+
limit: number;
|
|
263
|
+
offset: number;
|
|
264
|
+
}
|
|
265
|
+
/** Full query key builders — use these with queryClient.setQueryData() */
|
|
266
|
+
declare const FORM_QUERY_KEYS: {
|
|
267
|
+
/**
|
|
268
|
+
* Key for forms.list(params) query.
|
|
269
|
+
* Full key: ["forms", "list", "list", { status, limit, offset }]
|
|
270
|
+
*/
|
|
271
|
+
formsList: (params?: {
|
|
272
|
+
status?: "active" | "inactive" | "archived";
|
|
273
|
+
limit?: number;
|
|
274
|
+
offset?: number;
|
|
275
|
+
}) => readonly ["forms", "list", "list", FormsListDiscriminator];
|
|
276
|
+
/**
|
|
277
|
+
* Key for forms.byId(id) query.
|
|
278
|
+
* Full key: ["forms", "byId", "byId", id]
|
|
279
|
+
*/
|
|
280
|
+
formById: (id: string) => readonly ["forms", "byId", "byId", string];
|
|
281
|
+
/**
|
|
282
|
+
* Key for formSubmissions.list(params) query.
|
|
283
|
+
* Full key: ["formSubmissions", "list", { formId, limit, offset }]
|
|
284
|
+
*/
|
|
285
|
+
submissionsList: (params: {
|
|
286
|
+
formId: string;
|
|
287
|
+
limit?: number;
|
|
288
|
+
offset?: number;
|
|
289
|
+
}) => readonly ["formSubmissions", "list", SubmissionsListDiscriminator];
|
|
290
|
+
};
|
|
291
|
+
|
|
292
|
+
export { getFormById as c, getFormBySlug as d, getFormSubmissions as e, formBuilderBackendPlugin as f, getAllForms as g, serializeFormSubmission as h, serializeFormSubmissionWithData as i, FORM_QUERY_KEYS as j, serializeForm as s };
|
|
293
|
+
export type { FormBuilderApiRouter as F, SubmissionsListDiscriminator as S, FormsListDiscriminator as a, FormBuilderRouteKey as b };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@btst/stack",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.4.0",
|
|
4
4
|
"description": "A composable, plugin-based library for building full-stack applications.",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -163,6 +163,16 @@
|
|
|
163
163
|
"default": "./dist/plugins/ai-chat/client/hooks/index.cjs"
|
|
164
164
|
}
|
|
165
165
|
},
|
|
166
|
+
"./plugins/ai-chat/client/context": {
|
|
167
|
+
"import": {
|
|
168
|
+
"types": "./dist/plugins/ai-chat/client/context/page-ai-context.d.ts",
|
|
169
|
+
"default": "./dist/plugins/ai-chat/client/context/page-ai-context.mjs"
|
|
170
|
+
},
|
|
171
|
+
"require": {
|
|
172
|
+
"types": "./dist/plugins/ai-chat/client/context/page-ai-context.d.cts",
|
|
173
|
+
"default": "./dist/plugins/ai-chat/client/context/page-ai-context.cjs"
|
|
174
|
+
}
|
|
175
|
+
},
|
|
166
176
|
"./plugins/ai-chat/css": "./dist/plugins/ai-chat/style.css",
|
|
167
177
|
"./plugins/blog/css": "./dist/plugins/blog/style.css",
|
|
168
178
|
"./plugins/cms/api": {
|
|
@@ -392,6 +402,9 @@
|
|
|
392
402
|
"plugins/ai-chat/client/hooks": [
|
|
393
403
|
"./dist/plugins/ai-chat/client/hooks/index.d.ts"
|
|
394
404
|
],
|
|
405
|
+
"plugins/ai-chat/client/context": [
|
|
406
|
+
"./dist/plugins/ai-chat/client/context/page-ai-context.d.ts"
|
|
407
|
+
],
|
|
395
408
|
"plugins/cms/api": [
|
|
396
409
|
"./dist/plugins/cms/api/index.d.ts"
|
|
397
410
|
],
|
|
@@ -458,7 +471,7 @@
|
|
|
458
471
|
},
|
|
459
472
|
"peerDependencies": {
|
|
460
473
|
"@ai-sdk/react": ">=2.0.0",
|
|
461
|
-
"@btst/yar": ">=1.
|
|
474
|
+
"@btst/yar": ">=1.2.0",
|
|
462
475
|
"@hookform/resolvers": ">=5.0.0",
|
|
463
476
|
"@radix-ui/react-dialog": ">=1.1.0",
|
|
464
477
|
"@radix-ui/react-label": ">=2.1.0",
|
|
@@ -494,7 +507,7 @@
|
|
|
494
507
|
"devDependencies": {
|
|
495
508
|
"@ai-sdk/react": "^2.0.94",
|
|
496
509
|
"@btst/adapter-memory": "2.0.3",
|
|
497
|
-
"@btst/yar": "1.
|
|
510
|
+
"@btst/yar": "1.2.0",
|
|
498
511
|
"@types/react": "^19.0.0",
|
|
499
512
|
"@types/slug": "^5.0.9",
|
|
500
513
|
"@workspace/ui": "workspace:*",
|
|
@@ -89,10 +89,13 @@ export function ComposedRoute({
|
|
|
89
89
|
}) {
|
|
90
90
|
if (PageComponent) {
|
|
91
91
|
const content = <PageComponent {...props} />;
|
|
92
|
-
//
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
92
|
+
// Always provide the same fallback on server and client — using
|
|
93
|
+
// `typeof window !== "undefined"` here would produce a different JSX tree
|
|
94
|
+
// on each side, shifting React's useId() counter and causing hydration
|
|
95
|
+
// mismatches in any descendant that uses Radix (Select, Dialog, etc.).
|
|
96
|
+
// If the Suspense boundary never actually suspends during SSR (data is
|
|
97
|
+
// prefetched), React won't emit the fallback into the HTML anyway.
|
|
98
|
+
const suspenseFallback = LoadingComponent ? <LoadingComponent /> : null;
|
|
96
99
|
|
|
97
100
|
// If an ErrorComponent is provided (which itself may be lazy), ensure we have
|
|
98
101
|
// a Suspense boundary that can handle both the page content and the lazy error UI
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import { tool } from "ai";
|
|
2
|
+
import type { Tool } from "ai";
|
|
3
|
+
import { z } from "zod";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Maps each built-in page tool to the route names that are permitted to request it.
|
|
7
|
+
*
|
|
8
|
+
* The server cross-checks the `routeName` field sent with every chat request
|
|
9
|
+
* against this allowlist before including a built-in tool in the streamText call.
|
|
10
|
+
* A tool is only activated when both conditions are true:
|
|
11
|
+
* 1. The tool name appears in the request's `availableTools` list, AND
|
|
12
|
+
* 2. The request's `routeName` is in this tool's allowlist.
|
|
13
|
+
*
|
|
14
|
+
* Consumer-defined tools (via `clientToolSchemas`) are not validated here —
|
|
15
|
+
* the consumer is responsible for their own access control.
|
|
16
|
+
*/
|
|
17
|
+
export const BUILT_IN_PAGE_TOOL_ROUTE_ALLOWLIST: Record<string, string[]> = {
|
|
18
|
+
/** Blog new-post and edit-post pages */
|
|
19
|
+
fillBlogForm: ["blog-new-post", "blog-edit-post", "newPost", "editPost"],
|
|
20
|
+
/** UI builder edit page */
|
|
21
|
+
updatePageLayers: ["ui-builder-edit-page"],
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Built-in client-side-only tool schemas for route-aware AI context.
|
|
26
|
+
*
|
|
27
|
+
* These tools have no `execute` function — they are handled on the client side
|
|
28
|
+
* via the onToolCall handler in ChatInterface, which dispatches to handlers
|
|
29
|
+
* registered by pages via useRegisterPageAIContext.
|
|
30
|
+
*
|
|
31
|
+
* Consumers can add their own tool schemas via `clientToolSchemas` in AiChatBackendConfig.
|
|
32
|
+
*/
|
|
33
|
+
export const BUILT_IN_PAGE_TOOL_SCHEMAS: Record<string, Tool> = {
|
|
34
|
+
/**
|
|
35
|
+
* Fill in the blog post editor form fields.
|
|
36
|
+
* Registered by blog new/edit page via useRegisterPageAIContext.
|
|
37
|
+
*/
|
|
38
|
+
fillBlogForm: tool({
|
|
39
|
+
description:
|
|
40
|
+
"Fill in the blog post editor form fields. Call this when the user asks to write, draft, or populate a blog post. You can fill any combination of title, content, excerpt, and tags.",
|
|
41
|
+
inputSchema: z.object({
|
|
42
|
+
title: z.string().optional().describe("The post title"),
|
|
43
|
+
content: z
|
|
44
|
+
.string()
|
|
45
|
+
.optional()
|
|
46
|
+
.describe(
|
|
47
|
+
"Full markdown content for the post body. Use proper markdown formatting with headings, lists, etc.",
|
|
48
|
+
),
|
|
49
|
+
excerpt: z
|
|
50
|
+
.string()
|
|
51
|
+
.optional()
|
|
52
|
+
.describe("A short summary/excerpt of the post (1-2 sentences)"),
|
|
53
|
+
tags: z
|
|
54
|
+
.array(z.string())
|
|
55
|
+
.optional()
|
|
56
|
+
.describe("Array of tag names to apply to the post"),
|
|
57
|
+
}),
|
|
58
|
+
}),
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Replace the UI builder page layers with new ones.
|
|
62
|
+
* Registered by the UI builder edit page via useRegisterPageAIContext.
|
|
63
|
+
*/
|
|
64
|
+
updatePageLayers: tool({
|
|
65
|
+
description: `Replace the UI builder page component layers. Call this when the user asks to change, add, redesign, or update the page layout and components.
|
|
66
|
+
|
|
67
|
+
Rules:
|
|
68
|
+
- Provide the COMPLETE layer tree, not a partial diff. The entire tree will replace the current layers.
|
|
69
|
+
- Only use component types that appear in the "Available Component Types" list in the page context.
|
|
70
|
+
- Every layer must have a unique \`id\` string (e.g. "hero-section", "card-title-1").
|
|
71
|
+
- The \`type\` field must exactly match a name from the component registry (e.g. "div", "Button", "Card", "Flexbox").
|
|
72
|
+
- The \`name\` field is the human-readable label shown in the layers panel.
|
|
73
|
+
- \`props\` contains component-specific props (className uses Tailwind classes).
|
|
74
|
+
- \`children\` is either an array of child ComponentLayer objects, or a plain string for text content.
|
|
75
|
+
- Use \`Flexbox\` or \`Grid\` for layout instead of raw div flex/grid when possible.
|
|
76
|
+
- Preserve any layers the user has not asked to change — read the current layers from the page context first.
|
|
77
|
+
- ALWAYS use shadcn/ui semantic color tokens in className (e.g. bg-background, bg-card, bg-primary, text-foreground, text-muted-foreground, text-primary-foreground, border-border) instead of hardcoded Tailwind colors like bg-white, bg-gray-*, text-black, etc. This ensures the UI automatically adapts to light and dark themes.`,
|
|
78
|
+
inputSchema: z.object({
|
|
79
|
+
layers: z
|
|
80
|
+
.array(
|
|
81
|
+
z.object({
|
|
82
|
+
id: z.string().describe("Unique identifier for this layer"),
|
|
83
|
+
type: z
|
|
84
|
+
.string()
|
|
85
|
+
.describe(
|
|
86
|
+
"Component type — must match a key in the component registry (e.g. 'div', 'Button', 'Card', 'Flexbox')",
|
|
87
|
+
),
|
|
88
|
+
name: z
|
|
89
|
+
.string()
|
|
90
|
+
.describe(
|
|
91
|
+
"Human-readable display name shown in the layers panel",
|
|
92
|
+
),
|
|
93
|
+
props: z
|
|
94
|
+
.record(z.string(), z.any())
|
|
95
|
+
.describe(
|
|
96
|
+
"Component props object. Use Tailwind classes for className. See the component registry for valid props per type.",
|
|
97
|
+
),
|
|
98
|
+
children: z
|
|
99
|
+
.any()
|
|
100
|
+
.optional()
|
|
101
|
+
.describe(
|
|
102
|
+
"Child layers (array of ComponentLayer) or plain text string",
|
|
103
|
+
),
|
|
104
|
+
}),
|
|
105
|
+
)
|
|
106
|
+
.describe(
|
|
107
|
+
"Complete replacement layer tree. Must include ALL layers for the page, not just changed ones.",
|
|
108
|
+
),
|
|
109
|
+
}),
|
|
110
|
+
}),
|
|
111
|
+
};
|