initial commit
This commit is contained in:
44
src/lib/server/auth.ts
Normal file
44
src/lib/server/auth.ts
Normal file
@ -0,0 +1,44 @@
|
||||
import { Lucia } from 'lucia';
|
||||
import { dev } from '$app/environment';
|
||||
import { DrizzlePostgreSQLAdapter } from '@lucia-auth/adapter-drizzle';
|
||||
import { db } from './db';
|
||||
import { sessions, users } from './db/schema';
|
||||
import { Gitea } from 'arctic';
|
||||
import { GITEA_BASE_URL, GITEA_CLIENT_ID, GITEA_CLIENT_SECRET } from '$env/static/private';
|
||||
|
||||
const adapter = new DrizzlePostgreSQLAdapter(db, sessions, users);
|
||||
|
||||
export const lucia = new Lucia(adapter, {
|
||||
sessionCookie: {
|
||||
attributes: {
|
||||
secure: !dev
|
||||
}
|
||||
},
|
||||
getUserAttributes: (attributes) => {
|
||||
return {
|
||||
username: attributes.username,
|
||||
giteaId: attributes.giteaId,
|
||||
avatarUrl: attributes.avatarUrl
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
declare module 'lucia' {
|
||||
interface Register {
|
||||
Lucia: typeof lucia;
|
||||
DatabaseUserAttributes: DatabaseUserAttributes;
|
||||
}
|
||||
}
|
||||
|
||||
interface DatabaseUserAttributes {
|
||||
username: string;
|
||||
giteaId: number;
|
||||
avatarUrl: string;
|
||||
}
|
||||
|
||||
export const gitea = new Gitea(
|
||||
GITEA_BASE_URL,
|
||||
GITEA_CLIENT_ID,
|
||||
GITEA_CLIENT_SECRET,
|
||||
'http://localhost:5173/login/gitea/callback'
|
||||
);
|
||||
27
src/lib/server/comments.ts
Normal file
27
src/lib/server/comments.ts
Normal file
@ -0,0 +1,27 @@
|
||||
import { db } from '$lib/server/db';
|
||||
import { comments } from '$lib/server/db/schema';
|
||||
import { eq } from 'drizzle-orm';
|
||||
|
||||
export async function createComment(itemId: string, userId: string, text: string) {
|
||||
return await db.insert(comments).values({
|
||||
itemId,
|
||||
userId,
|
||||
text
|
||||
}).returning();
|
||||
}
|
||||
|
||||
export async function deleteComment(id: string) {
|
||||
return await db.delete(comments)
|
||||
.where(eq(comments.id, id))
|
||||
.returning();
|
||||
}
|
||||
|
||||
export async function getComments(itemId: string) {
|
||||
return await db.query.comments.findMany({
|
||||
where: eq(comments.itemId, itemId),
|
||||
with: {
|
||||
user: true
|
||||
},
|
||||
orderBy: (comments, { asc }) => [asc(comments.createdAt)]
|
||||
});
|
||||
}
|
||||
9
src/lib/server/db/index.ts
Normal file
9
src/lib/server/db/index.ts
Normal file
@ -0,0 +1,9 @@
|
||||
import { drizzle } from 'drizzle-orm/postgres-js';
|
||||
import postgres from 'postgres';
|
||||
import { env } from '$env/dynamic/private';
|
||||
import * as schema from './schema';
|
||||
|
||||
if (!env.DATABASE_URL) throw new Error('DATABASE_URL is not set');
|
||||
|
||||
const client = postgres(env.DATABASE_URL);
|
||||
export const db = drizzle(client, { schema });
|
||||
105
src/lib/server/db/schema.ts
Normal file
105
src/lib/server/db/schema.ts
Normal file
@ -0,0 +1,105 @@
|
||||
import { pgTable, uuid, text, integer, jsonb, timestamp, foreignKey } from 'drizzle-orm/pg-core';
|
||||
import { relations } from 'drizzle-orm';
|
||||
|
||||
export const folders = pgTable('folders', {
|
||||
id: uuid('id').primaryKey().defaultRandom(),
|
||||
name: text('name').notNull(),
|
||||
parentId: uuid('parent_id'),
|
||||
createdAt: timestamp('created_at').defaultNow().notNull(),
|
||||
updatedAt: timestamp('updated_at').defaultNow().notNull()
|
||||
}, (table) => {
|
||||
return {
|
||||
parentReference: foreignKey({
|
||||
columns: [table.parentId],
|
||||
foreignColumns: [table.id],
|
||||
name: 'folders_parent_id_fkey'
|
||||
})
|
||||
};
|
||||
});
|
||||
|
||||
export const categories = pgTable('categories', {
|
||||
id: uuid('id').primaryKey().defaultRandom(),
|
||||
name: text('name').notNull(),
|
||||
defaultProperties: jsonb('default_properties').$type<string[]>().default([]).notNull(),
|
||||
createdAt: timestamp('created_at').defaultNow().notNull(),
|
||||
updatedAt: timestamp('updated_at').defaultNow().notNull()
|
||||
});
|
||||
|
||||
export const items = pgTable('items', {
|
||||
id: uuid('id').primaryKey().defaultRandom(),
|
||||
folderId: uuid('folder_id').references(() => folders.id).notNull(),
|
||||
categoryId: uuid('category_id').references(() => categories.id).notNull(),
|
||||
name: text('name').notNull(),
|
||||
count: integer('count').default(0).notNull(),
|
||||
tags: jsonb('tags').$type<string[]>().default([]).notNull(),
|
||||
properties: jsonb('properties').$type<Record<string, any>>().default({}).notNull(),
|
||||
createdAt: timestamp('created_at').defaultNow().notNull(),
|
||||
updatedAt: timestamp('updated_at').defaultNow().notNull()
|
||||
});
|
||||
|
||||
export const users = pgTable('users', {
|
||||
id: text('id').primaryKey(),
|
||||
giteaId: integer('gitea_id').unique(),
|
||||
username: text('username').notNull(),
|
||||
avatarUrl: text('avatar_url')
|
||||
});
|
||||
|
||||
export const sessions = pgTable('sessions', {
|
||||
id: text('id').primaryKey(),
|
||||
userId: text('user_id')
|
||||
.notNull()
|
||||
.references(() => users.id),
|
||||
expiresAt: timestamp('expires_at', { withTimezone: true, mode: 'date' }).notNull()
|
||||
});
|
||||
|
||||
export const reservations = pgTable('reservations', {
|
||||
id: uuid('id').primaryKey().defaultRandom(),
|
||||
itemId: uuid('item_id')
|
||||
.notNull()
|
||||
.references(() => items.id, { onDelete: 'cascade' }),
|
||||
userId: text('user_id')
|
||||
.notNull()
|
||||
.references(() => users.id, { onDelete: 'cascade' }),
|
||||
count: integer('count').notNull(),
|
||||
createdAt: timestamp('created_at').defaultNow().notNull(),
|
||||
updatedAt: timestamp('updated_at').defaultNow().notNull()
|
||||
});
|
||||
|
||||
export const comments = pgTable('comments', {
|
||||
id: uuid('id').primaryKey().defaultRandom(),
|
||||
itemId: uuid('item_id')
|
||||
.notNull()
|
||||
.references(() => items.id, { onDelete: 'cascade' }),
|
||||
userId: text('user_id')
|
||||
.notNull()
|
||||
.references(() => users.id, { onDelete: 'cascade' }),
|
||||
text: text('text').notNull(),
|
||||
createdAt: timestamp('created_at').defaultNow().notNull()
|
||||
});
|
||||
|
||||
export const itemsRelations = relations(items, ({ many }) => ({
|
||||
reservations: many(reservations),
|
||||
comments: many(comments)
|
||||
}));
|
||||
|
||||
export const reservationsRelations = relations(reservations, ({ one }) => ({
|
||||
item: one(items, {
|
||||
fields: [reservations.itemId],
|
||||
references: [items.id]
|
||||
}),
|
||||
user: one(users, {
|
||||
fields: [reservations.userId],
|
||||
references: [users.id]
|
||||
})
|
||||
}));
|
||||
|
||||
export const commentsRelations = relations(comments, ({ one }) => ({
|
||||
item: one(items, {
|
||||
fields: [comments.itemId],
|
||||
references: [items.id]
|
||||
}),
|
||||
user: one(users, {
|
||||
fields: [comments.userId],
|
||||
references: [users.id]
|
||||
})
|
||||
}));
|
||||
37
src/lib/server/reservations.ts
Normal file
37
src/lib/server/reservations.ts
Normal file
@ -0,0 +1,37 @@
|
||||
import { db } from '$lib/server/db';
|
||||
import { reservations } from '$lib/server/db/schema';
|
||||
import { eq, and } from 'drizzle-orm';
|
||||
|
||||
export async function createReservation(itemId: string, userId: string, count: number) {
|
||||
return await db.insert(reservations).values({
|
||||
itemId,
|
||||
userId,
|
||||
count
|
||||
}).returning();
|
||||
}
|
||||
|
||||
export async function updateReservation(id: string, count: number) {
|
||||
if (count <= 0) {
|
||||
return await deleteReservation(id);
|
||||
}
|
||||
return await db.update(reservations)
|
||||
.set({ count, updatedAt: new Date() })
|
||||
.where(eq(reservations.id, id))
|
||||
.returning();
|
||||
}
|
||||
|
||||
export async function deleteReservation(id: string) {
|
||||
return await db.delete(reservations)
|
||||
.where(eq(reservations.id, id))
|
||||
.returning();
|
||||
}
|
||||
|
||||
export async function getReservations(itemId: string) {
|
||||
return await db.query.reservations.findMany({
|
||||
where: eq(reservations.itemId, itemId),
|
||||
with: {
|
||||
user: true // Assuming we want user details, need to check relations
|
||||
},
|
||||
orderBy: (reservations, { desc }) => [desc(reservations.createdAt)]
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user