@btst/stack 2.1.0 → 2.3.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/api/index.cjs +9 -1
- package/dist/api/index.d.cts +4 -4
- package/dist/api/index.d.mts +4 -4
- package/dist/api/index.d.ts +4 -4
- package/dist/api/index.mjs +9 -1
- package/dist/client/index.d.cts +2 -2
- package/dist/client/index.d.mts +2 -2
- package/dist/client/index.d.ts +2 -2
- package/dist/index.d.cts +1 -1
- package/dist/index.d.mts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/packages/stack/src/plugins/ai-chat/api/getters.cjs +42 -0
- package/dist/packages/stack/src/plugins/ai-chat/api/getters.mjs +39 -0
- package/dist/packages/stack/src/plugins/ai-chat/api/plugin.cjs +5 -0
- package/dist/packages/stack/src/plugins/ai-chat/api/plugin.mjs +5 -0
- package/dist/packages/stack/src/plugins/blog/api/getters.cjs +131 -0
- package/dist/packages/stack/src/plugins/blog/api/getters.mjs +127 -0
- package/dist/packages/stack/src/plugins/blog/api/plugin.cjs +60 -107
- package/dist/packages/stack/src/plugins/blog/api/plugin.mjs +60 -107
- 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/plugin.cjs +16 -1
- package/dist/packages/stack/src/plugins/blog/client/plugin.mjs +17 -2
- package/dist/packages/stack/src/plugins/cms/api/getters.cjs +156 -0
- package/dist/packages/stack/src/plugins/cms/api/getters.mjs +147 -0
- package/dist/packages/stack/src/plugins/cms/api/plugin.cjs +624 -617
- package/dist/packages/stack/src/plugins/cms/api/plugin.mjs +623 -616
- 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/components/pages/content-editor-page.internal.cjs +1 -1
- package/dist/packages/stack/src/plugins/cms/client/components/pages/content-editor-page.internal.mjs +1 -1
- package/dist/packages/stack/src/plugins/cms/client/hooks/cms-hooks.cjs +6 -3
- package/dist/packages/stack/src/plugins/cms/client/hooks/cms-hooks.mjs +6 -3
- 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 +120 -0
- package/dist/packages/stack/src/plugins/form-builder/api/getters.mjs +112 -0
- package/dist/packages/stack/src/plugins/form-builder/api/plugin.cjs +75 -86
- package/dist/packages/stack/src/plugins/form-builder/api/plugin.mjs +71 -82
- 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/components/pages/submissions-page.internal.cjs +1 -1
- package/dist/packages/stack/src/plugins/form-builder/client/components/pages/submissions-page.internal.mjs +1 -1
- 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/getters.cjs +84 -0
- package/dist/packages/stack/src/plugins/kanban/api/getters.mjs +81 -0
- package/dist/packages/stack/src/plugins/kanban/api/plugin.cjs +37 -123
- package/dist/packages/stack/src/plugins/kanban/api/plugin.mjs +37 -123
- 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/plugin.cjs +11 -1
- package/dist/packages/stack/src/plugins/kanban/client/plugin.mjs +12 -2
- 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.cjs +3 -0
- package/dist/plugins/ai-chat/api/index.d.cts +27 -4
- package/dist/plugins/ai-chat/api/index.d.mts +27 -4
- package/dist/plugins/ai-chat/api/index.d.ts +27 -4
- package/dist/plugins/ai-chat/api/index.mjs +1 -0
- package/dist/plugins/ai-chat/client/hooks/index.d.cts +2 -2
- package/dist/plugins/ai-chat/client/hooks/index.d.mts +2 -2
- package/dist/plugins/ai-chat/client/hooks/index.d.ts +2 -2
- package/dist/plugins/ai-chat/query-keys.d.cts +9 -284
- package/dist/plugins/ai-chat/query-keys.d.mts +9 -284
- package/dist/plugins/ai-chat/query-keys.d.ts +9 -284
- package/dist/plugins/api/index.d.cts +4 -3
- package/dist/plugins/api/index.d.mts +4 -3
- package/dist/plugins/api/index.d.ts +4 -3
- package/dist/plugins/blog/api/index.cjs +9 -0
- package/dist/plugins/blog/api/index.d.cts +20 -4
- package/dist/plugins/blog/api/index.d.mts +20 -4
- package/dist/plugins/blog/api/index.d.ts +20 -4
- package/dist/plugins/blog/api/index.mjs +3 -0
- package/dist/plugins/blog/client/hooks/index.d.cts +5 -5
- package/dist/plugins/blog/client/hooks/index.d.mts +5 -5
- package/dist/plugins/blog/client/hooks/index.d.ts +5 -5
- 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 +13 -9
- package/dist/plugins/blog/query-keys.d.cts +8 -333
- package/dist/plugins/blog/query-keys.d.mts +8 -333
- package/dist/plugins/blog/query-keys.d.ts +8 -333
- package/dist/plugins/blog/query-keys.mjs +13 -9
- package/dist/plugins/client/index.cjs +1 -0
- package/dist/plugins/client/index.d.cts +10 -3
- package/dist/plugins/client/index.d.mts +10 -3
- package/dist/plugins/client/index.d.ts +10 -3
- package/dist/plugins/client/index.mjs +1 -1
- package/dist/plugins/cms/api/index.cjs +10 -0
- package/dist/plugins/cms/api/index.d.cts +7 -163
- package/dist/plugins/cms/api/index.d.mts +7 -163
- package/dist/plugins/cms/api/index.d.ts +7 -163
- package/dist/plugins/cms/api/index.mjs +2 -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/query-keys.cjs +2 -1
- package/dist/plugins/cms/query-keys.d.cts +6 -9
- package/dist/plugins/cms/query-keys.d.mts +6 -9
- package/dist/plugins/cms/query-keys.d.ts +6 -9
- package/dist/plugins/cms/query-keys.mjs +2 -1
- package/dist/plugins/form-builder/api/index.cjs +10 -0
- package/dist/plugins/form-builder/api/index.d.cts +7 -141
- package/dist/plugins/form-builder/api/index.d.mts +7 -141
- package/dist/plugins/form-builder/api/index.d.ts +7 -141
- package/dist/plugins/form-builder/api/index.mjs +2 -0
- 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 +7 -6
- package/dist/plugins/form-builder/query-keys.d.mts +7 -6
- package/dist/plugins/form-builder/query-keys.d.ts +7 -6
- package/dist/plugins/form-builder/query-keys.mjs +3 -2
- package/dist/plugins/kanban/api/index.cjs +9 -0
- package/dist/plugins/kanban/api/index.d.cts +17 -395
- package/dist/plugins/kanban/api/index.d.mts +17 -395
- package/dist/plugins/kanban/api/index.d.ts +17 -395
- 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 +6 -12
- package/dist/plugins/kanban/query-keys.d.cts +5 -16
- package/dist/plugins/kanban/query-keys.d.mts +5 -16
- package/dist/plugins/kanban/query-keys.d.ts +5 -16
- package/dist/plugins/kanban/query-keys.mjs +6 -12
- package/dist/plugins/open-api/api/index.d.cts +2 -2
- package/dist/plugins/open-api/api/index.d.mts +2 -2
- package/dist/plugins/open-api/api/index.d.ts +2 -2
- package/dist/plugins/route-docs/client/index.d.cts +1 -1
- package/dist/plugins/route-docs/client/index.d.mts +1 -1
- package/dist/plugins/route-docs/client/index.d.ts +1 -1
- 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.BoA0xkJv.d.cts → stack.7n9Y_u7N.d.cts} +33 -7
- package/dist/shared/{stack.BoA0xkJv.d.mts → stack.7n9Y_u7N.d.mts} +33 -7
- package/dist/shared/{stack.BoA0xkJv.d.ts → stack.7n9Y_u7N.d.ts} +33 -7
- package/dist/shared/stack.B1EeBt1b.d.ts +297 -0
- package/dist/shared/stack.BIXEI6v_.d.mts +419 -0
- package/dist/shared/stack.BKfolAyK.d.ts +419 -0
- package/dist/shared/stack.BeSm90va.d.ts +289 -0
- package/dist/shared/stack.BpolpQpf.d.cts +445 -0
- package/dist/shared/stack.C5dtIncc.d.mts +293 -0
- package/dist/shared/stack.CIP6QS9l.d.ts +293 -0
- package/dist/shared/stack.CMh_EdxW.d.cts +289 -0
- package/dist/shared/stack.CP68pFEH.d.mts +297 -0
- package/dist/shared/{stack.BsXokfNh.d.mts → stack.CVDTkMoO.d.cts} +8 -2
- package/dist/shared/{stack.BsXokfNh.d.ts → stack.CVDTkMoO.d.mts} +8 -2
- package/dist/shared/{stack.BsXokfNh.d.cts → stack.CVDTkMoO.d.ts} +8 -2
- package/dist/shared/{stack.DKDMI-QO.d.mts → stack.DJaKVY7v.d.cts} +7 -1
- package/dist/shared/{stack.DKDMI-QO.d.ts → stack.DJaKVY7v.d.mts} +7 -1
- package/dist/shared/{stack.DKDMI-QO.d.cts → stack.DJaKVY7v.d.ts} +7 -1
- package/dist/shared/{stack.DzH_wcvr.d.mts → stack.DdI5W6MB.d.cts} +9 -3
- package/dist/shared/{stack.DzH_wcvr.d.ts → stack.DdI5W6MB.d.mts} +9 -3
- package/dist/shared/{stack.DzH_wcvr.d.cts → stack.DdI5W6MB.d.ts} +9 -3
- package/dist/shared/stack.Dg09R0oB.d.mts +289 -0
- package/dist/shared/stack.Dw0Ly2TM.d.cts +293 -0
- package/dist/shared/stack.IdtKDRka.d.cts +297 -0
- package/dist/shared/stack.TIBF2AOx.d.ts +445 -0
- package/dist/shared/stack.rTy7-wQU.d.mts +445 -0
- package/dist/shared/stack.snB1EDP7.d.cts +419 -0
- package/package.json +3 -3
- package/src/__tests__/stack-api.test.ts +118 -0
- package/src/api/index.ts +15 -1
- package/src/plugins/ai-chat/__tests__/getters.test.ts +109 -0
- package/src/plugins/ai-chat/api/getters.ts +71 -0
- package/src/plugins/ai-chat/api/index.ts +1 -0
- package/src/plugins/ai-chat/api/plugin.ts +8 -0
- package/src/plugins/api/index.ts +3 -1
- package/src/plugins/blog/__tests__/getters.test.ts +540 -0
- package/src/plugins/blog/api/getters.ts +243 -0
- package/src/plugins/blog/api/index.ts +9 -0
- package/src/plugins/blog/api/plugin.ts +98 -141
- 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/plugin.tsx +21 -1
- package/src/plugins/blog/query-keys.ts +21 -20
- package/src/plugins/client/index.ts +1 -1
- package/src/plugins/cms/__tests__/getters.test.ts +206 -0
- package/src/plugins/cms/api/getters.ts +268 -0
- package/src/plugins/cms/api/index.ts +15 -1
- package/src/plugins/cms/api/plugin.ts +151 -150
- 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/components/pages/content-editor-page.internal.tsx +1 -1
- package/src/plugins/cms/client/hooks/cms-hooks.tsx +3 -0
- package/src/plugins/cms/client/plugin.tsx +19 -0
- package/src/plugins/cms/query-keys.ts +2 -1
- package/src/plugins/cms/types.ts +1 -1
- package/src/plugins/form-builder/__tests__/getters.test.ts +159 -0
- package/src/plugins/form-builder/api/getters.ts +226 -0
- package/src/plugins/form-builder/api/index.ts +15 -1
- package/src/plugins/form-builder/api/plugin.ts +107 -109
- 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/components/pages/submissions-page.internal.tsx +1 -1
- package/src/plugins/form-builder/client/plugin.tsx +19 -0
- package/src/plugins/form-builder/query-keys.ts +6 -2
- package/src/plugins/form-builder/types.ts +2 -2
- package/src/plugins/kanban/__tests__/getters.test.ts +172 -0
- package/src/plugins/kanban/api/getters.ts +149 -0
- package/src/plugins/kanban/api/index.ts +4 -0
- package/src/plugins/kanban/api/plugin.ts +65 -146
- 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/plugin.tsx +15 -1
- package/src/plugins/kanban/query-keys.ts +10 -14
- package/src/plugins/utils.ts +19 -0
- package/src/types.ts +44 -5
- package/dist/shared/{stack.CbuN2zVV.d.cts → stack.CBON0dWL.d.cts} +7 -7
- package/dist/shared/{stack.CbuN2zVV.d.mts → stack.CBON0dWL.d.mts} +7 -7
- package/dist/shared/{stack.CbuN2zVV.d.ts → stack.CBON0dWL.d.ts} +7 -7
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
defineClientPlugin,
|
|
3
3
|
createApiClient,
|
|
4
|
+
isConnectionError,
|
|
4
5
|
} from "@btst/stack/plugins/client";
|
|
5
6
|
import { createRoute } from "@btst/yar";
|
|
6
7
|
import type { QueryClient } from "@tanstack/react-query";
|
|
@@ -178,6 +179,12 @@ function createBoardsLoader(config: KanbanClientConfig) {
|
|
|
178
179
|
await hooks.onLoadError(error, context);
|
|
179
180
|
}
|
|
180
181
|
} catch (error) {
|
|
182
|
+
if (isConnectionError(error)) {
|
|
183
|
+
console.warn(
|
|
184
|
+
"[btst/kanban] route.loader() failed — no server running at build time. " +
|
|
185
|
+
"Use myStack.api.kanban.prefetchForRoute() for SSG data prefetching.",
|
|
186
|
+
);
|
|
187
|
+
}
|
|
181
188
|
if (hooks?.onLoadError) {
|
|
182
189
|
await hooks.onLoadError(error as Error, context);
|
|
183
190
|
}
|
|
@@ -241,6 +248,12 @@ function createBoardLoader(boardId: string, config: KanbanClientConfig) {
|
|
|
241
248
|
await hooks.onLoadError(error, context);
|
|
242
249
|
}
|
|
243
250
|
} catch (error) {
|
|
251
|
+
if (isConnectionError(error)) {
|
|
252
|
+
console.warn(
|
|
253
|
+
"[btst/kanban] route.loader() failed — no server running at build time. " +
|
|
254
|
+
"Use myStack.api.kanban.prefetchForRoute() for SSG data prefetching.",
|
|
255
|
+
);
|
|
256
|
+
}
|
|
244
257
|
if (hooks?.onLoadError) {
|
|
245
258
|
await hooks.onLoadError(error as Error, context);
|
|
246
259
|
}
|
|
@@ -437,7 +450,8 @@ export const kanbanClientPlugin = (config: KanbanClientConfig) =>
|
|
|
437
450
|
method: "GET",
|
|
438
451
|
query: { limit: 100 },
|
|
439
452
|
});
|
|
440
|
-
boards
|
|
453
|
+
// /boards returns BoardListResult { items, total, limit, offset }
|
|
454
|
+
boards = ((res.data as any)?.items ??
|
|
441
455
|
[]) as SerializedBoardWithColumns[];
|
|
442
456
|
} catch {
|
|
443
457
|
// Ignore errors for sitemap
|
|
@@ -5,6 +5,7 @@ import {
|
|
|
5
5
|
import type { KanbanApiRouter } from "./api";
|
|
6
6
|
import { createApiClient } from "@btst/stack/plugins/client";
|
|
7
7
|
import type { SerializedBoardWithColumns } from "./types";
|
|
8
|
+
import { boardsListDiscriminator } from "./api/query-key-defs";
|
|
8
9
|
|
|
9
10
|
interface BoardsListParams {
|
|
10
11
|
slug?: string;
|
|
@@ -63,15 +64,7 @@ function createBoardsQueries(
|
|
|
63
64
|
) {
|
|
64
65
|
return createQueryKeys("boards", {
|
|
65
66
|
list: (params?: BoardsListParams) => ({
|
|
66
|
-
queryKey: [
|
|
67
|
-
{
|
|
68
|
-
slug: params?.slug,
|
|
69
|
-
ownerId: params?.ownerId,
|
|
70
|
-
organizationId: params?.organizationId,
|
|
71
|
-
limit: params?.limit ?? 50,
|
|
72
|
-
offset: params?.offset ?? 0,
|
|
73
|
-
},
|
|
74
|
-
],
|
|
67
|
+
queryKey: [boardsListDiscriminator(params)],
|
|
75
68
|
queryFn: async () => {
|
|
76
69
|
try {
|
|
77
70
|
const response = await client("/boards", {
|
|
@@ -91,8 +84,10 @@ function createBoardsQueries(
|
|
|
91
84
|
throw toError(errorResponse.error);
|
|
92
85
|
}
|
|
93
86
|
|
|
94
|
-
|
|
95
|
-
|
|
87
|
+
const envelope = (response as { data?: unknown }).data as
|
|
88
|
+
| { items?: SerializedBoardWithColumns[] }
|
|
89
|
+
| undefined;
|
|
90
|
+
return envelope?.items ?? ([] as SerializedBoardWithColumns[]);
|
|
96
91
|
} catch (error) {
|
|
97
92
|
throw error;
|
|
98
93
|
}
|
|
@@ -142,9 +137,10 @@ function createBoardsQueries(
|
|
|
142
137
|
throw toError(errorResponse.error);
|
|
143
138
|
}
|
|
144
139
|
|
|
145
|
-
const
|
|
146
|
-
|
|
147
|
-
|
|
140
|
+
const envelope = (response as { data?: unknown }).data as
|
|
141
|
+
| { items?: SerializedBoardWithColumns[] }
|
|
142
|
+
| undefined;
|
|
143
|
+
return envelope?.items?.[0] ?? null;
|
|
148
144
|
} catch (error) {
|
|
149
145
|
throw error;
|
|
150
146
|
}
|
package/src/plugins/utils.ts
CHANGED
|
@@ -1,4 +1,23 @@
|
|
|
1
1
|
import { createClient } from "better-call/client";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Returns true when a fetch error is a connection-refused / no-server error.
|
|
5
|
+
* Used in SSR loaders to emit an actionable build-time warning when
|
|
6
|
+
* `route.loader()` is called during `next build` with no HTTP server running.
|
|
7
|
+
*/
|
|
8
|
+
export function isConnectionError(err: unknown): boolean {
|
|
9
|
+
if (!(err instanceof Error)) return false;
|
|
10
|
+
const code =
|
|
11
|
+
(err as unknown as { cause?: { code?: string } }).cause?.code ??
|
|
12
|
+
(err as unknown as { code?: string }).code;
|
|
13
|
+
return (
|
|
14
|
+
err.message.includes("ECONNREFUSED") ||
|
|
15
|
+
err.message.includes("fetch failed") ||
|
|
16
|
+
err.message.includes("ERR_CONNECTION_REFUSED") ||
|
|
17
|
+
code === "ECONNREFUSED" ||
|
|
18
|
+
code === "ERR_CONNECTION_REFUSED"
|
|
19
|
+
);
|
|
20
|
+
}
|
|
2
21
|
import type { Router, Endpoint } from "better-call";
|
|
3
22
|
|
|
4
23
|
interface CreateApiClientOptions {
|
package/src/types.ts
CHANGED
|
@@ -8,7 +8,7 @@ import type { Endpoint, Router } from "better-call";
|
|
|
8
8
|
*/
|
|
9
9
|
export interface StackContext {
|
|
10
10
|
/** All registered backend plugins */
|
|
11
|
-
plugins: Record<string, BackendPlugin<any>>;
|
|
11
|
+
plugins: Record<string, BackendPlugin<any, any>>;
|
|
12
12
|
/** The API base path (e.g., "/api/data") */
|
|
13
13
|
basePath: string;
|
|
14
14
|
/** The database adapter */
|
|
@@ -40,9 +40,13 @@ export interface ClientStackContext<
|
|
|
40
40
|
* You can optionally provide a base schema via the dbSchema config option.
|
|
41
41
|
*
|
|
42
42
|
* @template TRoutes - The exact shape of routes this plugin provides (preserves keys and endpoint types)
|
|
43
|
+
* @template TApi - The shape of the server-side API surface exposed via `stack().api`.
|
|
44
|
+
* Defaults to `never` so that plugins without an `api` factory are excluded from the
|
|
45
|
+
* `stack().api` namespace entirely, preventing accidental access of `undefined` at runtime.
|
|
43
46
|
*/
|
|
44
47
|
export interface BackendPlugin<
|
|
45
48
|
TRoutes extends Record<string, Endpoint> = Record<string, Endpoint>,
|
|
49
|
+
TApi extends Record<string, (...args: any[]) => any> = never,
|
|
46
50
|
> {
|
|
47
51
|
name: string;
|
|
48
52
|
|
|
@@ -56,6 +60,15 @@ export interface BackendPlugin<
|
|
|
56
60
|
*/
|
|
57
61
|
routes: (adapter: Adapter, context?: StackContext) => TRoutes;
|
|
58
62
|
dbPlugin: DbPlugin;
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Optional factory that returns server-side getter functions bound to the adapter.
|
|
66
|
+
* The returned object is merged into `stack().api.<pluginName>.*` for direct
|
|
67
|
+
* server-side or SSG data access without going through HTTP.
|
|
68
|
+
*
|
|
69
|
+
* @param adapter - The adapter instance shared with `routes`
|
|
70
|
+
*/
|
|
71
|
+
api?: (adapter: Adapter) => TApi;
|
|
59
72
|
}
|
|
60
73
|
|
|
61
74
|
/**
|
|
@@ -87,13 +100,30 @@ export interface ClientPlugin<
|
|
|
87
100
|
sitemap?: () => Promise<Sitemap> | Sitemap;
|
|
88
101
|
}
|
|
89
102
|
|
|
103
|
+
/**
|
|
104
|
+
* Utility type that maps each plugin key to the return type of its `api` factory.
|
|
105
|
+
* Plugin keys whose `TApi` resolves to `never` (i.e. plugins with no `api` factory)
|
|
106
|
+
* are excluded from the resulting type via key remapping, preventing TypeScript from
|
|
107
|
+
* suggesting callable functions on what is actually `undefined` at runtime.
|
|
108
|
+
*/
|
|
109
|
+
export type PluginApis<
|
|
110
|
+
TPlugins extends Record<string, BackendPlugin<any, any>>,
|
|
111
|
+
> = {
|
|
112
|
+
[K in keyof TPlugins as _ApiOf<TPlugins[K]> extends never
|
|
113
|
+
? never
|
|
114
|
+
: K]: _ApiOf<TPlugins[K]>;
|
|
115
|
+
};
|
|
116
|
+
|
|
117
|
+
/** @internal Extract the TApi parameter from a BackendPlugin type. */
|
|
118
|
+
type _ApiOf<T> = T extends BackendPlugin<any, infer TApi> ? TApi : never;
|
|
119
|
+
|
|
90
120
|
/**
|
|
91
121
|
* Configuration for creating the backend library
|
|
92
122
|
*/
|
|
93
123
|
export interface BackendLibConfig<
|
|
94
|
-
TPlugins extends Record<string, BackendPlugin<any>> = Record<
|
|
124
|
+
TPlugins extends Record<string, BackendPlugin<any, any>> = Record<
|
|
95
125
|
string,
|
|
96
|
-
BackendPlugin<any>
|
|
126
|
+
BackendPlugin<any, any>
|
|
97
127
|
>,
|
|
98
128
|
> {
|
|
99
129
|
basePath: string;
|
|
@@ -150,11 +180,12 @@ export type PluginRoutes<
|
|
|
150
180
|
* Example: { messages: { list: Endpoint } } => { messages_list: Endpoint }
|
|
151
181
|
*/
|
|
152
182
|
export type PrefixedPluginRoutes<
|
|
153
|
-
TPlugins extends Record<string, BackendPlugin<any>>,
|
|
183
|
+
TPlugins extends Record<string, BackendPlugin<any, any>>,
|
|
154
184
|
> = UnionToIntersection<
|
|
155
185
|
{
|
|
156
186
|
[PluginKey in keyof TPlugins]: TPlugins[PluginKey] extends BackendPlugin<
|
|
157
|
-
infer TRoutes
|
|
187
|
+
infer TRoutes,
|
|
188
|
+
any
|
|
158
189
|
>
|
|
159
190
|
? {
|
|
160
191
|
[RouteKey in keyof TRoutes as `${PluginKey & string}_${RouteKey & string}`]: TRoutes[RouteKey];
|
|
@@ -172,10 +203,18 @@ export type PrefixedPluginRoutes<
|
|
|
172
203
|
*/
|
|
173
204
|
export interface BackendLib<
|
|
174
205
|
TRoutes extends Record<string, Endpoint> = Record<string, Endpoint>,
|
|
206
|
+
TApis extends Record<
|
|
207
|
+
string,
|
|
208
|
+
Record<string, (...args: any[]) => any>
|
|
209
|
+
> = Record<string, Record<string, (...args: any[]) => any>>,
|
|
175
210
|
> {
|
|
176
211
|
handler: (request: Request) => Promise<Response>; // API route handler
|
|
177
212
|
router: Router; // Better-call router
|
|
178
213
|
dbSchema: DatabaseDefinition; // Better-db schema
|
|
214
|
+
/** The database adapter shared across all plugins */
|
|
215
|
+
adapter: Adapter;
|
|
216
|
+
/** Fully-typed server-side getter functions, namespaced per plugin */
|
|
217
|
+
api: TApis;
|
|
179
218
|
}
|
|
180
219
|
|
|
181
220
|
/**
|
|
@@ -35,6 +35,13 @@ interface SerializedTag extends Omit<Tag, "createdAt" | "updatedAt"> {
|
|
|
35
35
|
}
|
|
36
36
|
|
|
37
37
|
declare const createPostSchema: z.ZodObject<{
|
|
38
|
+
tags: z.ZodDefault<z.ZodOptional<z.ZodArray<z.ZodUnion<readonly [z.ZodObject<{
|
|
39
|
+
name: z.ZodString;
|
|
40
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
41
|
+
id: z.ZodString;
|
|
42
|
+
name: z.ZodString;
|
|
43
|
+
slug: z.ZodString;
|
|
44
|
+
}, z.core.$strip>]>>>>;
|
|
38
45
|
slug: z.ZodOptional<z.ZodString>;
|
|
39
46
|
publishedAt: z.ZodOptional<z.ZodCoercedDate<unknown>>;
|
|
40
47
|
createdAt: z.ZodOptional<z.ZodCoercedDate<unknown>>;
|
|
@@ -44,13 +51,6 @@ declare const createPostSchema: z.ZodObject<{
|
|
|
44
51
|
excerpt: z.ZodString;
|
|
45
52
|
image: z.ZodOptional<z.ZodString>;
|
|
46
53
|
published: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
|
|
47
|
-
tags: z.ZodDefault<z.ZodOptional<z.ZodArray<z.ZodUnion<readonly [z.ZodObject<{
|
|
48
|
-
name: z.ZodString;
|
|
49
|
-
}, z.core.$strip>, z.ZodObject<{
|
|
50
|
-
id: z.ZodString;
|
|
51
|
-
name: z.ZodString;
|
|
52
|
-
slug: z.ZodString;
|
|
53
|
-
}, z.core.$strip>]>>>>;
|
|
54
54
|
}, z.core.$strip>;
|
|
55
55
|
declare const updatePostSchema: z.ZodObject<{
|
|
56
56
|
publishedAt: z.ZodOptional<z.ZodCoercedDate<unknown>>;
|
|
@@ -35,6 +35,13 @@ interface SerializedTag extends Omit<Tag, "createdAt" | "updatedAt"> {
|
|
|
35
35
|
}
|
|
36
36
|
|
|
37
37
|
declare const createPostSchema: z.ZodObject<{
|
|
38
|
+
tags: z.ZodDefault<z.ZodOptional<z.ZodArray<z.ZodUnion<readonly [z.ZodObject<{
|
|
39
|
+
name: z.ZodString;
|
|
40
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
41
|
+
id: z.ZodString;
|
|
42
|
+
name: z.ZodString;
|
|
43
|
+
slug: z.ZodString;
|
|
44
|
+
}, z.core.$strip>]>>>>;
|
|
38
45
|
slug: z.ZodOptional<z.ZodString>;
|
|
39
46
|
publishedAt: z.ZodOptional<z.ZodCoercedDate<unknown>>;
|
|
40
47
|
createdAt: z.ZodOptional<z.ZodCoercedDate<unknown>>;
|
|
@@ -44,13 +51,6 @@ declare const createPostSchema: z.ZodObject<{
|
|
|
44
51
|
excerpt: z.ZodString;
|
|
45
52
|
image: z.ZodOptional<z.ZodString>;
|
|
46
53
|
published: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
|
|
47
|
-
tags: z.ZodDefault<z.ZodOptional<z.ZodArray<z.ZodUnion<readonly [z.ZodObject<{
|
|
48
|
-
name: z.ZodString;
|
|
49
|
-
}, z.core.$strip>, z.ZodObject<{
|
|
50
|
-
id: z.ZodString;
|
|
51
|
-
name: z.ZodString;
|
|
52
|
-
slug: z.ZodString;
|
|
53
|
-
}, z.core.$strip>]>>>>;
|
|
54
54
|
}, z.core.$strip>;
|
|
55
55
|
declare const updatePostSchema: z.ZodObject<{
|
|
56
56
|
publishedAt: z.ZodOptional<z.ZodCoercedDate<unknown>>;
|
|
@@ -35,6 +35,13 @@ interface SerializedTag extends Omit<Tag, "createdAt" | "updatedAt"> {
|
|
|
35
35
|
}
|
|
36
36
|
|
|
37
37
|
declare const createPostSchema: z.ZodObject<{
|
|
38
|
+
tags: z.ZodDefault<z.ZodOptional<z.ZodArray<z.ZodUnion<readonly [z.ZodObject<{
|
|
39
|
+
name: z.ZodString;
|
|
40
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
41
|
+
id: z.ZodString;
|
|
42
|
+
name: z.ZodString;
|
|
43
|
+
slug: z.ZodString;
|
|
44
|
+
}, z.core.$strip>]>>>>;
|
|
38
45
|
slug: z.ZodOptional<z.ZodString>;
|
|
39
46
|
publishedAt: z.ZodOptional<z.ZodCoercedDate<unknown>>;
|
|
40
47
|
createdAt: z.ZodOptional<z.ZodCoercedDate<unknown>>;
|
|
@@ -44,13 +51,6 @@ declare const createPostSchema: z.ZodObject<{
|
|
|
44
51
|
excerpt: z.ZodString;
|
|
45
52
|
image: z.ZodOptional<z.ZodString>;
|
|
46
53
|
published: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
|
|
47
|
-
tags: z.ZodDefault<z.ZodOptional<z.ZodArray<z.ZodUnion<readonly [z.ZodObject<{
|
|
48
|
-
name: z.ZodString;
|
|
49
|
-
}, z.core.$strip>, z.ZodObject<{
|
|
50
|
-
id: z.ZodString;
|
|
51
|
-
name: z.ZodString;
|
|
52
|
-
slug: z.ZodString;
|
|
53
|
-
}, z.core.$strip>]>>>>;
|
|
54
54
|
}, z.core.$strip>;
|
|
55
55
|
declare const updatePostSchema: z.ZodObject<{
|
|
56
56
|
publishedAt: z.ZodOptional<z.ZodCoercedDate<unknown>>;
|