mirror of
https://github.com/jorgev259/soc_site-astro.git
synced 2025-06-29 07:57:41 +00:00
Migrate to Sequelize V7
This commit is contained in:
parent
a5a5f4ee2a
commit
a79cc8e172
45 changed files with 329 additions and 422 deletions
|
|
@ -2,26 +2,26 @@ import ApolloPackage from '@apollo/client'
|
|||
const { ApolloClient, InMemoryCache } = ApolloPackage;
|
||||
import { SchemaLink } from "@apollo/client/link/schema"
|
||||
import { makeExecutableSchema } from "@graphql-tools/schema";
|
||||
import { loadFilesSync } from '@graphql-tools/load-files'
|
||||
import { mergeResolvers } from '@graphql-tools/merge'
|
||||
import path from "node:path"
|
||||
|
||||
import { getSession } from 'auth-astro/server';
|
||||
import type { Session } from '@auth/core/types';
|
||||
import { typeDefs } from "./__generated__/typeDefs.generated";
|
||||
// import { resolvers } from "./__generated__/resolvers.generated";
|
||||
import db from "@/sequelize";
|
||||
import resolverArray from '@/graphql/resolvers'
|
||||
|
||||
export const resolvers = mergeResolvers(resolverArray)
|
||||
import resolvers from '@/graphql/resolvers'
|
||||
import type { MySqlDialect } from '@sequelize/mysql';
|
||||
import { Sequelize, type ModelStatic, type Options } from '@sequelize/core'
|
||||
|
||||
const schema = makeExecutableSchema({ typeDefs, resolvers })
|
||||
export type ResolverContext = { request?: Request, db: any /*session?: Session */ }
|
||||
export type ResolverContext = { request?: Request, session?: Session }
|
||||
|
||||
const envOptions: Options<MySqlDialect> = JSON.parse(import.meta.env.SEQUELIZE) || {}
|
||||
|
||||
export async function getApolloClient(request?: Request) {
|
||||
// const session = request ? await getSession(request) : undefined
|
||||
const session = request ? await getSession(request) : null
|
||||
const db = new Sequelize(envOptions)
|
||||
envOptions.models = Object.values<ModelStatic>(await import.meta.glob('@/sequelize/models/**/*.ts', { eager: true, import: 'default' }))
|
||||
|
||||
return new ApolloClient({
|
||||
ssrMode: true,
|
||||
link: new SchemaLink({ schema, context: { request, db } }),
|
||||
link: new SchemaLink({ schema, context: { request, session } }),
|
||||
cache: new InMemoryCache()
|
||||
})
|
||||
}
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
// import mutations from './mutations'
|
||||
import queries from './queries'
|
||||
import types from './types'
|
||||
import { mergeResolvers } from '@graphql-tools/merge'
|
||||
import type { IResolvers } from '@graphql-tools/utils'
|
||||
|
||||
const resolvers = { /*...mutations,*/ ...queries, ...types }
|
||||
const imports: IResolvers[] = Object.values(import.meta.glob('./**/*.ts', { eager: true, import: 'default' }))
|
||||
const resolvers = mergeResolvers(imports)
|
||||
|
||||
export default resolvers
|
||||
|
|
|
|||
|
|
@ -1,12 +0,0 @@
|
|||
import merge from 'lodash/merge'
|
||||
|
||||
import comments from './comments'
|
||||
import create from './create'
|
||||
import requests from './requests'
|
||||
import site from './site'
|
||||
import update from './update'
|
||||
import user from './user'
|
||||
|
||||
const mutations = merge(comments, create, requests, site, update, user)
|
||||
|
||||
export default mutations
|
||||
|
|
@ -1,26 +1,11 @@
|
|||
import bcrypt from 'bcrypt'
|
||||
import generator from 'generate-password'
|
||||
import { composeResolvers } from '@graphql-tools/resolvers-composition'
|
||||
import { DateTime } from 'luxon'
|
||||
import { Op } from 'sequelize'
|
||||
import path from 'path'
|
||||
import fs from 'fs-extra'
|
||||
import sharp from 'sharp'
|
||||
|
||||
import { createForgor } from '@/server/utils/forgor'
|
||||
import { isAuthedApp } from '@/server/utils/resolvers'
|
||||
import { processImage } from '@/server/utils/image'
|
||||
import { getSession, getUser } from '@/next/utils/getSession'
|
||||
import {
|
||||
ForbiddenError,
|
||||
UserInputError
|
||||
} from '@/next/server/utils/graphQLErrors'
|
||||
import type { Resolvers } from '@/graphql/__generated__/types.generated'
|
||||
|
||||
const resolversComposition = {
|
||||
'Mutation.updateUser': [isAuthedApp]
|
||||
//'Mutation.updateUser': [isAuthedApp]
|
||||
}
|
||||
|
||||
const streamToString = (stream) => {
|
||||
/* const streamToString = (stream) => {
|
||||
const chunks = []
|
||||
return new Promise((resolve, reject) => {
|
||||
stream.on('data', (chunk) => chunks.push(Buffer.from(chunk)))
|
||||
|
|
@ -45,51 +30,28 @@ async function cropPFP(streamItem, username, imgId) {
|
|||
sharpImage = sharpImage.extract(
|
||||
width > height
|
||||
? {
|
||||
left: Math.floor((width - height) / 2),
|
||||
top: 0,
|
||||
width: height,
|
||||
height
|
||||
}
|
||||
left: Math.floor((width - height) / 2),
|
||||
top: 0,
|
||||
width: height,
|
||||
height
|
||||
}
|
||||
: {
|
||||
left: 0,
|
||||
top: Math.floor((height - width) / 2),
|
||||
width,
|
||||
height: width
|
||||
}
|
||||
left: 0,
|
||||
top: Math.floor((height - width) / 2),
|
||||
width,
|
||||
height: width
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
await sharpImage.resize({ width: 200, height: 200 }).png().toFile(fullPath)
|
||||
|
||||
return await processImage(fullPath)
|
||||
}
|
||||
}*/
|
||||
|
||||
const resolvers = {
|
||||
const resolvers: Resolvers = {
|
||||
Mutation: {
|
||||
login: async (_, { username, password }, { db }) => {
|
||||
const user = await db.models.user.findByPk(username)
|
||||
if (!user) throw UserInputError()
|
||||
|
||||
const valid = await bcrypt.compare(password, user.password)
|
||||
if (!valid) throw UserInputError()
|
||||
|
||||
const session = await getSession()
|
||||
session.username = user.username
|
||||
// Remove this when new site version is fully implemented
|
||||
session.permissions = (await user.getRoles())
|
||||
.map((r) => r.permissions)
|
||||
.flat()
|
||||
await session.save()
|
||||
|
||||
return 200
|
||||
},
|
||||
logout: async () => {
|
||||
const session = await getSession()
|
||||
await session.destroy()
|
||||
|
||||
return 200
|
||||
},
|
||||
registerUser: async (_, { username, email, pfp }, { db }) => {
|
||||
/*registerUser: async (_, { username, email, pfp }, { db }) => {
|
||||
await Promise.all([
|
||||
db.models.user.findByPk(username).then((result) => {
|
||||
if (result) throw UserInputError('Username already in use')
|
||||
|
|
@ -213,7 +175,7 @@ const resolvers = {
|
|||
await role.destroy()
|
||||
|
||||
return name
|
||||
}
|
||||
}*/
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,9 +1,8 @@
|
|||
import type { Resolvers } from '@/graphql/__generated__/types.generated'
|
||||
import Sequelize from 'sequelize'
|
||||
import Sequelize from '@/sequelize'
|
||||
|
||||
const { Op } = Sequelize
|
||||
|
||||
const resolvers: Resolvers = {
|
||||
const resolvers = {
|
||||
Query: {
|
||||
artists: (parent, args, { db }, info) => db.models.artist.findAll(),
|
||||
platforms: (parent, args, { db }, info) => db.models.platform.findAll(),
|
||||
|
|
@ -19,9 +18,7 @@ const resolvers: Resolvers = {
|
|||
album: (_, { id }, { db }) => db.models.album.findByPk(id),
|
||||
downloads: (parent, { id }, { db }) =>
|
||||
db.models.download.findAll({ where: { albumId: id } }),
|
||||
albums: (_, __, { db }, info) =>
|
||||
db.models.album.findAll({
|
||||
}),
|
||||
albums: (_, __, { db }, info) => db.models.album.findAll({}),
|
||||
|
||||
platform: async (parent, { id }, { db }) => db.models.platform.findByPk(id),
|
||||
animation: (parent, { id }, { db }) => db.models.animation.findByPk(id),
|
||||
|
|
@ -1,16 +0,0 @@
|
|||
import merge from 'lodash/merge'
|
||||
|
||||
import search from './search'
|
||||
import site from './site'
|
||||
/*
|
||||
import album from './album'
|
||||
import requests from './requests'
|
||||
|
||||
|
||||
import user from './user'
|
||||
import vgmdb from './vgmdb'
|
||||
*/
|
||||
|
||||
const queries = merge(search, site)
|
||||
|
||||
export default queries
|
||||
|
|
@ -1,24 +1,30 @@
|
|||
import { Op, fn, col, where } from 'sequelize'
|
||||
import { Op, fn, col, where } from '@/sequelize'
|
||||
|
||||
const resolvers = {
|
||||
Query: {
|
||||
requests: (_, {
|
||||
state = ['complete', 'hold', 'pending'],
|
||||
donator = [true, false]
|
||||
}, { db }) => db.models.request.findAll({ where: { state, donator } }),
|
||||
request: (_, { link }, { db }) => db.models.request.findOne({ where: { link } }),
|
||||
requests: (
|
||||
_,
|
||||
{ state = ['complete', 'hold', 'pending'], donator = [true, false] },
|
||||
{ db }
|
||||
) => db.models.request.findAll({ where: { state, donator } }),
|
||||
request: (_, { link }, { db }) =>
|
||||
db.models.request.findOne({ where: { link } }),
|
||||
|
||||
searchRequests: async (_, {
|
||||
state = ['complete', 'hold', 'pending'],
|
||||
donator = [true, false],
|
||||
limit = 10,
|
||||
page = 0,
|
||||
filter
|
||||
}, { db }) => {
|
||||
searchRequests: async (
|
||||
_,
|
||||
{
|
||||
state = ['complete', 'hold', 'pending'],
|
||||
donator = [true, false],
|
||||
limit = 10,
|
||||
page = 0,
|
||||
filter
|
||||
},
|
||||
{ db }
|
||||
) => {
|
||||
const options = { limit, offset: limit * page }
|
||||
const optionsWhere = { state, donator }
|
||||
|
||||
async function exactSearch () {
|
||||
async function exactSearch() {
|
||||
if (!filter) return
|
||||
|
||||
const results = await db.models.request.findAndCountAll({
|
||||
|
|
@ -37,7 +43,7 @@ const resolvers = {
|
|||
if (results.rows.length > 0) return results
|
||||
}
|
||||
|
||||
function looseSearch () {
|
||||
function looseSearch() {
|
||||
return db.models.request.findAndCountAll({
|
||||
where: [
|
||||
optionsWhere,
|
||||
|
|
@ -47,7 +53,7 @@ const resolvers = {
|
|||
})
|
||||
}
|
||||
|
||||
return await exactSearch() || looseSearch()
|
||||
return (await exactSearch()) || looseSearch()
|
||||
},
|
||||
|
||||
submissions: (_, args, context) => {
|
||||
|
|
@ -63,7 +69,9 @@ const resolvers = {
|
|||
{ id: filter },
|
||||
{ vgmdb: filter },
|
||||
{ userUsername: filter },
|
||||
where(fn('LOWER', col('title')), { [Op.like]: `%${filter.toLowerCase()}%` })
|
||||
where(fn('LOWER', col('title')), {
|
||||
[Op.like]: `%${filter.toLowerCase()}%`
|
||||
})
|
||||
]
|
||||
}
|
||||
]
|
||||
|
|
|
|||
|
|
@ -1,14 +1,14 @@
|
|||
//@ts-ignore
|
||||
import { Op, literal } from 'sequelize'
|
||||
import { Op, literal } from '@sequelize/core'
|
||||
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: {
|
||||
searchAlbum: (_, args, { db }) => {
|
||||
searchAlbum: async (_, args, { db }) => {
|
||||
const { title, categories, limit = 10, offset = 0, order = ['createdAt'], mode = 'DESC', status = ['show'] } = args
|
||||
const fuzzyCondition = title ? {
|
||||
[Op.or]: [
|
||||
|
|
@ -18,9 +18,9 @@ const resolvers: Resolvers = {
|
|||
} : {}
|
||||
|
||||
const include = []
|
||||
if (categories) include.push({ model: db.models.category, where: { name: { [Op.in]: categories } } })
|
||||
if (categories) include.push({ model: Category, where: { name: { [Op.in]: categories } } })
|
||||
|
||||
return db.models.album.findAndCountAll({
|
||||
const result = await Album.findAndCountAll({
|
||||
limit, offset,
|
||||
where: {
|
||||
...fuzzyCondition,
|
||||
|
|
@ -29,6 +29,8 @@ const resolvers: Resolvers = {
|
|||
include,
|
||||
order: [literal('`album`.`status` = \'coming\' DESC'), ...order.map(o => [o, mode])]
|
||||
})
|
||||
|
||||
return result
|
||||
}
|
||||
/* searchAlbumByArtist: async (parent, { name, categories, limit, page = 0, order = ['createdAt'], mode = 'DESC', status = ['show'] }, { db }) => {
|
||||
const include = [{ model: db.models.artist, where: { name: { [Op.like]: `%${name}%` } } }]
|
||||
|
|
|
|||
|
|
@ -2,6 +2,8 @@
|
|||
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'
|
||||
|
||||
const resolversComposition = {
|
||||
|
|
@ -9,33 +11,31 @@ const resolversComposition = {
|
|||
}
|
||||
const resolvers: Resolvers = {
|
||||
Query: {
|
||||
config: (_, args, context) => {
|
||||
config: async (_, args) => {
|
||||
const { name } = args
|
||||
const { db } = context
|
||||
const [result] = await Config.findOrCreate({ where: { name } })
|
||||
|
||||
return db.models.config
|
||||
.findOrCreate({ where: { name } })
|
||||
.then(() => db.models.config.findByPk(name))
|
||||
return result
|
||||
},
|
||||
|
||||
highlight: async (parent, args, { db }) => {
|
||||
/* highlight: async (parent, args, { db }) => {
|
||||
const { value } = await db.models.config.findByPk('highlight')
|
||||
return db.models.album.findByPk(value)
|
||||
},
|
||||
},
|
||||
|
||||
/* banners: async (parent, args) => {
|
||||
banners: async (parent, args) => {
|
||||
const filePaths = await fg(['/var/www/soc_img/img/live/**/ /**.png'])
|
||||
const images = filePaths.map((f) => f.split('/').pop())
|
||||
|
||||
return images
|
||||
}, */
|
||||
},
|
||||
|
||||
recentComments: async (parent, { limit = 5 }, { db }) => {
|
||||
return db.models.comment.findAll({
|
||||
limit,
|
||||
order: [['updatedAt', 'DESC']]
|
||||
})
|
||||
}
|
||||
recentComments: async (parent, { limit = 5 }, { db }) => {
|
||||
return db.models.comment.findAll({
|
||||
limit,
|
||||
order: [['updatedAt', 'DESC']]
|
||||
})
|
||||
} */
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,11 +1,11 @@
|
|||
// import { GraphQLUpload } from 'graphql-upload-minimal'
|
||||
import type { Resolvers } from "@/graphql/__generated__/types.generated"
|
||||
import type Album from "@/sequelize/models/album"
|
||||
|
||||
const resolvers: Resolvers = {
|
||||
// Upload: GraphQLUpload,
|
||||
Album: {
|
||||
// @ts-ignore
|
||||
artists: (parent, args, context, info) => parent.getArtists(),
|
||||
artists: (parent: Album, args, context, info) => parent.getArtists(),
|
||||
/* categories: (parent, args, context, info) => parent.getCategories(),
|
||||
classifications: (parent, args, context, info) =>
|
||||
parent.getClassifications(),
|
||||
|
|
|
|||
|
|
@ -1,8 +0,0 @@
|
|||
// import merge from 'lodash/merge'
|
||||
|
||||
import album from './album'
|
||||
// import user from './user'
|
||||
|
||||
const types = /*(merge(*/album/*, user)*/
|
||||
|
||||
export default types
|
||||
|
|
@ -1,31 +1,34 @@
|
|||
import { Op } from 'sequelize'
|
||||
import type { Resolvers } from '@/graphql/__generated__/types.generated'
|
||||
|
||||
import pages from '@/next/constants/pages.json'
|
||||
import { getUser } from '@/next/utils/getSession'
|
||||
|
||||
const userResolvable = {
|
||||
roles: parent => parent.getRoles(),
|
||||
const userResolvable: Resolvers = {
|
||||
/* roles: parent => parent.getRoles(),
|
||||
permissions: async parent => {
|
||||
const roles = await parent.getRoles()
|
||||
return roles.map(r => r.permissions).flat()
|
||||
},
|
||||
pages: async parent => {
|
||||
}, */
|
||||
pages: async (_, __, { session }) => {
|
||||
const roles = await parent.getRoles()
|
||||
const permissions = roles.map(r => r.permissions).flat()
|
||||
|
||||
return pages.filter(({ perms }) => perms.length === 0 || perms.some(r => permissions.includes(r)))
|
||||
},
|
||||
comments: (user, _, { db }) => user.getComments({ where: { albumId: { [Op.not]: null } } }),
|
||||
favorites: user => user.getAlbums(),
|
||||
imgUrl: async user => `https://cdn.sittingonclouds.net/user/${
|
||||
user.imgId ? `${user.username}_${user.imgId}` : 'default'
|
||||
}.png`
|
||||
/* comments: (user, _, { db }) => user.getComments({ where: { albumId: { [Op.not]: null } } }),
|
||||
favorites: user => user.getAlbums(),
|
||||
imgUrl: async user => `https://cdn.sittingonclouds.net/user/${user.imgId ? `${user.username}_${user.imgId}` : 'default'
|
||||
}.png` */
|
||||
}
|
||||
|
||||
const funcs = {
|
||||
User: userResolvable,
|
||||
UserMe: userResolvable,
|
||||
Role: { permissions: parent => typeof parent.permissions === 'string' || parent.permissions instanceof String ? JSON.parse(parent.permissions) : parent.permissions },
|
||||
const resolvers: Resolvers = {
|
||||
// User: userResolvable,
|
||||
UserMe: {
|
||||
pages: async (_, __, { session }) => {
|
||||
const roles = await parent.getRoles()
|
||||
const permissions = roles.map(r => r.permissions).flat()
|
||||
|
||||
return pages.filter(({ perms }) => perms.length === 0 || perms.some(r => permissions.includes(r)))
|
||||
},
|
||||
},
|
||||
/*Role: { permissions: parent => typeof parent.permissions === 'string' || parent.permissions instanceof String ? JSON.parse(parent.permissions) : parent.permissions },
|
||||
Submission: {
|
||||
submitter: submission => submission.getUser(),
|
||||
links: async (submission, _, { db }) => {
|
||||
|
|
@ -40,7 +43,7 @@ const funcs = {
|
|||
return submission.links
|
||||
},
|
||||
request: submission => submission.getRequest()
|
||||
}
|
||||
}*/
|
||||
}
|
||||
|
||||
export default funcs
|
||||
export default resolvers
|
||||
|
|
|
|||
|
|
@ -1,57 +1,60 @@
|
|||
type User {
|
||||
username: String!
|
||||
roles: [Role]!
|
||||
permissions: [String]!
|
||||
pages: [Page]!
|
||||
createdAt: Float!
|
||||
placeholder: String!
|
||||
imgUrl: String!
|
||||
}
|
||||
type User {
|
||||
username: String!
|
||||
roles: [Role]!
|
||||
permissions: [String]!
|
||||
pages: [Page]!
|
||||
createdAt: Float!
|
||||
imgUrl: String!
|
||||
}
|
||||
|
||||
type UserMe {
|
||||
email: String!
|
||||
username: String!
|
||||
roles: [Role]!
|
||||
permissions: [String]!
|
||||
pages: [Page]!
|
||||
createdAt: Float!
|
||||
placeholder: String!
|
||||
imgUrl: String!
|
||||
}
|
||||
type UserMe {
|
||||
email: String!
|
||||
username: String!
|
||||
roles: [Role]!
|
||||
permissions: [String]!
|
||||
pages: [Page]!
|
||||
createdAt: Float!
|
||||
imgUrl: String!
|
||||
}
|
||||
|
||||
type Page {
|
||||
url: String!
|
||||
perms: [String!]!
|
||||
}
|
||||
type Page {
|
||||
url: String!
|
||||
perms: [String!]!
|
||||
}
|
||||
|
||||
type Role {
|
||||
name: String!
|
||||
permissions: [String]!
|
||||
}
|
||||
type Role {
|
||||
name: String!
|
||||
permissions: [String]!
|
||||
}
|
||||
|
||||
type Query {
|
||||
me: UserMe
|
||||
roles: [Role]!
|
||||
permissions: [String]!
|
||||
users(search: String): [User]!
|
||||
user(username: String!): User
|
||||
type Query {
|
||||
me: UserMe
|
||||
roles: [Role]!
|
||||
permissions: [String]!
|
||||
users(search: String): [User]!
|
||||
user(username: String!): User
|
||||
|
||||
login(username: String!, password: String!): Int!
|
||||
}
|
||||
login(username: String!, password: String!): Int!
|
||||
}
|
||||
|
||||
type Mutation {
|
||||
login(username: String!, password: String!): Int!
|
||||
logout: Int!
|
||||
|
||||
registerUser(email: String!, username: String!, pfp: Upload): Boolean!
|
||||
updateUserRoles(username: String!, roles: [String]!): Boolean!
|
||||
deleteUser(username: String!): Int
|
||||
type Mutation {
|
||||
login(username: String!, password: String!): Int!
|
||||
logout: Int!
|
||||
|
||||
createForgorLink(key: String!): Boolean!
|
||||
updatePass(key: String!, pass:String!): Boolean!
|
||||
updateUser(username: String, password: String, email: String, pfp: Upload): Boolean!
|
||||
registerUser(email: String!, username: String!, pfp: Upload): Boolean!
|
||||
updateUserRoles(username: String!, roles: [String]!): Boolean!
|
||||
deleteUser(username: String!): Int
|
||||
|
||||
createRole(name: String!, permissions: [String]!): Role
|
||||
updateRole(key:String!, name: String!, permissions: [String]!): Role
|
||||
deleteRole(name: String!): String
|
||||
}
|
||||
createForgorLink(key: String!): Boolean!
|
||||
updatePass(key: String!, pass: String!): Boolean!
|
||||
updateUser(
|
||||
username: String
|
||||
password: String
|
||||
email: String
|
||||
pfp: Upload
|
||||
): Boolean!
|
||||
|
||||
createRole(name: String!, permissions: [String]!): Role
|
||||
updateRole(key: String!, name: String!, permissions: [String]!): Role
|
||||
deleteRole(name: String!): String
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,22 +0,0 @@
|
|||
import mysql2 from 'mysql2'
|
||||
import { Sequelize } from 'sequelize'
|
||||
|
||||
import relations from './relations'
|
||||
import models from './models'
|
||||
|
||||
const options = process.env.GITHUB_ACTIONS
|
||||
? 'sqlite::memory:'
|
||||
: JSON.parse(import.meta.env.SEQUELIZE)
|
||||
|
||||
if (!process.env.GITHUB_ACTIONS && options.dialect === 'mysql')
|
||||
options.dialectModule = mysql2
|
||||
|
||||
if (import.meta.env.DEV && options.logging === undefined)
|
||||
options.logging = console.log
|
||||
|
||||
const db = new Sequelize(options)
|
||||
|
||||
Object.values(models).forEach((model) => model(db))
|
||||
relations(db)
|
||||
|
||||
export default db
|
||||
|
|
@ -1,22 +0,0 @@
|
|||
import { DataTypes } from 'sequelize'
|
||||
import { PLACEHOLDER } from '@/constants'
|
||||
|
||||
const model = (sequelize) =>
|
||||
sequelize.define('album', {
|
||||
id: {
|
||||
type: DataTypes.INTEGER,
|
||||
primaryKey: true,
|
||||
autoIncrement: true
|
||||
},
|
||||
title: DataTypes.STRING,
|
||||
subTitle: DataTypes.TEXT,
|
||||
releaseDate: DataTypes.DATEONLY,
|
||||
label: DataTypes.STRING,
|
||||
vgmdb: DataTypes.STRING,
|
||||
description: DataTypes.STRING,
|
||||
status: { type: DataTypes.STRING, defaultValue: 'show' },
|
||||
placeholder: { type: DataTypes.TEXT, defaultValue: PLACEHOLDER },
|
||||
headerColor: { type: DataTypes.STRING, defaultValue: '#ffffff' }
|
||||
})
|
||||
|
||||
export default model
|
||||
47
src/sequelize/models/album.ts
Normal file
47
src/sequelize/models/album.ts
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
import { DataTypes, Model, type BelongsToManyGetAssociationsMixin, type CreationOptional, type InferAttributes, type InferCreationAttributes, type NonAttribute } from '@sequelize/core';
|
||||
import { Attribute, PrimaryKey, AutoIncrement, Default, BelongsToMany } from '@sequelize/core/decorators-legacy';
|
||||
|
||||
import Category from './category';
|
||||
import Artist from './artist';
|
||||
|
||||
export default class Album extends Model<InferAttributes<Album>, InferCreationAttributes<Album>> {
|
||||
@Attribute(DataTypes.INTEGER)
|
||||
@PrimaryKey
|
||||
@AutoIncrement
|
||||
declare id: CreationOptional<number>
|
||||
|
||||
@Attribute(DataTypes.STRING)
|
||||
declare title: string
|
||||
|
||||
@Attribute(DataTypes.TEXT)
|
||||
declare subTitle: string
|
||||
|
||||
@Attribute(DataTypes.DATEONLY)
|
||||
declare releaseDate: string
|
||||
|
||||
@Attribute(DataTypes.STRING)
|
||||
declare label: string
|
||||
|
||||
@Attribute(DataTypes.STRING)
|
||||
declare vgmdb: string
|
||||
|
||||
@Attribute(DataTypes.STRING)
|
||||
declare description: string
|
||||
|
||||
@Attribute(DataTypes.ENUM('show', 'hidden', 'coming'))
|
||||
@Default('hidden')
|
||||
declare status: CreationOptional<string>
|
||||
|
||||
@Attribute(DataTypes.STRING)
|
||||
@Default('#ff7c12')
|
||||
declare headerColor: CreationOptional<string>
|
||||
|
||||
@BelongsToMany(() => Category, { through: 'Album_Category', foreignKey: { onDelete: 'SET NULL' } })
|
||||
declare categories?: NonAttribute<Category[]>
|
||||
|
||||
@BelongsToMany(() => Artist, { through: 'Album_Artist', foreignKey: { onDelete: 'SET NULL' } })
|
||||
declare artists?: NonAttribute<Artist[]>
|
||||
|
||||
declare getArtists: BelongsToManyGetAssociationsMixin<Artist>
|
||||
}
|
||||
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
import { DataTypes } from 'sequelize'
|
||||
import { DataTypes } from '@/sequelize'
|
||||
import { PLACEHOLDER } from '@/constants'
|
||||
|
||||
const animation = (sequelize) => {
|
||||
|
|
|
|||
|
|
@ -1,20 +0,0 @@
|
|||
import { DataTypes } from 'sequelize'
|
||||
|
||||
const model = (sequelize) => {
|
||||
const Artist = sequelize.define(
|
||||
'artist',
|
||||
{
|
||||
slug: {
|
||||
type: DataTypes.STRING,
|
||||
primaryKey: true
|
||||
},
|
||||
name: DataTypes.STRING
|
||||
},
|
||||
{
|
||||
freezeTableName: true
|
||||
}
|
||||
)
|
||||
return Artist
|
||||
}
|
||||
|
||||
export default model
|
||||
15
src/sequelize/models/artist.ts
Normal file
15
src/sequelize/models/artist.ts
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
import { DataTypes, Model, type CreationOptional, type InferAttributes, type InferCreationAttributes, type NonAttribute } from '@sequelize/core';
|
||||
import { Attribute, PrimaryKey, AutoIncrement, Default, BelongsToMany, Table, NotNull, HasMany } from '@sequelize/core/decorators-legacy';
|
||||
|
||||
import Album from './album';
|
||||
|
||||
@Table({ freezeTableName: true })
|
||||
export default class Artist extends Model<InferAttributes<Artist>, InferCreationAttributes<Artist>> {
|
||||
@PrimaryKey
|
||||
@Attribute(DataTypes.STRING)
|
||||
declare slug: string
|
||||
|
||||
@Attribute(DataTypes.STRING)
|
||||
@NotNull
|
||||
declare name: string
|
||||
}
|
||||
|
|
@ -1,19 +0,0 @@
|
|||
import { DataTypes } from 'sequelize'
|
||||
const model = (sequelize) => {
|
||||
const Category = sequelize.define(
|
||||
'category',
|
||||
{
|
||||
name: {
|
||||
type: DataTypes.STRING,
|
||||
primaryKey: true
|
||||
}
|
||||
},
|
||||
{
|
||||
freezeTableName: true
|
||||
}
|
||||
)
|
||||
|
||||
return Category
|
||||
}
|
||||
|
||||
export default model
|
||||
10
src/sequelize/models/category.ts
Normal file
10
src/sequelize/models/category.ts
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
import { DataTypes, Model, type CreationOptional, type InferAttributes, type InferCreationAttributes } from '@sequelize/core';
|
||||
import { Attribute, PrimaryKey, Table } from '@sequelize/core/decorators-legacy';
|
||||
|
||||
@Table({ freezeTableName: true })
|
||||
export default class Category extends Model<InferAttributes<Category>, InferCreationAttributes<Category>> {
|
||||
@PrimaryKey
|
||||
@Attribute(DataTypes.STRING)
|
||||
declare name: string
|
||||
}
|
||||
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
import { DataTypes } from 'sequelize'
|
||||
import { DataTypes } from '@/sequelize'
|
||||
const model = (sequelize) => {
|
||||
const Classification = sequelize.define(
|
||||
'classification',
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { DataTypes } from 'sequelize'
|
||||
import { DataTypes } from '@/sequelize'
|
||||
|
||||
const model = (sequelize) => {
|
||||
sequelize.define('comment', {
|
||||
|
|
|
|||
|
|
@ -1,23 +0,0 @@
|
|||
import { DataTypes } from 'sequelize'
|
||||
const model = (sequelize) => {
|
||||
const config = sequelize.define(
|
||||
'config',
|
||||
{
|
||||
name: {
|
||||
type: DataTypes.STRING,
|
||||
primaryKey: true
|
||||
},
|
||||
value: {
|
||||
type: DataTypes.STRING,
|
||||
defaultValue: ''
|
||||
}
|
||||
},
|
||||
{
|
||||
freezeTableName: true
|
||||
}
|
||||
)
|
||||
|
||||
return config
|
||||
}
|
||||
|
||||
export default model
|
||||
15
src/sequelize/models/config.ts
Normal file
15
src/sequelize/models/config.ts
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
import { DataTypes, Model, type CreationOptional, type InferAttributes, type InferCreationAttributes } from '@sequelize/core';
|
||||
import { Attribute, PrimaryKey, AutoIncrement, Default, Table } from '@sequelize/core/decorators-legacy';
|
||||
|
||||
@Table({
|
||||
freezeTableName: true,
|
||||
})
|
||||
export default class Config extends Model<InferAttributes<Config>, InferCreationAttributes<Config>> {
|
||||
@Attribute(DataTypes.STRING)
|
||||
@PrimaryKey
|
||||
declare name: string
|
||||
|
||||
@Attribute(DataTypes.STRING)
|
||||
declare value: string
|
||||
}
|
||||
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
import { DataTypes } from 'sequelize'
|
||||
import { DataTypes } from '@/sequelize'
|
||||
const model = (sequelize) => {
|
||||
const Disc = sequelize.define('disc', {
|
||||
number: DataTypes.INTEGER,
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { DataTypes } from 'sequelize'
|
||||
import { DataTypes } from '@/sequelize'
|
||||
const model = (sequelize) => {
|
||||
const Download = sequelize.define('download', {
|
||||
title: DataTypes.STRING,
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { DataTypes } from 'sequelize'
|
||||
import { DataTypes } from '@/sequelize'
|
||||
import { PLACEHOLDER } from '@/constants'
|
||||
|
||||
const model = (sequelize) => {
|
||||
|
|
|
|||
|
|
@ -1,45 +0,0 @@
|
|||
import album from './album'
|
||||
import animation from './animation'
|
||||
import artist from './artist'
|
||||
import category from './category'
|
||||
import classification from './classification'
|
||||
import comment from './comment'
|
||||
import config from './config'
|
||||
import disc from './disc'
|
||||
import download from './download'
|
||||
import game from './game'
|
||||
import link from './link'
|
||||
import log from './log'
|
||||
import platform from './platform'
|
||||
import publisher from './publisher'
|
||||
import request from './request'
|
||||
import role from './role'
|
||||
import series from './series'
|
||||
import store from './store'
|
||||
import submission from './submission'
|
||||
import user from './user'
|
||||
|
||||
const models = {
|
||||
album,
|
||||
animation,
|
||||
artist,
|
||||
category,
|
||||
classification,
|
||||
comment,
|
||||
config,
|
||||
disc,
|
||||
download,
|
||||
game,
|
||||
link,
|
||||
log,
|
||||
platform,
|
||||
publisher,
|
||||
request,
|
||||
role,
|
||||
series,
|
||||
store,
|
||||
submission,
|
||||
user
|
||||
}
|
||||
|
||||
export default models
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
import { DataTypes } from 'sequelize'
|
||||
import { DataTypes } from '@/sequelize'
|
||||
const model = (sequelize) => {
|
||||
const Link = sequelize.define('link', {
|
||||
url: DataTypes.STRING,
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { DataTypes } from 'sequelize'
|
||||
import { DataTypes } from '@/sequelize'
|
||||
const model = (sequelize) => {
|
||||
return sequelize.define('log', {
|
||||
id: {
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { DataTypes } from 'sequelize'
|
||||
import { DataTypes } from '@/sequelize'
|
||||
const model = (sequelize) => {
|
||||
const Platform = sequelize.define(
|
||||
'platform',
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { DataTypes } from 'sequelize'
|
||||
import { DataTypes } from '@/sequelize'
|
||||
const model = (sequelize) => {
|
||||
const Publisher = sequelize.define(
|
||||
'publisher',
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { DataTypes } from 'sequelize'
|
||||
import { DataTypes } from '@/sequelize'
|
||||
|
||||
const request = (sequelize) =>
|
||||
sequelize.define('request', {
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { DataTypes } from 'sequelize'
|
||||
import { DataTypes } from '@/sequelize'
|
||||
const model = (sequelize) => {
|
||||
const Role = sequelize.define('role', {
|
||||
name: {
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { DataTypes } from 'sequelize'
|
||||
import { DataTypes } from '@/sequelize'
|
||||
import { PLACEHOLDER } from '@/constants'
|
||||
|
||||
const model = (sequelize) => {
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { DataTypes } from 'sequelize'
|
||||
import { DataTypes } from '@/sequelize'
|
||||
const model = (sequelize) => {
|
||||
const Store = sequelize.define('store', {
|
||||
url: DataTypes.STRING,
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { DataTypes } from 'sequelize'
|
||||
import { DataTypes } from '@/sequelize'
|
||||
|
||||
const model = (sequelize) =>
|
||||
sequelize.define('submission', {
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { DataTypes } from 'sequelize'
|
||||
import { DataTypes } from '@/sequelize'
|
||||
|
||||
const model = (sequelize) => {
|
||||
const User = sequelize.define('user', {
|
||||
|
|
|
|||
|
|
@ -1,11 +1,27 @@
|
|||
export default function relations (sequelize) {
|
||||
export default function relations(sequelize) {
|
||||
const {
|
||||
album, classification, disc, download, link,
|
||||
publisher, game, series,
|
||||
platform, artist, category, store,
|
||||
animation, studio,
|
||||
user, role, forgor, log, comment, rating,
|
||||
submission, request
|
||||
album,
|
||||
classification,
|
||||
disc,
|
||||
download,
|
||||
link,
|
||||
publisher,
|
||||
game,
|
||||
series,
|
||||
platform,
|
||||
artist,
|
||||
category,
|
||||
store,
|
||||
animation,
|
||||
studio,
|
||||
user,
|
||||
role,
|
||||
forgor,
|
||||
log,
|
||||
comment,
|
||||
rating,
|
||||
submission,
|
||||
request
|
||||
} = sequelize.models
|
||||
|
||||
user.belongsToMany(role, { through: 'User_Role' })
|
||||
|
|
@ -32,15 +48,25 @@ export default function relations (sequelize) {
|
|||
platform.belongsToMany(game, { through: 'Game_Platform' })
|
||||
|
||||
album.belongsToMany(artist, { onDelete: 'SET NULL', through: 'Album_Artist' })
|
||||
album.belongsToMany(classification, { onDelete: 'SET NULL', through: 'Album_Classification' })
|
||||
album.belongsToMany(category, { onDelete: 'SET NULL', through: 'Album_Category' })
|
||||
album.belongsToMany(platform, { onDelete: 'SET NULL', through: 'Album_Platform' })
|
||||
album.belongsToMany(classification, {
|
||||
onDelete: 'SET NULL',
|
||||
through: 'Album_Classification'
|
||||
})
|
||||
// album.belongsToMany(category, { onDelete: 'SET NULL', through: 'Album_Category' })
|
||||
album.belongsToMany(platform, {
|
||||
onDelete: 'SET NULL',
|
||||
through: 'Album_Platform'
|
||||
})
|
||||
album.belongsToMany(game, { onDelete: 'SET NULL', through: 'Album_Game' })
|
||||
album.belongsToMany(animation, { through: 'Album_Animation' })
|
||||
album.hasMany(disc, { onDelete: 'SET NULL' })
|
||||
album.hasMany(download, { onDelete: 'SET NULL' })
|
||||
album.hasMany(store, { onDelete: 'SET NULL' })
|
||||
album.belongsToMany(album, { onDelete: 'SET NULL', through: 'related_album', as: 'related' })
|
||||
album.belongsToMany(album, {
|
||||
onDelete: 'SET NULL',
|
||||
through: 'related_album',
|
||||
as: 'related'
|
||||
})
|
||||
|
||||
platform.belongsToMany(album, { through: 'Album_Platform' })
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue