Amaterasu runner file
Some checks failed
/ build (push) Failing after 4m36s

This commit is contained in:
Jorge Vargas 2025-03-14 21:33:45 -06:00
parent 3fb513d6fa
commit 5294748076
6 changed files with 294 additions and 2 deletions

View file

@ -0,0 +1,16 @@
on:
workflow_dispatch:
push:
jobs:
build:
runs-on: docker
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 'latest'
check-latest: true
cache: 'yarn'
- run: |
yarn build

View file

@ -6,7 +6,7 @@ import { AlbumStatus } from '@prisma/client'
import { Status, parseForm, slug } from 'utils/form'
import { writeImg, getImgColor } from 'utils/img'
import { handleComplete } from 'integrations/requestCat'
import { CreateAlbum } from 'schemas/album'
import { AlbumSchema } from 'schemas/album'
export const POST: APIRoute = async ({ request, locals }) => {
const { session, permissions, user } = locals

View file

@ -0,0 +1,93 @@
import type { APIRoute } from 'astro'
import * as s from 'superstruct'
import { AlbumStatus } from '@prisma/client'
import prismaClient from 'utils/prisma-client'
import { Status, parseForm, slug } from 'utils/form'
import { writeImg, getImgColor } from 'utils/img'
import { handleComplete } from 'integrations/requestCat'
import { AlbumSchema } from 'schemas/album'
const UpdateAlbum = s.assign(s.partial(AlbumSchema), s.object({ albumId: s.number() }))
export const POST: APIRoute = async ({ request, locals }) => {
const { session, permissions, user } = locals
if (!session || !user) return Status(401)
if (!permissions.includes('UPDATE')) return Status(403)
let body
try {
const formData = await parseForm(request)
body = s.create(formData, UpdateAlbum)
} catch (err) {
return Status(422, (err as Error).message)
}
try {
const albumRow = await prismaClient.$transaction(async (tx) => {
const artistRows = body.artists.map((name: string) => ({ slug: slug(name), name }))
const albumRow = await tx.albums.update({
where: {id: body.albumId}
data: {
title: body.title,
subTitle: body.subTitle,
releaseDate: body.releaseDate,
label: body.label,
vgmdb: body.vgmdb,
description: body.description,
createdBy: user.name,
status: body.status,
animations: { create: body.animations.map((id) => ({ animation: { connect: { id } } })) },
artists: {
set: artistRows.map((a) => ({
artist: {
connectOrCreate: {
create: a,
where: { slug: a.slug }
}
}
}))
},
categories: { create: body.categories.map((c) => ({ category: { connect: { name: c } } })) },
classifications: { create: body.classifications.map((name) => ({ classification: { connect: { name } } })) },
games: { create: body.games.map((slug) => ({ game: { connect: { slug } } })) },
platforms: { create: body.platforms.map((id) => ({ platform: { connect: { id } } })) },
// albumHistories
discs: { createMany: { data: body.discs } },
relatedAlbums: { create: body.related.map((id) => ({ relatedAlbum: { connect: { id } } })) }
},
include: { artists: { include: { artist: { select: { name: true } } } } }
})
const handleCover = async () => {
const coverPath = await writeImg(body.cover, 'album', albumRow.id)
const headerColor = await getImgColor(coverPath)
await tx.albums.update({ where: { id: albumRow.id }, data: { headerColor } })
albumRow.headerColor = headerColor
}
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 }
}))
})
])
return albumRow
})
if (albumRow.status === AlbumStatus.SHOW) await handleComplete(albumRow, body.request)
return Status(200, albumRow.id.toString())
} catch (err) {
return Status(500, (err as Error).message)
}
}

View file

@ -0,0 +1,90 @@
import type { APIRoute } from 'astro'
import * as s from 'superstruct'
import prismaClient from 'utils/prisma-client'
import { AlbumStatus } from '@prisma/client'
import { Status, formToObject, slug } from 'utils/form'
import { writeImg, getImgColor } from 'utils/img'
import { handleComplete } from 'integrations/requestCat'
import { AlbumSchema } from 'schemas/album'
export const POST: APIRoute = async ({ request, locals }) => {
const { session, permissions, user } = locals
if (!session || !user) return Status(401)
if (!permissions.includes('UPDATE')) return Status(403)
let body
try {
const formData = await request.formData()
body = s.create(formToObject(formData), AlbumSchema)
} catch (err) {
return Status(422, (err as Error).message)
}
try {
const albumRow = await prismaClient.$transaction(async (tx) => {
const artistRows = body.artists.map((name: string) => ({ slug: slug(name), name }))
const albumRow = await tx.albums.create({
data: {
title: body.title,
subTitle: body.subTitle,
releaseDate: body.releaseDate,
label: body.label,
vgmdb: body.vgmdb,
description: body.description,
createdBy: user.name,
status: body.status,
animations: { create: body.animations.map((id) => ({ animation: { connect: { id } } })) },
artists: {
create: artistRows.map((a) => ({
artist: {
connectOrCreate: {
create: a,
where: { slug: a.slug }
}
}
}))
},
categories: { create: body.categories.map((c) => ({ category: { connect: { name: c } } })) },
classifications: { create: body.classifications.map((name) => ({ classification: { connect: { name } } })) },
games: { create: body.games.map((slug) => ({ game: { connect: { slug } } })) },
platforms: { create: body.platforms.map((id) => ({ platform: { connect: { id } } })) },
// albumHistories
discs: { createMany: { data: body.discs } },
relatedAlbums: { create: body.related.map((id) => ({ relatedAlbum: { connect: { id } } })) }
},
include: { artists: { include: { artist: { select: { name: true } } } } }
})
const handleCover = async () => {
const coverPath = await writeImg(body.cover, 'album', albumRow.id)
const headerColor = await getImgColor(coverPath)
await tx.albums.update({ where: { id: albumRow.id }, data: { headerColor } })
albumRow.headerColor = headerColor
}
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 }
}))
})
])
return albumRow
})
if (albumRow.status === AlbumStatus.SHOW) await handleComplete(albumRow, body.request)
return Status(200, albumRow.id.toString())
} catch (err) {
return Status(500, (err as Error).message)
}
}

View file

@ -0,0 +1,93 @@
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 { writeImg, getImgColor } from 'utils/img'
import { handleComplete } from 'integrations/requestCat'
import { AlbumSchema } from 'schemas/album'
const UpdateAlbum = s.assign(s.partial(AlbumSchema), s.object({ albumId: s.number() }))
export const POST: APIRoute = async ({ request, locals }) => {
const { session, permissions, user } = locals
if (!session || !user) return Status(401)
if (!permissions.includes('UPDATE')) return Status(403)
let body
try {
const formData = await request.formData()
body = s.create(formToObject(formData), UpdateAlbum)
} catch (err) {
return Status(422, (err as Error).message)
}
try {
const albumRow = await prismaClient.$transaction(async (tx) => {
const artistRows = body.artists.map((name: string) => ({ slug: slug(name), name }))
const albumRow = await tx.albums.update({
where: {id: body.albumId}
data: {
title: body.title,
subTitle: body.subTitle,
releaseDate: body.releaseDate,
label: body.label,
vgmdb: body.vgmdb,
description: body.description,
createdBy: user.name,
status: body.status,
animations: { create: body.animations.map((id) => ({ animation: { connect: { id } } })) },
artists: {
set: artistRows.map((a) => ({
artist: {
connectOrCreate: {
create: a,
where: { slug: a.slug }
}
}
}))
},
categories: { create: body.categories.map((c) => ({ category: { connect: { name: c } } })) },
classifications: { create: body.classifications.map((name) => ({ classification: { connect: { name } } })) },
games: { create: body.games.map((slug) => ({ game: { connect: { slug } } })) },
platforms: { create: body.platforms.map((id) => ({ platform: { connect: { id } } })) },
// albumHistories
discs: { createMany: { data: body.discs } },
relatedAlbums: { create: body.related.map((id) => ({ relatedAlbum: { connect: { id } } })) }
},
include: { artists: { include: { artist: { select: { name: true } } } } }
})
const handleCover = async () => {
const coverPath = await writeImg(body.cover, 'album', albumRow.id)
const headerColor = await getImgColor(coverPath)
await tx.albums.update({ where: { id: albumRow.id }, data: { headerColor } })
albumRow.headerColor = headerColor
}
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 }
}))
})
])
return albumRow
})
if (albumRow.status === AlbumStatus.SHOW) await handleComplete(albumRow, body.request)
return Status(200, albumRow.id.toString())
} catch (err) {
return Status(500, (err as Error).message)
}
}

View file

@ -15,7 +15,7 @@ export const DownloadInput = s.object({
links: s.defaulted(s.array(LinkInput), [])
})
export const CreateAlbum = s.object({
export const AlbumSchema = s.object({
cover: s.instance(File),
title: s.optional(s.string()),
subTitle: s.optional(s.string()),