mirror of
https://github.com/ArthurDanjou/website.git
synced 2026-01-14 12:14:42 +01:00
@@ -1,5 +1,5 @@
|
||||
export default defineEventHandler(async () => {
|
||||
return useDB().query.announcements.findFirst({
|
||||
orderBy: (announcement, {asc}) => [asc(announcement.createdAt)]
|
||||
orderBy: (announcement, { asc }) => [asc(announcement.createdAt)],
|
||||
})
|
||||
})
|
||||
|
||||
@@ -5,12 +5,12 @@ const PostSchema = z.object({ slug: z.string() }).parse
|
||||
export default defineEventHandler(async (event) => {
|
||||
const { slug } = await readValidatedBody(event, PostSchema)
|
||||
return useDB().insert(tables.posts).values({
|
||||
slug
|
||||
slug,
|
||||
}).onConflictDoUpdate({
|
||||
target: tables.posts.id,
|
||||
set: {
|
||||
views: sql`${tables.posts.views}
|
||||
+ 1`
|
||||
}
|
||||
+ 1`,
|
||||
},
|
||||
})
|
||||
})
|
||||
|
||||
@@ -7,14 +7,14 @@ export default defineEventHandler(async (event) => {
|
||||
with: {
|
||||
bookmarkCategories: {
|
||||
with: {
|
||||
category: true
|
||||
}
|
||||
}
|
||||
}
|
||||
category: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
return bookmarks.filter(bookmark =>
|
||||
(category === 'all' || bookmark.bookmarkCategories.some(cat => cat.category.slug === category))
|
||||
&& (favorite === 'false' || bookmark.favorite)
|
||||
&& (favorite === 'false' || bookmark.favorite),
|
||||
)
|
||||
})
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { z } from 'zod'
|
||||
import {z} from 'zod'
|
||||
|
||||
const PostSchema = z.object({ slug: z.string() }).parse
|
||||
|
||||
@@ -7,7 +7,7 @@ export default defineEventHandler(async (event) => {
|
||||
return useDB().update(tables.posts)
|
||||
.set({
|
||||
likes: sql`${tables.posts.likes}
|
||||
+ 1`
|
||||
+ 1`,
|
||||
})
|
||||
.where(eq(tables.posts.slug, slug))
|
||||
})
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
export default defineEventHandler(async () => {
|
||||
const maintenance = await useDB().query.maintenances.findFirst({
|
||||
orderBy: [asc(tables.maintenances.createdAt)]
|
||||
orderBy: [asc(tables.maintenances.createdAt)],
|
||||
})
|
||||
let enabled = true
|
||||
// eslint-disable-next-line node/prefer-global/process
|
||||
|
||||
if (process.env.NODE_ENV === 'development') {
|
||||
enabled = false
|
||||
}
|
||||
@@ -17,6 +17,6 @@ export default defineEventHandler(async () => {
|
||||
|
||||
return {
|
||||
enabled,
|
||||
maintenance
|
||||
maintenance,
|
||||
}
|
||||
})
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { z } from 'zod'
|
||||
import {z} from 'zod'
|
||||
|
||||
const MessageValidator = z.object({
|
||||
id: z.number()
|
||||
id: z.number(),
|
||||
}).parse
|
||||
|
||||
export default defineEventHandler(async (event) => {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { z } from 'zod'
|
||||
import {z} from 'zod'
|
||||
|
||||
const MessageValidator = z.object({
|
||||
message: z.string()
|
||||
message: z.string(),
|
||||
}).parse
|
||||
|
||||
export default defineEventHandler(async (event) => {
|
||||
@@ -12,19 +12,19 @@ export default defineEventHandler(async (event) => {
|
||||
await sendDiscordWebhookMessage(config, {
|
||||
title: 'New guestbook message ✨',
|
||||
description: `**${user.username}** has signed the book : "*${message}*"`,
|
||||
color: 15893567
|
||||
color: 15893567,
|
||||
})
|
||||
return useDB().insert(tables.guestbookMessages)
|
||||
.values({
|
||||
message,
|
||||
email: user.email,
|
||||
username: user.username,
|
||||
image: user.picture
|
||||
image: user.picture,
|
||||
})
|
||||
.onConflictDoUpdate({
|
||||
target: tables.guestbookMessages.email,
|
||||
set: {
|
||||
message
|
||||
}
|
||||
message,
|
||||
},
|
||||
})
|
||||
})
|
||||
|
||||
@@ -8,8 +8,8 @@ export default defineCachedEventHandler(async (event) => {
|
||||
coding,
|
||||
editors,
|
||||
os,
|
||||
languages
|
||||
languages,
|
||||
}
|
||||
}, {
|
||||
maxAge: 60 * 60 * 3 // 3 hours,
|
||||
maxAge: 60 * 60 * 3, // 3 hours,
|
||||
})
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { z } from 'zod'
|
||||
import {z} from 'zod'
|
||||
|
||||
const SuggestionValidator = z.object({
|
||||
content: z.string()
|
||||
content: z.string(),
|
||||
}).parse
|
||||
|
||||
export default defineEventHandler(async (event) => {
|
||||
@@ -12,23 +12,23 @@ export default defineEventHandler(async (event) => {
|
||||
await sendDiscordWebhookMessage(config, {
|
||||
title: 'New suggestion ✨',
|
||||
description: `**${user.username}** has requested **${content}** for the talents page.`,
|
||||
color: 15237114
|
||||
color: 15237114,
|
||||
})
|
||||
|
||||
return useDB().insert(tables.suggestions)
|
||||
.values({
|
||||
email: user.email,
|
||||
content
|
||||
content,
|
||||
})
|
||||
.onConflictDoUpdate({
|
||||
target: tables.suggestions.email,
|
||||
set: {
|
||||
content
|
||||
content,
|
||||
},
|
||||
setWhere: sql`${tables.suggestions.email}
|
||||
=
|
||||
${user.email}`
|
||||
${user.email}`,
|
||||
}).returning({
|
||||
content: tables.suggestions.content
|
||||
content: tables.suggestions.content,
|
||||
})
|
||||
})
|
||||
|
||||
@@ -7,14 +7,14 @@ export default defineEventHandler(async (event) => {
|
||||
with: {
|
||||
talentCategories: {
|
||||
with: {
|
||||
category: true
|
||||
}
|
||||
}
|
||||
}
|
||||
category: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
return talents.filter(talent =>
|
||||
(category === 'all' || talent.talentCategories.some(cat => cat.category.slug === category))
|
||||
&& (favorite === 'false' || talent.favorite)
|
||||
&& (favorite === 'false' || talent.favorite),
|
||||
)
|
||||
})
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { z } from 'zod'
|
||||
import {z} from 'zod'
|
||||
|
||||
const PostSchema = z.object({ slug: z.string() }).parse
|
||||
|
||||
@@ -7,7 +7,7 @@ export default defineEventHandler(async (event) => {
|
||||
return useDB().update(tables.posts)
|
||||
.set({
|
||||
views: sql`${tables.posts.views}
|
||||
+ 1`
|
||||
+ 1`,
|
||||
})
|
||||
.where(eq(tables.posts.slug, slug))
|
||||
})
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { boolean, date, integer, pgEnum, pgTable, primaryKey, serial, text, timestamp } from 'drizzle-orm/pg-core'
|
||||
import { relations } from 'drizzle-orm'
|
||||
import {boolean, date, integer, pgEnum, pgTable, primaryKey, serial, text, timestamp} from 'drizzle-orm/pg-core'
|
||||
import {relations} from 'drizzle-orm'
|
||||
|
||||
// O B J E C T S
|
||||
|
||||
@@ -9,13 +9,13 @@ export const maintenances = pgTable('maintenances', {
|
||||
enabled: boolean('enabled').default(false).notNull(),
|
||||
beginAt: date('begin_at').defaultNow().notNull(),
|
||||
endAt: date('end_at').defaultNow().notNull(),
|
||||
createdAt: timestamp('created_at').defaultNow().notNull()
|
||||
createdAt: timestamp('created_at').defaultNow().notNull(),
|
||||
})
|
||||
|
||||
export const announcements = pgTable('announcements', {
|
||||
id: serial('id').primaryKey(),
|
||||
content: text('content').default('').notNull(),
|
||||
createdAt: timestamp('created_at').defaultNow().notNull()
|
||||
createdAt: timestamp('created_at').defaultNow().notNull(),
|
||||
})
|
||||
|
||||
export const posts = pgTable('posts', {
|
||||
@@ -23,7 +23,7 @@ export const posts = pgTable('posts', {
|
||||
slug: text('slug').notNull(),
|
||||
likes: integer('likes').default(0).notNull(),
|
||||
views: integer('views').default(0).notNull(),
|
||||
createdAt: timestamp('created_at').defaultNow().notNull()
|
||||
createdAt: timestamp('created_at').defaultNow().notNull(),
|
||||
})
|
||||
|
||||
export const suggestions = pgTable('suggestions', {
|
||||
@@ -32,9 +32,9 @@ export const suggestions = pgTable('suggestions', {
|
||||
content: text('content').notNull(),
|
||||
added: boolean('added').default(false).notNull(),
|
||||
createdAt: timestamp('created_at').defaultNow().notNull(),
|
||||
updatedAt: timestamp('updated_at').defaultNow().notNull()
|
||||
updatedAt: timestamp('updated_at').defaultNow().notNull(),
|
||||
}, t => ({
|
||||
pk: primaryKey({columns: [t.id, t.email]})
|
||||
pk: primaryKey({ columns: [t.id, t.email] }),
|
||||
}))
|
||||
|
||||
export const guestbookMessages = pgTable('guestbook_messages', {
|
||||
@@ -43,7 +43,7 @@ export const guestbookMessages = pgTable('guestbook_messages', {
|
||||
email: text('email').notNull().unique(),
|
||||
username: text('username').notNull(),
|
||||
image: text('image').notNull(),
|
||||
createdAt: timestamp('created_at').defaultNow().notNull()
|
||||
createdAt: timestamp('created_at').defaultNow().notNull(),
|
||||
})
|
||||
|
||||
export const categoriesType = pgEnum('categoryType', ['talent', 'bookmark'])
|
||||
@@ -53,7 +53,7 @@ export const categories = pgTable('categories', {
|
||||
slug: text('slug').unique().notNull(),
|
||||
name: text('name').notNull(),
|
||||
type: categoriesType('type').notNull(),
|
||||
createdAt: timestamp('created_at').defaultNow().notNull()
|
||||
createdAt: timestamp('created_at').defaultNow().notNull(),
|
||||
})
|
||||
|
||||
export const talents = pgTable('talents', {
|
||||
@@ -63,14 +63,14 @@ export const talents = pgTable('talents', {
|
||||
website: text('website').default('').notNull(),
|
||||
work: text('work').default('').notNull(),
|
||||
favorite: boolean('favorite').default(false).notNull(),
|
||||
createdAt: timestamp('created_at').defaultNow().notNull()
|
||||
createdAt: timestamp('created_at').defaultNow().notNull(),
|
||||
})
|
||||
|
||||
export const talentsToCategories = pgTable('talents_categories', {
|
||||
talentId: integer('talent_id').notNull()
|
||||
.references(() => talents.id, { onDelete: 'cascade' }),
|
||||
categoryId: integer('category_id').notNull()
|
||||
.references(() => categories.id, {onDelete: 'cascade'})
|
||||
.references(() => categories.id, { onDelete: 'cascade' }),
|
||||
})
|
||||
|
||||
export const bookmarks = pgTable('bookmarks', {
|
||||
@@ -78,51 +78,51 @@ export const bookmarks = pgTable('bookmarks', {
|
||||
name: text('name').notNull(),
|
||||
website: text('website').default('').notNull(),
|
||||
favorite: boolean('favorite').default(false).notNull(),
|
||||
createdAt: timestamp('created_at').defaultNow().notNull()
|
||||
createdAt: timestamp('created_at').defaultNow().notNull(),
|
||||
})
|
||||
|
||||
export const bookmarksToCategories = pgTable('bookmarks_categories', {
|
||||
bookmarkId: integer('bookmark_id').notNull()
|
||||
.references(() => bookmarks.id, { onDelete: 'cascade' }),
|
||||
categoryId: integer('category_id').notNull()
|
||||
.references(() => categories.id, {onDelete: 'cascade'})
|
||||
.references(() => categories.id, { onDelete: 'cascade' }),
|
||||
}, t => ({
|
||||
pk: primaryKey({columns: [t.bookmarkId, t.categoryId]})
|
||||
pk: primaryKey({ columns: [t.bookmarkId, t.categoryId] }),
|
||||
}))
|
||||
|
||||
// R E L A T I O N S
|
||||
|
||||
export const talentsRelations = relations(talents, ({ many }) => ({
|
||||
talentCategories: many(talentsToCategories)
|
||||
talentCategories: many(talentsToCategories),
|
||||
}))
|
||||
|
||||
export const bookmarksRelations = relations(bookmarks, ({ many }) => ({
|
||||
bookmarkCategories: many(bookmarksToCategories)
|
||||
bookmarkCategories: many(bookmarksToCategories),
|
||||
}))
|
||||
|
||||
export const categoriesRelations = relations(categories, ({ many }) => ({
|
||||
talentsToCategories: many(talentsToCategories),
|
||||
bookmarksToCategories: many(bookmarksToCategories)
|
||||
bookmarksToCategories: many(bookmarksToCategories),
|
||||
}))
|
||||
|
||||
export const talentsToCategoriesRelations = relations(talentsToCategories, ({ one }) => ({
|
||||
talent: one(talents, {
|
||||
references: [talents.id],
|
||||
fields: [talentsToCategories.talentId]
|
||||
fields: [talentsToCategories.talentId],
|
||||
}),
|
||||
category: one(categories, {
|
||||
references: [categories.id],
|
||||
fields: [talentsToCategories.categoryId]
|
||||
})
|
||||
fields: [talentsToCategories.categoryId],
|
||||
}),
|
||||
}))
|
||||
|
||||
export const bookmarksToCategoriesRelations = relations(bookmarksToCategories, ({ one }) => ({
|
||||
bookmark: one(bookmarks, {
|
||||
references: [bookmarks.id],
|
||||
fields: [bookmarksToCategories.bookmarkId]
|
||||
fields: [bookmarksToCategories.bookmarkId],
|
||||
}),
|
||||
category: one(categories, {
|
||||
references: [categories.id],
|
||||
fields: [bookmarksToCategories.categoryId]
|
||||
})
|
||||
fields: [bookmarksToCategories.categoryId],
|
||||
}),
|
||||
}))
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
export default oauth.githubEventHandler({
|
||||
config: {
|
||||
emailRequired: true
|
||||
emailRequired: true,
|
||||
},
|
||||
async onSuccess(event, {user}) {
|
||||
async onSuccess(event, { user }) {
|
||||
await setUserSession(event, {
|
||||
user: {
|
||||
email: user.email,
|
||||
picture: user.avatar_url,
|
||||
username: String(user.name).trim(),
|
||||
admin: user.email === process.env.NUXT_AUTH_ADMIN_EMAIL
|
||||
}
|
||||
admin: user.email === process.env.NUXT_AUTH_ADMIN_EMAIL,
|
||||
},
|
||||
})
|
||||
return sendRedirect(event, getCookie(event, 'last-route') || '/')
|
||||
},
|
||||
onError(error) {
|
||||
console.error('GitHub OAuth error:', error)
|
||||
}
|
||||
},
|
||||
})
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
export default oauth.googleEventHandler({
|
||||
async onSuccess(event, {user}) {
|
||||
async onSuccess(event, { user }) {
|
||||
await setUserSession(event, {
|
||||
user: {
|
||||
email: user.email,
|
||||
picture: user.picture,
|
||||
username: String(user.name).trim(),
|
||||
admin: user.email === process.env.NUXT_AUTH_ADMIN_EMAIL
|
||||
}
|
||||
admin: user.email === process.env.NUXT_AUTH_ADMIN_EMAIL,
|
||||
},
|
||||
})
|
||||
return sendRedirect(event, getCookie(event, 'last-route') || '/')
|
||||
},
|
||||
onError(error) {
|
||||
console.error('Google OAuth error:', error)
|
||||
}
|
||||
},
|
||||
})
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
import { drizzle } from 'drizzle-orm/postgres-js'
|
||||
import {drizzle} from 'drizzle-orm/postgres-js'
|
||||
import postgres from 'postgres'
|
||||
import * as schema from '../database/schema'
|
||||
|
||||
export const tables = schema
|
||||
export { sql, eq, and, or, asc, desc, sum, inArray } from 'drizzle-orm'
|
||||
|
||||
// eslint-disable-next-line node/prefer-global/process
|
||||
const connectionString = process.env.DATABASE_URL as string
|
||||
const client = postgres(connectionString, { prepare: false })
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { RuntimeConfig } from 'nuxt/schema'
|
||||
import type {RuntimeConfig} from 'nuxt/schema'
|
||||
|
||||
interface WebhookContent {
|
||||
title: string
|
||||
@@ -17,12 +17,12 @@ export async function sendDiscordWebhookMessage(config: RuntimeConfig, content:
|
||||
color: content.color,
|
||||
url: 'https://arthurdanjou.fr/talents',
|
||||
footer: {
|
||||
text: 'Powered by Nuxt'
|
||||
text: 'Powered by Nuxt',
|
||||
},
|
||||
timestamp: new Date().toISOString()
|
||||
}
|
||||
timestamp: new Date().toISOString(),
|
||||
},
|
||||
],
|
||||
username: 'ArtDanjRobot - Website'
|
||||
}
|
||||
username: 'ArtDanjRobot - Website',
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user