Update dependencies, fix most of signup, add seed file for Drizzle and command.

This commit is contained in:
Bradley Shellnut 2024-02-07 17:16:17 -08:00
parent 679f59c0fd
commit 049a9536c4
8 changed files with 773 additions and 618 deletions

View file

@ -18,6 +18,7 @@
"site:update": "pnpm update -i -L",
"generate": "drizzle-kit generate:mysql",
"migrate": "tsx ./src/migrate.ts",
"seed": "tsx ./src/seed/insert.ts",
"push": "drizzle-kit push:mysql"
},
"prisma": {
@ -26,35 +27,35 @@
"devDependencies": {
"@melt-ui/pp": "^0.3.0",
"@melt-ui/svelte": "^0.70.0",
"@playwright/test": "^1.41.1",
"@playwright/test": "^1.41.2",
"@resvg/resvg-js": "^2.6.0",
"@sveltejs/adapter-auto": "^3.1.1",
"@sveltejs/enhanced-img": "^0.1.8",
"@sveltejs/kit": "^2.5.0",
"@sveltejs/vite-plugin-svelte": "^3.0.2",
"@types/cookie": "^0.5.4",
"@types/node": "^18.19.10",
"@typescript-eslint/eslint-plugin": "^6.20.0",
"@typescript-eslint/parser": "^6.20.0",
"@types/node": "^18.19.14",
"@typescript-eslint/eslint-plugin": "^6.21.0",
"@typescript-eslint/parser": "^6.21.0",
"autoprefixer": "^10.4.17",
"dotenv": "^16.4.1",
"drizzle-kit": "^0.20.13",
"drizzle-kit": "^0.20.14",
"eslint": "^8.56.0",
"eslint-config-prettier": "^9.1.0",
"eslint-plugin-svelte": "^2.35.1",
"just-clone": "^6.2.0",
"just-debounce-it": "^3.2.0",
"postcss": "^8.4.33",
"postcss": "^8.4.35",
"postcss-import": "^15.1.0",
"postcss-load-config": "^4.0.2",
"postcss-preset-env": "^9.3.0",
"prettier": "^3.2.4",
"prettier": "^3.2.5",
"prettier-plugin-svelte": "^3.1.2",
"prisma": "^5.8.1",
"sass": "^1.70.0",
"satori": "^0.10.13",
"satori-html": "^0.3.2",
"svelte": "^4.2.9",
"svelte": "^4.2.10",
"svelte-check": "^3.6.3",
"svelte-meta-tags": "^3.1.0",
"svelte-preprocess": "^5.1.3",
@ -79,13 +80,13 @@
"@fontsource/fira-mono": "^4.5.10",
"@iconify-icons/line-md": "^1.2.26",
"@iconify-icons/mdi": "^1.2.47",
"@lucia-auth/adapter-drizzle": "^1.0.0",
"@lucia-auth/adapter-drizzle": "^1.0.1",
"@lucia-auth/adapter-prisma": "4.0.0",
"@lukeed/uuid": "^2.0.1",
"@paralleldrive/cuid2": "^2.2.2",
"@planetscale/database": "^1.14.0",
"@planetscale/database": "^1.15.0",
"@prisma/client": "^5.8.1",
"@sentry/sveltekit": "^7.88.0",
"@sentry/sveltekit": "^7.100.1",
"@sveltejs/adapter-vercel": "^5.1.0",
"@types/feather-icons": "^4.29.4",
"@vercel/og": "^0.5.20",
@ -106,7 +107,7 @@
"mysql2": "^3.9.1",
"nanoid": "^5.0.5",
"open-props": "^1.6.18",
"oslo": "^1.0.3",
"oslo": "^1.1.0",
"radix-svelte": "^0.9.0",
"svelte-french-toast": "^1.2.0",
"svelte-lazy-loader": "^1.0.0",

File diff suppressed because it is too large Load diff

View file

@ -1,6 +1,7 @@
import { drizzle } from 'drizzle-orm/mysql2';
import mysql from 'mysql2/promise';
import { DATABASE_USER, DATABASE_PASSWORD, DATABASE_HOST, DATABASE_DB } from '$env/static/private';
import * as schema from '../schema';
// create the connection
const connection = await mysql.createConnection({
@ -11,6 +12,6 @@ const connection = await mysql.createConnection({
database: DATABASE_DB
});
const db = drizzle(connection);
const db = drizzle(connection, { schema: schema, mode: 'default' });
export default db;

View file

@ -0,0 +1,3 @@
export const normalizeEmail = (email: string): string => {
return decodeURIComponent(email).toLowerCase().trim();
};

View file

@ -8,8 +8,9 @@ import { userSchema } from '$lib/config/zod-schemas';
import { add_user_to_role } from '$server/roles';
import type { Message } from '$lib/types.js';
import db from '$lib/drizzle';
import { users } from '../../../schema';
import { collections, users, wishlists } from '../../../schema';
import { eq } from 'drizzle-orm';
import { nanoid } from 'nanoid';
const signUpSchema = userSchema
.pick({
@ -58,6 +59,19 @@ export const actions: Actions = {
let sessionCookie;
// Adding user to the db
try {
console.log('Check if user already exists');
const existing_user = await db.query
.users
.findFirst({ where: eq(users.username, form.data.username) });
if (existing_user) {
return fail(400, {
form,
message: 'You cannot create an account with that username'
});
}
console.log('Creating user');
const hashedPassword = await new Argon2id().hash(form.data.password);
@ -77,25 +91,29 @@ export const actions: Actions = {
.from(users)
.where(eq(users.username, form.data.username));
console.log('signup user', user);
if (!user || user.length === 0) {
return fail(400, {
form,
message: `Could not create your account. Please try again. If the problem persists, please contact support. Error ID: ${nanoid()}`
});
}
add_user_to_role(user[0].id, 'user');
// await prisma.collection.create({
// data: {
// user_id: user.id
// }
// });
// await prisma.wishlist.create({
// data: {
// user_id: user.id
// }
// });
await db.insert(collections)
.values({
user_id: user[0].id
});
await db.insert(wishlists)
.values({
user_id: user[0].id
});
// console.log('User', user);
// session = await lucia.createSession(user.id, {
// ipCountry: event.locals.session?.ipCountry,
// ipAddress: event.locals.session?.ipAddress
// });
// sessionCookie = lucia.createSessionCookie(session.id);
session = await lucia.createSession(user[0].id, {
ip_country: event.locals.session?.ipCountry,
ip_address: event.locals.session?.ipAddress
});
sessionCookie = lucia.createSessionCookie(session.id);
} catch (e: any) {
if (e.message.toUpperCase() === `DUPLICATE_KEY_ID`) {
// key already exists
@ -111,13 +129,13 @@ export const actions: Actions = {
error(500, message);
}
// event.cookies.set(sessionCookie.name, sessionCookie.value, {
// path: ".",
// ...sessionCookie.attributes
// });
event.cookies.set(sessionCookie.name, sessionCookie.value, {
path: ".",
...sessionCookie.attributes
});
redirect(302, '/');
// const message = { type: 'success', message: 'Signed Up!' } as const;
// throw flashRedirect(message, event);
// redirect(302, '/');
const message = { type: 'success', message: 'Signed Up!' } as const;
throw flashRedirect(message, event);
}
};

View file

@ -70,27 +70,27 @@ export const user_roles = mysqlTable("user_roles", {
length: 255
}).primaryKey()
.$defaultFn(() => nanoid()),
userId: varchar("user_id", {
user_id: varchar("user_id", {
length: 255
})
.notNull()
.references(() => users.id, { onDelete: 'cascade' }),
roleId: varchar("role_id", {
role_id: varchar("role_id", {
length: 255
})
.notNull()
.references(() => roles.id, { onDelete: 'cascade' }),
createdAt: datetime("created_at").default(sql`(now(6))`),
updatedAt: datetime("updated_at").default(sql`(now(6))`)
created_at: datetime("created_at").default(sql`(now(6))`),
updated_at: datetime("updated_at").default(sql`(now(6))`)
});
export const user_role_relations = relations(user_roles, ({ one }) => ({
role: one(roles, {
fields: [user_roles.roleId],
fields: [user_roles.role_id],
references: [roles.id]
}),
user: one(users, {
fields: [user_roles.userId],
fields: [user_roles.user_id],
references: [users.id]
})
}));
@ -107,26 +107,26 @@ export const games = mysqlTable("games", {
length: 255
}),
description: text("description"),
yearPublished: year("year_published"),
minPlayers: int("min_players"),
maxPlayers: int("max_players"),
year_published: year("year_published"),
min_players: int("min_players"),
max_players: int("max_players"),
playtime: int("playtime"),
minPlaytime: int("min_playtime"),
maxPlaytime: int("max_playtime"),
minAge: int("min_age"),
imageUrl: varchar("image_url", {
min_playtime: int("min_playtime"),
max_playtime: int("max_playtime"),
min_age: int("min_age"),
image_url: varchar("image_url", {
length: 255
}),
thumbUrl: varchar("thumb_url", {
thumb_url: varchar("thumb_url", {
length: 255
}),
url: varchar("url", {
length: 255
}),
externalId: int("external_id").unique(),
lastSyncAt: datetime("last_sync_at"),
createdAt: datetime("created_at").default(sql`(now(6))`),
updatedAt: datetime("updated_at").default(sql`(now(6))`)
external_id: int("external_id").unique(),
last_sync_at: datetime("last_sync_at"),
created_at: datetime("created_at").default(sql`(now(6))`),
updated_at: datetime("updated_at").default(sql`(now(6))`)
});
export type Games = InferSelectModel<typeof games>;
@ -144,27 +144,27 @@ export const expansions = mysqlTable("expansions", {
length: 255
}).primaryKey()
.$defaultFn(() => nanoid()),
baseGameId: varchar("base_game_id", {
base_game_id: varchar("base_game_id", {
length: 255
})
.notNull()
.references(() => games.id, { onDelete: 'cascade' }),
gameId: varchar("game_id", {
game_id: varchar("game_id", {
length: 255
})
.notNull()
.references(() => games.id, { onDelete: 'cascade' }),
createdAt: datetime("created_at").default(sql`(now(6))`),
updatedAt: datetime("updated_at").default(sql`(now(6))`)
created_at: datetime("created_at").default(sql`(now(6))`),
updated_at: datetime("updated_at").default(sql`(now(6))`)
})
export const expansion_relations = relations(expansions, ({ one }) => ({
baseGame: one(games, {
fields: [expansions.baseGameId],
fields: [expansions.base_game_id],
references: [games.id]
}),
game: one(games, {
fields: [expansions.gameId],
fields: [expansions.game_id],
references: [games.id]
})
}));
@ -174,18 +174,18 @@ export const collections = mysqlTable("collections", {
length: 255
}).primaryKey()
.$defaultFn(() => nanoid()),
userId: varchar("user_id", {
user_id: varchar("user_id", {
length: 255
})
.notNull()
.references(() => users.id, { onDelete: 'cascade' }),
createdAt: datetime("created_at").default(sql`(now(6))`),
updatedAt: datetime("updated_at").default(sql`(now(6))`)
created_at: datetime("created_at").default(sql`(now(6))`),
updated_at: datetime("updated_at").default(sql`(now(6))`)
});
export const collection_relations = relations(collections, ({ one }) => ({
user: one(users, {
fields: [collections.userId],
fields: [collections.user_id],
references: [users.id]
}),
}))
@ -195,27 +195,27 @@ export const collection_items = mysqlTable("collection_items", {
length: 255
}).primaryKey()
.$defaultFn(() => nanoid()),
collectionId: varchar("collection_id", {
collection_id: varchar("collection_id", {
length: 255
})
.notNull()
.references(() => collections.id, { onDelete: 'cascade' }),
gameId: varchar("game_id", {
game_id: varchar("game_id", {
length: 255
})
.notNull()
.references(() => games.id, { onDelete: 'cascade' }),
createdAt: datetime("created_at").default(sql`(now(6))`),
updatedAt: datetime("updated_at").default(sql`(now(6))`)
created_at: datetime("created_at").default(sql`(now(6))`),
updated_at: datetime("updated_at").default(sql`(now(6))`)
});
export const collection_item_relations = relations(collection_items, ({ one }) =>({
collection: one(collections, {
fields: [collection_items.collectionId],
fields: [collection_items.collection_id],
references: [collections.id]
}),
game: one(games, {
fields: [collection_items.gameId],
fields: [collection_items.game_id],
references: [games.id]
})
}));
@ -225,18 +225,18 @@ export const wishlists = mysqlTable("wishlists", {
length: 255
}).primaryKey()
.$defaultFn(() => nanoid()),
userId: varchar("user_id", {
user_id: varchar("user_id", {
length: 255
})
.notNull()
.references(() => users.id, { onDelete: 'cascade' }),
createdAt: datetime("created_at").default(sql`(now(6))`),
updatedAt: datetime("updated_at").default(sql`(now(6))`)
created_at: datetime("created_at").default(sql`(now(6))`),
updated_at: datetime("updated_at").default(sql`(now(6))`)
});
export const wishlists_relations = relations(wishlists, ({ one }) => ({
user: one(users, {
fields: [wishlists.userId],
fields: [wishlists.user_id],
references: [users.id]
}),
}))
@ -247,27 +247,27 @@ export const wishlist_items = mysqlTable('wishlist_items', {
})
.primaryKey()
.$defaultFn(() => nanoid()),
wishlistId: varchar('wishlist_id', {
wishlist_id: varchar('wishlist_id', {
length: 255
})
.notNull()
.references(() => wishlists.id, { onDelete: 'cascade' }),
gameId: varchar('game_id', {
game_id: varchar('game_id', {
length: 255
})
.notNull()
.references(() => games.id, { onDelete: 'cascade' }),
createdAt: datetime('created_at').default(sql`(now(6))`),
updatedAt: datetime('updated_at').default(sql`(now(6))`)
created_at: datetime('created_at').default(sql`(now(6))`),
updated_at: datetime('updated_at').default(sql`(now(6))`)
});
export const wishlist_item_relations = relations(wishlist_items, ({ one }) => ({
wishlist: one(wishlists, {
fields: [wishlist_items.wishlistId],
fields: [wishlist_items.wishlist_id],
references: [wishlists.id]
}),
game: one(games, {
fields: [wishlist_items.gameId],
fields: [wishlist_items.game_id],
references: [games.id]
})
}))
@ -283,9 +283,9 @@ export const publishers = mysqlTable("publishers", {
slug: varchar("slug", {
length: 255
}),
externalId: int("external_id"),
createdAt: datetime("created_at").default(sql`(now(6))`),
updatedAt: datetime("updated_at").default(sql`(now(6))`)
external_id: int("external_id"),
created_at: datetime("created_at").default(sql`(now(6))`),
updated_at: datetime("updated_at").default(sql`(now(6))`)
});
export const publishers_relations = relations(publishers, ({ many }) => ({
@ -303,9 +303,9 @@ export const categories = mysqlTable("categories", {
slug: varchar("slug", {
length: 255
}),
externalId: int("external_id"),
createdAt: datetime("created_at").default(sql`(now(6))`),
updatedAt: datetime("updated_at").default(sql`(now(6))`)
external_id: int("external_id"),
created_at: datetime("created_at").default(sql`(now(6))`),
updated_at: datetime("updated_at").default(sql`(now(6))`)
});
export const categories_relations = relations(categories, ({ many }) => ({
@ -323,9 +323,9 @@ export const mechanics = mysqlTable("mechanics", {
slug: varchar("slug", {
length: 255
}),
externalId: int("external_id"),
createdAt: datetime("created_at").default(sql`(now(6))`),
updatedAt: datetime("updated_at").default(sql`(now(6))`)
external_id: int("external_id"),
created_at: datetime("created_at").default(sql`(now(6))`),
updated_at: datetime("updated_at").default(sql`(now(6))`)
});
export const mechanic_relations = relations(mechanics, ({ many }) => ({
@ -343,9 +343,9 @@ export const designers = mysqlTable("designers", {
slug: varchar("slug", {
length: 255
}),
externalId: int("external_id"),
createdAt: datetime("created_at").default(sql`(now(6))`),
updatedAt: datetime("updated_at").default(sql`(now(6))`)
external_id: int("external_id"),
created_at: datetime("created_at").default(sql`(now(6))`),
updated_at: datetime("updated_at").default(sql`(now(6))`)
});
export const designers_relations = relations(designers, ({ many }) => ({
@ -363,9 +363,9 @@ export const artists = mysqlTable("artists", {
slug: varchar("slug", {
length: 255
}),
externalId: int("external_id"),
createdAt: datetime("created_at").default(sql`(now(6))`),
updatedAt: datetime("updated_at").default(sql`(now(6))`)
external_id: int("external_id"),
created_at: datetime("created_at").default(sql`(now(6))`),
updated_at: datetime("updated_at").default(sql`(now(6))`)
});
export const artists_relations = relations(artists, ({ many }) => ({
@ -373,101 +373,101 @@ export const artists_relations = relations(artists, ({ many }) => ({
}));
export const artists_to_games = mysqlTable('artists_to_games', {
artistId: varchar('artist_id', {
artist_id: varchar('artist_id', {
length: 255
}),
gameId: varchar('game_id', {
game_id: varchar('game_id', {
length: 255
}),
});
export const artists_to_games_relations = relations(artists_to_games, ({ one }) => ({
artist: one(artists, {
fields: [artists_to_games.artistId],
fields: [artists_to_games.artist_id],
references: [artists.id]
}),
game: one(games, {
fields: [artists_to_games.gameId],
fields: [artists_to_games.game_id],
references: [games.id]
}),
}));
export const categories_to_games = mysqlTable("categories_to_games", {
categoryId: varchar("category_id", {
category_id: varchar("category_id", {
length: 255
}),
gameId: varchar("game_id", {
game_id: varchar("game_id", {
length: 255
}),
});
export const categories_to_games_relations = relations(categories_to_games, ({ one }) => ({
category: one(categories, {
fields: [categories_to_games.categoryId],
fields: [categories_to_games.category_id],
references: [categories.id]
}),
game: one(games, {
fields: [categories_to_games.gameId],
fields: [categories_to_games.game_id],
references: [games.id]
}),
}))
export const designers_to_games = mysqlTable("designers_to_games", {
designerId: varchar("designer_id", {
designer_id: varchar("designer_id", {
length: 255
}),
gameId: varchar("game_id", {
game_id: varchar("game_id", {
length: 255
}),
});
export const designers_to_games_relations = relations(designers_to_games, ({ one }) => ({
designer: one(designers, {
fields: [designers_to_games.designerId],
fields: [designers_to_games.designer_id],
references: [designers.id]
}),
game: one(games, {
fields: [designers_to_games.gameId],
fields: [designers_to_games.game_id],
references: [games.id]
}),
}))
export const mechanics_to_games = mysqlTable("mechanics_to_games", {
mechanicId: varchar("mechanic_id", {
mechanic_id: varchar("mechanic_id", {
length: 255
}),
gameId: varchar("game_id", {
game_id: varchar("game_id", {
length: 255
}),
});
export const mechanics_to_games_relations = relations(mechanics_to_games, ({ one }) => ({
mechanic: one(mechanics, {
fields: [mechanics_to_games.mechanicId],
fields: [mechanics_to_games.mechanic_id],
references: [mechanics.id]
}),
game: one(games, {
fields: [mechanics_to_games.gameId],
fields: [mechanics_to_games.game_id],
references: [games.id]
}),
}));
export const publishers_to_games = mysqlTable("publishers_to_games", {
publisherId: varchar("publisher_id", {
publisher_id: varchar("publisher_id", {
length: 255
}),
gameId: varchar("game_id", {
game_id: varchar("game_id", {
length: 255
}),
});
export const publishers_to_games_relations = relations(publishers_to_games, ({ one }) => ({
publisher: one(publishers, {
fields: [publishers_to_games.publisherId],
fields: [publishers_to_games.publisher_id],
references: [publishers.id]
}),
game: one(games, {
fields: [publishers_to_games.gameId],
fields: [publishers_to_games.game_id],
references: [games.id]
}),
}));

27
src/seed/insert.ts Normal file
View file

@ -0,0 +1,27 @@
import 'dotenv/config';
import { drizzle } from 'drizzle-orm/mysql2';
import { createConnection } from 'mysql2';
import * as schema from '../schema';
const connection = createConnection({
host: process.env.DATABASE_HOST,
port: 3306,
user: process.env.DATABASE_USER,
password: process.env.DATABASE_PASSWORD,
database: process.env.DATABASE_DB
});
const db = drizzle(connection, { schema: schema, mode: 'default' });
const existingRoles = await db.query.roles.findMany();
if (existingRoles.length === 0) {
await db.insert(schema.roles).values([{
name: 'admin'
}, {
name: 'user'
}]);
console.log('Roles created.');
} else {
console.log('Roles already exist. No action taken.');
}
await connection.end();

View file

@ -1,31 +1,21 @@
import prisma from "$lib/prisma";
import db from "$lib/drizzle";
import { eq } from "drizzle-orm";
import { roles, user_roles } from "../schema";
export async function add_user_to_role(user_id: string, role_name: string) {
// Find the role by its name
const role = await prisma.role.findUnique({
where: {
name: role_name
}
const role = await db.query.roles.findFirst({
where: eq(roles.name, role_name)
});
if (!role) {
if (!role || !role.id) {
throw new Error(`Role with name ${role_name} not found`);
}
// Create a UserRole entry linking the user and the role
const userRole = await prisma.userRole.create({
data: {
user: {
connect: {
id: user_id
}
},
role: {
connect: {
id: role.id
}
}
}
const userRole = await db.insert(user_roles).values({
user_id,
role_id: role.id
});
return userRole;