Skip to content
This repository was archived by the owner on Feb 22, 2025. It is now read-only.

Commit a8f5a88

Browse files
committed
feat(prisma): ⬆️ Update prisma
1 parent 69c158a commit a8f5a88

File tree

15 files changed

+309
-211
lines changed

15 files changed

+309
-211
lines changed

debug.log

+2
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,4 @@
11
[0811/193959.923:ERROR:crashpad_client_win.cc(810)] not connected
22
[0816/152509.516:ERROR:crashpad_client_win.cc(810)] not connected
3+
[0822/222834.763:ERROR:crashpad_client_win.cc(810)] not connected
4+
[0822/222834.850:ERROR:crashpad_client_win.cc(810)] not connected

package.json

+2-2
Original file line numberDiff line numberDiff line change
@@ -39,15 +39,15 @@
3939
"eslint-config-airbnb-base": "^15.0.0",
4040
"eslint-plugin-import": "^2.26.0",
4141
"postcss": "^8.4.31",
42-
"prisma": "5",
42+
"prisma": "^5.18.0",
4343
"ts-node": "^10.9.1",
4444
"typescript": "^4.9.4"
4545
},
4646
"dependencies": {
4747
"@aws-sdk/client-s3": "^3.427.0",
4848
"@bte-germany/terraconvert": "^1.0.1",
4949
"@keycloak/keycloak-admin-client": "^20.0.2",
50-
"@prisma/client": "5",
50+
"@prisma/client": "^5.18.0",
5151
"@turf/helpers": "^6.5.0",
5252
"@turf/turf": "^6.5.0",
5353
"axios": "^1.6.7",
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
/*
2+
Warnings:
3+
4+
- You are about to drop the `Newsletter` table. If the table is not empty, all the data it contains will be lost.
5+
6+
*/
7+
-- DropTable
8+
DROP TABLE "Newsletter";
9+
10+
-- CreateTable
11+
CREATE TABLE "Blog" (
12+
"id" TEXT NOT NULL,
13+
"title" TEXT NOT NULL,
14+
"content" TEXT NOT NULL,
15+
"publishedAt" TIMESTAMP(3) NOT NULL,
16+
"authorId" TEXT NOT NULL,
17+
"public" BOOLEAN,
18+
19+
CONSTRAINT "Blog_pkey" PRIMARY KEY ("id")
20+
);
21+
22+
-- AddForeignKey
23+
ALTER TABLE "Blog" ADD CONSTRAINT "Blog_authorId_fkey" FOREIGN KEY ("authorId") REFERENCES "User"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
/*
2+
Warnings:
3+
4+
- A unique constraint covering the columns `[slug]` on the table `Blog` will be added. If there are existing duplicate values, this will fail.
5+
- Added the required column `slug` to the `Blog` table without a default value. This is not possible if the table is not empty.
6+
7+
*/
8+
-- AlterTable
9+
ALTER TABLE "Blog" ADD COLUMN "slug" TEXT NOT NULL;
10+
11+
-- CreateIndex
12+
CREATE UNIQUE INDEX "Blog_slug_key" ON "Blog"("slug");
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
/*
2+
Warnings:
3+
4+
- Added the required column `summary` to the `Blog` table without a default value. This is not possible if the table is not empty.
5+
- Added the required column `thumbnailId` to the `Blog` table without a default value. This is not possible if the table is not empty.
6+
7+
*/
8+
-- AlterTable
9+
ALTER TABLE "Blog" ADD COLUMN "summary" TEXT NOT NULL,
10+
ADD COLUMN "thumbnailId" TEXT NOT NULL;
11+
12+
-- AddForeignKey
13+
ALTER TABLE "Blog" ADD CONSTRAINT "Blog_thumbnailId_fkey" FOREIGN KEY ("thumbnailId") REFERENCES "Upload"("id") ON DELETE RESTRICT ON UPDATE CASCADE;

prisma/schema.prisma

+14-7
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ model User {
2222
claimsBuilder Claim[] @relation("builders")
2323
joinedBuildTeams BuildTeam[] @relation("members")
2424
verifications MinecraftVerifications[]
25+
writtenBlogs Blog[]
2526
}
2627

2728
model BuildTeam {
@@ -137,13 +138,18 @@ model Contact {
137138
avatar String?
138139
}
139140

140-
model Newsletter {
141-
id String @id @default(uuid())
142-
issue Int @unique
143-
title String
144-
published_date DateTime
145-
links String[]
146-
public Boolean?
141+
model Blog {
142+
id String @id @default(uuid())
143+
slug String @unique
144+
title String
145+
summary String
146+
content String
147+
thumbnail Upload @relation(fields: [thumbnailId], references: [id])
148+
thumbnailId String
149+
publishedAt DateTime
150+
author User @relation(fields: [authorId], references: [id])
151+
authorId String
152+
public Boolean?
147153
}
148154

149155
model Claim {
@@ -213,6 +219,7 @@ model Upload {
213219
Showcase Showcase[]
214220
Claim Claim? @relation(fields: [claimId], references: [id])
215221
claimId String?
222+
Blog Blog[]
216223
}
217224

218225
model CalendarEvent {

src/Core.ts

+18-46
Original file line numberDiff line numberDiff line change
@@ -58,19 +58,7 @@ class Core {
5858
this.keycloakAdmin = new KeycloakAdmin(this);
5959
this.keycloakAdmin.authKcClient().then(() => {
6060
this.getLogger().debug("Keycloak Admin is initialized.");
61-
this.prisma = new PrismaClient().$extends({
62-
name: "uploadSrc",
63-
result: {
64-
upload: {
65-
src: {
66-
needs: { name: true },
67-
compute: (upload) => {
68-
return `https://cdn.buildtheearth.net/uploads/${upload.name}`;
69-
},
70-
},
71-
},
72-
},
73-
});
61+
this.prisma = createPrismaClient();
7462
// this.prisma.$use(middlewareUploadSrc);
7563
this.web = new Web(this);
7664
this.web.startWebserver();
@@ -179,36 +167,20 @@ class Core {
179167

180168
export default Core;
181169

182-
export type ExtendedPrismaClient =
183-
| PrismaClient<Prisma.PrismaClientOptions, never, DefaultArgs>
184-
| DynamicClientExtensionThis<
185-
Prisma.TypeMap<
186-
InternalArgs & {
187-
result: {
188-
upload: {
189-
src: () => {
190-
needs: { name: true };
191-
compute: (upload: { name: string }) => string;
192-
};
193-
};
194-
};
195-
model: {};
196-
query: {};
197-
client: {};
198-
}
199-
>,
200-
Prisma.TypeMapCb,
201-
{
202-
result: {
203-
upload: {
204-
src: () => {
205-
needs: { name: true };
206-
compute: (upload: { name: string }) => string;
207-
};
208-
};
209-
};
210-
model: {};
211-
query: {};
212-
client: {};
213-
}
214-
>;
170+
function createPrismaClient() {
171+
return new PrismaClient().$extends({
172+
name: "uploadSrc",
173+
result: {
174+
upload: {
175+
src: {
176+
needs: { name: true },
177+
compute: (upload) => {
178+
return `https://cdn.buildtheearth.net/uploads/${upload.name}`;
179+
},
180+
},
181+
},
182+
},
183+
});
184+
}
185+
186+
export type ExtendedPrismaClient = ReturnType<typeof createPrismaClient>;

src/controllers/AdminController.ts

+6-7
Original file line numberDiff line numberDiff line change
@@ -243,16 +243,15 @@ class AdminController {
243243
* @returns Generated Has
244244
*/
245245
async function getHash(src: string) {
246-
try {
247-
const buffer = await fetch(src).then(async (res) =>
248-
Buffer.from(await res.arrayBuffer()),
249-
);
246+
247+
const buffer = await fetch(src)
248+
.then(async (res) => Buffer.from(await res.arrayBuffer()))
249+
.catch((r) => console.error(`getHash error for ${src}: $${r}`));
250+
251+
if (!buffer) return "";
250252

251253
const { base64 } = await getPlaiceholder(buffer);
252254
return base64;
253-
} catch (e) {
254-
return "";
255-
}
256255
}
257256

258257
export default AdminController;

src/controllers/BlogController.ts

+140
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
import { Request, Response } from "express";
2+
import { ERROR_GENERIC, ERROR_VALIDATION } from "../util/Errors.js";
3+
import { FrontendRoutesGroups, rerenderFrontend } from "../util/Frontend.js";
4+
5+
import { validationResult } from "express-validator";
6+
import { selectFields } from "express-validator/src/select-fields.js";
7+
import { connect } from "http2";
8+
import Core from "../Core.js";
9+
10+
class BlogController {
11+
private core: Core;
12+
13+
constructor(core: Core) {
14+
this.core = core;
15+
}
16+
17+
public async getBlogPosts(req: Request, res: Response) {
18+
const errors = validationResult(req);
19+
if (!errors.isEmpty()) {
20+
return ERROR_VALIDATION(req, res, errors.array());
21+
}
22+
if (req.query && req.query.page) {
23+
let page = parseInt(req.query.page as string);
24+
const blogPosts = await this.core.getPrisma().blog.findMany({
25+
skip: page * 10,
26+
take: 10,
27+
include: {
28+
author: {
29+
select: {
30+
id: true,
31+
discordId: true,
32+
avatar: true,
33+
username: true,
34+
minecraft: true,
35+
ssoId: true,
36+
},
37+
},
38+
},
39+
});
40+
let count = await this.core.getPrisma().blog.count();
41+
res.send({ pages: Math.ceil(count / 10), data: blogPosts });
42+
} else {
43+
const blogPosts = await this.core.getPrisma().blog.findMany({
44+
include: {
45+
author: {
46+
select: {
47+
id: true,
48+
discordId: true,
49+
avatar: true,
50+
username: true,
51+
minecraft: true,
52+
ssoId: true,
53+
},
54+
},
55+
},
56+
});
57+
res.send(blogPosts);
58+
}
59+
}
60+
61+
public async getBlogPost(req: Request, res: Response) {
62+
const errors = validationResult(req);
63+
if (!errors.isEmpty()) {
64+
return ERROR_VALIDATION(req, res, errors.array());
65+
}
66+
const blogPost = await this.core.getPrisma().blog.findUnique({
67+
where: req.query.slug
68+
? { slug: req.params.id }
69+
: {
70+
id: req.params.id,
71+
},
72+
include: {
73+
author: {
74+
select: {
75+
id: true,
76+
discordId: true,
77+
avatar: true,
78+
username: true,
79+
minecraft: true,
80+
ssoId: true,
81+
},
82+
},
83+
},
84+
});
85+
if (blogPost) {
86+
res.send(blogPost);
87+
} else {
88+
ERROR_GENERIC(req, res, 404, "Blog Post does not exist.");
89+
}
90+
return;
91+
}
92+
93+
public async createBlogPost(req: Request, res: Response) {
94+
const errors = validationResult(req);
95+
if (!errors.isEmpty()) {
96+
return ERROR_VALIDATION(req, res, errors.array());
97+
}
98+
99+
const blogPost = await this.core.getPrisma().blog.create({
100+
data: {
101+
title: req.body.title,
102+
publishedAt: new Date(),
103+
public: req.body.public ? req.body.public : true,
104+
content: req.body.content,
105+
summary: req.body.summary,
106+
slug: req.body.slug,
107+
author: {
108+
connect: {
109+
id: req.body.authorId,
110+
},
111+
},
112+
thumbnail: {
113+
connect: {
114+
id: req.body.thumbnailId,
115+
},
116+
},
117+
},
118+
include: {
119+
author: {
120+
select: {
121+
id: true,
122+
discordId: true,
123+
avatar: true,
124+
username: true,
125+
minecraft: true,
126+
ssoId: true,
127+
},
128+
},
129+
thumbnail: { select: {} },
130+
},
131+
});
132+
133+
rerenderFrontend(FrontendRoutesGroups.FAQ, {
134+
slug: blogPost.slug,
135+
});
136+
res.send(blogPost);
137+
}
138+
}
139+
140+
export default BlogController;

0 commit comments

Comments
 (0)