@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
|
@@ -5,7 +5,58 @@ const z = require('zod');
|
|
|
5
5
|
const db = require('../db.cjs');
|
|
6
6
|
const utils = require('../utils.cjs');
|
|
7
7
|
const schemas = require('../schemas.cjs');
|
|
8
|
+
const getters = require('./getters.cjs');
|
|
9
|
+
const queryKeyDefs = require('./query-key-defs.cjs');
|
|
10
|
+
const serializers = require('./serializers.cjs');
|
|
8
11
|
|
|
12
|
+
function createBlogPrefetchForRoute(adapter) {
|
|
13
|
+
return async function prefetchForRoute(key, qc, params) {
|
|
14
|
+
switch (key) {
|
|
15
|
+
case "posts":
|
|
16
|
+
case "drafts": {
|
|
17
|
+
const published = key === "posts";
|
|
18
|
+
const [result, tags] = await Promise.all([
|
|
19
|
+
getters.getAllPosts(adapter, { published, limit: 10 }),
|
|
20
|
+
getters.getAllTags(adapter)
|
|
21
|
+
]);
|
|
22
|
+
qc.setQueryData(queryKeyDefs.BLOG_QUERY_KEYS.postsList({ published, limit: 10 }), {
|
|
23
|
+
pages: [result.items.map(serializers.serializePost)],
|
|
24
|
+
pageParams: [0]
|
|
25
|
+
});
|
|
26
|
+
qc.setQueryData(queryKeyDefs.BLOG_QUERY_KEYS.tagsList(), tags.map(serializers.serializeTag));
|
|
27
|
+
break;
|
|
28
|
+
}
|
|
29
|
+
case "post":
|
|
30
|
+
case "editPost": {
|
|
31
|
+
const slug = params?.slug ?? "";
|
|
32
|
+
if (slug) {
|
|
33
|
+
const post = await getters.getPostBySlug(adapter, slug);
|
|
34
|
+
qc.setQueryData(
|
|
35
|
+
queryKeyDefs.BLOG_QUERY_KEYS.postDetail(slug),
|
|
36
|
+
post ? serializers.serializePost(post) : null
|
|
37
|
+
);
|
|
38
|
+
}
|
|
39
|
+
break;
|
|
40
|
+
}
|
|
41
|
+
case "tag": {
|
|
42
|
+
const tagSlug = params?.tagSlug ?? "";
|
|
43
|
+
const [result, tags] = await Promise.all([
|
|
44
|
+
getters.getAllPosts(adapter, { published: true, limit: 10, tagSlug }),
|
|
45
|
+
getters.getAllTags(adapter)
|
|
46
|
+
]);
|
|
47
|
+
qc.setQueryData(
|
|
48
|
+
queryKeyDefs.BLOG_QUERY_KEYS.postsList({ published: true, limit: 10, tagSlug }),
|
|
49
|
+
{
|
|
50
|
+
pages: [result.items.map(serializers.serializePost)],
|
|
51
|
+
pageParams: [0]
|
|
52
|
+
}
|
|
53
|
+
);
|
|
54
|
+
qc.setQueryData(queryKeyDefs.BLOG_QUERY_KEYS.tagsList(), tags.map(serializers.serializeTag));
|
|
55
|
+
break;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
};
|
|
59
|
+
}
|
|
9
60
|
const PostListQuerySchema = z.z.object({
|
|
10
61
|
slug: z.z.string().optional(),
|
|
11
62
|
tagSlug: z.z.string().optional(),
|
|
@@ -25,6 +76,12 @@ const NextPreviousPostsQuerySchema = z.z.object({
|
|
|
25
76
|
const blogBackendPlugin = (hooks) => api.defineBackendPlugin({
|
|
26
77
|
name: "blog",
|
|
27
78
|
dbPlugin: db.blogSchema,
|
|
79
|
+
api: (adapter) => ({
|
|
80
|
+
getAllPosts: (params) => getters.getAllPosts(adapter, params),
|
|
81
|
+
getPostBySlug: (slug) => getters.getPostBySlug(adapter, slug),
|
|
82
|
+
getAllTags: () => getters.getAllTags(adapter),
|
|
83
|
+
prefetchForRoute: createBlogPrefetchForRoute(adapter)
|
|
84
|
+
}),
|
|
28
85
|
routes: (adapter) => {
|
|
29
86
|
const findOrCreateTags = async (tagInputs) => {
|
|
30
87
|
if (tagInputs.length === 0) return [];
|
|
@@ -105,111 +162,9 @@ const blogBackendPlugin = (hooks) => api.defineBackendPlugin({
|
|
|
105
162
|
});
|
|
106
163
|
}
|
|
107
164
|
}
|
|
108
|
-
|
|
109
|
-
if (query.tagSlug) {
|
|
110
|
-
const tag = await adapter.findOne({
|
|
111
|
-
model: "tag",
|
|
112
|
-
where: [
|
|
113
|
-
{
|
|
114
|
-
field: "slug",
|
|
115
|
-
value: query.tagSlug,
|
|
116
|
-
operator: "eq"
|
|
117
|
-
}
|
|
118
|
-
]
|
|
119
|
-
});
|
|
120
|
-
if (!tag) {
|
|
121
|
-
return [];
|
|
122
|
-
}
|
|
123
|
-
const postTags = await adapter.findMany({
|
|
124
|
-
model: "postTag",
|
|
125
|
-
where: [
|
|
126
|
-
{
|
|
127
|
-
field: "tagId",
|
|
128
|
-
value: tag.id,
|
|
129
|
-
operator: "eq"
|
|
130
|
-
}
|
|
131
|
-
]
|
|
132
|
-
});
|
|
133
|
-
tagFilterPostIds = new Set(postTags.map((pt) => pt.postId));
|
|
134
|
-
if (tagFilterPostIds.size === 0) {
|
|
135
|
-
return [];
|
|
136
|
-
}
|
|
137
|
-
}
|
|
138
|
-
const whereConditions = [];
|
|
139
|
-
if (query.published !== void 0) {
|
|
140
|
-
whereConditions.push({
|
|
141
|
-
field: "published",
|
|
142
|
-
value: query.published,
|
|
143
|
-
operator: "eq"
|
|
144
|
-
});
|
|
145
|
-
}
|
|
146
|
-
if (query.slug) {
|
|
147
|
-
whereConditions.push({
|
|
148
|
-
field: "slug",
|
|
149
|
-
value: query.slug,
|
|
150
|
-
operator: "eq"
|
|
151
|
-
});
|
|
152
|
-
}
|
|
153
|
-
const posts = await adapter.findMany({
|
|
154
|
-
model: "post",
|
|
155
|
-
limit: query.query || query.tagSlug ? void 0 : query.limit ?? 10,
|
|
156
|
-
offset: query.query || query.tagSlug ? void 0 : query.offset ?? 0,
|
|
157
|
-
where: whereConditions,
|
|
158
|
-
sortBy: {
|
|
159
|
-
field: "createdAt",
|
|
160
|
-
direction: "desc"
|
|
161
|
-
},
|
|
162
|
-
join: {
|
|
163
|
-
postTag: true
|
|
164
|
-
}
|
|
165
|
-
});
|
|
166
|
-
const tagIds = /* @__PURE__ */ new Set();
|
|
167
|
-
for (const post of posts) {
|
|
168
|
-
if (post.postTag) {
|
|
169
|
-
for (const pt of post.postTag) {
|
|
170
|
-
tagIds.add(pt.tagId);
|
|
171
|
-
}
|
|
172
|
-
}
|
|
173
|
-
}
|
|
174
|
-
const tags = tagIds.size > 0 ? await adapter.findMany({
|
|
175
|
-
model: "tag"
|
|
176
|
-
}) : [];
|
|
177
|
-
const tagMap = /* @__PURE__ */ new Map();
|
|
178
|
-
for (const tag of tags) {
|
|
179
|
-
if (tagIds.has(tag.id)) {
|
|
180
|
-
tagMap.set(tag.id, tag);
|
|
181
|
-
}
|
|
182
|
-
}
|
|
183
|
-
let result = posts.map((post) => {
|
|
184
|
-
const postTags = (post.postTag || []).map((pt) => {
|
|
185
|
-
const tag = tagMap.get(pt.tagId);
|
|
186
|
-
return tag ? { ...tag } : void 0;
|
|
187
|
-
}).filter((tag) => tag !== void 0);
|
|
188
|
-
const { postTag: _, ...postWithoutJoin } = post;
|
|
189
|
-
return {
|
|
190
|
-
...postWithoutJoin,
|
|
191
|
-
tags: postTags
|
|
192
|
-
};
|
|
193
|
-
});
|
|
194
|
-
if (tagFilterPostIds) {
|
|
195
|
-
result = result.filter((post) => tagFilterPostIds.has(post.id));
|
|
196
|
-
}
|
|
197
|
-
if (query.query) {
|
|
198
|
-
const searchLower = query.query.toLowerCase();
|
|
199
|
-
result = result.filter((post) => {
|
|
200
|
-
const titleMatch = post.title?.toLowerCase().includes(searchLower);
|
|
201
|
-
const contentMatch = post.content?.toLowerCase().includes(searchLower);
|
|
202
|
-
const excerptMatch = post.excerpt?.toLowerCase().includes(searchLower);
|
|
203
|
-
return titleMatch || contentMatch || excerptMatch;
|
|
204
|
-
});
|
|
205
|
-
}
|
|
206
|
-
if (query.tagSlug || query.query) {
|
|
207
|
-
const offset = query.offset ?? 0;
|
|
208
|
-
const limit = query.limit ?? 10;
|
|
209
|
-
result = result.slice(offset, offset + limit);
|
|
210
|
-
}
|
|
165
|
+
const result = await getters.getAllPosts(adapter, query);
|
|
211
166
|
if (hooks?.onPostsRead) {
|
|
212
|
-
await hooks.onPostsRead(result, query, context);
|
|
167
|
+
await hooks.onPostsRead(result.items, query, context);
|
|
213
168
|
}
|
|
214
169
|
return result;
|
|
215
170
|
} catch (error) {
|
|
@@ -552,9 +507,7 @@ const blogBackendPlugin = (hooks) => api.defineBackendPlugin({
|
|
|
552
507
|
method: "GET"
|
|
553
508
|
},
|
|
554
509
|
async () => {
|
|
555
|
-
return await
|
|
556
|
-
model: "tag"
|
|
557
|
-
});
|
|
510
|
+
return await getters.getAllTags(adapter);
|
|
558
511
|
}
|
|
559
512
|
);
|
|
560
513
|
return {
|
|
@@ -3,7 +3,58 @@ import { z } from 'zod';
|
|
|
3
3
|
import { blogSchema } from '../db.mjs';
|
|
4
4
|
import { slugify } from '../utils.mjs';
|
|
5
5
|
import { createPostSchema, updatePostSchema } from '../schemas.mjs';
|
|
6
|
+
import { getAllTags, getPostBySlug, getAllPosts } from './getters.mjs';
|
|
7
|
+
import { BLOG_QUERY_KEYS } from './query-key-defs.mjs';
|
|
8
|
+
import { serializePost, serializeTag } from './serializers.mjs';
|
|
6
9
|
|
|
10
|
+
function createBlogPrefetchForRoute(adapter) {
|
|
11
|
+
return async function prefetchForRoute(key, qc, params) {
|
|
12
|
+
switch (key) {
|
|
13
|
+
case "posts":
|
|
14
|
+
case "drafts": {
|
|
15
|
+
const published = key === "posts";
|
|
16
|
+
const [result, tags] = await Promise.all([
|
|
17
|
+
getAllPosts(adapter, { published, limit: 10 }),
|
|
18
|
+
getAllTags(adapter)
|
|
19
|
+
]);
|
|
20
|
+
qc.setQueryData(BLOG_QUERY_KEYS.postsList({ published, limit: 10 }), {
|
|
21
|
+
pages: [result.items.map(serializePost)],
|
|
22
|
+
pageParams: [0]
|
|
23
|
+
});
|
|
24
|
+
qc.setQueryData(BLOG_QUERY_KEYS.tagsList(), tags.map(serializeTag));
|
|
25
|
+
break;
|
|
26
|
+
}
|
|
27
|
+
case "post":
|
|
28
|
+
case "editPost": {
|
|
29
|
+
const slug = params?.slug ?? "";
|
|
30
|
+
if (slug) {
|
|
31
|
+
const post = await getPostBySlug(adapter, slug);
|
|
32
|
+
qc.setQueryData(
|
|
33
|
+
BLOG_QUERY_KEYS.postDetail(slug),
|
|
34
|
+
post ? serializePost(post) : null
|
|
35
|
+
);
|
|
36
|
+
}
|
|
37
|
+
break;
|
|
38
|
+
}
|
|
39
|
+
case "tag": {
|
|
40
|
+
const tagSlug = params?.tagSlug ?? "";
|
|
41
|
+
const [result, tags] = await Promise.all([
|
|
42
|
+
getAllPosts(adapter, { published: true, limit: 10, tagSlug }),
|
|
43
|
+
getAllTags(adapter)
|
|
44
|
+
]);
|
|
45
|
+
qc.setQueryData(
|
|
46
|
+
BLOG_QUERY_KEYS.postsList({ published: true, limit: 10, tagSlug }),
|
|
47
|
+
{
|
|
48
|
+
pages: [result.items.map(serializePost)],
|
|
49
|
+
pageParams: [0]
|
|
50
|
+
}
|
|
51
|
+
);
|
|
52
|
+
qc.setQueryData(BLOG_QUERY_KEYS.tagsList(), tags.map(serializeTag));
|
|
53
|
+
break;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
};
|
|
57
|
+
}
|
|
7
58
|
const PostListQuerySchema = z.object({
|
|
8
59
|
slug: z.string().optional(),
|
|
9
60
|
tagSlug: z.string().optional(),
|
|
@@ -23,6 +74,12 @@ const NextPreviousPostsQuerySchema = z.object({
|
|
|
23
74
|
const blogBackendPlugin = (hooks) => defineBackendPlugin({
|
|
24
75
|
name: "blog",
|
|
25
76
|
dbPlugin: blogSchema,
|
|
77
|
+
api: (adapter) => ({
|
|
78
|
+
getAllPosts: (params) => getAllPosts(adapter, params),
|
|
79
|
+
getPostBySlug: (slug) => getPostBySlug(adapter, slug),
|
|
80
|
+
getAllTags: () => getAllTags(adapter),
|
|
81
|
+
prefetchForRoute: createBlogPrefetchForRoute(adapter)
|
|
82
|
+
}),
|
|
26
83
|
routes: (adapter) => {
|
|
27
84
|
const findOrCreateTags = async (tagInputs) => {
|
|
28
85
|
if (tagInputs.length === 0) return [];
|
|
@@ -103,111 +160,9 @@ const blogBackendPlugin = (hooks) => defineBackendPlugin({
|
|
|
103
160
|
});
|
|
104
161
|
}
|
|
105
162
|
}
|
|
106
|
-
|
|
107
|
-
if (query.tagSlug) {
|
|
108
|
-
const tag = await adapter.findOne({
|
|
109
|
-
model: "tag",
|
|
110
|
-
where: [
|
|
111
|
-
{
|
|
112
|
-
field: "slug",
|
|
113
|
-
value: query.tagSlug,
|
|
114
|
-
operator: "eq"
|
|
115
|
-
}
|
|
116
|
-
]
|
|
117
|
-
});
|
|
118
|
-
if (!tag) {
|
|
119
|
-
return [];
|
|
120
|
-
}
|
|
121
|
-
const postTags = await adapter.findMany({
|
|
122
|
-
model: "postTag",
|
|
123
|
-
where: [
|
|
124
|
-
{
|
|
125
|
-
field: "tagId",
|
|
126
|
-
value: tag.id,
|
|
127
|
-
operator: "eq"
|
|
128
|
-
}
|
|
129
|
-
]
|
|
130
|
-
});
|
|
131
|
-
tagFilterPostIds = new Set(postTags.map((pt) => pt.postId));
|
|
132
|
-
if (tagFilterPostIds.size === 0) {
|
|
133
|
-
return [];
|
|
134
|
-
}
|
|
135
|
-
}
|
|
136
|
-
const whereConditions = [];
|
|
137
|
-
if (query.published !== void 0) {
|
|
138
|
-
whereConditions.push({
|
|
139
|
-
field: "published",
|
|
140
|
-
value: query.published,
|
|
141
|
-
operator: "eq"
|
|
142
|
-
});
|
|
143
|
-
}
|
|
144
|
-
if (query.slug) {
|
|
145
|
-
whereConditions.push({
|
|
146
|
-
field: "slug",
|
|
147
|
-
value: query.slug,
|
|
148
|
-
operator: "eq"
|
|
149
|
-
});
|
|
150
|
-
}
|
|
151
|
-
const posts = await adapter.findMany({
|
|
152
|
-
model: "post",
|
|
153
|
-
limit: query.query || query.tagSlug ? void 0 : query.limit ?? 10,
|
|
154
|
-
offset: query.query || query.tagSlug ? void 0 : query.offset ?? 0,
|
|
155
|
-
where: whereConditions,
|
|
156
|
-
sortBy: {
|
|
157
|
-
field: "createdAt",
|
|
158
|
-
direction: "desc"
|
|
159
|
-
},
|
|
160
|
-
join: {
|
|
161
|
-
postTag: true
|
|
162
|
-
}
|
|
163
|
-
});
|
|
164
|
-
const tagIds = /* @__PURE__ */ new Set();
|
|
165
|
-
for (const post of posts) {
|
|
166
|
-
if (post.postTag) {
|
|
167
|
-
for (const pt of post.postTag) {
|
|
168
|
-
tagIds.add(pt.tagId);
|
|
169
|
-
}
|
|
170
|
-
}
|
|
171
|
-
}
|
|
172
|
-
const tags = tagIds.size > 0 ? await adapter.findMany({
|
|
173
|
-
model: "tag"
|
|
174
|
-
}) : [];
|
|
175
|
-
const tagMap = /* @__PURE__ */ new Map();
|
|
176
|
-
for (const tag of tags) {
|
|
177
|
-
if (tagIds.has(tag.id)) {
|
|
178
|
-
tagMap.set(tag.id, tag);
|
|
179
|
-
}
|
|
180
|
-
}
|
|
181
|
-
let result = posts.map((post) => {
|
|
182
|
-
const postTags = (post.postTag || []).map((pt) => {
|
|
183
|
-
const tag = tagMap.get(pt.tagId);
|
|
184
|
-
return tag ? { ...tag } : void 0;
|
|
185
|
-
}).filter((tag) => tag !== void 0);
|
|
186
|
-
const { postTag: _, ...postWithoutJoin } = post;
|
|
187
|
-
return {
|
|
188
|
-
...postWithoutJoin,
|
|
189
|
-
tags: postTags
|
|
190
|
-
};
|
|
191
|
-
});
|
|
192
|
-
if (tagFilterPostIds) {
|
|
193
|
-
result = result.filter((post) => tagFilterPostIds.has(post.id));
|
|
194
|
-
}
|
|
195
|
-
if (query.query) {
|
|
196
|
-
const searchLower = query.query.toLowerCase();
|
|
197
|
-
result = result.filter((post) => {
|
|
198
|
-
const titleMatch = post.title?.toLowerCase().includes(searchLower);
|
|
199
|
-
const contentMatch = post.content?.toLowerCase().includes(searchLower);
|
|
200
|
-
const excerptMatch = post.excerpt?.toLowerCase().includes(searchLower);
|
|
201
|
-
return titleMatch || contentMatch || excerptMatch;
|
|
202
|
-
});
|
|
203
|
-
}
|
|
204
|
-
if (query.tagSlug || query.query) {
|
|
205
|
-
const offset = query.offset ?? 0;
|
|
206
|
-
const limit = query.limit ?? 10;
|
|
207
|
-
result = result.slice(offset, offset + limit);
|
|
208
|
-
}
|
|
163
|
+
const result = await getAllPosts(adapter, query);
|
|
209
164
|
if (hooks?.onPostsRead) {
|
|
210
|
-
await hooks.onPostsRead(result, query, context);
|
|
165
|
+
await hooks.onPostsRead(result.items, query, context);
|
|
211
166
|
}
|
|
212
167
|
return result;
|
|
213
168
|
} catch (error) {
|
|
@@ -550,9 +505,7 @@ const blogBackendPlugin = (hooks) => defineBackendPlugin({
|
|
|
550
505
|
method: "GET"
|
|
551
506
|
},
|
|
552
507
|
async () => {
|
|
553
|
-
return await adapter
|
|
554
|
-
model: "tag"
|
|
555
|
-
});
|
|
508
|
+
return await getAllTags(adapter);
|
|
556
509
|
}
|
|
557
510
|
);
|
|
558
511
|
return {
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
function postsListDiscriminator(params) {
|
|
4
|
+
return {
|
|
5
|
+
query: params.query !== void 0 && params.query.trim() === "" ? void 0 : params.query,
|
|
6
|
+
limit: params.limit ?? 10,
|
|
7
|
+
published: params.published,
|
|
8
|
+
tagSlug: params.tagSlug
|
|
9
|
+
};
|
|
10
|
+
}
|
|
11
|
+
const BLOG_QUERY_KEYS = {
|
|
12
|
+
postsList: (params) => ["posts", "list", postsListDiscriminator(params)],
|
|
13
|
+
postDetail: (slug) => ["posts", "detail", slug],
|
|
14
|
+
tagsList: () => ["tags", "list", "tags"]
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
exports.BLOG_QUERY_KEYS = BLOG_QUERY_KEYS;
|
|
18
|
+
exports.postsListDiscriminator = postsListDiscriminator;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
function postsListDiscriminator(params) {
|
|
2
|
+
return {
|
|
3
|
+
query: params.query !== void 0 && params.query.trim() === "" ? void 0 : params.query,
|
|
4
|
+
limit: params.limit ?? 10,
|
|
5
|
+
published: params.published,
|
|
6
|
+
tagSlug: params.tagSlug
|
|
7
|
+
};
|
|
8
|
+
}
|
|
9
|
+
const BLOG_QUERY_KEYS = {
|
|
10
|
+
postsList: (params) => ["posts", "list", postsListDiscriminator(params)],
|
|
11
|
+
postDetail: (slug) => ["posts", "detail", slug],
|
|
12
|
+
tagsList: () => ["tags", "list", "tags"]
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
export { BLOG_QUERY_KEYS, postsListDiscriminator };
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
function serializeTag(tag) {
|
|
4
|
+
return {
|
|
5
|
+
...tag,
|
|
6
|
+
createdAt: tag.createdAt.toISOString(),
|
|
7
|
+
updatedAt: tag.updatedAt.toISOString()
|
|
8
|
+
};
|
|
9
|
+
}
|
|
10
|
+
function serializePost(post) {
|
|
11
|
+
return {
|
|
12
|
+
...post,
|
|
13
|
+
createdAt: post.createdAt.toISOString(),
|
|
14
|
+
updatedAt: post.updatedAt.toISOString(),
|
|
15
|
+
publishedAt: post.publishedAt?.toISOString(),
|
|
16
|
+
tags: post.tags.map(serializeTag)
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
exports.serializePost = serializePost;
|
|
21
|
+
exports.serializeTag = serializeTag;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
function serializeTag(tag) {
|
|
2
|
+
return {
|
|
3
|
+
...tag,
|
|
4
|
+
createdAt: tag.createdAt.toISOString(),
|
|
5
|
+
updatedAt: tag.updatedAt.toISOString()
|
|
6
|
+
};
|
|
7
|
+
}
|
|
8
|
+
function serializePost(post) {
|
|
9
|
+
return {
|
|
10
|
+
...post,
|
|
11
|
+
createdAt: post.createdAt.toISOString(),
|
|
12
|
+
updatedAt: post.updatedAt.toISOString(),
|
|
13
|
+
publishedAt: post.publishedAt?.toISOString(),
|
|
14
|
+
tags: post.tags.map(serializeTag)
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export { serializePost, serializeTag };
|
|
@@ -64,6 +64,11 @@ function createPostsLoader(published, config) {
|
|
|
64
64
|
}
|
|
65
65
|
}
|
|
66
66
|
} catch (error) {
|
|
67
|
+
if (client.isConnectionError(error)) {
|
|
68
|
+
console.warn(
|
|
69
|
+
"[btst/blog] route.loader() failed \u2014 no server running at build time. Use myStack.api.blog.prefetchForRoute() for SSG data prefetching."
|
|
70
|
+
);
|
|
71
|
+
}
|
|
67
72
|
if (hooks?.onLoadError) {
|
|
68
73
|
await hooks.onLoadError(error, context);
|
|
69
74
|
}
|
|
@@ -112,6 +117,11 @@ function createPostLoader(slug, config, path) {
|
|
|
112
117
|
}
|
|
113
118
|
}
|
|
114
119
|
} catch (error) {
|
|
120
|
+
if (client.isConnectionError(error)) {
|
|
121
|
+
console.warn(
|
|
122
|
+
"[btst/blog] route.loader() failed \u2014 no server running at build time. Use myStack.api.blog.prefetchForRoute() for SSG data prefetching."
|
|
123
|
+
);
|
|
124
|
+
}
|
|
115
125
|
if (hooks?.onLoadError) {
|
|
116
126
|
await hooks.onLoadError(error, context);
|
|
117
127
|
}
|
|
@@ -190,6 +200,11 @@ function createTagLoader(tagSlug, config) {
|
|
|
190
200
|
await hooks.onLoadError(error, context);
|
|
191
201
|
}
|
|
192
202
|
} catch (error) {
|
|
203
|
+
if (client.isConnectionError(error)) {
|
|
204
|
+
console.warn(
|
|
205
|
+
"[btst/blog] route.loader() failed \u2014 no server running at build time. Use myStack.api.blog.prefetchForRoute() for SSG data prefetching."
|
|
206
|
+
);
|
|
207
|
+
}
|
|
193
208
|
if (hooks?.onLoadError) {
|
|
194
209
|
await hooks.onLoadError(error, context);
|
|
195
210
|
}
|
|
@@ -472,7 +487,7 @@ const blogClientPlugin = (config) => client.defineClientPlugin({
|
|
|
472
487
|
published: "true"
|
|
473
488
|
}
|
|
474
489
|
});
|
|
475
|
-
const page = res.data ?? [];
|
|
490
|
+
const page = res.data?.items ?? [];
|
|
476
491
|
posts.push(...page);
|
|
477
492
|
if (page.length < limit) break;
|
|
478
493
|
offset += limit;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { jsx } from 'react/jsx-runtime';
|
|
2
|
-
import { defineClientPlugin, createApiClient } from '@btst/stack/plugins/client';
|
|
2
|
+
import { defineClientPlugin, createApiClient, isConnectionError } from '@btst/stack/plugins/client';
|
|
3
3
|
import { createRoute } from '@btst/yar';
|
|
4
4
|
import { createBlogQueryKeys } from '../../../../../../plugins/blog/query-keys.mjs';
|
|
5
5
|
import { HomePageComponent } from './components/pages/home-page.mjs';
|
|
@@ -62,6 +62,11 @@ function createPostsLoader(published, config) {
|
|
|
62
62
|
}
|
|
63
63
|
}
|
|
64
64
|
} catch (error) {
|
|
65
|
+
if (isConnectionError(error)) {
|
|
66
|
+
console.warn(
|
|
67
|
+
"[btst/blog] route.loader() failed \u2014 no server running at build time. Use myStack.api.blog.prefetchForRoute() for SSG data prefetching."
|
|
68
|
+
);
|
|
69
|
+
}
|
|
65
70
|
if (hooks?.onLoadError) {
|
|
66
71
|
await hooks.onLoadError(error, context);
|
|
67
72
|
}
|
|
@@ -110,6 +115,11 @@ function createPostLoader(slug, config, path) {
|
|
|
110
115
|
}
|
|
111
116
|
}
|
|
112
117
|
} catch (error) {
|
|
118
|
+
if (isConnectionError(error)) {
|
|
119
|
+
console.warn(
|
|
120
|
+
"[btst/blog] route.loader() failed \u2014 no server running at build time. Use myStack.api.blog.prefetchForRoute() for SSG data prefetching."
|
|
121
|
+
);
|
|
122
|
+
}
|
|
113
123
|
if (hooks?.onLoadError) {
|
|
114
124
|
await hooks.onLoadError(error, context);
|
|
115
125
|
}
|
|
@@ -188,6 +198,11 @@ function createTagLoader(tagSlug, config) {
|
|
|
188
198
|
await hooks.onLoadError(error, context);
|
|
189
199
|
}
|
|
190
200
|
} catch (error) {
|
|
201
|
+
if (isConnectionError(error)) {
|
|
202
|
+
console.warn(
|
|
203
|
+
"[btst/blog] route.loader() failed \u2014 no server running at build time. Use myStack.api.blog.prefetchForRoute() for SSG data prefetching."
|
|
204
|
+
);
|
|
205
|
+
}
|
|
191
206
|
if (hooks?.onLoadError) {
|
|
192
207
|
await hooks.onLoadError(error, context);
|
|
193
208
|
}
|
|
@@ -470,7 +485,7 @@ const blogClientPlugin = (config) => defineClientPlugin({
|
|
|
470
485
|
published: "true"
|
|
471
486
|
}
|
|
472
487
|
});
|
|
473
|
-
const page = res.data ?? [];
|
|
488
|
+
const page = res.data?.items ?? [];
|
|
474
489
|
posts.push(...page);
|
|
475
490
|
if (page.length < limit) break;
|
|
476
491
|
offset += limit;
|