Switch post html/content to Bytes from Text
This commit is contained in:
parent
34a92a265f
commit
69c482a165
7 changed files with 114 additions and 67 deletions
|
@ -151,7 +151,7 @@ const Post = ({
|
|||
setSubmitting(false)
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
await sendRequest("/api/post", {
|
||||
title,
|
||||
files: docs,
|
||||
|
|
|
@ -47,14 +47,13 @@ export async function createPostFromGist(
|
|||
|
||||
return {
|
||||
title: file.filename,
|
||||
content: content,
|
||||
content: Buffer.from(content, "utf-8"),
|
||||
sha: crypto
|
||||
.createHash("sha256")
|
||||
.update(content)
|
||||
.digest("hex")
|
||||
.toString(),
|
||||
// TODO: shouldn't need this cast
|
||||
html: html as string,
|
||||
html: Buffer.from(html as string, "utf-8"),
|
||||
userId: userId
|
||||
}
|
||||
})
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
import type { File } from "@lib/server/prisma"
|
||||
import markdown from "@wcj/markdown-to-html"
|
||||
/**
|
||||
* returns rendered HTML from a Drift file
|
||||
|
@ -6,7 +5,10 @@ import markdown from "@wcj/markdown-to-html"
|
|||
export async function getHtmlFromFile({
|
||||
content,
|
||||
title
|
||||
}: Pick<File, "content" | "title">) {
|
||||
}: {
|
||||
content: string
|
||||
title: string
|
||||
}) {
|
||||
const renderAsMarkdown = [
|
||||
"markdown",
|
||||
"md",
|
||||
|
|
|
@ -36,12 +36,44 @@ if (config.enable_admin) {
|
|||
|
||||
if (process.env.NODE_ENV !== "production") global.prisma = prisma
|
||||
|
||||
export type PostWithFiles = Post & {
|
||||
files: File[]
|
||||
const postWithFiles = Prisma.validator<Prisma.PostArgs>()({
|
||||
include: {
|
||||
files: true
|
||||
}
|
||||
})
|
||||
|
||||
const postWithAuthor = Prisma.validator<Prisma.PostArgs>()({
|
||||
include: {
|
||||
author: true
|
||||
}
|
||||
})
|
||||
|
||||
const postWithFilesAndAuthor = Prisma.validator<Prisma.PostArgs>()({
|
||||
include: {
|
||||
files: true,
|
||||
author: true
|
||||
}
|
||||
})
|
||||
|
||||
export type ServerPostWithFiles = Prisma.PostGetPayload<typeof postWithFiles>
|
||||
export type PostWithAuthor = Prisma.PostGetPayload<typeof postWithAuthor>
|
||||
export type ServerPostWithFilesAndAuthor = Prisma.PostGetPayload<typeof postWithFilesAndAuthor>
|
||||
|
||||
export type PostWithFiles = Omit<ServerPostWithFiles, "files"> & {
|
||||
files: Omit<ServerPostWithFiles["files"][number], "content" | "html"> & {
|
||||
content: string
|
||||
html: string
|
||||
}[]
|
||||
}
|
||||
|
||||
export type PostWithFilesAndAuthor = PostWithFiles & {
|
||||
author: User
|
||||
export type PostWithFilesAndAuthor = Omit<
|
||||
ServerPostWithFilesAndAuthor,
|
||||
"files"
|
||||
> & {
|
||||
files: Omit<ServerPostWithFilesAndAuthor["files"][number], "content" | "html"> & {
|
||||
content: string
|
||||
html: string
|
||||
}[]
|
||||
}
|
||||
|
||||
export const getFilesForPost = async (postId: string) => {
|
||||
|
@ -68,7 +100,7 @@ export async function getPostsByUser(userId: string): Promise<Post[]>
|
|||
export async function getPostsByUser(
|
||||
userId: string,
|
||||
includeFiles: true
|
||||
): Promise<PostWithFiles[]>
|
||||
): Promise<ServerPostWithFiles[]>
|
||||
export async function getPostsByUser(userId: User["id"], withFiles?: boolean) {
|
||||
const posts = await prisma.post.findMany({
|
||||
where: {
|
||||
|
@ -148,13 +180,26 @@ export const getPostById = async (
|
|||
postId: Post["id"],
|
||||
options?: GetPostByIdOptions
|
||||
): Promise<Post | PostWithFiles | PostWithFilesAndAuthor | null> => {
|
||||
const post = await prisma.post.findUnique({
|
||||
let post = await prisma.post.findUnique({
|
||||
where: {
|
||||
id: postId
|
||||
},
|
||||
...options
|
||||
})
|
||||
|
||||
if (post) {
|
||||
if ("files" in post) {
|
||||
// @ts-expect-error TODO: fix types so files can exist
|
||||
console.log(post.files)
|
||||
// @ts-expect-error TODO: fix types so files can exist
|
||||
post.files = post.files.map((file) => ({
|
||||
...file,
|
||||
content: file.content ? file.content.toString() : undefined,
|
||||
html: file.html ? file.html.toString() : undefined
|
||||
}))
|
||||
}
|
||||
}
|
||||
|
||||
return post
|
||||
}
|
||||
|
||||
|
@ -167,7 +212,7 @@ export const getAllPosts = async ({
|
|||
withFiles?: boolean
|
||||
withAuthor?: boolean
|
||||
} & Prisma.PostFindManyArgs = {}): Promise<
|
||||
Post[] | PostWithFiles[] | PostWithFilesAndAuthor[]
|
||||
Post[] | ServerPostWithFiles[] | ServerPostWithFilesAndAuthor[]
|
||||
> => {
|
||||
const posts = await prisma.post.findMany({
|
||||
include: {
|
||||
|
@ -216,7 +261,7 @@ export const searchPosts = async (
|
|||
userId?: User["id"]
|
||||
publicOnly?: boolean
|
||||
} = {}
|
||||
): Promise<PostWithFiles[]> => {
|
||||
): Promise<ServerPostWithFiles[]> => {
|
||||
const posts = await prisma.post.findMany({
|
||||
where: {
|
||||
OR: [
|
||||
|
@ -231,9 +276,8 @@ export const searchPosts = async (
|
|||
files: {
|
||||
some: {
|
||||
content: {
|
||||
search: query
|
||||
},
|
||||
userId: userId
|
||||
in: Buffer.from(query)
|
||||
}
|
||||
}
|
||||
},
|
||||
visibility: publicOnly ? "public" : undefined
|
||||
|
@ -245,5 +289,5 @@ export const searchPosts = async (
|
|||
}
|
||||
})
|
||||
|
||||
return posts as PostWithFiles[]
|
||||
return posts as ServerPostWithFiles[]
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { withMethods } from "@lib/api-middleware/with-methods"
|
||||
import { parseQueryParam } from "@lib/server/parse-query-param"
|
||||
import { getPostById } from "@lib/server/prisma"
|
||||
import { getPostById, PostWithFiles } from "@lib/server/prisma"
|
||||
import type { NextApiRequest, NextApiResponse } from "next"
|
||||
import { getSession } from "next-auth/react"
|
||||
import { prisma } from "lib/server/prisma"
|
||||
|
@ -16,7 +16,6 @@ export default withMethods(["GET", "PUT", "DELETE"], handler)
|
|||
|
||||
async function handleGet(req: NextApiRequest, res: NextApiResponse<any>) {
|
||||
const id = parseQueryParam(req.query.id)
|
||||
const files = req.query.files ? parseQueryParam(req.query.files) : true
|
||||
|
||||
if (!id) {
|
||||
return res.status(400).json({ error: "Missing id" })
|
||||
|
@ -44,7 +43,9 @@ async function handleGet(req: NextApiRequest, res: NextApiResponse<any>) {
|
|||
|
||||
// the user can always go directly to their own post
|
||||
if (session?.user.id === post.authorId) {
|
||||
return res.json(post)
|
||||
return res.json({
|
||||
...post,
|
||||
})
|
||||
}
|
||||
|
||||
if (post.visibility === "protected") {
|
||||
|
@ -56,7 +57,9 @@ async function handleGet(req: NextApiRequest, res: NextApiResponse<any>) {
|
|||
.toString()
|
||||
|
||||
if (hash === post.password) {
|
||||
return res.json(post)
|
||||
return res.json({
|
||||
...post,
|
||||
})
|
||||
} else {
|
||||
return {
|
||||
isProtected: true,
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
import { withMethods } from "@lib/api-middleware/with-methods"
|
||||
|
||||
import { authOptions } from "@lib/server/auth"
|
||||
import {prisma, getPostById } from "@lib/server/prisma"
|
||||
import { prisma, getPostById } from "@lib/server/prisma"
|
||||
import { NextApiRequest, NextApiResponse } from "next"
|
||||
import { unstable_getServerSession } from "next-auth/next"
|
||||
import { File } from "@lib/server/prisma"
|
||||
|
@ -25,7 +25,7 @@ async function handlePost(req: NextApiRequest, res: NextApiResponse<any>) {
|
|||
return res.status(401).json({ error: "Unauthorized" })
|
||||
}
|
||||
|
||||
const files = req.body.files as File[]
|
||||
const files = req.body.files as Omit<File, 'content' | 'html'> & { content: string; html: string; }[]
|
||||
const fileTitles = files.map((file) => file.title)
|
||||
const missingTitles = fileTitles.filter((title) => title === "")
|
||||
if (missingTitles.length > 0) {
|
||||
|
@ -44,52 +44,51 @@ async function handlePost(req: NextApiRequest, res: NextApiResponse<any>) {
|
|||
.digest("hex")
|
||||
}
|
||||
|
||||
const post = await prisma.post.create({
|
||||
data: {
|
||||
title: req.body.title,
|
||||
description: req.body.description,
|
||||
visibility: req.body.visibility,
|
||||
password: hashedPassword,
|
||||
expiresAt: req.body.expiresAt,
|
||||
parentId: req.body.parentId,
|
||||
authorId: session.user.id,
|
||||
|
||||
// files: {
|
||||
// connectOrCreate: postFiles.map((file) => ({
|
||||
// where: {
|
||||
// sha: file.sha
|
||||
// },
|
||||
// create: file
|
||||
// }))
|
||||
// }
|
||||
}
|
||||
})
|
||||
|
||||
await Promise.all(
|
||||
const fileHtml = await Promise.all(
|
||||
files.map(async (file) => {
|
||||
const html = (await getHtmlFromFile(file)) as string
|
||||
|
||||
return prisma.file.create({
|
||||
data: {
|
||||
title: file.title,
|
||||
content: file.content,
|
||||
sha: crypto
|
||||
.createHash("sha256")
|
||||
.update(file.content)
|
||||
.digest("hex")
|
||||
.toString(),
|
||||
html: html,
|
||||
userId: session.user.id,
|
||||
post: {
|
||||
connect: {
|
||||
id: post.id
|
||||
}
|
||||
}
|
||||
}
|
||||
return await getHtmlFromFile({
|
||||
content: file.content,
|
||||
title: file.title
|
||||
})
|
||||
})
|
||||
)
|
||||
|
||||
const post = await prisma.post
|
||||
.create({
|
||||
data: {
|
||||
title: req.body.title,
|
||||
description: req.body.description,
|
||||
visibility: req.body.visibility,
|
||||
password: hashedPassword,
|
||||
expiresAt: req.body.expiresAt,
|
||||
parentId: req.body.parentId,
|
||||
authorId: session.user.id,
|
||||
files: {
|
||||
create: files.map((file) => {
|
||||
console.log(file)
|
||||
return {
|
||||
title: file.title,
|
||||
content: Buffer.from(file.content, "utf-8"),
|
||||
sha: crypto
|
||||
.createHash("sha256")
|
||||
.update(file.content)
|
||||
.digest("hex")
|
||||
.toString(),
|
||||
html: Buffer.from(
|
||||
fileHtml[files.indexOf(file)] as string,
|
||||
"utf-8"
|
||||
),
|
||||
userId: session.user.id
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
console.log(error)
|
||||
return res.status(500).json(error)
|
||||
})
|
||||
|
||||
return res.json(post)
|
||||
} catch (error) {
|
||||
return res.status(500).json(error)
|
||||
|
|
|
@ -16,9 +16,9 @@ model SequelizeMeta {
|
|||
model File {
|
||||
id String @id @default(cuid())
|
||||
title String
|
||||
content String
|
||||
content Bytes
|
||||
sha String
|
||||
html String
|
||||
html Bytes
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
deletedAt DateTime?
|
||||
|
|
Loading…
Reference in a new issue