@btst/stack 2.11.1 → 2.11.3
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/plugins/blog/api/mutations.cjs +170 -0
- package/dist/packages/stack/src/plugins/blog/api/mutations.mjs +166 -0
- package/dist/packages/stack/src/plugins/blog/api/plugin.cjs +34 -157
- package/dist/packages/stack/src/plugins/blog/api/plugin.mjs +40 -163
- package/dist/plugins/blog/api/index.cjs +4 -0
- 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/api/index.mjs +1 -0
- package/dist/plugins/blog/query-keys.d.cts +1 -1
- package/dist/plugins/blog/query-keys.d.mts +1 -1
- package/dist/plugins/blog/query-keys.d.ts +1 -1
- package/dist/plugins/kanban/api/index.d.cts +1 -1
- package/dist/plugins/kanban/api/index.d.mts +1 -1
- package/dist/plugins/kanban/api/index.d.ts +1 -1
- package/dist/plugins/kanban/query-keys.d.cts +1 -1
- package/dist/plugins/kanban/query-keys.d.mts +1 -1
- package/dist/plugins/kanban/query-keys.d.ts +1 -1
- package/dist/shared/{stack.qta0-CPq.d.ts → stack.BQSy-NDc.d.ts} +85 -2
- package/dist/shared/{stack.DvMUCTTl.d.mts → stack.CLrGRIj0.d.mts} +85 -2
- package/dist/shared/{stack.DEW8EtFu.d.cts → stack.CntKf20s.d.cts} +85 -2
- package/package.json +4 -4
- package/src/plugins/blog/api/index.ts +7 -0
- package/src/plugins/blog/api/mutations.ts +287 -0
- package/src/plugins/blog/api/plugin.ts +43 -184
- package/dist/shared/{stack.BvCR4-9H.d.ts → stack.CMbX8Q5C.d.ts} +13 -13
- package/dist/shared/{stack.CWxAl9K3.d.mts → stack.Dj04W2c3.d.mts} +13 -13
- package/dist/shared/{stack.BOokfhZD.d.cts → stack.eq5eg1yt.d.cts} +13 -13
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const utils = require('../utils.cjs');
|
|
4
|
+
|
|
5
|
+
async function findOrCreateTags(adapter, tagInputs) {
|
|
6
|
+
if (tagInputs.length === 0) return [];
|
|
7
|
+
const normalizeTagName = (name) => name.trim();
|
|
8
|
+
const tagsWithIds = [];
|
|
9
|
+
const tagsToFindOrCreate = [];
|
|
10
|
+
for (const tagInput of tagInputs) {
|
|
11
|
+
if ("id" in tagInput && tagInput.id) {
|
|
12
|
+
tagsWithIds.push({
|
|
13
|
+
id: tagInput.id,
|
|
14
|
+
name: normalizeTagName(tagInput.name),
|
|
15
|
+
slug: tagInput.slug,
|
|
16
|
+
createdAt: /* @__PURE__ */ new Date(),
|
|
17
|
+
updatedAt: /* @__PURE__ */ new Date()
|
|
18
|
+
});
|
|
19
|
+
} else {
|
|
20
|
+
tagsToFindOrCreate.push({ name: normalizeTagName(tagInput.name) });
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
if (tagsToFindOrCreate.length === 0) {
|
|
24
|
+
return tagsWithIds;
|
|
25
|
+
}
|
|
26
|
+
const allTags = await adapter.findMany({ model: "tag" });
|
|
27
|
+
const tagMapBySlug = /* @__PURE__ */ new Map();
|
|
28
|
+
for (const tag of allTags) {
|
|
29
|
+
tagMapBySlug.set(tag.slug, tag);
|
|
30
|
+
}
|
|
31
|
+
const tagSlugs = tagsToFindOrCreate.map((tag) => utils.slugify(tag.name));
|
|
32
|
+
const foundTags = [];
|
|
33
|
+
for (const slug of tagSlugs) {
|
|
34
|
+
const tag = tagMapBySlug.get(slug);
|
|
35
|
+
if (tag) {
|
|
36
|
+
foundTags.push(tag);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
const existingSlugs = /* @__PURE__ */ new Set([
|
|
40
|
+
...tagsWithIds.map((tag) => tag.slug),
|
|
41
|
+
...foundTags.map((tag) => tag.slug)
|
|
42
|
+
]);
|
|
43
|
+
const tagsToCreate = tagsToFindOrCreate.filter(
|
|
44
|
+
(tag) => !existingSlugs.has(utils.slugify(tag.name))
|
|
45
|
+
);
|
|
46
|
+
const createdTags = [];
|
|
47
|
+
for (const tag of tagsToCreate) {
|
|
48
|
+
const normalizedName = normalizeTagName(tag.name);
|
|
49
|
+
const newTag = await adapter.create({
|
|
50
|
+
model: "tag",
|
|
51
|
+
data: {
|
|
52
|
+
name: normalizedName,
|
|
53
|
+
slug: utils.slugify(normalizedName),
|
|
54
|
+
createdAt: /* @__PURE__ */ new Date(),
|
|
55
|
+
updatedAt: /* @__PURE__ */ new Date()
|
|
56
|
+
}
|
|
57
|
+
});
|
|
58
|
+
createdTags.push(newTag);
|
|
59
|
+
}
|
|
60
|
+
return [...tagsWithIds, ...foundTags, ...createdTags];
|
|
61
|
+
}
|
|
62
|
+
async function createPost(adapter, input) {
|
|
63
|
+
const { tags: tagInputs, ...postData } = input;
|
|
64
|
+
const tagList = tagInputs ?? [];
|
|
65
|
+
const newPost = await adapter.create({
|
|
66
|
+
model: "post",
|
|
67
|
+
data: {
|
|
68
|
+
...postData,
|
|
69
|
+
published: postData.published ?? false,
|
|
70
|
+
tags: [],
|
|
71
|
+
createdAt: postData.createdAt ?? /* @__PURE__ */ new Date(),
|
|
72
|
+
updatedAt: postData.updatedAt ?? /* @__PURE__ */ new Date()
|
|
73
|
+
}
|
|
74
|
+
});
|
|
75
|
+
if (tagList.length > 0) {
|
|
76
|
+
const resolvedTags = await findOrCreateTags(adapter, tagList);
|
|
77
|
+
await adapter.transaction(async (tx) => {
|
|
78
|
+
for (const tag of resolvedTags) {
|
|
79
|
+
await tx.create({
|
|
80
|
+
model: "postTag",
|
|
81
|
+
data: {
|
|
82
|
+
postId: newPost.id,
|
|
83
|
+
tagId: tag.id
|
|
84
|
+
}
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
});
|
|
88
|
+
newPost.tags = resolvedTags.map((tag) => ({ ...tag }));
|
|
89
|
+
} else {
|
|
90
|
+
newPost.tags = [];
|
|
91
|
+
}
|
|
92
|
+
return newPost;
|
|
93
|
+
}
|
|
94
|
+
async function updatePost(adapter, id, input) {
|
|
95
|
+
const { tags: tagInputs, ...postData } = input;
|
|
96
|
+
return adapter.transaction(async (tx) => {
|
|
97
|
+
const updatedPost = await tx.update({
|
|
98
|
+
model: "post",
|
|
99
|
+
where: [{ field: "id", value: id }],
|
|
100
|
+
update: {
|
|
101
|
+
...postData,
|
|
102
|
+
updatedAt: /* @__PURE__ */ new Date()
|
|
103
|
+
}
|
|
104
|
+
});
|
|
105
|
+
if (!updatedPost) return null;
|
|
106
|
+
if (tagInputs !== void 0) {
|
|
107
|
+
const existingPostTags = await tx.findMany({
|
|
108
|
+
model: "postTag",
|
|
109
|
+
where: [{ field: "postId", value: id, operator: "eq" }]
|
|
110
|
+
});
|
|
111
|
+
for (const postTag of existingPostTags) {
|
|
112
|
+
await tx.delete({
|
|
113
|
+
model: "postTag",
|
|
114
|
+
where: [
|
|
115
|
+
{
|
|
116
|
+
field: "postId",
|
|
117
|
+
value: postTag.postId,
|
|
118
|
+
operator: "eq"
|
|
119
|
+
},
|
|
120
|
+
{
|
|
121
|
+
field: "tagId",
|
|
122
|
+
value: postTag.tagId,
|
|
123
|
+
operator: "eq"
|
|
124
|
+
}
|
|
125
|
+
]
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
if (tagInputs.length > 0) {
|
|
129
|
+
const resolvedTags = await findOrCreateTags(adapter, tagInputs);
|
|
130
|
+
for (const tag of resolvedTags) {
|
|
131
|
+
await tx.create({
|
|
132
|
+
model: "postTag",
|
|
133
|
+
data: {
|
|
134
|
+
postId: id,
|
|
135
|
+
tagId: tag.id
|
|
136
|
+
}
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
updatedPost.tags = resolvedTags.map((tag) => ({ ...tag }));
|
|
140
|
+
} else {
|
|
141
|
+
updatedPost.tags = [];
|
|
142
|
+
}
|
|
143
|
+
} else {
|
|
144
|
+
const existingPostTags = await tx.findMany({
|
|
145
|
+
model: "postTag",
|
|
146
|
+
where: [{ field: "postId", value: id, operator: "eq" }]
|
|
147
|
+
});
|
|
148
|
+
if (existingPostTags.length > 0) {
|
|
149
|
+
const tagIds = existingPostTags.map((pt) => pt.tagId);
|
|
150
|
+
const tags = await tx.findMany({
|
|
151
|
+
model: "tag"
|
|
152
|
+
});
|
|
153
|
+
updatedPost.tags = tags.filter((tag) => tagIds.includes(tag.id)).map((tag) => ({ ...tag }));
|
|
154
|
+
} else {
|
|
155
|
+
updatedPost.tags = [];
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
return updatedPost;
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
async function deletePost(adapter, id) {
|
|
162
|
+
await adapter.delete({
|
|
163
|
+
model: "post",
|
|
164
|
+
where: [{ field: "id", value: id }]
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
exports.createPost = createPost;
|
|
169
|
+
exports.deletePost = deletePost;
|
|
170
|
+
exports.updatePost = updatePost;
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
import { slugify } from '../utils.mjs';
|
|
2
|
+
|
|
3
|
+
async function findOrCreateTags(adapter, tagInputs) {
|
|
4
|
+
if (tagInputs.length === 0) return [];
|
|
5
|
+
const normalizeTagName = (name) => name.trim();
|
|
6
|
+
const tagsWithIds = [];
|
|
7
|
+
const tagsToFindOrCreate = [];
|
|
8
|
+
for (const tagInput of tagInputs) {
|
|
9
|
+
if ("id" in tagInput && tagInput.id) {
|
|
10
|
+
tagsWithIds.push({
|
|
11
|
+
id: tagInput.id,
|
|
12
|
+
name: normalizeTagName(tagInput.name),
|
|
13
|
+
slug: tagInput.slug,
|
|
14
|
+
createdAt: /* @__PURE__ */ new Date(),
|
|
15
|
+
updatedAt: /* @__PURE__ */ new Date()
|
|
16
|
+
});
|
|
17
|
+
} else {
|
|
18
|
+
tagsToFindOrCreate.push({ name: normalizeTagName(tagInput.name) });
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
if (tagsToFindOrCreate.length === 0) {
|
|
22
|
+
return tagsWithIds;
|
|
23
|
+
}
|
|
24
|
+
const allTags = await adapter.findMany({ model: "tag" });
|
|
25
|
+
const tagMapBySlug = /* @__PURE__ */ new Map();
|
|
26
|
+
for (const tag of allTags) {
|
|
27
|
+
tagMapBySlug.set(tag.slug, tag);
|
|
28
|
+
}
|
|
29
|
+
const tagSlugs = tagsToFindOrCreate.map((tag) => slugify(tag.name));
|
|
30
|
+
const foundTags = [];
|
|
31
|
+
for (const slug of tagSlugs) {
|
|
32
|
+
const tag = tagMapBySlug.get(slug);
|
|
33
|
+
if (tag) {
|
|
34
|
+
foundTags.push(tag);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
const existingSlugs = /* @__PURE__ */ new Set([
|
|
38
|
+
...tagsWithIds.map((tag) => tag.slug),
|
|
39
|
+
...foundTags.map((tag) => tag.slug)
|
|
40
|
+
]);
|
|
41
|
+
const tagsToCreate = tagsToFindOrCreate.filter(
|
|
42
|
+
(tag) => !existingSlugs.has(slugify(tag.name))
|
|
43
|
+
);
|
|
44
|
+
const createdTags = [];
|
|
45
|
+
for (const tag of tagsToCreate) {
|
|
46
|
+
const normalizedName = normalizeTagName(tag.name);
|
|
47
|
+
const newTag = await adapter.create({
|
|
48
|
+
model: "tag",
|
|
49
|
+
data: {
|
|
50
|
+
name: normalizedName,
|
|
51
|
+
slug: slugify(normalizedName),
|
|
52
|
+
createdAt: /* @__PURE__ */ new Date(),
|
|
53
|
+
updatedAt: /* @__PURE__ */ new Date()
|
|
54
|
+
}
|
|
55
|
+
});
|
|
56
|
+
createdTags.push(newTag);
|
|
57
|
+
}
|
|
58
|
+
return [...tagsWithIds, ...foundTags, ...createdTags];
|
|
59
|
+
}
|
|
60
|
+
async function createPost(adapter, input) {
|
|
61
|
+
const { tags: tagInputs, ...postData } = input;
|
|
62
|
+
const tagList = tagInputs ?? [];
|
|
63
|
+
const newPost = await adapter.create({
|
|
64
|
+
model: "post",
|
|
65
|
+
data: {
|
|
66
|
+
...postData,
|
|
67
|
+
published: postData.published ?? false,
|
|
68
|
+
tags: [],
|
|
69
|
+
createdAt: postData.createdAt ?? /* @__PURE__ */ new Date(),
|
|
70
|
+
updatedAt: postData.updatedAt ?? /* @__PURE__ */ new Date()
|
|
71
|
+
}
|
|
72
|
+
});
|
|
73
|
+
if (tagList.length > 0) {
|
|
74
|
+
const resolvedTags = await findOrCreateTags(adapter, tagList);
|
|
75
|
+
await adapter.transaction(async (tx) => {
|
|
76
|
+
for (const tag of resolvedTags) {
|
|
77
|
+
await tx.create({
|
|
78
|
+
model: "postTag",
|
|
79
|
+
data: {
|
|
80
|
+
postId: newPost.id,
|
|
81
|
+
tagId: tag.id
|
|
82
|
+
}
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
});
|
|
86
|
+
newPost.tags = resolvedTags.map((tag) => ({ ...tag }));
|
|
87
|
+
} else {
|
|
88
|
+
newPost.tags = [];
|
|
89
|
+
}
|
|
90
|
+
return newPost;
|
|
91
|
+
}
|
|
92
|
+
async function updatePost(adapter, id, input) {
|
|
93
|
+
const { tags: tagInputs, ...postData } = input;
|
|
94
|
+
return adapter.transaction(async (tx) => {
|
|
95
|
+
const updatedPost = await tx.update({
|
|
96
|
+
model: "post",
|
|
97
|
+
where: [{ field: "id", value: id }],
|
|
98
|
+
update: {
|
|
99
|
+
...postData,
|
|
100
|
+
updatedAt: /* @__PURE__ */ new Date()
|
|
101
|
+
}
|
|
102
|
+
});
|
|
103
|
+
if (!updatedPost) return null;
|
|
104
|
+
if (tagInputs !== void 0) {
|
|
105
|
+
const existingPostTags = await tx.findMany({
|
|
106
|
+
model: "postTag",
|
|
107
|
+
where: [{ field: "postId", value: id, operator: "eq" }]
|
|
108
|
+
});
|
|
109
|
+
for (const postTag of existingPostTags) {
|
|
110
|
+
await tx.delete({
|
|
111
|
+
model: "postTag",
|
|
112
|
+
where: [
|
|
113
|
+
{
|
|
114
|
+
field: "postId",
|
|
115
|
+
value: postTag.postId,
|
|
116
|
+
operator: "eq"
|
|
117
|
+
},
|
|
118
|
+
{
|
|
119
|
+
field: "tagId",
|
|
120
|
+
value: postTag.tagId,
|
|
121
|
+
operator: "eq"
|
|
122
|
+
}
|
|
123
|
+
]
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
if (tagInputs.length > 0) {
|
|
127
|
+
const resolvedTags = await findOrCreateTags(adapter, tagInputs);
|
|
128
|
+
for (const tag of resolvedTags) {
|
|
129
|
+
await tx.create({
|
|
130
|
+
model: "postTag",
|
|
131
|
+
data: {
|
|
132
|
+
postId: id,
|
|
133
|
+
tagId: tag.id
|
|
134
|
+
}
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
updatedPost.tags = resolvedTags.map((tag) => ({ ...tag }));
|
|
138
|
+
} else {
|
|
139
|
+
updatedPost.tags = [];
|
|
140
|
+
}
|
|
141
|
+
} else {
|
|
142
|
+
const existingPostTags = await tx.findMany({
|
|
143
|
+
model: "postTag",
|
|
144
|
+
where: [{ field: "postId", value: id, operator: "eq" }]
|
|
145
|
+
});
|
|
146
|
+
if (existingPostTags.length > 0) {
|
|
147
|
+
const tagIds = existingPostTags.map((pt) => pt.tagId);
|
|
148
|
+
const tags = await tx.findMany({
|
|
149
|
+
model: "tag"
|
|
150
|
+
});
|
|
151
|
+
updatedPost.tags = tags.filter((tag) => tagIds.includes(tag.id)).map((tag) => ({ ...tag }));
|
|
152
|
+
} else {
|
|
153
|
+
updatedPost.tags = [];
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
return updatedPost;
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
async function deletePost(adapter, id) {
|
|
160
|
+
await adapter.delete({
|
|
161
|
+
model: "post",
|
|
162
|
+
where: [{ field: "id", value: id }]
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
export { createPost, deletePost, updatePost };
|
|
@@ -6,6 +6,7 @@ const db = require('../db.cjs');
|
|
|
6
6
|
const utils$1 = require('../utils.cjs');
|
|
7
7
|
const schemas = require('../schemas.cjs');
|
|
8
8
|
const getters = require('./getters.cjs');
|
|
9
|
+
const mutations = require('./mutations.cjs');
|
|
9
10
|
const queryKeyDefs = require('./query-key-defs.cjs');
|
|
10
11
|
const serializers = require('./serializers.cjs');
|
|
11
12
|
const utils = require('../../utils.cjs');
|
|
@@ -81,70 +82,13 @@ const blogBackendPlugin = (hooks) => api.defineBackendPlugin({
|
|
|
81
82
|
getAllPosts: (params) => getters.getAllPosts(adapter, params),
|
|
82
83
|
getPostBySlug: (slug) => getters.getPostBySlug(adapter, slug),
|
|
83
84
|
getAllTags: () => getters.getAllTags(adapter),
|
|
84
|
-
prefetchForRoute: createBlogPrefetchForRoute(adapter)
|
|
85
|
+
prefetchForRoute: createBlogPrefetchForRoute(adapter),
|
|
86
|
+
// Mutations
|
|
87
|
+
createPost: (input) => mutations.createPost(adapter, input),
|
|
88
|
+
updatePost: (id, input) => mutations.updatePost(adapter, id, input),
|
|
89
|
+
deletePost: (id) => mutations.deletePost(adapter, id)
|
|
85
90
|
}),
|
|
86
91
|
routes: (adapter) => {
|
|
87
|
-
const findOrCreateTags = async (tagInputs) => {
|
|
88
|
-
if (tagInputs.length === 0) return [];
|
|
89
|
-
const normalizeTagName = (name) => {
|
|
90
|
-
return name.trim();
|
|
91
|
-
};
|
|
92
|
-
const tagsWithIds = [];
|
|
93
|
-
const tagsToFindOrCreate = [];
|
|
94
|
-
for (const tagInput of tagInputs) {
|
|
95
|
-
if ("id" in tagInput && tagInput.id) {
|
|
96
|
-
tagsWithIds.push({
|
|
97
|
-
id: tagInput.id,
|
|
98
|
-
name: normalizeTagName(tagInput.name),
|
|
99
|
-
slug: tagInput.slug,
|
|
100
|
-
createdAt: /* @__PURE__ */ new Date(),
|
|
101
|
-
updatedAt: /* @__PURE__ */ new Date()
|
|
102
|
-
});
|
|
103
|
-
} else {
|
|
104
|
-
tagsToFindOrCreate.push({ name: normalizeTagName(tagInput.name) });
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
if (tagsToFindOrCreate.length === 0) {
|
|
108
|
-
return tagsWithIds;
|
|
109
|
-
}
|
|
110
|
-
const allTags = await adapter.findMany({
|
|
111
|
-
model: "tag"
|
|
112
|
-
});
|
|
113
|
-
const tagMapBySlug = /* @__PURE__ */ new Map();
|
|
114
|
-
for (const tag of allTags) {
|
|
115
|
-
tagMapBySlug.set(tag.slug, tag);
|
|
116
|
-
}
|
|
117
|
-
const tagSlugs = tagsToFindOrCreate.map((tag) => utils$1.slugify(tag.name));
|
|
118
|
-
const foundTags = [];
|
|
119
|
-
for (const slug of tagSlugs) {
|
|
120
|
-
const tag = tagMapBySlug.get(slug);
|
|
121
|
-
if (tag) {
|
|
122
|
-
foundTags.push(tag);
|
|
123
|
-
}
|
|
124
|
-
}
|
|
125
|
-
const existingSlugs = /* @__PURE__ */ new Set([
|
|
126
|
-
...tagsWithIds.map((tag) => tag.slug),
|
|
127
|
-
...foundTags.map((tag) => tag.slug)
|
|
128
|
-
]);
|
|
129
|
-
const tagsToCreate = tagsToFindOrCreate.filter(
|
|
130
|
-
(tag) => !existingSlugs.has(utils$1.slugify(tag.name))
|
|
131
|
-
);
|
|
132
|
-
const createdTags = [];
|
|
133
|
-
for (const tag of tagsToCreate) {
|
|
134
|
-
const normalizedName = normalizeTagName(tag.name);
|
|
135
|
-
const newTag = await adapter.create({
|
|
136
|
-
model: "tag",
|
|
137
|
-
data: {
|
|
138
|
-
name: normalizedName,
|
|
139
|
-
slug: utils$1.slugify(normalizedName),
|
|
140
|
-
createdAt: /* @__PURE__ */ new Date(),
|
|
141
|
-
updatedAt: /* @__PURE__ */ new Date()
|
|
142
|
-
}
|
|
143
|
-
});
|
|
144
|
-
createdTags.push(newTag);
|
|
145
|
-
}
|
|
146
|
-
return [...tagsWithIds, ...foundTags, ...createdTags];
|
|
147
|
-
};
|
|
148
92
|
const listPosts = api.createEndpoint(
|
|
149
93
|
"/posts",
|
|
150
94
|
{
|
|
@@ -194,41 +138,26 @@ const blogBackendPlugin = (hooks) => api.defineBackendPlugin({
|
|
|
194
138
|
"Unauthorized: Cannot create post"
|
|
195
139
|
);
|
|
196
140
|
}
|
|
197
|
-
const {
|
|
198
|
-
|
|
199
|
-
|
|
141
|
+
const {
|
|
142
|
+
tags,
|
|
143
|
+
slug: rawSlug,
|
|
144
|
+
createdAt: _ca,
|
|
145
|
+
updatedAt: _ua,
|
|
146
|
+
...postData
|
|
147
|
+
} = ctx.body;
|
|
148
|
+
const slug = utils$1.slugify(rawSlug || postData.title);
|
|
200
149
|
if (!slug) {
|
|
201
150
|
throw ctx.error(400, {
|
|
202
151
|
message: "Invalid slug: must contain at least one alphanumeric character"
|
|
203
152
|
});
|
|
204
153
|
}
|
|
205
|
-
const newPost = await
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
createdAt: /* @__PURE__ */ new Date(),
|
|
212
|
-
updatedAt: /* @__PURE__ */ new Date()
|
|
213
|
-
}
|
|
154
|
+
const newPost = await mutations.createPost(adapter, {
|
|
155
|
+
...postData,
|
|
156
|
+
slug,
|
|
157
|
+
tags: tags ?? [],
|
|
158
|
+
createdAt: /* @__PURE__ */ new Date(),
|
|
159
|
+
updatedAt: /* @__PURE__ */ new Date()
|
|
214
160
|
});
|
|
215
|
-
if (tagNames.length > 0) {
|
|
216
|
-
const createdTags = await findOrCreateTags(tagNames);
|
|
217
|
-
await adapter.transaction(async (tx) => {
|
|
218
|
-
for (const tag of createdTags) {
|
|
219
|
-
await tx.create({
|
|
220
|
-
model: "postTag",
|
|
221
|
-
data: {
|
|
222
|
-
postId: newPost.id,
|
|
223
|
-
tagId: tag.id
|
|
224
|
-
}
|
|
225
|
-
});
|
|
226
|
-
}
|
|
227
|
-
});
|
|
228
|
-
newPost.tags = createdTags.map((tag) => ({ ...tag }));
|
|
229
|
-
} else {
|
|
230
|
-
newPost.tags = [];
|
|
231
|
-
}
|
|
232
161
|
if (hooks?.onPostCreated) {
|
|
233
162
|
await hooks.onPostCreated(newPost, context);
|
|
234
163
|
}
|
|
@@ -261,76 +190,27 @@ const blogBackendPlugin = (hooks) => api.defineBackendPlugin({
|
|
|
261
190
|
"Unauthorized: Cannot update post"
|
|
262
191
|
);
|
|
263
192
|
}
|
|
264
|
-
const {
|
|
265
|
-
|
|
193
|
+
const {
|
|
194
|
+
tags,
|
|
195
|
+
slug: rawSlug,
|
|
196
|
+
createdAt: _ca,
|
|
197
|
+
updatedAt: _ua,
|
|
198
|
+
...restPostData
|
|
199
|
+
} = ctx.body;
|
|
266
200
|
const slugified = rawSlug ? utils$1.slugify(rawSlug) : void 0;
|
|
267
201
|
if (rawSlug && !slugified) {
|
|
268
202
|
throw ctx.error(400, {
|
|
269
203
|
message: "Invalid slug: must contain at least one alphanumeric character"
|
|
270
204
|
});
|
|
271
205
|
}
|
|
272
|
-
const
|
|
206
|
+
const updated = await mutations.updatePost(adapter, ctx.params.id, {
|
|
273
207
|
...restPostData,
|
|
274
|
-
...slugified ? { slug: slugified } : {}
|
|
275
|
-
|
|
276
|
-
const updated = await adapter.transaction(async (tx) => {
|
|
277
|
-
const existingPostTags = await tx.findMany({
|
|
278
|
-
model: "postTag",
|
|
279
|
-
where: [
|
|
280
|
-
{
|
|
281
|
-
field: "postId",
|
|
282
|
-
value: ctx.params.id,
|
|
283
|
-
operator: "eq"
|
|
284
|
-
}
|
|
285
|
-
]
|
|
286
|
-
});
|
|
287
|
-
const updatedPost = await tx.update({
|
|
288
|
-
model: "post",
|
|
289
|
-
where: [{ field: "id", value: ctx.params.id }],
|
|
290
|
-
update: {
|
|
291
|
-
...postData,
|
|
292
|
-
updatedAt: /* @__PURE__ */ new Date()
|
|
293
|
-
}
|
|
294
|
-
});
|
|
295
|
-
if (!updatedPost) {
|
|
296
|
-
throw ctx.error(404, {
|
|
297
|
-
message: "Post not found"
|
|
298
|
-
});
|
|
299
|
-
}
|
|
300
|
-
for (const postTag of existingPostTags) {
|
|
301
|
-
await tx.delete({
|
|
302
|
-
model: "postTag",
|
|
303
|
-
where: [
|
|
304
|
-
{
|
|
305
|
-
field: "postId",
|
|
306
|
-
value: postTag.postId,
|
|
307
|
-
operator: "eq"
|
|
308
|
-
},
|
|
309
|
-
{
|
|
310
|
-
field: "tagId",
|
|
311
|
-
value: postTag.tagId,
|
|
312
|
-
operator: "eq"
|
|
313
|
-
}
|
|
314
|
-
]
|
|
315
|
-
});
|
|
316
|
-
}
|
|
317
|
-
if (tagNames.length > 0) {
|
|
318
|
-
const createdTags = await findOrCreateTags(tagNames);
|
|
319
|
-
for (const tag of createdTags) {
|
|
320
|
-
await tx.create({
|
|
321
|
-
model: "postTag",
|
|
322
|
-
data: {
|
|
323
|
-
postId: ctx.params.id,
|
|
324
|
-
tagId: tag.id
|
|
325
|
-
}
|
|
326
|
-
});
|
|
327
|
-
}
|
|
328
|
-
updatedPost.tags = createdTags.map((tag) => ({ ...tag }));
|
|
329
|
-
} else {
|
|
330
|
-
updatedPost.tags = [];
|
|
331
|
-
}
|
|
332
|
-
return updatedPost;
|
|
208
|
+
...slugified ? { slug: slugified } : {},
|
|
209
|
+
tags: tags ?? []
|
|
333
210
|
});
|
|
211
|
+
if (!updated) {
|
|
212
|
+
throw ctx.error(404, { message: "Post not found" });
|
|
213
|
+
}
|
|
334
214
|
if (hooks?.onPostUpdated) {
|
|
335
215
|
await hooks.onPostUpdated(updated, context);
|
|
336
216
|
}
|
|
@@ -361,10 +241,7 @@ const blogBackendPlugin = (hooks) => api.defineBackendPlugin({
|
|
|
361
241
|
"Unauthorized: Cannot delete post"
|
|
362
242
|
);
|
|
363
243
|
}
|
|
364
|
-
await adapter.
|
|
365
|
-
model: "post",
|
|
366
|
-
where: [{ field: "id", value: ctx.params.id }]
|
|
367
|
-
});
|
|
244
|
+
await mutations.deletePost(adapter, ctx.params.id);
|
|
368
245
|
if (hooks?.onPostDeleted) {
|
|
369
246
|
await hooks.onPostDeleted(ctx.params.id, context);
|
|
370
247
|
}
|