@btst/stack 1.2.2 → 1.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/packages/better-stack/src/plugins/blog/api/plugin.cjs +95 -120
- package/dist/packages/better-stack/src/plugins/blog/api/plugin.mjs +95 -120
- package/dist/packages/better-stack/src/plugins/blog/db.cjs +12 -2
- package/dist/packages/better-stack/src/plugins/blog/db.mjs +12 -2
- package/dist/plugins/blog/api/index.d.cts +1 -1
- package/dist/plugins/blog/api/index.d.mts +1 -1
- package/dist/plugins/blog/api/index.d.ts +1 -1
- package/dist/plugins/blog/client/hooks/index.d.cts +2 -2
- package/dist/plugins/blog/client/hooks/index.d.mts +2 -2
- package/dist/plugins/blog/client/hooks/index.d.ts +2 -2
- package/dist/plugins/blog/client/index.d.cts +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.d.cts +5 -5
- package/dist/plugins/blog/query-keys.d.mts +5 -5
- package/dist/plugins/blog/query-keys.d.ts +5 -5
- package/package.json +3 -3
- package/src/plugins/blog/api/plugin.ts +116 -147
- package/src/plugins/blog/db.ts +10 -0
- package/src/plugins/blog/types.ts +7 -0
- package/dist/shared/{stack.Cr2JoQdo.d.cts → stack.DLhzx1-D.d.cts} +2 -2
- package/dist/shared/{stack.Cr2JoQdo.d.mts → stack.DLhzx1-D.d.mts} +2 -2
- package/dist/shared/{stack.Cr2JoQdo.d.ts → stack.DLhzx1-D.d.ts} +2 -2
|
@@ -26,53 +26,7 @@ const blogBackendPlugin = (hooks) => api.defineBackendPlugin({
|
|
|
26
26
|
name: "blog",
|
|
27
27
|
dbPlugin: db.blogSchema,
|
|
28
28
|
routes: (adapter) => {
|
|
29
|
-
const
|
|
30
|
-
let cache = null;
|
|
31
|
-
return {
|
|
32
|
-
getAllTags: async () => {
|
|
33
|
-
if (!cache) {
|
|
34
|
-
cache = await adapter.findMany({
|
|
35
|
-
model: "tag"
|
|
36
|
-
});
|
|
37
|
-
}
|
|
38
|
-
return cache;
|
|
39
|
-
},
|
|
40
|
-
invalidate: () => {
|
|
41
|
-
cache = null;
|
|
42
|
-
},
|
|
43
|
-
addTag: (tag) => {
|
|
44
|
-
if (cache) {
|
|
45
|
-
cache.push(tag);
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
};
|
|
49
|
-
};
|
|
50
|
-
const createPostTagCache = () => {
|
|
51
|
-
let cache = null;
|
|
52
|
-
const getAllPostTags = async () => {
|
|
53
|
-
if (!cache) {
|
|
54
|
-
cache = await adapter.findMany({
|
|
55
|
-
model: "postTag"
|
|
56
|
-
});
|
|
57
|
-
}
|
|
58
|
-
return cache;
|
|
59
|
-
};
|
|
60
|
-
return {
|
|
61
|
-
getAllPostTags,
|
|
62
|
-
invalidate: () => {
|
|
63
|
-
cache = null;
|
|
64
|
-
},
|
|
65
|
-
getByTagId: async (tagId) => {
|
|
66
|
-
const allPostTags = await getAllPostTags();
|
|
67
|
-
return allPostTags.filter((pt) => pt.tagId === tagId);
|
|
68
|
-
},
|
|
69
|
-
getByPostId: async (postId) => {
|
|
70
|
-
const allPostTags = await getAllPostTags();
|
|
71
|
-
return allPostTags.filter((pt) => pt.postId === postId);
|
|
72
|
-
}
|
|
73
|
-
};
|
|
74
|
-
};
|
|
75
|
-
const findOrCreateTags = async (tagInputs, tagCache) => {
|
|
29
|
+
const findOrCreateTags = async (tagInputs) => {
|
|
76
30
|
if (tagInputs.length === 0) return [];
|
|
77
31
|
const normalizeTagName = (name) => {
|
|
78
32
|
return name.trim();
|
|
@@ -95,7 +49,9 @@ const blogBackendPlugin = (hooks) => api.defineBackendPlugin({
|
|
|
95
49
|
if (tagsToFindOrCreate.length === 0) {
|
|
96
50
|
return tagsWithIds;
|
|
97
51
|
}
|
|
98
|
-
const allTags = await
|
|
52
|
+
const allTags = await adapter.findMany({
|
|
53
|
+
model: "tag"
|
|
54
|
+
});
|
|
99
55
|
const tagMapBySlug = /* @__PURE__ */ new Map();
|
|
100
56
|
for (const tag of allTags) {
|
|
101
57
|
tagMapBySlug.set(tag.slug, tag);
|
|
@@ -128,33 +84,9 @@ const blogBackendPlugin = (hooks) => api.defineBackendPlugin({
|
|
|
128
84
|
}
|
|
129
85
|
});
|
|
130
86
|
createdTags.push(newTag);
|
|
131
|
-
tagCache.addTag(newTag);
|
|
132
87
|
}
|
|
133
88
|
return [...tagsWithIds, ...foundTags, ...createdTags];
|
|
134
89
|
};
|
|
135
|
-
const loadTagsForPosts = async (postIds, tagCache, postTagCache) => {
|
|
136
|
-
if (postIds.length === 0) return /* @__PURE__ */ new Map();
|
|
137
|
-
const allPostTags = await postTagCache.getAllPostTags();
|
|
138
|
-
const relevantPostTags = allPostTags.filter(
|
|
139
|
-
(pt) => postIds.includes(pt.postId)
|
|
140
|
-
);
|
|
141
|
-
const tagIds = [...new Set(relevantPostTags.map((pt) => pt.tagId))];
|
|
142
|
-
if (tagIds.length === 0) return /* @__PURE__ */ new Map();
|
|
143
|
-
const allTags = await tagCache.getAllTags();
|
|
144
|
-
const tagMap = /* @__PURE__ */ new Map();
|
|
145
|
-
for (const tag of allTags) {
|
|
146
|
-
tagMap.set(tag.id, tag);
|
|
147
|
-
}
|
|
148
|
-
const postTagsMap = /* @__PURE__ */ new Map();
|
|
149
|
-
for (const postTag of relevantPostTags) {
|
|
150
|
-
const tag = tagMap.get(postTag.tagId);
|
|
151
|
-
if (tag) {
|
|
152
|
-
const existing = postTagsMap.get(postTag.postId) || [];
|
|
153
|
-
postTagsMap.set(postTag.postId, [...existing, { ...tag }]);
|
|
154
|
-
}
|
|
155
|
-
}
|
|
156
|
-
return postTagsMap;
|
|
157
|
-
};
|
|
158
90
|
const listPosts = api.createEndpoint(
|
|
159
91
|
"/posts",
|
|
160
92
|
{
|
|
@@ -164,8 +96,6 @@ const blogBackendPlugin = (hooks) => api.defineBackendPlugin({
|
|
|
164
96
|
async (ctx) => {
|
|
165
97
|
const { query, headers } = ctx;
|
|
166
98
|
const context = { query, headers };
|
|
167
|
-
const tagCache = createTagCache();
|
|
168
|
-
const postTagCache = createPostTagCache();
|
|
169
99
|
try {
|
|
170
100
|
if (hooks?.onBeforeListPosts) {
|
|
171
101
|
const canList = await hooks.onBeforeListPosts(query, context);
|
|
@@ -177,12 +107,29 @@ const blogBackendPlugin = (hooks) => api.defineBackendPlugin({
|
|
|
177
107
|
}
|
|
178
108
|
let tagFilterPostIds = null;
|
|
179
109
|
if (query.tagSlug) {
|
|
180
|
-
const
|
|
181
|
-
|
|
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
|
+
});
|
|
182
120
|
if (!tag) {
|
|
183
121
|
return [];
|
|
184
122
|
}
|
|
185
|
-
const postTags = await
|
|
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
|
+
});
|
|
186
133
|
tagFilterPostIds = new Set(postTags.map((pt) => pt.postId));
|
|
187
134
|
if (tagFilterPostIds.size === 0) {
|
|
188
135
|
return [];
|
|
@@ -211,17 +158,36 @@ const blogBackendPlugin = (hooks) => api.defineBackendPlugin({
|
|
|
211
158
|
sortBy: {
|
|
212
159
|
field: "createdAt",
|
|
213
160
|
direction: "desc"
|
|
161
|
+
},
|
|
162
|
+
join: {
|
|
163
|
+
postTag: true
|
|
214
164
|
}
|
|
215
165
|
});
|
|
216
|
-
const
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
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) => tagMap.get(pt.tagId)).filter((tag) => tag !== void 0);
|
|
185
|
+
const { postTag: _, ...postWithoutJoin } = post;
|
|
186
|
+
return {
|
|
187
|
+
...postWithoutJoin,
|
|
188
|
+
tags: postTags
|
|
189
|
+
};
|
|
190
|
+
});
|
|
225
191
|
if (tagFilterPostIds) {
|
|
226
192
|
result = result.filter((post) => tagFilterPostIds.has(post.id));
|
|
227
193
|
}
|
|
@@ -262,7 +228,6 @@ const blogBackendPlugin = (hooks) => api.defineBackendPlugin({
|
|
|
262
228
|
body: ctx.body,
|
|
263
229
|
headers: ctx.headers
|
|
264
230
|
};
|
|
265
|
-
const tagCache = createTagCache();
|
|
266
231
|
try {
|
|
267
232
|
if (hooks?.onBeforeCreatePost) {
|
|
268
233
|
const canCreate = await hooks.onBeforeCreatePost(
|
|
@@ -288,7 +253,7 @@ const blogBackendPlugin = (hooks) => api.defineBackendPlugin({
|
|
|
288
253
|
}
|
|
289
254
|
});
|
|
290
255
|
if (tagNames.length > 0) {
|
|
291
|
-
const createdTags = await findOrCreateTags(tagNames
|
|
256
|
+
const createdTags = await findOrCreateTags(tagNames);
|
|
292
257
|
await adapter.transaction(async (tx) => {
|
|
293
258
|
for (const tag of createdTags) {
|
|
294
259
|
await tx.create({
|
|
@@ -328,7 +293,6 @@ const blogBackendPlugin = (hooks) => api.defineBackendPlugin({
|
|
|
328
293
|
params: ctx.params,
|
|
329
294
|
headers: ctx.headers
|
|
330
295
|
};
|
|
331
|
-
const tagCache = createTagCache();
|
|
332
296
|
try {
|
|
333
297
|
if (hooks?.onBeforeUpdatePost) {
|
|
334
298
|
const canUpdate = await hooks.onBeforeUpdatePost(
|
|
@@ -386,7 +350,7 @@ const blogBackendPlugin = (hooks) => api.defineBackendPlugin({
|
|
|
386
350
|
});
|
|
387
351
|
}
|
|
388
352
|
if (tagNames.length > 0) {
|
|
389
|
-
const createdTags = await findOrCreateTags(tagNames
|
|
353
|
+
const createdTags = await findOrCreateTags(tagNames);
|
|
390
354
|
for (const tag of createdTags) {
|
|
391
355
|
await tx.create({
|
|
392
356
|
model: "postTag",
|
|
@@ -436,15 +400,9 @@ const blogBackendPlugin = (hooks) => api.defineBackendPlugin({
|
|
|
436
400
|
});
|
|
437
401
|
}
|
|
438
402
|
}
|
|
439
|
-
await adapter.
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
where: [{ field: "postId", value: ctx.params.id }]
|
|
443
|
-
});
|
|
444
|
-
await tx.delete({
|
|
445
|
-
model: "post",
|
|
446
|
-
where: [{ field: "id", value: ctx.params.id }]
|
|
447
|
-
});
|
|
403
|
+
await adapter.delete({
|
|
404
|
+
model: "post",
|
|
405
|
+
where: [{ field: "id", value: ctx.params.id }]
|
|
448
406
|
});
|
|
449
407
|
if (hooks?.onPostDeleted) {
|
|
450
408
|
await hooks.onPostDeleted(ctx.params.id, context);
|
|
@@ -467,8 +425,6 @@ const blogBackendPlugin = (hooks) => api.defineBackendPlugin({
|
|
|
467
425
|
async (ctx) => {
|
|
468
426
|
const { query, headers } = ctx;
|
|
469
427
|
const context = { query, headers };
|
|
470
|
-
const tagCache = createTagCache();
|
|
471
|
-
const postTagCache = createPostTagCache();
|
|
472
428
|
try {
|
|
473
429
|
if (hooks?.onBeforeListPosts) {
|
|
474
430
|
const canList = await hooks.onBeforeListPosts(
|
|
@@ -482,7 +438,7 @@ const blogBackendPlugin = (hooks) => api.defineBackendPlugin({
|
|
|
482
438
|
}
|
|
483
439
|
}
|
|
484
440
|
const date = query.date;
|
|
485
|
-
const
|
|
441
|
+
const previousPosts = await adapter.findMany({
|
|
486
442
|
model: "post",
|
|
487
443
|
limit: 1,
|
|
488
444
|
where: [
|
|
@@ -500,9 +456,12 @@ const blogBackendPlugin = (hooks) => api.defineBackendPlugin({
|
|
|
500
456
|
sortBy: {
|
|
501
457
|
field: "createdAt",
|
|
502
458
|
direction: "desc"
|
|
459
|
+
},
|
|
460
|
+
join: {
|
|
461
|
+
postTag: true
|
|
503
462
|
}
|
|
504
463
|
});
|
|
505
|
-
const
|
|
464
|
+
const nextPosts = await adapter.findMany({
|
|
506
465
|
model: "post",
|
|
507
466
|
limit: 1,
|
|
508
467
|
where: [
|
|
@@ -520,26 +479,42 @@ const blogBackendPlugin = (hooks) => api.defineBackendPlugin({
|
|
|
520
479
|
sortBy: {
|
|
521
480
|
field: "createdAt",
|
|
522
481
|
direction: "asc"
|
|
482
|
+
},
|
|
483
|
+
join: {
|
|
484
|
+
postTag: true
|
|
523
485
|
}
|
|
524
486
|
});
|
|
525
|
-
const
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
487
|
+
const tagIds = /* @__PURE__ */ new Set();
|
|
488
|
+
const allPosts = [...previousPosts, ...nextPosts];
|
|
489
|
+
for (const post of allPosts) {
|
|
490
|
+
if (post.postTag) {
|
|
491
|
+
for (const pt of post.postTag) {
|
|
492
|
+
tagIds.add(pt.tagId);
|
|
493
|
+
}
|
|
494
|
+
}
|
|
495
|
+
}
|
|
496
|
+
const tagMap = /* @__PURE__ */ new Map();
|
|
497
|
+
if (tagIds.size > 0) {
|
|
498
|
+
const tags = await adapter.findMany({
|
|
499
|
+
model: "tag"
|
|
500
|
+
});
|
|
501
|
+
for (const tag of tags) {
|
|
502
|
+
if (tagIds.has(tag.id)) {
|
|
503
|
+
tagMap.set(tag.id, tag);
|
|
504
|
+
}
|
|
505
|
+
}
|
|
506
|
+
}
|
|
507
|
+
const mapPostWithTags = (post) => {
|
|
508
|
+
const tags = (post.postTag || []).map((pt) => tagMap.get(pt.tagId)).filter((tag) => tag !== void 0);
|
|
509
|
+
const { postTag: _, ...postWithoutJoin } = post;
|
|
510
|
+
return {
|
|
511
|
+
...postWithoutJoin,
|
|
512
|
+
tags
|
|
513
|
+
};
|
|
514
|
+
};
|
|
534
515
|
return {
|
|
535
|
-
previous:
|
|
536
|
-
|
|
537
|
-
tags: postTagsMap.get(previousPost[0].id) || []
|
|
538
|
-
} : null,
|
|
539
|
-
next: nextPost?.[0] ? {
|
|
540
|
-
...nextPost[0],
|
|
541
|
-
tags: postTagsMap.get(nextPost[0].id) || []
|
|
542
|
-
} : null
|
|
516
|
+
previous: previousPosts[0] ? mapPostWithTags(previousPosts[0]) : null,
|
|
517
|
+
next: nextPosts[0] ? mapPostWithTags(nextPosts[0]) : null
|
|
543
518
|
};
|
|
544
519
|
} catch (error) {
|
|
545
520
|
if (hooks?.onListPostsError) {
|
|
@@ -24,53 +24,7 @@ const blogBackendPlugin = (hooks) => defineBackendPlugin({
|
|
|
24
24
|
name: "blog",
|
|
25
25
|
dbPlugin: blogSchema,
|
|
26
26
|
routes: (adapter) => {
|
|
27
|
-
const
|
|
28
|
-
let cache = null;
|
|
29
|
-
return {
|
|
30
|
-
getAllTags: async () => {
|
|
31
|
-
if (!cache) {
|
|
32
|
-
cache = await adapter.findMany({
|
|
33
|
-
model: "tag"
|
|
34
|
-
});
|
|
35
|
-
}
|
|
36
|
-
return cache;
|
|
37
|
-
},
|
|
38
|
-
invalidate: () => {
|
|
39
|
-
cache = null;
|
|
40
|
-
},
|
|
41
|
-
addTag: (tag) => {
|
|
42
|
-
if (cache) {
|
|
43
|
-
cache.push(tag);
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
};
|
|
47
|
-
};
|
|
48
|
-
const createPostTagCache = () => {
|
|
49
|
-
let cache = null;
|
|
50
|
-
const getAllPostTags = async () => {
|
|
51
|
-
if (!cache) {
|
|
52
|
-
cache = await adapter.findMany({
|
|
53
|
-
model: "postTag"
|
|
54
|
-
});
|
|
55
|
-
}
|
|
56
|
-
return cache;
|
|
57
|
-
};
|
|
58
|
-
return {
|
|
59
|
-
getAllPostTags,
|
|
60
|
-
invalidate: () => {
|
|
61
|
-
cache = null;
|
|
62
|
-
},
|
|
63
|
-
getByTagId: async (tagId) => {
|
|
64
|
-
const allPostTags = await getAllPostTags();
|
|
65
|
-
return allPostTags.filter((pt) => pt.tagId === tagId);
|
|
66
|
-
},
|
|
67
|
-
getByPostId: async (postId) => {
|
|
68
|
-
const allPostTags = await getAllPostTags();
|
|
69
|
-
return allPostTags.filter((pt) => pt.postId === postId);
|
|
70
|
-
}
|
|
71
|
-
};
|
|
72
|
-
};
|
|
73
|
-
const findOrCreateTags = async (tagInputs, tagCache) => {
|
|
27
|
+
const findOrCreateTags = async (tagInputs) => {
|
|
74
28
|
if (tagInputs.length === 0) return [];
|
|
75
29
|
const normalizeTagName = (name) => {
|
|
76
30
|
return name.trim();
|
|
@@ -93,7 +47,9 @@ const blogBackendPlugin = (hooks) => defineBackendPlugin({
|
|
|
93
47
|
if (tagsToFindOrCreate.length === 0) {
|
|
94
48
|
return tagsWithIds;
|
|
95
49
|
}
|
|
96
|
-
const allTags = await
|
|
50
|
+
const allTags = await adapter.findMany({
|
|
51
|
+
model: "tag"
|
|
52
|
+
});
|
|
97
53
|
const tagMapBySlug = /* @__PURE__ */ new Map();
|
|
98
54
|
for (const tag of allTags) {
|
|
99
55
|
tagMapBySlug.set(tag.slug, tag);
|
|
@@ -126,33 +82,9 @@ const blogBackendPlugin = (hooks) => defineBackendPlugin({
|
|
|
126
82
|
}
|
|
127
83
|
});
|
|
128
84
|
createdTags.push(newTag);
|
|
129
|
-
tagCache.addTag(newTag);
|
|
130
85
|
}
|
|
131
86
|
return [...tagsWithIds, ...foundTags, ...createdTags];
|
|
132
87
|
};
|
|
133
|
-
const loadTagsForPosts = async (postIds, tagCache, postTagCache) => {
|
|
134
|
-
if (postIds.length === 0) return /* @__PURE__ */ new Map();
|
|
135
|
-
const allPostTags = await postTagCache.getAllPostTags();
|
|
136
|
-
const relevantPostTags = allPostTags.filter(
|
|
137
|
-
(pt) => postIds.includes(pt.postId)
|
|
138
|
-
);
|
|
139
|
-
const tagIds = [...new Set(relevantPostTags.map((pt) => pt.tagId))];
|
|
140
|
-
if (tagIds.length === 0) return /* @__PURE__ */ new Map();
|
|
141
|
-
const allTags = await tagCache.getAllTags();
|
|
142
|
-
const tagMap = /* @__PURE__ */ new Map();
|
|
143
|
-
for (const tag of allTags) {
|
|
144
|
-
tagMap.set(tag.id, tag);
|
|
145
|
-
}
|
|
146
|
-
const postTagsMap = /* @__PURE__ */ new Map();
|
|
147
|
-
for (const postTag of relevantPostTags) {
|
|
148
|
-
const tag = tagMap.get(postTag.tagId);
|
|
149
|
-
if (tag) {
|
|
150
|
-
const existing = postTagsMap.get(postTag.postId) || [];
|
|
151
|
-
postTagsMap.set(postTag.postId, [...existing, { ...tag }]);
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
return postTagsMap;
|
|
155
|
-
};
|
|
156
88
|
const listPosts = createEndpoint(
|
|
157
89
|
"/posts",
|
|
158
90
|
{
|
|
@@ -162,8 +94,6 @@ const blogBackendPlugin = (hooks) => defineBackendPlugin({
|
|
|
162
94
|
async (ctx) => {
|
|
163
95
|
const { query, headers } = ctx;
|
|
164
96
|
const context = { query, headers };
|
|
165
|
-
const tagCache = createTagCache();
|
|
166
|
-
const postTagCache = createPostTagCache();
|
|
167
97
|
try {
|
|
168
98
|
if (hooks?.onBeforeListPosts) {
|
|
169
99
|
const canList = await hooks.onBeforeListPosts(query, context);
|
|
@@ -175,12 +105,29 @@ const blogBackendPlugin = (hooks) => defineBackendPlugin({
|
|
|
175
105
|
}
|
|
176
106
|
let tagFilterPostIds = null;
|
|
177
107
|
if (query.tagSlug) {
|
|
178
|
-
const
|
|
179
|
-
|
|
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
|
+
});
|
|
180
118
|
if (!tag) {
|
|
181
119
|
return [];
|
|
182
120
|
}
|
|
183
|
-
const postTags = await
|
|
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
|
+
});
|
|
184
131
|
tagFilterPostIds = new Set(postTags.map((pt) => pt.postId));
|
|
185
132
|
if (tagFilterPostIds.size === 0) {
|
|
186
133
|
return [];
|
|
@@ -209,17 +156,36 @@ const blogBackendPlugin = (hooks) => defineBackendPlugin({
|
|
|
209
156
|
sortBy: {
|
|
210
157
|
field: "createdAt",
|
|
211
158
|
direction: "desc"
|
|
159
|
+
},
|
|
160
|
+
join: {
|
|
161
|
+
postTag: true
|
|
212
162
|
}
|
|
213
163
|
});
|
|
214
|
-
const
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
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) => tagMap.get(pt.tagId)).filter((tag) => tag !== void 0);
|
|
183
|
+
const { postTag: _, ...postWithoutJoin } = post;
|
|
184
|
+
return {
|
|
185
|
+
...postWithoutJoin,
|
|
186
|
+
tags: postTags
|
|
187
|
+
};
|
|
188
|
+
});
|
|
223
189
|
if (tagFilterPostIds) {
|
|
224
190
|
result = result.filter((post) => tagFilterPostIds.has(post.id));
|
|
225
191
|
}
|
|
@@ -260,7 +226,6 @@ const blogBackendPlugin = (hooks) => defineBackendPlugin({
|
|
|
260
226
|
body: ctx.body,
|
|
261
227
|
headers: ctx.headers
|
|
262
228
|
};
|
|
263
|
-
const tagCache = createTagCache();
|
|
264
229
|
try {
|
|
265
230
|
if (hooks?.onBeforeCreatePost) {
|
|
266
231
|
const canCreate = await hooks.onBeforeCreatePost(
|
|
@@ -286,7 +251,7 @@ const blogBackendPlugin = (hooks) => defineBackendPlugin({
|
|
|
286
251
|
}
|
|
287
252
|
});
|
|
288
253
|
if (tagNames.length > 0) {
|
|
289
|
-
const createdTags = await findOrCreateTags(tagNames
|
|
254
|
+
const createdTags = await findOrCreateTags(tagNames);
|
|
290
255
|
await adapter.transaction(async (tx) => {
|
|
291
256
|
for (const tag of createdTags) {
|
|
292
257
|
await tx.create({
|
|
@@ -326,7 +291,6 @@ const blogBackendPlugin = (hooks) => defineBackendPlugin({
|
|
|
326
291
|
params: ctx.params,
|
|
327
292
|
headers: ctx.headers
|
|
328
293
|
};
|
|
329
|
-
const tagCache = createTagCache();
|
|
330
294
|
try {
|
|
331
295
|
if (hooks?.onBeforeUpdatePost) {
|
|
332
296
|
const canUpdate = await hooks.onBeforeUpdatePost(
|
|
@@ -384,7 +348,7 @@ const blogBackendPlugin = (hooks) => defineBackendPlugin({
|
|
|
384
348
|
});
|
|
385
349
|
}
|
|
386
350
|
if (tagNames.length > 0) {
|
|
387
|
-
const createdTags = await findOrCreateTags(tagNames
|
|
351
|
+
const createdTags = await findOrCreateTags(tagNames);
|
|
388
352
|
for (const tag of createdTags) {
|
|
389
353
|
await tx.create({
|
|
390
354
|
model: "postTag",
|
|
@@ -434,15 +398,9 @@ const blogBackendPlugin = (hooks) => defineBackendPlugin({
|
|
|
434
398
|
});
|
|
435
399
|
}
|
|
436
400
|
}
|
|
437
|
-
await adapter.
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
where: [{ field: "postId", value: ctx.params.id }]
|
|
441
|
-
});
|
|
442
|
-
await tx.delete({
|
|
443
|
-
model: "post",
|
|
444
|
-
where: [{ field: "id", value: ctx.params.id }]
|
|
445
|
-
});
|
|
401
|
+
await adapter.delete({
|
|
402
|
+
model: "post",
|
|
403
|
+
where: [{ field: "id", value: ctx.params.id }]
|
|
446
404
|
});
|
|
447
405
|
if (hooks?.onPostDeleted) {
|
|
448
406
|
await hooks.onPostDeleted(ctx.params.id, context);
|
|
@@ -465,8 +423,6 @@ const blogBackendPlugin = (hooks) => defineBackendPlugin({
|
|
|
465
423
|
async (ctx) => {
|
|
466
424
|
const { query, headers } = ctx;
|
|
467
425
|
const context = { query, headers };
|
|
468
|
-
const tagCache = createTagCache();
|
|
469
|
-
const postTagCache = createPostTagCache();
|
|
470
426
|
try {
|
|
471
427
|
if (hooks?.onBeforeListPosts) {
|
|
472
428
|
const canList = await hooks.onBeforeListPosts(
|
|
@@ -480,7 +436,7 @@ const blogBackendPlugin = (hooks) => defineBackendPlugin({
|
|
|
480
436
|
}
|
|
481
437
|
}
|
|
482
438
|
const date = query.date;
|
|
483
|
-
const
|
|
439
|
+
const previousPosts = await adapter.findMany({
|
|
484
440
|
model: "post",
|
|
485
441
|
limit: 1,
|
|
486
442
|
where: [
|
|
@@ -498,9 +454,12 @@ const blogBackendPlugin = (hooks) => defineBackendPlugin({
|
|
|
498
454
|
sortBy: {
|
|
499
455
|
field: "createdAt",
|
|
500
456
|
direction: "desc"
|
|
457
|
+
},
|
|
458
|
+
join: {
|
|
459
|
+
postTag: true
|
|
501
460
|
}
|
|
502
461
|
});
|
|
503
|
-
const
|
|
462
|
+
const nextPosts = await adapter.findMany({
|
|
504
463
|
model: "post",
|
|
505
464
|
limit: 1,
|
|
506
465
|
where: [
|
|
@@ -518,26 +477,42 @@ const blogBackendPlugin = (hooks) => defineBackendPlugin({
|
|
|
518
477
|
sortBy: {
|
|
519
478
|
field: "createdAt",
|
|
520
479
|
direction: "asc"
|
|
480
|
+
},
|
|
481
|
+
join: {
|
|
482
|
+
postTag: true
|
|
521
483
|
}
|
|
522
484
|
});
|
|
523
|
-
const
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
485
|
+
const tagIds = /* @__PURE__ */ new Set();
|
|
486
|
+
const allPosts = [...previousPosts, ...nextPosts];
|
|
487
|
+
for (const post of allPosts) {
|
|
488
|
+
if (post.postTag) {
|
|
489
|
+
for (const pt of post.postTag) {
|
|
490
|
+
tagIds.add(pt.tagId);
|
|
491
|
+
}
|
|
492
|
+
}
|
|
493
|
+
}
|
|
494
|
+
const tagMap = /* @__PURE__ */ new Map();
|
|
495
|
+
if (tagIds.size > 0) {
|
|
496
|
+
const tags = await adapter.findMany({
|
|
497
|
+
model: "tag"
|
|
498
|
+
});
|
|
499
|
+
for (const tag of tags) {
|
|
500
|
+
if (tagIds.has(tag.id)) {
|
|
501
|
+
tagMap.set(tag.id, tag);
|
|
502
|
+
}
|
|
503
|
+
}
|
|
504
|
+
}
|
|
505
|
+
const mapPostWithTags = (post) => {
|
|
506
|
+
const tags = (post.postTag || []).map((pt) => tagMap.get(pt.tagId)).filter((tag) => tag !== void 0);
|
|
507
|
+
const { postTag: _, ...postWithoutJoin } = post;
|
|
508
|
+
return {
|
|
509
|
+
...postWithoutJoin,
|
|
510
|
+
tags
|
|
511
|
+
};
|
|
512
|
+
};
|
|
532
513
|
return {
|
|
533
|
-
previous:
|
|
534
|
-
|
|
535
|
-
tags: postTagsMap.get(previousPost[0].id) || []
|
|
536
|
-
} : null,
|
|
537
|
-
next: nextPost?.[0] ? {
|
|
538
|
-
...nextPost[0],
|
|
539
|
-
tags: postTagsMap.get(nextPost[0].id) || []
|
|
540
|
-
} : null
|
|
514
|
+
previous: previousPosts[0] ? mapPostWithTags(previousPosts[0]) : null,
|
|
515
|
+
next: nextPosts[0] ? mapPostWithTags(nextPosts[0]) : null
|
|
541
516
|
};
|
|
542
517
|
} catch (error) {
|
|
543
518
|
if (hooks?.onListPostsError) {
|
|
@@ -77,11 +77,21 @@ const blogSchema = db.createDbPlugin("blog", {
|
|
|
77
77
|
fields: {
|
|
78
78
|
postId: {
|
|
79
79
|
type: "string",
|
|
80
|
-
required: true
|
|
80
|
+
required: true,
|
|
81
|
+
references: {
|
|
82
|
+
model: "post",
|
|
83
|
+
field: "id",
|
|
84
|
+
onDelete: "cascade"
|
|
85
|
+
}
|
|
81
86
|
},
|
|
82
87
|
tagId: {
|
|
83
88
|
type: "string",
|
|
84
|
-
required: true
|
|
89
|
+
required: true,
|
|
90
|
+
references: {
|
|
91
|
+
model: "tag",
|
|
92
|
+
field: "id",
|
|
93
|
+
onDelete: "cascade"
|
|
94
|
+
}
|
|
85
95
|
}
|
|
86
96
|
}
|
|
87
97
|
}
|