Add Prisma ORM

This commit is contained in:
Jorge Vargas 2024-11-13 22:46:54 -06:00
parent e8530f0f01
commit bce35d73ca
15 changed files with 1296 additions and 148 deletions

View file

@ -1,6 +1,6 @@
---
import { gql } from '@/graphql/__generated__/client/index.js'
import { getApolloClient } from '@/graphql/apolloClient.mjs'
import { getApolloClient } from '@/graphql/apolloClient.js'
import { Image, Picture } from 'astro:assets'
import { getSession } from 'auth-astro/server'
import * as m from '../paraglide/messages.js'
@ -45,13 +45,7 @@ const session = await getSession(Astro.request)
</div>
<div class='relative px-20 size-full'>
<a href='/'>
<Image
src={logo}
class='h-full py-0.5 w-auto'
alt='logo'
height={150}
width={265}
/>
<Image src={logo} class='h-full py-0.5 w-auto' alt='logo' height={150} width={265} />
</a>
<div class='absolute top-0 right-0 space-x-2 mr-10'>

View file

@ -1,24 +0,0 @@
import ApolloPackage from '@apollo/client'
const { ApolloClient, InMemoryCache } = ApolloPackage;
import { SchemaLink } from "@apollo/client/link/schema"
import { makeExecutableSchema } from "@graphql-tools/schema";
import { getSession } from 'auth-astro/server';
import type { Session } from '@auth/core/types';
import { typeDefs } from "./__generated__/typeDefs.generated";
import resolvers from '@/graphql/resolvers'
import db from 'sequelize';
const schema = makeExecutableSchema({ typeDefs, resolvers })
export type ResolverContext = { request?: Request, session?: Session }
export async function getApolloClient(request?: Request) {
const session = request ? await getSession(request) : null
return new ApolloClient({
ssrMode: true,
link: new SchemaLink({ schema, context: { request, session, db } }),
cache: new InMemoryCache()
})
}

View file

@ -0,0 +1,23 @@
import { ApolloClient, InMemoryCache } from '@apollo/client/core'
import { SchemaLink } from '@apollo/client/link/schema'
import { makeExecutableSchema } from '@graphql-tools/schema'
import { getSession } from 'auth-astro/server'
import type { Session } from '@auth/core/types'
import prismaClient, { type users } from 'prisma/client'
import { typeDefs } from './__generated__/typeDefs.generated'
import resolvers from '@/graphql/resolvers'
const schema = makeExecutableSchema({ typeDefs, resolvers })
export type ResolverContext = { request?: Request; session?: Session; user?: users }
export async function getApolloClient(request?: Request) {
const session = async () => (request ? getSession(request) : null)
const user = async () => (session ? prismaClient.users.findUnique({ where: { username: session.id } }) : null)
return new ApolloClient({
ssrMode: true,
link: new SchemaLink({ schema, context: { request, session, user } }),
cache: new InMemoryCache()
})
}

View file

@ -1,35 +1,41 @@
import { Op, literal } from '@sequelize/core'
import prismaClient from 'prisma/client'
import type { Resolvers } from '@/graphql/__generated__/types.generated'
import Category from 'sequelize/models/category'
import Album from 'sequelize/models/album'
const fuzzySearch = (words: string[]) => `^${words.map(w => `(?=.*\b${w}\b)`)}.+/i`
const resolvers: Resolvers = {
Query: {
// @ts-ignore
searchAlbum: async (_, args, { db }) => {
const { title, categories, limit = 10, offset = 0, order = ['createdAt'], mode = 'DESC', status = ['show'] } = args
const fuzzyCondition = title ? {
[Op.or]: [
{ title: { [Op.regexp]: fuzzySearch(title.split(' ')) } },
{ subTitle: { [Op.regexp]: fuzzySearch(title.split(' ')) } }
]
} : {}
searchAlbum: async (_, args, context, info) => {
const {
title,
categories,
limit = 10,
offset = 0,
order = ['createdAt'],
mode = 'DESC',
status = ['show']
} = args
const fuzzyCondition = title
? {
OR: [
{ title: { search: title.toLowerCase().split(' ').join(' & ') } },
{ subTitle: { search: title.toLowerCase().split(' ').join(' & ') } }
]
}
: {}
const include = []
if (categories) include.push({ model: Category, where: { name: { [Op.in]: categories } } })
const result = await Album.findAndCountAll({
limit, offset,
const result = prismaClient.albums.findMany({
take: limit,
skip: offset,
where: {
...fuzzyCondition,
status: { [Op.in]: status }
AND: {
...fuzzyCondition,
// category condition
status: { in: status }
}
},
include,
// @ts-ignore
order: [literal('`album`.`status` = \'coming\' DESC'), ...order.map(o => [o, mode])]
include: { Album_Category: !!categories },
orderBy: [...order.map((o) => ({ [o]: mode.toLowerCase() }))]
// order: [literal("`album`.`status` = 'coming' DESC")]
})
return result

View file

@ -1,22 +1,21 @@
// import fg from 'fast-glob'
import type { Resolvers } from '@/graphql/__generated__/types.generated'
import { composeResolvers } from '@graphql-tools/resolvers-composition'
import Config from 'sequelize/models/config'
// import { hasRole } from 'server/utils/resolvers'
import type { Resolvers } from '@/graphql/__generated__/types.generated'
import prismaClient from 'prisma/client'
const resolversComposition = {
/* 'Query.banners': hasRole('UPDATE') */
}
const resolvers: Resolvers = {
Query: {
config: async (_, args) => {
const { name } = args
const [result] = await Config.findOrCreate({ where: { name } })
return result
},
config: async (_, { name }) =>
prismaClient.config.upsert({
where: { name },
create: { name },
update: {}
})
/* highlight: async (parent, args, { db }) => {
const { value } = await db.models.config.findByPk('highlight')

View file

@ -1,12 +1,12 @@
// import { GraphQLUpload } from 'graphql-upload-minimal'
import type { Resolvers } from "@/graphql/__generated__/types.generated"
import type Album from "sequelize/models/album"
import prismaClient from 'prisma/client'
import type { Resolvers } from '@/graphql/__generated__/types.generated'
const resolvers: Resolvers = {
// Upload: GraphQLUpload,
Album: {
// @ts-ignore
artists: (parent, args, context, info) => parent.getArtists(),
artists: (album) => prismaClient.artist.findMany({ where: { Album_Artist: { some: { albumId: album.id } } } })
/* categories: (parent, args, context, info) => parent.getCategories(),
classifications: (parent, args, context, info) =>
parent.getClassifications(),
@ -46,7 +46,7 @@ const resolvers: Resolvers = {
placeholder: (album, _, { db }) => checkPlaceholder(album, 'album'),
headerColor: (album, _, { db }) => checkHeaderColor(album, 'album'),
avgRating: async (album, _, { db }) => solveRating(album) */
},
}
/* Comment: {
username: (parent) => (parent.anon ? null : parent.username),

View file

@ -150,7 +150,7 @@ type Query {
order: [String]
mode: String
status: [String!]
): SearchAlbumResult
): [Album]!
searchAlbumByArtist(
name: String!
categories: [String]
@ -160,34 +160,10 @@ type Query {
mode: String
status: [String!]
): SearchAlbumResult
searchAnimation(
title: String
limit: Int
page: Int
order: String
mode: String
): SearchAnimResult
searchStudio(
name: String
limit: Int
page: Int
order: String
mode: String
): SearchStudioResult
searchGame(
name: String
limit: Int
page: Int
order: String
mode: String
): SearchGameResult
searchSeries(
name: String
limit: Int
page: Int
order: String
mode: String
): SearchSeriesResult
searchAnimation(title: String, limit: Int, page: Int, order: String, mode: String): SearchAnimResult
searchStudio(name: String, limit: Int, page: Int, order: String, mode: String): SearchStudioResult
searchGame(name: String, limit: Int, page: Int, order: String, mode: String): SearchGameResult
searchSeries(name: String, limit: Int, page: Int, order: String, mode: String): SearchSeriesResult
searchSeriesByName(name: String): [Series]
recentSeries(limit: Int!): [Series]
@ -237,13 +213,7 @@ type Mutation {
updateStudio(slug: String, name: String): Studio!
deleteStudio(slug: String!): Int
createAnimation(
title: String
subTitle: String
releaseDate: String
studios: [String]
cover: Upload
): Animation
createAnimation(title: String, subTitle: String, releaseDate: String, studios: [String], cover: Upload): Animation
updateAnimation(
id: ID!
title: String

View file

@ -21,4 +21,4 @@ type SearchGameResult {
type SearchSeriesResult {
rows: [Series]
count: Int
}
}

View file

@ -1,13 +1,12 @@
import rss, { type RSSFeedItem } from '@astrojs/rss';
import type { APIContext } from 'astro';
import rss, { type RSSFeedItem } from '@astrojs/rss'
import type { APIContext } from 'astro'
import { getApolloClient } from '@/graphql/apolloClient.mjs';
import { gql } from '@/graphql/__generated__/client';
import { getApolloClient } from '@/graphql/apolloClient.js'
import { gql } from '@/graphql/__generated__/client'
const addedQuery = gql(`
query LastAdded ($limit: Int) {
added: searchAlbum(limit: $limit, status: ["show"]) {
rows {
id
createdAt
title
@ -15,7 +14,6 @@ const addedQuery = gql(`
artists {
name
}
}
}
}
`)
@ -23,15 +21,13 @@ const addedQuery = gql(`
export async function GET(context: APIContext) {
const client = await getApolloClient()
const { data } = await client.query({ query: addedQuery, variables: { limit: 15 } })
const { added } = data
if (!data.added?.rows) throw new Error()
const { rows } = data.added
const items: RSSFeedItem[] = rows.map((album) => ({
const items: RSSFeedItem[] = added.map((album) => ({
guid: `album/${album?.id}`,
title: album?.title,
pubDate: new Date(album?.createdAt || ''),
description: album?.subTitle || album?.artists.map(a => a?.name).join(' - '),
description: album?.subTitle || album?.artists.map((a) => a?.name).join(' - '),
link: `https://www.sittingonclouds.net/album/${album?.id}`,
customData: `<media:content
type="image/png"
@ -39,18 +35,18 @@ export async function GET(context: APIContext) {
height="100"
medium="image"
url="https://cdn.sittingonclouds.net/album/${album?.id}.png" />
`,
`
}))
return rss({
xmlns: {
media: "http://search.yahoo.com/mrss/",
media: 'http://search.yahoo.com/mrss/'
},
stylesheet: '/rss/pretty-feed-v3.xsl',
title: 'Sitting on Clouds',
description: 'High Quality soundtrack library',
site: context.site as unknown as string,
trailingSlash: false,
items,
});
}
items
})
}

5
src/prisma/client.ts Normal file
View file

@ -0,0 +1,5 @@
import { PrismaClient } from '@prisma/client'
const prismaClient = new PrismaClient()
export default prismaClient