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
|
|
@ -1,21 +1,24 @@
|
||||||
/** @type {import("eslint").Linter.Config} */
|
/** @type {import("eslint").Linter.Config} */
|
||||||
module.exports = {
|
module.exports = {
|
||||||
extends: ["plugin:astro/recommended"],
|
extends: ['plugin:astro/recommended'],
|
||||||
parser: "@typescript-eslint/parser",
|
parser: '@typescript-eslint/parser',
|
||||||
parserOptions: {
|
parserOptions: {
|
||||||
tsconfigRootDir: __dirname,
|
tsconfigRootDir: __dirname,
|
||||||
sourceType: "module",
|
sourceType: 'module',
|
||||||
ecmaVersion: "latest",
|
ecmaVersion: 'latest'
|
||||||
},
|
},
|
||||||
overrides: [
|
overrides: [
|
||||||
{
|
{
|
||||||
files: ["*.astro"],
|
files: ['*.astro'],
|
||||||
parser: "astro-eslint-parser",
|
parser: 'astro-eslint-parser',
|
||||||
parserOptions: {
|
parserOptions: {
|
||||||
parser: "@typescript-eslint/parser",
|
parser: '@typescript-eslint/parser',
|
||||||
extraFileExtensions: [".astro"],
|
extraFileExtensions: ['.astro']
|
||||||
},
|
},
|
||||||
rules: {},
|
rules: {}
|
||||||
},
|
}
|
||||||
],
|
],
|
||||||
};
|
rules: {
|
||||||
|
'no-multiple-empty-lines': [2, { max: 1 }]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -27,14 +27,13 @@
|
||||||
"@graphql-tools/resolvers-composition": "^7.0.1",
|
"@graphql-tools/resolvers-composition": "^7.0.1",
|
||||||
"@graphql-tools/schema": "^10.0.4",
|
"@graphql-tools/schema": "^10.0.4",
|
||||||
"@inlang/paraglide-astro": "^0.2.2",
|
"@inlang/paraglide-astro": "^0.2.2",
|
||||||
|
"@sequelize/core": "^7.0.0-alpha.37",
|
||||||
|
"@sequelize/mysql": "^7.0.0-alpha.41",
|
||||||
"astro": "^4.13.1",
|
"astro": "^4.13.1",
|
||||||
"astro-icon": "^1.1.1",
|
"astro-icon": "^1.1.1",
|
||||||
"auth-astro": "^4.1.2",
|
"auth-astro": "^4.1.2",
|
||||||
"bcrypt": "^5.1.1",
|
"bcrypt": "^5.1.1",
|
||||||
"graphql-scalars": "^1.23.0",
|
"graphql-scalars": "^1.23.0",
|
||||||
"lodash": "^4.17.21",
|
|
||||||
"mysql2": "^3.11.0",
|
|
||||||
"sequelize": "^6.37.3",
|
|
||||||
"sharp": "^0.33.5",
|
"sharp": "^0.33.5",
|
||||||
"tailwindcss": "^3.4.8"
|
"tailwindcss": "^3.4.8"
|
||||||
},
|
},
|
||||||
|
|
@ -42,7 +41,6 @@
|
||||||
"@inlang/paraglide-js": "1.11.2",
|
"@inlang/paraglide-js": "1.11.2",
|
||||||
"@parcel/watcher": "^2.4.1",
|
"@parcel/watcher": "^2.4.1",
|
||||||
"@types/bcrypt": "^5.0.2",
|
"@types/bcrypt": "^5.0.2",
|
||||||
"@types/lodash": "^4.17.7",
|
|
||||||
"@typescript-eslint/parser": "^6.21.0",
|
"@typescript-eslint/parser": "^6.21.0",
|
||||||
"concurrently": "^8.2.2",
|
"concurrently": "^8.2.2",
|
||||||
"eslint": "^8.57.0",
|
"eslint": "^8.57.0",
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,15 @@
|
||||||
/** @type {import("prettier").Config} */
|
/** @type {import("prettier").Config} */
|
||||||
module.exports = {
|
module.exports = {
|
||||||
...require("prettier-config-standard"),
|
...require('prettier-config-standard'),
|
||||||
|
|
||||||
pluginSearchDirs: [__dirname],
|
pluginSearchDirs: [__dirname],
|
||||||
plugins: [require.resolve("prettier-plugin-astro")],
|
plugins: [require.resolve('prettier-plugin-astro')],
|
||||||
overrides: [
|
overrides: [
|
||||||
{
|
{
|
||||||
files: "*.astro",
|
files: '*.astro',
|
||||||
options: {
|
options: {
|
||||||
parser: "astro",
|
parser: 'astro'
|
||||||
},
|
}
|
||||||
},
|
}
|
||||||
],
|
]
|
||||||
};
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,26 +2,26 @@ import ApolloPackage from '@apollo/client'
|
||||||
const { ApolloClient, InMemoryCache } = ApolloPackage;
|
const { ApolloClient, InMemoryCache } = ApolloPackage;
|
||||||
import { SchemaLink } from "@apollo/client/link/schema"
|
import { SchemaLink } from "@apollo/client/link/schema"
|
||||||
import { makeExecutableSchema } from "@graphql-tools/schema";
|
import { makeExecutableSchema } from "@graphql-tools/schema";
|
||||||
import { loadFilesSync } from '@graphql-tools/load-files'
|
import { getSession } from 'auth-astro/server';
|
||||||
import { mergeResolvers } from '@graphql-tools/merge'
|
import type { Session } from '@auth/core/types';
|
||||||
import path from "node:path"
|
|
||||||
|
|
||||||
import { typeDefs } from "./__generated__/typeDefs.generated";
|
import { typeDefs } from "./__generated__/typeDefs.generated";
|
||||||
// import { resolvers } from "./__generated__/resolvers.generated";
|
import resolvers from '@/graphql/resolvers'
|
||||||
import db from "@/sequelize";
|
import type { MySqlDialect } from '@sequelize/mysql';
|
||||||
import resolverArray from '@/graphql/resolvers'
|
import { Sequelize, type ModelStatic, type Options } from '@sequelize/core'
|
||||||
|
|
||||||
export const resolvers = mergeResolvers(resolverArray)
|
|
||||||
|
|
||||||
const schema = makeExecutableSchema({ typeDefs, resolvers })
|
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) {
|
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({
|
return new ApolloClient({
|
||||||
ssrMode: true,
|
ssrMode: true,
|
||||||
link: new SchemaLink({ schema, context: { request, db } }),
|
link: new SchemaLink({ schema, context: { request, session } }),
|
||||||
cache: new InMemoryCache()
|
cache: new InMemoryCache()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
// import mutations from './mutations'
|
import { mergeResolvers } from '@graphql-tools/merge'
|
||||||
import queries from './queries'
|
import type { IResolvers } from '@graphql-tools/utils'
|
||||||
import types from './types'
|
|
||||||
|
|
||||||
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
|
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 { composeResolvers } from '@graphql-tools/resolvers-composition'
|
||||||
import { DateTime } from 'luxon'
|
import type { Resolvers } from '@/graphql/__generated__/types.generated'
|
||||||
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'
|
|
||||||
|
|
||||||
const resolversComposition = {
|
const resolversComposition = {
|
||||||
'Mutation.updateUser': [isAuthedApp]
|
//'Mutation.updateUser': [isAuthedApp]
|
||||||
}
|
}
|
||||||
|
|
||||||
const streamToString = (stream) => {
|
/* const streamToString = (stream) => {
|
||||||
const chunks = []
|
const chunks = []
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
stream.on('data', (chunk) => chunks.push(Buffer.from(chunk)))
|
stream.on('data', (chunk) => chunks.push(Buffer.from(chunk)))
|
||||||
|
|
@ -45,51 +30,28 @@ async function cropPFP(streamItem, username, imgId) {
|
||||||
sharpImage = sharpImage.extract(
|
sharpImage = sharpImage.extract(
|
||||||
width > height
|
width > height
|
||||||
? {
|
? {
|
||||||
left: Math.floor((width - height) / 2),
|
left: Math.floor((width - height) / 2),
|
||||||
top: 0,
|
top: 0,
|
||||||
width: height,
|
width: height,
|
||||||
height
|
height
|
||||||
}
|
}
|
||||||
: {
|
: {
|
||||||
left: 0,
|
left: 0,
|
||||||
top: Math.floor((height - width) / 2),
|
top: Math.floor((height - width) / 2),
|
||||||
width,
|
width,
|
||||||
height: width
|
height: width
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
await sharpImage.resize({ width: 200, height: 200 }).png().toFile(fullPath)
|
await sharpImage.resize({ width: 200, height: 200 }).png().toFile(fullPath)
|
||||||
|
|
||||||
return await processImage(fullPath)
|
return await processImage(fullPath)
|
||||||
}
|
}*/
|
||||||
|
|
||||||
const resolvers = {
|
const resolvers: Resolvers = {
|
||||||
Mutation: {
|
Mutation: {
|
||||||
login: async (_, { username, password }, { db }) => {
|
/*registerUser: async (_, { username, email, pfp }, { 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 }) => {
|
|
||||||
await Promise.all([
|
await Promise.all([
|
||||||
db.models.user.findByPk(username).then((result) => {
|
db.models.user.findByPk(username).then((result) => {
|
||||||
if (result) throw UserInputError('Username already in use')
|
if (result) throw UserInputError('Username already in use')
|
||||||
|
|
@ -213,7 +175,7 @@ const resolvers = {
|
||||||
await role.destroy()
|
await role.destroy()
|
||||||
|
|
||||||
return name
|
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 { Op } = Sequelize
|
||||||
|
|
||||||
const resolvers: Resolvers = {
|
const resolvers = {
|
||||||
Query: {
|
Query: {
|
||||||
artists: (parent, args, { db }, info) => db.models.artist.findAll(),
|
artists: (parent, args, { db }, info) => db.models.artist.findAll(),
|
||||||
platforms: (parent, args, { db }, info) => db.models.platform.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),
|
album: (_, { id }, { db }) => db.models.album.findByPk(id),
|
||||||
downloads: (parent, { id }, { db }) =>
|
downloads: (parent, { id }, { db }) =>
|
||||||
db.models.download.findAll({ where: { albumId: id } }),
|
db.models.download.findAll({ where: { albumId: id } }),
|
||||||
albums: (_, __, { db }, info) =>
|
albums: (_, __, { db }, info) => db.models.album.findAll({}),
|
||||||
db.models.album.findAll({
|
|
||||||
}),
|
|
||||||
|
|
||||||
platform: async (parent, { id }, { db }) => db.models.platform.findByPk(id),
|
platform: async (parent, { id }, { db }) => db.models.platform.findByPk(id),
|
||||||
animation: (parent, { id }, { db }) => db.models.animation.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 = {
|
const resolvers = {
|
||||||
Query: {
|
Query: {
|
||||||
requests: (_, {
|
requests: (
|
||||||
state = ['complete', 'hold', 'pending'],
|
_,
|
||||||
donator = [true, false]
|
{ state = ['complete', 'hold', 'pending'], donator = [true, false] },
|
||||||
}, { db }) => db.models.request.findAll({ where: { state, donator } }),
|
{ db }
|
||||||
request: (_, { link }, { db }) => db.models.request.findOne({ where: { link } }),
|
) => db.models.request.findAll({ where: { state, donator } }),
|
||||||
|
request: (_, { link }, { db }) =>
|
||||||
|
db.models.request.findOne({ where: { link } }),
|
||||||
|
|
||||||
searchRequests: async (_, {
|
searchRequests: async (
|
||||||
state = ['complete', 'hold', 'pending'],
|
_,
|
||||||
donator = [true, false],
|
{
|
||||||
limit = 10,
|
state = ['complete', 'hold', 'pending'],
|
||||||
page = 0,
|
donator = [true, false],
|
||||||
filter
|
limit = 10,
|
||||||
}, { db }) => {
|
page = 0,
|
||||||
|
filter
|
||||||
|
},
|
||||||
|
{ db }
|
||||||
|
) => {
|
||||||
const options = { limit, offset: limit * page }
|
const options = { limit, offset: limit * page }
|
||||||
const optionsWhere = { state, donator }
|
const optionsWhere = { state, donator }
|
||||||
|
|
||||||
async function exactSearch () {
|
async function exactSearch() {
|
||||||
if (!filter) return
|
if (!filter) return
|
||||||
|
|
||||||
const results = await db.models.request.findAndCountAll({
|
const results = await db.models.request.findAndCountAll({
|
||||||
|
|
@ -37,7 +43,7 @@ const resolvers = {
|
||||||
if (results.rows.length > 0) return results
|
if (results.rows.length > 0) return results
|
||||||
}
|
}
|
||||||
|
|
||||||
function looseSearch () {
|
function looseSearch() {
|
||||||
return db.models.request.findAndCountAll({
|
return db.models.request.findAndCountAll({
|
||||||
where: [
|
where: [
|
||||||
optionsWhere,
|
optionsWhere,
|
||||||
|
|
@ -47,7 +53,7 @@ const resolvers = {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
return await exactSearch() || looseSearch()
|
return (await exactSearch()) || looseSearch()
|
||||||
},
|
},
|
||||||
|
|
||||||
submissions: (_, args, context) => {
|
submissions: (_, args, context) => {
|
||||||
|
|
@ -63,7 +69,9 @@ const resolvers = {
|
||||||
{ id: filter },
|
{ id: filter },
|
||||||
{ vgmdb: filter },
|
{ vgmdb: filter },
|
||||||
{ userUsername: 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/core'
|
||||||
import { Op, literal } from 'sequelize'
|
|
||||||
import type { Resolvers } from '@/graphql/__generated__/types.generated'
|
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 fuzzySearch = (words: string[]) => `^${words.map(w => `(?=.*\b${w}\b)`)}.+/i`
|
||||||
|
|
||||||
const resolvers: Resolvers = {
|
const resolvers: Resolvers = {
|
||||||
Query: {
|
Query: {
|
||||||
searchAlbum: (_, args, { db }) => {
|
searchAlbum: async (_, args, { db }) => {
|
||||||
const { title, categories, limit = 10, offset = 0, order = ['createdAt'], mode = 'DESC', status = ['show'] } = args
|
const { title, categories, limit = 10, offset = 0, order = ['createdAt'], mode = 'DESC', status = ['show'] } = args
|
||||||
const fuzzyCondition = title ? {
|
const fuzzyCondition = title ? {
|
||||||
[Op.or]: [
|
[Op.or]: [
|
||||||
|
|
@ -18,9 +18,9 @@ const resolvers: Resolvers = {
|
||||||
} : {}
|
} : {}
|
||||||
|
|
||||||
const include = []
|
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,
|
limit, offset,
|
||||||
where: {
|
where: {
|
||||||
...fuzzyCondition,
|
...fuzzyCondition,
|
||||||
|
|
@ -29,6 +29,8 @@ const resolvers: Resolvers = {
|
||||||
include,
|
include,
|
||||||
order: [literal('`album`.`status` = \'coming\' DESC'), ...order.map(o => [o, mode])]
|
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 }) => {
|
/* 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}%` } } }]
|
const include = [{ model: db.models.artist, where: { name: { [Op.like]: `%${name}%` } } }]
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,8 @@
|
||||||
import type { Resolvers } from '@/graphql/__generated__/types.generated'
|
import type { Resolvers } from '@/graphql/__generated__/types.generated'
|
||||||
import { composeResolvers } from '@graphql-tools/resolvers-composition'
|
import { composeResolvers } from '@graphql-tools/resolvers-composition'
|
||||||
|
|
||||||
|
import Config from '@/sequelize/models/config'
|
||||||
|
|
||||||
// import { hasRole } from '@/server/utils/resolvers'
|
// import { hasRole } from '@/server/utils/resolvers'
|
||||||
|
|
||||||
const resolversComposition = {
|
const resolversComposition = {
|
||||||
|
|
@ -9,33 +11,31 @@ const resolversComposition = {
|
||||||
}
|
}
|
||||||
const resolvers: Resolvers = {
|
const resolvers: Resolvers = {
|
||||||
Query: {
|
Query: {
|
||||||
config: (_, args, context) => {
|
config: async (_, args) => {
|
||||||
const { name } = args
|
const { name } = args
|
||||||
const { db } = context
|
const [result] = await Config.findOrCreate({ where: { name } })
|
||||||
|
|
||||||
return db.models.config
|
return result
|
||||||
.findOrCreate({ where: { name } })
|
|
||||||
.then(() => db.models.config.findByPk(name))
|
|
||||||
},
|
},
|
||||||
|
|
||||||
highlight: async (parent, args, { db }) => {
|
/* highlight: async (parent, args, { db }) => {
|
||||||
const { value } = await db.models.config.findByPk('highlight')
|
const { value } = await db.models.config.findByPk('highlight')
|
||||||
return db.models.album.findByPk(value)
|
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 filePaths = await fg(['/var/www/soc_img/img/live/**/ /**.png'])
|
||||||
const images = filePaths.map((f) => f.split('/').pop())
|
const images = filePaths.map((f) => f.split('/').pop())
|
||||||
|
|
||||||
return images
|
return images
|
||||||
}, */
|
},
|
||||||
|
|
||||||
recentComments: async (parent, { limit = 5 }, { db }) => {
|
recentComments: async (parent, { limit = 5 }, { db }) => {
|
||||||
return db.models.comment.findAll({
|
return db.models.comment.findAll({
|
||||||
limit,
|
limit,
|
||||||
order: [['updatedAt', 'DESC']]
|
order: [['updatedAt', 'DESC']]
|
||||||
})
|
})
|
||||||
}
|
} */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,11 @@
|
||||||
// import { GraphQLUpload } from 'graphql-upload-minimal'
|
// import { GraphQLUpload } from 'graphql-upload-minimal'
|
||||||
import type { Resolvers } from "@/graphql/__generated__/types.generated"
|
import type { Resolvers } from "@/graphql/__generated__/types.generated"
|
||||||
|
import type Album from "@/sequelize/models/album"
|
||||||
|
|
||||||
const resolvers: Resolvers = {
|
const resolvers: Resolvers = {
|
||||||
// Upload: GraphQLUpload,
|
// Upload: GraphQLUpload,
|
||||||
Album: {
|
Album: {
|
||||||
// @ts-ignore
|
artists: (parent: Album, args, context, info) => parent.getArtists(),
|
||||||
artists: (parent, args, context, info) => parent.getArtists(),
|
|
||||||
/* categories: (parent, args, context, info) => parent.getCategories(),
|
/* categories: (parent, args, context, info) => parent.getCategories(),
|
||||||
classifications: (parent, args, context, info) =>
|
classifications: (parent, args, context, info) =>
|
||||||
parent.getClassifications(),
|
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'
|
const userResolvable: Resolvers = {
|
||||||
import { getUser } from '@/next/utils/getSession'
|
/* roles: parent => parent.getRoles(),
|
||||||
|
|
||||||
const userResolvable = {
|
|
||||||
roles: parent => parent.getRoles(),
|
|
||||||
permissions: async parent => {
|
permissions: async parent => {
|
||||||
const roles = await parent.getRoles()
|
const roles = await parent.getRoles()
|
||||||
return roles.map(r => r.permissions).flat()
|
return roles.map(r => r.permissions).flat()
|
||||||
},
|
}, */
|
||||||
pages: async parent => {
|
pages: async (_, __, { session }) => {
|
||||||
const roles = await parent.getRoles()
|
const roles = await parent.getRoles()
|
||||||
const permissions = roles.map(r => r.permissions).flat()
|
const permissions = roles.map(r => r.permissions).flat()
|
||||||
|
|
||||||
return pages.filter(({ perms }) => perms.length === 0 || perms.some(r => permissions.includes(r)))
|
return pages.filter(({ perms }) => perms.length === 0 || perms.some(r => permissions.includes(r)))
|
||||||
},
|
},
|
||||||
comments: (user, _, { db }) => user.getComments({ where: { albumId: { [Op.not]: null } } }),
|
/* comments: (user, _, { db }) => user.getComments({ where: { albumId: { [Op.not]: null } } }),
|
||||||
favorites: user => user.getAlbums(),
|
favorites: user => user.getAlbums(),
|
||||||
imgUrl: async user => `https://cdn.sittingonclouds.net/user/${
|
imgUrl: async user => `https://cdn.sittingonclouds.net/user/${user.imgId ? `${user.username}_${user.imgId}` : 'default'
|
||||||
user.imgId ? `${user.username}_${user.imgId}` : 'default'
|
}.png` */
|
||||||
}.png`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const funcs = {
|
const resolvers: Resolvers = {
|
||||||
User: userResolvable,
|
// User: userResolvable,
|
||||||
UserMe: userResolvable,
|
UserMe: {
|
||||||
Role: { permissions: parent => typeof parent.permissions === 'string' || parent.permissions instanceof String ? JSON.parse(parent.permissions) : parent.permissions },
|
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: {
|
Submission: {
|
||||||
submitter: submission => submission.getUser(),
|
submitter: submission => submission.getUser(),
|
||||||
links: async (submission, _, { db }) => {
|
links: async (submission, _, { db }) => {
|
||||||
|
|
@ -40,7 +43,7 @@ const funcs = {
|
||||||
return submission.links
|
return submission.links
|
||||||
},
|
},
|
||||||
request: submission => submission.getRequest()
|
request: submission => submission.getRequest()
|
||||||
}
|
}*/
|
||||||
}
|
}
|
||||||
|
|
||||||
export default funcs
|
export default resolvers
|
||||||
|
|
|
||||||
|
|
@ -1,57 +1,60 @@
|
||||||
type User {
|
type User {
|
||||||
username: String!
|
username: String!
|
||||||
roles: [Role]!
|
roles: [Role]!
|
||||||
permissions: [String]!
|
permissions: [String]!
|
||||||
pages: [Page]!
|
pages: [Page]!
|
||||||
createdAt: Float!
|
createdAt: Float!
|
||||||
placeholder: String!
|
imgUrl: String!
|
||||||
imgUrl: String!
|
}
|
||||||
}
|
|
||||||
|
|
||||||
type UserMe {
|
type UserMe {
|
||||||
email: String!
|
email: String!
|
||||||
username: String!
|
username: String!
|
||||||
roles: [Role]!
|
roles: [Role]!
|
||||||
permissions: [String]!
|
permissions: [String]!
|
||||||
pages: [Page]!
|
pages: [Page]!
|
||||||
createdAt: Float!
|
createdAt: Float!
|
||||||
placeholder: String!
|
imgUrl: String!
|
||||||
imgUrl: String!
|
}
|
||||||
}
|
|
||||||
|
|
||||||
type Page {
|
type Page {
|
||||||
url: String!
|
url: String!
|
||||||
perms: [String!]!
|
perms: [String!]!
|
||||||
}
|
}
|
||||||
|
|
||||||
type Role {
|
type Role {
|
||||||
name: String!
|
name: String!
|
||||||
permissions: [String]!
|
permissions: [String]!
|
||||||
}
|
}
|
||||||
|
|
||||||
type Query {
|
type Query {
|
||||||
me: UserMe
|
me: UserMe
|
||||||
roles: [Role]!
|
roles: [Role]!
|
||||||
permissions: [String]!
|
permissions: [String]!
|
||||||
users(search: String): [User]!
|
users(search: String): [User]!
|
||||||
user(username: String!): User
|
user(username: String!): User
|
||||||
|
|
||||||
login(username: String!, password: String!): Int!
|
login(username: String!, password: String!): Int!
|
||||||
}
|
}
|
||||||
|
|
||||||
type Mutation {
|
type Mutation {
|
||||||
login(username: String!, password: String!): Int!
|
login(username: String!, password: String!): Int!
|
||||||
logout: Int!
|
logout: Int!
|
||||||
|
|
||||||
registerUser(email: String!, username: String!, pfp: Upload): Boolean!
|
|
||||||
updateUserRoles(username: String!, roles: [String]!): Boolean!
|
|
||||||
deleteUser(username: String!): Int
|
|
||||||
|
|
||||||
createForgorLink(key: String!): Boolean!
|
registerUser(email: String!, username: String!, pfp: Upload): Boolean!
|
||||||
updatePass(key: String!, pass:String!): Boolean!
|
updateUserRoles(username: String!, roles: [String]!): Boolean!
|
||||||
updateUser(username: String, password: String, email: String, pfp: Upload): Boolean!
|
deleteUser(username: String!): Int
|
||||||
|
|
||||||
createRole(name: String!, permissions: [String]!): Role
|
createForgorLink(key: String!): Boolean!
|
||||||
updateRole(key:String!, name: String!, permissions: [String]!): Role
|
updatePass(key: String!, pass: String!): Boolean!
|
||||||
deleteRole(name: String!): String
|
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'
|
import { PLACEHOLDER } from '@/constants'
|
||||||
|
|
||||||
const animation = (sequelize) => {
|
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 model = (sequelize) => {
|
||||||
const Classification = sequelize.define(
|
const Classification = sequelize.define(
|
||||||
'classification',
|
'classification',
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import { DataTypes } from 'sequelize'
|
import { DataTypes } from '@/sequelize'
|
||||||
|
|
||||||
const model = (sequelize) => {
|
const model = (sequelize) => {
|
||||||
sequelize.define('comment', {
|
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 model = (sequelize) => {
|
||||||
const Disc = sequelize.define('disc', {
|
const Disc = sequelize.define('disc', {
|
||||||
number: DataTypes.INTEGER,
|
number: DataTypes.INTEGER,
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import { DataTypes } from 'sequelize'
|
import { DataTypes } from '@/sequelize'
|
||||||
const model = (sequelize) => {
|
const model = (sequelize) => {
|
||||||
const Download = sequelize.define('download', {
|
const Download = sequelize.define('download', {
|
||||||
title: DataTypes.STRING,
|
title: DataTypes.STRING,
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import { DataTypes } from 'sequelize'
|
import { DataTypes } from '@/sequelize'
|
||||||
import { PLACEHOLDER } from '@/constants'
|
import { PLACEHOLDER } from '@/constants'
|
||||||
|
|
||||||
const model = (sequelize) => {
|
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 model = (sequelize) => {
|
||||||
const Link = sequelize.define('link', {
|
const Link = sequelize.define('link', {
|
||||||
url: DataTypes.STRING,
|
url: DataTypes.STRING,
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import { DataTypes } from 'sequelize'
|
import { DataTypes } from '@/sequelize'
|
||||||
const model = (sequelize) => {
|
const model = (sequelize) => {
|
||||||
return sequelize.define('log', {
|
return sequelize.define('log', {
|
||||||
id: {
|
id: {
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import { DataTypes } from 'sequelize'
|
import { DataTypes } from '@/sequelize'
|
||||||
const model = (sequelize) => {
|
const model = (sequelize) => {
|
||||||
const Platform = sequelize.define(
|
const Platform = sequelize.define(
|
||||||
'platform',
|
'platform',
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import { DataTypes } from 'sequelize'
|
import { DataTypes } from '@/sequelize'
|
||||||
const model = (sequelize) => {
|
const model = (sequelize) => {
|
||||||
const Publisher = sequelize.define(
|
const Publisher = sequelize.define(
|
||||||
'publisher',
|
'publisher',
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import { DataTypes } from 'sequelize'
|
import { DataTypes } from '@/sequelize'
|
||||||
|
|
||||||
const request = (sequelize) =>
|
const request = (sequelize) =>
|
||||||
sequelize.define('request', {
|
sequelize.define('request', {
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import { DataTypes } from 'sequelize'
|
import { DataTypes } from '@/sequelize'
|
||||||
const model = (sequelize) => {
|
const model = (sequelize) => {
|
||||||
const Role = sequelize.define('role', {
|
const Role = sequelize.define('role', {
|
||||||
name: {
|
name: {
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import { DataTypes } from 'sequelize'
|
import { DataTypes } from '@/sequelize'
|
||||||
import { PLACEHOLDER } from '@/constants'
|
import { PLACEHOLDER } from '@/constants'
|
||||||
|
|
||||||
const model = (sequelize) => {
|
const model = (sequelize) => {
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import { DataTypes } from 'sequelize'
|
import { DataTypes } from '@/sequelize'
|
||||||
const model = (sequelize) => {
|
const model = (sequelize) => {
|
||||||
const Store = sequelize.define('store', {
|
const Store = sequelize.define('store', {
|
||||||
url: DataTypes.STRING,
|
url: DataTypes.STRING,
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import { DataTypes } from 'sequelize'
|
import { DataTypes } from '@/sequelize'
|
||||||
|
|
||||||
const model = (sequelize) =>
|
const model = (sequelize) =>
|
||||||
sequelize.define('submission', {
|
sequelize.define('submission', {
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import { DataTypes } from 'sequelize'
|
import { DataTypes } from '@/sequelize'
|
||||||
|
|
||||||
const model = (sequelize) => {
|
const model = (sequelize) => {
|
||||||
const User = sequelize.define('user', {
|
const User = sequelize.define('user', {
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,27 @@
|
||||||
export default function relations (sequelize) {
|
export default function relations(sequelize) {
|
||||||
const {
|
const {
|
||||||
album, classification, disc, download, link,
|
album,
|
||||||
publisher, game, series,
|
classification,
|
||||||
platform, artist, category, store,
|
disc,
|
||||||
animation, studio,
|
download,
|
||||||
user, role, forgor, log, comment, rating,
|
link,
|
||||||
submission, request
|
publisher,
|
||||||
|
game,
|
||||||
|
series,
|
||||||
|
platform,
|
||||||
|
artist,
|
||||||
|
category,
|
||||||
|
store,
|
||||||
|
animation,
|
||||||
|
studio,
|
||||||
|
user,
|
||||||
|
role,
|
||||||
|
forgor,
|
||||||
|
log,
|
||||||
|
comment,
|
||||||
|
rating,
|
||||||
|
submission,
|
||||||
|
request
|
||||||
} = sequelize.models
|
} = sequelize.models
|
||||||
|
|
||||||
user.belongsToMany(role, { through: 'User_Role' })
|
user.belongsToMany(role, { through: 'User_Role' })
|
||||||
|
|
@ -32,15 +48,25 @@ export default function relations (sequelize) {
|
||||||
platform.belongsToMany(game, { through: 'Game_Platform' })
|
platform.belongsToMany(game, { through: 'Game_Platform' })
|
||||||
|
|
||||||
album.belongsToMany(artist, { onDelete: 'SET NULL', through: 'Album_Artist' })
|
album.belongsToMany(artist, { onDelete: 'SET NULL', through: 'Album_Artist' })
|
||||||
album.belongsToMany(classification, { onDelete: 'SET NULL', through: 'Album_Classification' })
|
album.belongsToMany(classification, {
|
||||||
album.belongsToMany(category, { onDelete: 'SET NULL', through: 'Album_Category' })
|
onDelete: 'SET NULL',
|
||||||
album.belongsToMany(platform, { onDelete: 'SET NULL', through: 'Album_Platform' })
|
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(game, { onDelete: 'SET NULL', through: 'Album_Game' })
|
||||||
album.belongsToMany(animation, { through: 'Album_Animation' })
|
album.belongsToMany(animation, { through: 'Album_Animation' })
|
||||||
album.hasMany(disc, { onDelete: 'SET NULL' })
|
album.hasMany(disc, { onDelete: 'SET NULL' })
|
||||||
album.hasMany(download, { onDelete: 'SET NULL' })
|
album.hasMany(download, { onDelete: 'SET NULL' })
|
||||||
album.hasMany(store, { 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' })
|
platform.belongsToMany(album, { through: 'Album_Platform' })
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,16 @@
|
||||||
{
|
{
|
||||||
"extends": "astro/tsconfigs/strict",
|
"extends": "astro/tsconfigs/strict",
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
|
"experimentalDecorators": true,
|
||||||
"moduleResolution": "Bundler",
|
"moduleResolution": "Bundler",
|
||||||
"allowJs": true,
|
"allowJs": true,
|
||||||
"baseUrl": "src",
|
"baseUrl": "src",
|
||||||
"paths": {
|
"paths": {
|
||||||
"@/*": [
|
"@/*": [
|
||||||
"*"
|
"*"
|
||||||
|
],
|
||||||
|
"@/root/*": [
|
||||||
|
"../*"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue