@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,327 @@
|
|
|
1
|
+
import * as _btst_stack_plugins_api from '@btst/stack/plugins/api';
|
|
2
|
+
import { a as SerializedContentItemWithType, S as SerializedContentType, b as ContentType, c as ContentItem, d as SerializedContentItem, e as ContentItemWithType, f as CMSBackendConfig, I as InverseRelation } from './stack.CVDTkMoO.js';
|
|
3
|
+
import * as better_call from 'better-call';
|
|
4
|
+
import { z } from 'zod';
|
|
5
|
+
import { Adapter } from '@btst/db';
|
|
6
|
+
import { QueryClient } from '@tanstack/react-query';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Serialize a ContentType for SSR/SSG use (convert dates to strings).
|
|
10
|
+
* Applies lazy migration for legacy schemas (version 1 → 2).
|
|
11
|
+
*/
|
|
12
|
+
declare function serializeContentType(ct: ContentType): SerializedContentType;
|
|
13
|
+
/**
|
|
14
|
+
* Serialize a ContentItem for SSR/SSG use (convert dates to strings).
|
|
15
|
+
*/
|
|
16
|
+
declare function serializeContentItem(item: ContentItem): SerializedContentItem;
|
|
17
|
+
/**
|
|
18
|
+
* Serialize a ContentItem with parsed data and joined ContentType.
|
|
19
|
+
* Throws a SyntaxError if `item.data` is not valid JSON, so corrupted rows
|
|
20
|
+
* produce a visible, debuggable error rather than silently returning null.
|
|
21
|
+
*/
|
|
22
|
+
declare function serializeContentItemWithType(item: ContentItemWithType): SerializedContentItemWithType;
|
|
23
|
+
/**
|
|
24
|
+
* Retrieve all content types.
|
|
25
|
+
* Pure DB function — no hooks, no HTTP context. Safe for SSG and server-side use.
|
|
26
|
+
*
|
|
27
|
+
* @remarks **Security:** Authorization hooks are NOT called. The caller is
|
|
28
|
+
* responsible for any access-control checks before invoking this function.
|
|
29
|
+
*
|
|
30
|
+
* @param adapter - The database adapter
|
|
31
|
+
*/
|
|
32
|
+
declare function getAllContentTypes(adapter: Adapter): Promise<SerializedContentType[]>;
|
|
33
|
+
/**
|
|
34
|
+
* Retrieve all content items for a given content type, with optional pagination.
|
|
35
|
+
* Pure DB function — no hooks, no HTTP context. Safe for SSG and server-side use.
|
|
36
|
+
*
|
|
37
|
+
* @remarks **Security:** Authorization hooks (e.g. `onBeforeListItems`) are NOT
|
|
38
|
+
* called. The caller is responsible for any access-control checks before
|
|
39
|
+
* invoking this function.
|
|
40
|
+
*
|
|
41
|
+
* @param adapter - The database adapter
|
|
42
|
+
* @param contentTypeSlug - The slug of the content type to query
|
|
43
|
+
* @param params - Optional filter/pagination parameters
|
|
44
|
+
*/
|
|
45
|
+
declare function getAllContentItems(adapter: Adapter, contentTypeSlug: string, params?: {
|
|
46
|
+
slug?: string;
|
|
47
|
+
limit?: number;
|
|
48
|
+
offset?: number;
|
|
49
|
+
}): Promise<{
|
|
50
|
+
items: SerializedContentItemWithType[];
|
|
51
|
+
total: number;
|
|
52
|
+
limit?: number;
|
|
53
|
+
offset?: number;
|
|
54
|
+
}>;
|
|
55
|
+
/**
|
|
56
|
+
* Retrieve a single content item by its ID.
|
|
57
|
+
* Returns null if the item 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 id - The content item ID (UUID)
|
|
65
|
+
*/
|
|
66
|
+
declare function getContentItemById(adapter: Adapter, id: string): Promise<SerializedContentItemWithType | null>;
|
|
67
|
+
/**
|
|
68
|
+
* Retrieve a single content item by its slug within a content type.
|
|
69
|
+
* Returns null if the content type or item is not found.
|
|
70
|
+
* Pure DB function — no hooks, no HTTP context. Safe for SSG and 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 contentTypeSlug - The slug of the content type
|
|
77
|
+
* @param slug - The slug of the content item
|
|
78
|
+
*/
|
|
79
|
+
declare function getContentItemBySlug(adapter: Adapter, contentTypeSlug: string, slug: string): Promise<SerializedContentItemWithType | null>;
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Input for creating a new CMS content item.
|
|
83
|
+
*/
|
|
84
|
+
interface CreateCMSContentItemInput {
|
|
85
|
+
/** URL-safe slug for the item */
|
|
86
|
+
slug: string;
|
|
87
|
+
/** Arbitrary data payload — should match the content type schema */
|
|
88
|
+
data: Record<string, unknown>;
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Create a new content item for a content type (looked up by slug).
|
|
92
|
+
*
|
|
93
|
+
* Bypasses Zod schema validation and relation processing — the caller is
|
|
94
|
+
* responsible for providing valid, relation-free data. For relation fields or
|
|
95
|
+
* schema validation, use the HTTP endpoint instead.
|
|
96
|
+
*
|
|
97
|
+
* Throws if the content type is not found or the slug is already taken within
|
|
98
|
+
* that content type.
|
|
99
|
+
*
|
|
100
|
+
* @remarks **Security:** No authorization hooks (`onBeforeCreate`, `onAfterCreate`)
|
|
101
|
+
* are called. The caller is responsible for any access-control checks before
|
|
102
|
+
* invoking this function.
|
|
103
|
+
*
|
|
104
|
+
* @param adapter - The database adapter
|
|
105
|
+
* @param contentTypeSlug - Slug of the target content type
|
|
106
|
+
* @param input - Item slug and data payload
|
|
107
|
+
*/
|
|
108
|
+
declare function createCMSContentItem(adapter: Adapter, contentTypeSlug: string, input: CreateCMSContentItemInput): Promise<SerializedContentItem>;
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* Route keys for the CMS plugin — matches the keys returned by
|
|
112
|
+
* `stackClient.router.getRoute(path).routeKey`.
|
|
113
|
+
*/
|
|
114
|
+
type CMSRouteKey = "dashboard" | "contentList" | "newContent" | "editContent";
|
|
115
|
+
interface CMSPrefetchForRoute {
|
|
116
|
+
(key: "dashboard" | "newContent", qc: QueryClient): Promise<void>;
|
|
117
|
+
(key: "contentList", qc: QueryClient, params: {
|
|
118
|
+
typeSlug: string;
|
|
119
|
+
}): Promise<void>;
|
|
120
|
+
(key: "editContent", qc: QueryClient, params: {
|
|
121
|
+
typeSlug: string;
|
|
122
|
+
id: string;
|
|
123
|
+
}): Promise<void>;
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* CMS backend plugin
|
|
127
|
+
* Provides API endpoints for managing content types and content items
|
|
128
|
+
*
|
|
129
|
+
* @param config - Configuration with content types and optional hooks
|
|
130
|
+
*/
|
|
131
|
+
declare const cmsBackendPlugin: (config: CMSBackendConfig) => _btst_stack_plugins_api.BackendPlugin<{
|
|
132
|
+
listContentTypes: better_call.StrictEndpoint<"/content-types", {
|
|
133
|
+
method: "GET";
|
|
134
|
+
}, {
|
|
135
|
+
itemCount: number;
|
|
136
|
+
createdAt: string;
|
|
137
|
+
updatedAt: string;
|
|
138
|
+
name: string;
|
|
139
|
+
id: string;
|
|
140
|
+
slug: string;
|
|
141
|
+
description?: string | undefined;
|
|
142
|
+
jsonSchema: string;
|
|
143
|
+
fieldConfig?: string | undefined;
|
|
144
|
+
autoFormVersion?: number | undefined;
|
|
145
|
+
}[]>;
|
|
146
|
+
getContentTypeBySlug: better_call.StrictEndpoint<"/content-types/:slug", {
|
|
147
|
+
method: "GET";
|
|
148
|
+
params: z.ZodObject<{
|
|
149
|
+
slug: z.ZodString;
|
|
150
|
+
}, z.core.$strip>;
|
|
151
|
+
}, SerializedContentType>;
|
|
152
|
+
listContentItems: better_call.StrictEndpoint<"/content/:typeSlug", {
|
|
153
|
+
method: "GET";
|
|
154
|
+
params: z.ZodObject<{
|
|
155
|
+
typeSlug: z.ZodString;
|
|
156
|
+
}, z.core.$strip>;
|
|
157
|
+
query: z.ZodObject<{
|
|
158
|
+
slug: z.ZodOptional<z.ZodString>;
|
|
159
|
+
limit: z.ZodDefault<z.ZodOptional<z.ZodCoercedNumber<unknown>>>;
|
|
160
|
+
offset: z.ZodDefault<z.ZodOptional<z.ZodCoercedNumber<unknown>>>;
|
|
161
|
+
}, z.core.$strip>;
|
|
162
|
+
}, {
|
|
163
|
+
items: SerializedContentItemWithType[];
|
|
164
|
+
total: number;
|
|
165
|
+
limit?: number;
|
|
166
|
+
offset?: number;
|
|
167
|
+
}>;
|
|
168
|
+
getContentItem: better_call.StrictEndpoint<"/content/:typeSlug/:id", {
|
|
169
|
+
method: "GET";
|
|
170
|
+
params: z.ZodObject<{
|
|
171
|
+
typeSlug: z.ZodString;
|
|
172
|
+
id: z.ZodString;
|
|
173
|
+
}, z.core.$strip>;
|
|
174
|
+
}, SerializedContentItemWithType<Record<string, unknown>>>;
|
|
175
|
+
createContentItem: better_call.StrictEndpoint<"/content/:typeSlug", {
|
|
176
|
+
method: "POST";
|
|
177
|
+
params: z.ZodObject<{
|
|
178
|
+
typeSlug: z.ZodString;
|
|
179
|
+
}, z.core.$strip>;
|
|
180
|
+
body: z.ZodObject<{
|
|
181
|
+
slug: z.ZodString;
|
|
182
|
+
data: z.ZodObject<{}, z.core.$loose>;
|
|
183
|
+
}, z.core.$strip>;
|
|
184
|
+
}, {
|
|
185
|
+
parsedData: Record<string, unknown>;
|
|
186
|
+
createdAt: string;
|
|
187
|
+
updatedAt: string;
|
|
188
|
+
id: string;
|
|
189
|
+
slug: string;
|
|
190
|
+
contentTypeId: string;
|
|
191
|
+
data: string;
|
|
192
|
+
authorId?: string | undefined;
|
|
193
|
+
}>;
|
|
194
|
+
updateContentItem: better_call.StrictEndpoint<"/content/:typeSlug/:id", {
|
|
195
|
+
method: "PUT";
|
|
196
|
+
params: z.ZodObject<{
|
|
197
|
+
typeSlug: z.ZodString;
|
|
198
|
+
id: z.ZodString;
|
|
199
|
+
}, z.core.$strip>;
|
|
200
|
+
body: z.ZodObject<{
|
|
201
|
+
slug: z.ZodOptional<z.ZodString>;
|
|
202
|
+
data: z.ZodOptional<z.ZodObject<{}, z.core.$loose>>;
|
|
203
|
+
}, z.core.$strip>;
|
|
204
|
+
}, SerializedContentItemWithType<Record<string, unknown>>>;
|
|
205
|
+
deleteContentItem: better_call.StrictEndpoint<"/content/:typeSlug/:id", {
|
|
206
|
+
method: "DELETE";
|
|
207
|
+
params: z.ZodObject<{
|
|
208
|
+
typeSlug: z.ZodString;
|
|
209
|
+
id: z.ZodString;
|
|
210
|
+
}, z.core.$strip>;
|
|
211
|
+
}, {
|
|
212
|
+
success: boolean;
|
|
213
|
+
}>;
|
|
214
|
+
getContentItemPopulated: better_call.StrictEndpoint<"/content/:typeSlug/:id/populated", {
|
|
215
|
+
method: "GET";
|
|
216
|
+
params: z.ZodObject<{
|
|
217
|
+
typeSlug: z.ZodString;
|
|
218
|
+
id: z.ZodString;
|
|
219
|
+
}, z.core.$strip>;
|
|
220
|
+
}, {
|
|
221
|
+
_relations: Record<string, SerializedContentItemWithType<Record<string, unknown>>[]>;
|
|
222
|
+
parsedData: Record<string, unknown>;
|
|
223
|
+
contentType?: SerializedContentType;
|
|
224
|
+
createdAt: string;
|
|
225
|
+
updatedAt: string;
|
|
226
|
+
id: string;
|
|
227
|
+
slug: string;
|
|
228
|
+
contentTypeId: string;
|
|
229
|
+
data: string;
|
|
230
|
+
authorId?: string | undefined;
|
|
231
|
+
}>;
|
|
232
|
+
listContentByRelation: better_call.StrictEndpoint<"/content/:typeSlug/by-relation", {
|
|
233
|
+
method: "GET";
|
|
234
|
+
params: z.ZodObject<{
|
|
235
|
+
typeSlug: z.ZodString;
|
|
236
|
+
}, z.core.$strip>;
|
|
237
|
+
query: z.ZodObject<{
|
|
238
|
+
field: z.ZodString;
|
|
239
|
+
targetId: z.ZodString;
|
|
240
|
+
limit: z.ZodDefault<z.ZodOptional<z.ZodCoercedNumber<unknown>>>;
|
|
241
|
+
offset: z.ZodDefault<z.ZodOptional<z.ZodCoercedNumber<unknown>>>;
|
|
242
|
+
}, z.core.$strip>;
|
|
243
|
+
}, {
|
|
244
|
+
items: SerializedContentItemWithType<Record<string, unknown>>[];
|
|
245
|
+
total: number;
|
|
246
|
+
limit: number;
|
|
247
|
+
offset: number;
|
|
248
|
+
}>;
|
|
249
|
+
getInverseRelations: better_call.StrictEndpoint<"/content-types/:slug/inverse-relations", {
|
|
250
|
+
method: "GET";
|
|
251
|
+
params: z.ZodObject<{
|
|
252
|
+
slug: z.ZodString;
|
|
253
|
+
}, z.core.$strip>;
|
|
254
|
+
query: z.ZodObject<{
|
|
255
|
+
itemId: z.ZodOptional<z.ZodString>;
|
|
256
|
+
}, z.core.$strip>;
|
|
257
|
+
}, {
|
|
258
|
+
inverseRelations: InverseRelation[];
|
|
259
|
+
}>;
|
|
260
|
+
listInverseRelationItems: better_call.StrictEndpoint<"/content-types/:slug/inverse-relations/:sourceType", {
|
|
261
|
+
method: "GET";
|
|
262
|
+
params: z.ZodObject<{
|
|
263
|
+
slug: z.ZodString;
|
|
264
|
+
sourceType: z.ZodString;
|
|
265
|
+
}, z.core.$strip>;
|
|
266
|
+
query: z.ZodObject<{
|
|
267
|
+
itemId: z.ZodString;
|
|
268
|
+
fieldName: z.ZodString;
|
|
269
|
+
limit: z.ZodDefault<z.ZodOptional<z.ZodCoercedNumber<unknown>>>;
|
|
270
|
+
offset: z.ZodDefault<z.ZodOptional<z.ZodCoercedNumber<unknown>>>;
|
|
271
|
+
}, z.core.$strip>;
|
|
272
|
+
}, {
|
|
273
|
+
items: SerializedContentItemWithType<Record<string, unknown>>[];
|
|
274
|
+
total: number;
|
|
275
|
+
limit: number;
|
|
276
|
+
offset: number;
|
|
277
|
+
}>;
|
|
278
|
+
}, {
|
|
279
|
+
getAllContentTypes: () => Promise<SerializedContentType[]>;
|
|
280
|
+
getAllContentItems: (contentTypeSlug: string, params?: Parameters<typeof getAllContentItems>[2]) => Promise<{
|
|
281
|
+
items: SerializedContentItemWithType[];
|
|
282
|
+
total: number;
|
|
283
|
+
limit?: number;
|
|
284
|
+
offset?: number;
|
|
285
|
+
}>;
|
|
286
|
+
getContentItemBySlug: (contentTypeSlug: string, slug: string) => Promise<SerializedContentItemWithType<Record<string, unknown>> | null>;
|
|
287
|
+
getContentItemById: (id: string) => Promise<SerializedContentItemWithType<Record<string, unknown>> | null>;
|
|
288
|
+
prefetchForRoute: CMSPrefetchForRoute;
|
|
289
|
+
createContentItem: (typeSlug: string, input: Parameters<typeof createCMSContentItem>[2]) => Promise<SerializedContentItem>;
|
|
290
|
+
}>;
|
|
291
|
+
type CMSApiRouter = ReturnType<ReturnType<typeof cmsBackendPlugin>["routes"]>;
|
|
292
|
+
|
|
293
|
+
/**
|
|
294
|
+
* Internal query key constants for the CMS plugin.
|
|
295
|
+
* Shared between query-keys.ts (HTTP path) and prefetchForRoute (DB path)
|
|
296
|
+
* to prevent key drift between SSR loaders and SSG prefetching.
|
|
297
|
+
*/
|
|
298
|
+
interface ContentListDiscriminator {
|
|
299
|
+
typeSlug: string;
|
|
300
|
+
limit: number;
|
|
301
|
+
offset: number;
|
|
302
|
+
}
|
|
303
|
+
/** Full query key builders — use these with queryClient.setQueryData() */
|
|
304
|
+
declare const CMS_QUERY_KEYS: {
|
|
305
|
+
/**
|
|
306
|
+
* Key for the cmsTypes.list() query.
|
|
307
|
+
* Full key: ["cmsTypes", "list", "list"]
|
|
308
|
+
*/
|
|
309
|
+
typesList: () => readonly ["cmsTypes", "list", "list"];
|
|
310
|
+
/**
|
|
311
|
+
* Key for the cmsContent.list({ typeSlug, limit, offset }) query.
|
|
312
|
+
* Full key: ["cmsContent", "list", { typeSlug, limit, offset }]
|
|
313
|
+
*/
|
|
314
|
+
contentList: (params: {
|
|
315
|
+
typeSlug: string;
|
|
316
|
+
limit?: number;
|
|
317
|
+
offset?: number;
|
|
318
|
+
}) => readonly ["cmsContent", "list", ContentListDiscriminator];
|
|
319
|
+
/**
|
|
320
|
+
* Key for the cmsContent.detail(typeSlug, id) query.
|
|
321
|
+
* Full key: ["cmsContent", "detail", typeSlug, id]
|
|
322
|
+
*/
|
|
323
|
+
contentDetail: (typeSlug: string, id: string) => readonly ["cmsContent", "detail", string, string];
|
|
324
|
+
};
|
|
325
|
+
|
|
326
|
+
export { cmsBackendPlugin as c, getAllContentItems as d, getContentItemBySlug as e, getContentItemById as f, getAllContentTypes as g, serializeContentItem as h, serializeContentItemWithType as i, createCMSContentItem as j, CMS_QUERY_KEYS as l, serializeContentType as s };
|
|
327
|
+
export type { CMSApiRouter as C, ContentListDiscriminator as a, CMSRouteKey as b, CreateCMSContentItemInput as k };
|
|
@@ -73,4 +73,4 @@ interface SerializedBoardWithColumns extends SerializedBoard {
|
|
|
73
73
|
columns: SerializedColumn[];
|
|
74
74
|
}
|
|
75
75
|
|
|
76
|
-
export type { BoardWithColumns as B,
|
|
76
|
+
export type { BoardWithColumns as B, ColumnWithTasks as C, Priority as P, SerializedBoardWithColumns as S, Task as T, SerializedColumn as a, SerializedTask as b, SerializedBoard as c, Board as d, Column as e };
|
|
@@ -73,4 +73,4 @@ interface SerializedBoardWithColumns extends SerializedBoard {
|
|
|
73
73
|
columns: SerializedColumn[];
|
|
74
74
|
}
|
|
75
75
|
|
|
76
|
-
export type { BoardWithColumns as B,
|
|
76
|
+
export type { BoardWithColumns as B, ColumnWithTasks as C, Priority as P, SerializedBoardWithColumns as S, Task as T, SerializedColumn as a, SerializedTask as b, SerializedBoard as c, Board as d, Column as e };
|
|
@@ -73,4 +73,4 @@ interface SerializedBoardWithColumns extends SerializedBoard {
|
|
|
73
73
|
columns: SerializedColumn[];
|
|
74
74
|
}
|
|
75
75
|
|
|
76
|
-
export type { BoardWithColumns as B,
|
|
76
|
+
export type { BoardWithColumns as B, ColumnWithTasks as C, Priority as P, SerializedBoardWithColumns as S, Task as T, SerializedColumn as a, SerializedTask as b, SerializedBoard as c, Board as d, Column as e };
|
|
@@ -5,7 +5,7 @@ import * as _btst_stack_plugins_api from '@btst/stack/plugins/api';
|
|
|
5
5
|
import * as better_call from 'better-call';
|
|
6
6
|
import * as zod_v4_core from 'zod/v4/core';
|
|
7
7
|
import * as zod from 'zod';
|
|
8
|
-
import {
|
|
8
|
+
import { Tool, LanguageModel } from 'ai';
|
|
9
9
|
|
|
10
10
|
/**
|
|
11
11
|
* Context passed to AI Chat API hooks
|
|
@@ -67,6 +67,18 @@ interface AiChatBackendHooks {
|
|
|
67
67
|
* @param context - Request context with headers, etc.
|
|
68
68
|
*/
|
|
69
69
|
onBeforeDeleteConversation?: (conversationId: string, context: ChatApiContext) => Promise<boolean> | boolean;
|
|
70
|
+
/**
|
|
71
|
+
* Called after the structural routeName/allowlist validation, with the list
|
|
72
|
+
* of tool names that passed. Return a filtered subset to further restrict
|
|
73
|
+
* which tools the LLM sees, or return [] to suppress all page tools.
|
|
74
|
+
* Throw an Error to abort the entire chat request with a 403 response.
|
|
75
|
+
* Not called when no tools passed the structural validation step.
|
|
76
|
+
*
|
|
77
|
+
* @param toolNames - Names that passed the routeName allowlist check
|
|
78
|
+
* @param routeName - routeName claimed by the request (may be undefined)
|
|
79
|
+
* @param context - Full request context (headers, body, etc.)
|
|
80
|
+
*/
|
|
81
|
+
onBeforeToolsActivated?: (toolNames: string[], routeName: string | undefined, context: ChatApiContext) => Promise<string[]> | string[];
|
|
70
82
|
/**
|
|
71
83
|
* Called after a chat message is processed successfully
|
|
72
84
|
* @param conversationId - ID of the conversation
|
|
@@ -152,6 +164,23 @@ type AiChatMode = "authenticated" | "public";
|
|
|
152
164
|
/**
|
|
153
165
|
* Configuration for AI Chat backend plugin
|
|
154
166
|
*/
|
|
167
|
+
/**
|
|
168
|
+
* Extracts only the literal (non-index-signature) keys from a type.
|
|
169
|
+
* For `Record<string, T>` this resolves to `never`, so collision checks are
|
|
170
|
+
* skipped when the tools map is typed with a broad string index.
|
|
171
|
+
*/
|
|
172
|
+
type KnownKeys<T> = {
|
|
173
|
+
[K in keyof T]: string extends K ? never : K;
|
|
174
|
+
}[keyof T];
|
|
175
|
+
/**
|
|
176
|
+
* Ensures `TClientTools` has no keys that are also literal keys in `TTools`.
|
|
177
|
+
* Colliding keys are mapped to `never`, which produces a compile-time error
|
|
178
|
+
* at the point of the duplicate key. When `TTools` uses a string index
|
|
179
|
+
* signature the check is skipped to avoid false positives.
|
|
180
|
+
*/
|
|
181
|
+
type NoKeyCollision<TTools, TClientTools extends Record<string, Tool>> = KnownKeys<TTools> & keyof TClientTools extends never ? TClientTools : {
|
|
182
|
+
[K in keyof TClientTools]: K extends KnownKeys<TTools> ? never : TClientTools[K];
|
|
183
|
+
};
|
|
155
184
|
interface AiChatBackendConfig {
|
|
156
185
|
/**
|
|
157
186
|
* The language model to use for chat completions.
|
|
@@ -182,6 +211,29 @@ interface AiChatBackendConfig {
|
|
|
182
211
|
* @see https://ai-sdk.dev/docs/ai-sdk-core/tools-and-tool-calling
|
|
183
212
|
*/
|
|
184
213
|
tools?: Record<string, Tool>;
|
|
214
|
+
/**
|
|
215
|
+
* Enable route-aware page tools.
|
|
216
|
+
* When true, the server will include tool schemas for client-side page tools
|
|
217
|
+
* (e.g. fillBlogForm, updatePageLayers) based on the availableTools list
|
|
218
|
+
* sent with each request.
|
|
219
|
+
* @default false
|
|
220
|
+
*/
|
|
221
|
+
enablePageTools?: boolean;
|
|
222
|
+
/**
|
|
223
|
+
* Custom client-side tool schemas for non-BTST pages.
|
|
224
|
+
* Merged with built-in page tool schemas (fillBlogForm, updatePageLayers).
|
|
225
|
+
* Only included when enablePageTools is true and the tool name appears in
|
|
226
|
+
* the availableTools list sent with the request.
|
|
227
|
+
*
|
|
228
|
+
* @example
|
|
229
|
+
* clientToolSchemas: {
|
|
230
|
+
* addToCart: tool({
|
|
231
|
+
* description: "Add current product to cart",
|
|
232
|
+
* parameters: z.object({ quantity: z.number().int().min(1) }),
|
|
233
|
+
* }),
|
|
234
|
+
* }
|
|
235
|
+
*/
|
|
236
|
+
clientToolSchemas?: Record<string, Tool>;
|
|
185
237
|
/**
|
|
186
238
|
* Optional hooks for customizing plugin behavior
|
|
187
239
|
*/
|
|
@@ -194,7 +246,10 @@ interface AiChatBackendConfig {
|
|
|
194
246
|
*
|
|
195
247
|
* @param config - Configuration including model, tools, and optional hooks
|
|
196
248
|
*/
|
|
197
|
-
declare const aiChatBackendPlugin: (config: AiChatBackendConfig
|
|
249
|
+
declare const aiChatBackendPlugin: <TTools extends Record<string, Tool> = Record<never, Tool>, TClientTools extends Record<string, Tool> = Record<never, Tool>>(config: Omit<AiChatBackendConfig, "tools" | "clientToolSchemas"> & {
|
|
250
|
+
tools?: TTools;
|
|
251
|
+
clientToolSchemas?: NoKeyCollision<TTools, TClientTools>;
|
|
252
|
+
}) => _btst_stack_plugins_api.BackendPlugin<{
|
|
198
253
|
chat: better_call.StrictEndpoint<"/chat", {
|
|
199
254
|
method: "POST";
|
|
200
255
|
body: zod.ZodObject<{
|
|
@@ -223,6 +278,9 @@ declare const aiChatBackendPlugin: (config: AiChatBackendConfig) => _btst_stack_
|
|
|
223
278
|
}, zod_v4_core.$strip>]>>;
|
|
224
279
|
conversationId: zod.ZodOptional<zod.ZodString>;
|
|
225
280
|
model: zod.ZodOptional<zod.ZodString>;
|
|
281
|
+
pageContext: zod.ZodOptional<zod.ZodString>;
|
|
282
|
+
availableTools: zod.ZodOptional<zod.ZodArray<zod.ZodString>>;
|
|
283
|
+
routeName: zod.ZodOptional<zod.ZodString>;
|
|
226
284
|
}, zod_v4_core.$strip>;
|
|
227
285
|
}, Response>;
|
|
228
286
|
createConversation: better_call.StrictEndpoint<"/chat/conversations", {
|
|
@@ -5,7 +5,7 @@ import * as _btst_stack_plugins_api from '@btst/stack/plugins/api';
|
|
|
5
5
|
import * as better_call from 'better-call';
|
|
6
6
|
import * as zod_v4_core from 'zod/v4/core';
|
|
7
7
|
import * as zod from 'zod';
|
|
8
|
-
import {
|
|
8
|
+
import { Tool, LanguageModel } from 'ai';
|
|
9
9
|
|
|
10
10
|
/**
|
|
11
11
|
* Context passed to AI Chat API hooks
|
|
@@ -67,6 +67,18 @@ interface AiChatBackendHooks {
|
|
|
67
67
|
* @param context - Request context with headers, etc.
|
|
68
68
|
*/
|
|
69
69
|
onBeforeDeleteConversation?: (conversationId: string, context: ChatApiContext) => Promise<boolean> | boolean;
|
|
70
|
+
/**
|
|
71
|
+
* Called after the structural routeName/allowlist validation, with the list
|
|
72
|
+
* of tool names that passed. Return a filtered subset to further restrict
|
|
73
|
+
* which tools the LLM sees, or return [] to suppress all page tools.
|
|
74
|
+
* Throw an Error to abort the entire chat request with a 403 response.
|
|
75
|
+
* Not called when no tools passed the structural validation step.
|
|
76
|
+
*
|
|
77
|
+
* @param toolNames - Names that passed the routeName allowlist check
|
|
78
|
+
* @param routeName - routeName claimed by the request (may be undefined)
|
|
79
|
+
* @param context - Full request context (headers, body, etc.)
|
|
80
|
+
*/
|
|
81
|
+
onBeforeToolsActivated?: (toolNames: string[], routeName: string | undefined, context: ChatApiContext) => Promise<string[]> | string[];
|
|
70
82
|
/**
|
|
71
83
|
* Called after a chat message is processed successfully
|
|
72
84
|
* @param conversationId - ID of the conversation
|
|
@@ -152,6 +164,23 @@ type AiChatMode = "authenticated" | "public";
|
|
|
152
164
|
/**
|
|
153
165
|
* Configuration for AI Chat backend plugin
|
|
154
166
|
*/
|
|
167
|
+
/**
|
|
168
|
+
* Extracts only the literal (non-index-signature) keys from a type.
|
|
169
|
+
* For `Record<string, T>` this resolves to `never`, so collision checks are
|
|
170
|
+
* skipped when the tools map is typed with a broad string index.
|
|
171
|
+
*/
|
|
172
|
+
type KnownKeys<T> = {
|
|
173
|
+
[K in keyof T]: string extends K ? never : K;
|
|
174
|
+
}[keyof T];
|
|
175
|
+
/**
|
|
176
|
+
* Ensures `TClientTools` has no keys that are also literal keys in `TTools`.
|
|
177
|
+
* Colliding keys are mapped to `never`, which produces a compile-time error
|
|
178
|
+
* at the point of the duplicate key. When `TTools` uses a string index
|
|
179
|
+
* signature the check is skipped to avoid false positives.
|
|
180
|
+
*/
|
|
181
|
+
type NoKeyCollision<TTools, TClientTools extends Record<string, Tool>> = KnownKeys<TTools> & keyof TClientTools extends never ? TClientTools : {
|
|
182
|
+
[K in keyof TClientTools]: K extends KnownKeys<TTools> ? never : TClientTools[K];
|
|
183
|
+
};
|
|
155
184
|
interface AiChatBackendConfig {
|
|
156
185
|
/**
|
|
157
186
|
* The language model to use for chat completions.
|
|
@@ -182,6 +211,29 @@ interface AiChatBackendConfig {
|
|
|
182
211
|
* @see https://ai-sdk.dev/docs/ai-sdk-core/tools-and-tool-calling
|
|
183
212
|
*/
|
|
184
213
|
tools?: Record<string, Tool>;
|
|
214
|
+
/**
|
|
215
|
+
* Enable route-aware page tools.
|
|
216
|
+
* When true, the server will include tool schemas for client-side page tools
|
|
217
|
+
* (e.g. fillBlogForm, updatePageLayers) based on the availableTools list
|
|
218
|
+
* sent with each request.
|
|
219
|
+
* @default false
|
|
220
|
+
*/
|
|
221
|
+
enablePageTools?: boolean;
|
|
222
|
+
/**
|
|
223
|
+
* Custom client-side tool schemas for non-BTST pages.
|
|
224
|
+
* Merged with built-in page tool schemas (fillBlogForm, updatePageLayers).
|
|
225
|
+
* Only included when enablePageTools is true and the tool name appears in
|
|
226
|
+
* the availableTools list sent with the request.
|
|
227
|
+
*
|
|
228
|
+
* @example
|
|
229
|
+
* clientToolSchemas: {
|
|
230
|
+
* addToCart: tool({
|
|
231
|
+
* description: "Add current product to cart",
|
|
232
|
+
* parameters: z.object({ quantity: z.number().int().min(1) }),
|
|
233
|
+
* }),
|
|
234
|
+
* }
|
|
235
|
+
*/
|
|
236
|
+
clientToolSchemas?: Record<string, Tool>;
|
|
185
237
|
/**
|
|
186
238
|
* Optional hooks for customizing plugin behavior
|
|
187
239
|
*/
|
|
@@ -194,7 +246,10 @@ interface AiChatBackendConfig {
|
|
|
194
246
|
*
|
|
195
247
|
* @param config - Configuration including model, tools, and optional hooks
|
|
196
248
|
*/
|
|
197
|
-
declare const aiChatBackendPlugin: (config: AiChatBackendConfig
|
|
249
|
+
declare const aiChatBackendPlugin: <TTools extends Record<string, Tool> = Record<never, Tool>, TClientTools extends Record<string, Tool> = Record<never, Tool>>(config: Omit<AiChatBackendConfig, "tools" | "clientToolSchemas"> & {
|
|
250
|
+
tools?: TTools;
|
|
251
|
+
clientToolSchemas?: NoKeyCollision<TTools, TClientTools>;
|
|
252
|
+
}) => _btst_stack_plugins_api.BackendPlugin<{
|
|
198
253
|
chat: better_call.StrictEndpoint<"/chat", {
|
|
199
254
|
method: "POST";
|
|
200
255
|
body: zod.ZodObject<{
|
|
@@ -223,6 +278,9 @@ declare const aiChatBackendPlugin: (config: AiChatBackendConfig) => _btst_stack_
|
|
|
223
278
|
}, zod_v4_core.$strip>]>>;
|
|
224
279
|
conversationId: zod.ZodOptional<zod.ZodString>;
|
|
225
280
|
model: zod.ZodOptional<zod.ZodString>;
|
|
281
|
+
pageContext: zod.ZodOptional<zod.ZodString>;
|
|
282
|
+
availableTools: zod.ZodOptional<zod.ZodArray<zod.ZodString>>;
|
|
283
|
+
routeName: zod.ZodOptional<zod.ZodString>;
|
|
226
284
|
}, zod_v4_core.$strip>;
|
|
227
285
|
}, Response>;
|
|
228
286
|
createConversation: better_call.StrictEndpoint<"/chat/conversations", {
|
|
@@ -48,6 +48,12 @@ type FormSubmission = {
|
|
|
48
48
|
/** User agent for analytics */
|
|
49
49
|
userAgent?: string;
|
|
50
50
|
};
|
|
51
|
+
/**
|
|
52
|
+
* Form submission with its parent form joined
|
|
53
|
+
*/
|
|
54
|
+
type FormSubmissionWithForm = FormSubmission & {
|
|
55
|
+
form?: Form;
|
|
56
|
+
};
|
|
51
57
|
/**
|
|
52
58
|
* Serialized form for API responses (dates as strings)
|
|
53
59
|
*/
|
|
@@ -192,4 +198,4 @@ interface FormBuilderBackendConfig {
|
|
|
192
198
|
hooks?: FormBuilderBackendHooks;
|
|
193
199
|
}
|
|
194
200
|
|
|
195
|
-
export type {
|
|
201
|
+
export type { Form as F, PaginatedForms as P, SerializedForm as S, SerializedFormSubmission as a, SerializedFormSubmissionWithData as b, PaginatedFormSubmissions as c, FormSubmission as d, FormSubmissionWithForm as e, FormBuilderBackendConfig as f };
|
|
@@ -48,6 +48,12 @@ type FormSubmission = {
|
|
|
48
48
|
/** User agent for analytics */
|
|
49
49
|
userAgent?: string;
|
|
50
50
|
};
|
|
51
|
+
/**
|
|
52
|
+
* Form submission with its parent form joined
|
|
53
|
+
*/
|
|
54
|
+
type FormSubmissionWithForm = FormSubmission & {
|
|
55
|
+
form?: Form;
|
|
56
|
+
};
|
|
51
57
|
/**
|
|
52
58
|
* Serialized form for API responses (dates as strings)
|
|
53
59
|
*/
|
|
@@ -192,4 +198,4 @@ interface FormBuilderBackendConfig {
|
|
|
192
198
|
hooks?: FormBuilderBackendHooks;
|
|
193
199
|
}
|
|
194
200
|
|
|
195
|
-
export type {
|
|
201
|
+
export type { Form as F, PaginatedForms as P, SerializedForm as S, SerializedFormSubmission as a, SerializedFormSubmissionWithData as b, PaginatedFormSubmissions as c, FormSubmission as d, FormSubmissionWithForm as e, FormBuilderBackendConfig as f };
|
|
@@ -48,6 +48,12 @@ type FormSubmission = {
|
|
|
48
48
|
/** User agent for analytics */
|
|
49
49
|
userAgent?: string;
|
|
50
50
|
};
|
|
51
|
+
/**
|
|
52
|
+
* Form submission with its parent form joined
|
|
53
|
+
*/
|
|
54
|
+
type FormSubmissionWithForm = FormSubmission & {
|
|
55
|
+
form?: Form;
|
|
56
|
+
};
|
|
51
57
|
/**
|
|
52
58
|
* Serialized form for API responses (dates as strings)
|
|
53
59
|
*/
|
|
@@ -192,4 +198,4 @@ interface FormBuilderBackendConfig {
|
|
|
192
198
|
hooks?: FormBuilderBackendHooks;
|
|
193
199
|
}
|
|
194
200
|
|
|
195
|
-
export type {
|
|
201
|
+
export type { Form as F, PaginatedForms as P, SerializedForm as S, SerializedFormSubmission as a, SerializedFormSubmissionWithData as b, PaginatedFormSubmissions as c, FormSubmission as d, FormSubmissionWithForm as e, FormBuilderBackendConfig as f };
|