diff --git a/prisma/migrations/20250311042107_more_table_cleanup/migration.sql b/prisma/migrations/20250311042107_more_table_cleanup/migration.sql new file mode 100644 index 0000000..d63d245 --- /dev/null +++ b/prisma/migrations/20250311042107_more_table_cleanup/migration.sql @@ -0,0 +1,10 @@ +/* + Warnings: + + - You are about to drop the column `createdAt` on the `links` table. All the data in the column will be lost. + - You are about to drop the column `updatedAt` on the `links` table. All the data in the column will be lost. + +*/ +-- AlterTable +ALTER TABLE `links` DROP COLUMN `createdAt`, + DROP COLUMN `updatedAt`; diff --git a/prisma/schema.prisma b/prisma/schema.prisma index 041f50c..eb3efd6 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -275,8 +275,6 @@ model links { directUrl String? @db.VarChar(255) provider String? @db.VarChar(255) custom String? @db.VarChar(255) - createdAt DateTime @db.DateTime(0) - updatedAt DateTime @db.DateTime(0) downloadId Int url2 String? @db.VarChar(255) download downloads? @relation(fields: [downloadId], references: [id], map: "links_ibfk_1") diff --git a/src/pages/api/album/create.ts b/src/pages/api/album/create.ts index a219faf..1427b18 100644 --- a/src/pages/api/album/create.ts +++ b/src/pages/api/album/create.ts @@ -1,34 +1,12 @@ import type { APIRoute } from 'astro' import * as s from 'superstruct' -import { AlbumStatus } from '@prisma/client' - import prismaClient from 'utils/prisma-client' -import { Status, formToObject, slug } from 'utils/form' + +import { AlbumStatus } from '@prisma/client' +import { Status, slug } from 'utils/form' import { writeImg, getImgColor } from 'utils/img' import { handleComplete } from 'integrations/requestCat' -import { DownloadInput } from 'schemas/album' - -const CreateAlbum = s.object({ - cover: s.instance(File), - title: s.optional(s.string()), - subTitle: s.optional(s.string()), - releaseDate: s.optional(s.string()), - label: s.optional(s.string()), - vgmdb: s.optional(s.string()), - description: s.optional(s.string()), - status: s.defaulted(s.enums(Object.values(AlbumStatus)), AlbumStatus.HIDDEN), - animations: s.defaulted(s.array(s.integer()), []), - artists: s.defaulted(s.array(s.string()), []), - categories: s.defaulted(s.array(s.string()), []), - classifications: s.defaulted(s.array(s.string()), []), - games: s.defaulted(s.array(s.string()), []), - platforms: s.defaulted(s.array(s.integer()), []), - discs: s.defaulted(s.array(s.object({ number: s.integer(), body: s.string() })), []), - downloads: s.defaulted(s.array(DownloadInput), []), - related: s.defaulted(s.array(s.number()), []), - stores: s.defaulted(s.array(s.object({ provider: s.string(), url: s.string() })), []), - request: s.optional(s.integer()) -}) +import { CreateAlbum } from 'schemas/album' export const POST: APIRoute = async ({ request, locals }) => { const { session, permissions, user } = locals @@ -39,7 +17,10 @@ export const POST: APIRoute = async ({ request, locals }) => { let body try { const formData = await request.formData() - body = s.create(formToObject(formData), CreateAlbum) + const data = formData.get('data') as string + const cover = formData.get('cover') + const formObject = { cover, ...JSON.parse(data) } + body = s.create(formObject, CreateAlbum) } catch (err) { return Status(422, (err as Error).message) } @@ -52,7 +33,7 @@ export const POST: APIRoute = async ({ request, locals }) => { data: { title: body.title, subTitle: body.subTitle, - releaseDate: body.releaseDate, + releaseDate: body.releaseDate ? new Date(body.releaseDate) : null, label: body.label, vgmdb: body.vgmdb, description: body.description, @@ -89,14 +70,18 @@ export const POST: APIRoute = async ({ request, locals }) => { await Promise.all([ handleCover(), - tx.downloads.createMany({ - data: body.downloads.map((d) => ({ - title: d.title, - small: d.small, - albumId: albumRow.id, - links: { create: d.links } - })) - }) + Promise.all( + body.downloads.map((d) => + tx.downloads.create({ + data: { + title: d.title, + small: d.small, + albumId: albumRow.id, + links: { create: d.links } + } + }) + ) + ) ]) return albumRow @@ -106,6 +91,7 @@ export const POST: APIRoute = async ({ request, locals }) => { return Status(200, albumRow.id.toString()) } catch (err) { + console.error(err) return Status(500, (err as Error).message) } } diff --git a/src/schemas/album.ts b/src/schemas/album.ts index f532cc0..7102683 100644 --- a/src/schemas/album.ts +++ b/src/schemas/album.ts @@ -1,4 +1,5 @@ import * as s from 'superstruct' +import { AlbumStatus } from '@prisma/client' const LinkInput = s.object({ provider: s.string(), @@ -13,3 +14,25 @@ export const DownloadInput = s.object({ small: s.defaulted(s.boolean(), false), links: s.defaulted(s.array(LinkInput), []) }) + +export const CreateAlbum = s.object({ + cover: s.instance(File), + title: s.optional(s.string()), + subTitle: s.optional(s.string()), + releaseDate: s.optional(s.string()), + label: s.optional(s.string()), + vgmdb: s.optional(s.string()), + description: s.optional(s.string()), + status: s.defaulted(s.enums(Object.values(AlbumStatus)), AlbumStatus.HIDDEN), + animations: s.defaulted(s.array(s.integer()), []), + artists: s.defaulted(s.array(s.string()), []), + categories: s.defaulted(s.array(s.string()), []), + classifications: s.defaulted(s.array(s.string()), []), + games: s.defaulted(s.array(s.string()), []), + platforms: s.defaulted(s.array(s.integer()), []), + discs: s.defaulted(s.array(s.object({ number: s.integer(), body: s.string() })), []), + downloads: s.defaulted(s.array(DownloadInput), []), + related: s.defaulted(s.array(s.number()), []), + stores: s.defaulted(s.array(s.object({ provider: s.string(), url: s.string() })), []), + request: s.optional(s.integer()) +}) diff --git a/src/utils/form.ts b/src/utils/form.ts index a645620..845e119 100644 --- a/src/utils/form.ts +++ b/src/utils/form.ts @@ -2,20 +2,3 @@ import slugify from 'slugify' export const Status = (status: number, statusText?: string) => new Response(null, { status, statusText }) export const slug = (text: string) => slugify(text, { lower: true, strict: true }) - -export function formToObject(formData: FormData) { - const object: Record = {} - formData.forEach((value, key) => { - // Reflect.has in favor of: object.hasOwnProperty(key) - if (!Reflect.has(object, key)) { - object[key] = value - return - } - if (!Array.isArray(object[key])) { - object[key] = [object[key]] - } - object[key].push(value) - }) - - return object -}