add blog editor
This commit is contained in:
@@ -5,7 +5,7 @@ import { sveltekitCookies } from 'better-auth/svelte-kit';
|
||||
import { getRequestEvent } from '$app/server';
|
||||
import { db } from '$lib/server/db';
|
||||
import * as schema from '$lib/server/db/schema';
|
||||
import type { RequestEvent } from '@sveltejs/kit';
|
||||
import { error, type RequestEvent } from '@sveltejs/kit';
|
||||
|
||||
export const auth = betterAuth({
|
||||
baseURL: env.ORIGIN ?? 'http://localhost:3000',
|
||||
@@ -30,9 +30,6 @@ export function isAdmin(event: RequestEvent): boolean {
|
||||
|
||||
export function requireAdmin(event: RequestEvent): void {
|
||||
if (!isAdmin(event)) {
|
||||
throw new Response(JSON.stringify({ error: 'Unauthorized' }), {
|
||||
status: 401,
|
||||
headers: { 'Content-Type': 'application/json' }
|
||||
});
|
||||
error(401, { message: 'Unauthorized' });
|
||||
}
|
||||
}
|
||||
|
||||
@@ -69,14 +69,21 @@ export const publications = pgTable('publications', {
|
||||
// Legacy ^
|
||||
// New
|
||||
|
||||
export const blogArticles = pgTable('blog_articles', {
|
||||
id: serial('id').primaryKey(),
|
||||
title: varchar('title', { length: 256 }),
|
||||
slug: varchar('slug', { length: 256 }),
|
||||
content: varchar('content', { length: 8192 }),
|
||||
createdAt: timestamp('created_at').defaultNow(),
|
||||
updatedAt: timestamp('updated_at').defaultNow()
|
||||
});
|
||||
export const blogArticleStatus = pgEnum('blog_article_status', ['draft', 'published']);
|
||||
|
||||
export const blogArticles = pgTable(
|
||||
'blog_articles',
|
||||
{
|
||||
id: serial('id').primaryKey(),
|
||||
title: varchar('title', { length: 256 }).notNull(),
|
||||
slug: varchar('slug', { length: 256 }).notNull(),
|
||||
content: text('content').default(''),
|
||||
status: blogArticleStatus('status').notNull().default('draft'),
|
||||
createdAt: timestamp('created_at').defaultNow(),
|
||||
updatedAt: timestamp('updated_at').defaultNow()
|
||||
},
|
||||
(table) => [unique().on(table.slug)]
|
||||
);
|
||||
|
||||
// CatchEmAll
|
||||
|
||||
|
||||
29
src/lib/server/slugify.ts
Normal file
29
src/lib/server/slugify.ts
Normal file
@@ -0,0 +1,29 @@
|
||||
import { db } from '$lib/server/db';
|
||||
import { blogArticles } from '$lib/server/db/schema';
|
||||
import { eq } from 'drizzle-orm';
|
||||
|
||||
export function slugify(title: string): string {
|
||||
return (
|
||||
title
|
||||
.toLowerCase()
|
||||
.trim()
|
||||
.replace(/[^a-z0-9]+/g, '-')
|
||||
.replace(/^-+|-+$/g, '') || 'article'
|
||||
);
|
||||
}
|
||||
|
||||
export async function uniqueSlug(title: string): Promise<string> {
|
||||
const base = slugify(title);
|
||||
let slug = base;
|
||||
let suffix = 2;
|
||||
|
||||
while (
|
||||
(await db.select({ id: blogArticles.id }).from(blogArticles).where(eq(blogArticles.slug, slug)))
|
||||
.length > 0
|
||||
) {
|
||||
slug = `${base}-${suffix}`;
|
||||
suffix += 1;
|
||||
}
|
||||
|
||||
return slug;
|
||||
}
|
||||
10
src/lib/validation/blog.ts
Normal file
10
src/lib/validation/blog.ts
Normal file
@@ -0,0 +1,10 @@
|
||||
import { z } from 'zod';
|
||||
|
||||
export const createArticleSchema = z.object({
|
||||
title: z.string().min(1).max(256)
|
||||
});
|
||||
|
||||
export const updateArticleSchema = z.object({
|
||||
title: z.string().min(1).max(256),
|
||||
content: z.string().max(50000)
|
||||
});
|
||||
Reference in New Issue
Block a user