183 lines
5.0 KiB
TypeScript
183 lines
5.0 KiB
TypeScript
import { relations, sql } from "drizzle-orm";
|
|
import { pgTableCreator, index, primaryKey } from "drizzle-orm/pg-core";
|
|
import { type AdapterAccount } from "next-auth/adapters";
|
|
import { createId } from "@paralleldrive/cuid2";
|
|
/**
|
|
* This is an example of how to use the multi-project schema feature of Drizzle ORM. Use the same
|
|
* database instance for multiple projects.
|
|
*
|
|
* @see https://orm.drizzle.team/docs/goodies#multi-project-schema
|
|
*/
|
|
export const createTable = pgTableCreator((name) => `game-master_${name}`);
|
|
|
|
const defaultTimeStamp = (name: string, d: any) =>
|
|
d
|
|
.timestamp(name, { withTimezone: true })
|
|
.default(sql`CURRENT_TIMESTAMP`)
|
|
.notNull();
|
|
|
|
export const lobbies = createTable("lobby", (d) => ({
|
|
id: d
|
|
.varchar({ length: 255 })
|
|
.primaryKey()
|
|
.notNull()
|
|
.$defaultFn(() => createId()),
|
|
name: d.varchar({ length: 255 }).notNull(),
|
|
maxPlayers: d.integer().notNull().default(0),
|
|
createdById: d
|
|
.varchar({ length: 255 })
|
|
.notNull()
|
|
.references(() => players.id, { onDelete: "cascade" }),
|
|
createdAt: defaultTimeStamp("created_at", d),
|
|
updatedAt: d
|
|
.timestamp("updated_at", { withTimezone: true })
|
|
.$onUpdate(() => new Date()),
|
|
}));
|
|
|
|
export type Lobby = typeof lobbies.$inferSelect & {
|
|
members?: LobbyMember[];
|
|
leader?: Player;
|
|
};
|
|
|
|
export const lobbyRelations = relations(lobbies, ({ many, one }) => ({
|
|
leader: one(players, {
|
|
fields: [lobbies.createdById],
|
|
references: [players.id],
|
|
}),
|
|
members: many(lobbyMembers),
|
|
}));
|
|
|
|
export const lobbyMembers = createTable(
|
|
"lobby_member",
|
|
(d) => ({
|
|
playerId: d
|
|
.varchar({ length: 255 })
|
|
.notNull()
|
|
.references(() => players.id, { onDelete: "cascade" }),
|
|
lobbyId: d
|
|
.varchar({ length: 255 })
|
|
.notNull()
|
|
.references(() => lobbies.id, { onDelete: "cascade" }),
|
|
joinedAt: defaultTimeStamp("joined_at", d),
|
|
role: d
|
|
.varchar({ length: 255 })
|
|
.notNull()
|
|
.$type<LobbyMemberRole>()
|
|
.default("player"),
|
|
isReady: d.boolean().notNull(),
|
|
}),
|
|
(t) => [primaryKey({ columns: [t.playerId] })],
|
|
);
|
|
|
|
export type LobbyMember = typeof lobbyMembers.$inferSelect & {
|
|
player?: Player;
|
|
};
|
|
|
|
export const lobbyMembersRelations = relations(lobbyMembers, ({ one }) => ({
|
|
lobby: one(lobbies, {
|
|
fields: [lobbyMembers.lobbyId],
|
|
references: [lobbies.id],
|
|
}),
|
|
player: one(players, {
|
|
fields: [lobbyMembers.playerId],
|
|
references: [players.id],
|
|
}),
|
|
}));
|
|
|
|
export const players = createTable(
|
|
"player",
|
|
(d) => ({
|
|
id: d
|
|
.varchar({ length: 255 })
|
|
.notNull()
|
|
.references(() => users.id, { onDelete: "cascade" }),
|
|
displayName: d.varchar({ length: 255 }),
|
|
avatar: d.varchar({ length: 255 }),
|
|
joinedAt: defaultTimeStamp("joined_at", d),
|
|
}),
|
|
(t) => [
|
|
primaryKey({
|
|
columns: [t.id],
|
|
}),
|
|
],
|
|
);
|
|
export type Player = typeof players.$inferSelect;
|
|
|
|
export const users = createTable("user", (d) => ({
|
|
id: d
|
|
.varchar({ length: 255 })
|
|
.notNull()
|
|
.primaryKey()
|
|
.$defaultFn(() => createId()),
|
|
name: d.varchar({ length: 255 }),
|
|
email: d.varchar({ length: 255 }).notNull(),
|
|
emailVerified: d
|
|
.timestamp("email_verified", {
|
|
mode: "date",
|
|
withTimezone: true,
|
|
})
|
|
.default(sql`CURRENT_TIMESTAMP`),
|
|
}));
|
|
|
|
export const usersRelations = relations(users, ({ many }) => ({
|
|
accounts: many(accounts),
|
|
sessions: many(sessions),
|
|
}));
|
|
|
|
export const accounts = createTable(
|
|
"account",
|
|
(d) => ({
|
|
userId: d
|
|
.varchar({ length: 255 })
|
|
.notNull()
|
|
.references(() => users.id, { onDelete: "cascade" }),
|
|
type: d.varchar({ length: 255 }).$type<AdapterAccount["type"]>().notNull(),
|
|
provider: d.varchar({ length: 255 }).notNull(),
|
|
providerAccountId: d.varchar({ length: 255 }).notNull(),
|
|
refresh_token: d.text(),
|
|
access_token: d.text(),
|
|
expires_at: d.integer(),
|
|
token_type: d.varchar({ length: 255 }),
|
|
scope: d.varchar({ length: 255 }),
|
|
id_token: d.text(),
|
|
session_state: d.varchar({ length: 255 }),
|
|
}),
|
|
(t) => [
|
|
primaryKey({
|
|
columns: [t.provider, t.providerAccountId],
|
|
}),
|
|
index("account_user_id_idx").on(t.userId),
|
|
],
|
|
);
|
|
|
|
export const accountsRelations = relations(accounts, ({ one }) => ({
|
|
user: one(users, { fields: [accounts.userId], references: [users.id] }),
|
|
}));
|
|
|
|
export const sessions = createTable(
|
|
"session",
|
|
(d) => ({
|
|
sessionToken: d.varchar({ length: 255 }).notNull().primaryKey(),
|
|
userId: d
|
|
.varchar({ length: 255 })
|
|
.notNull()
|
|
.references(() => users.id, { onDelete: "cascade" }),
|
|
expires: d.timestamp({ mode: "date" }).notNull(),
|
|
}),
|
|
(t) => [index("session_user_id_idx").on(t.userId)],
|
|
);
|
|
|
|
export const sessionsRelations = relations(sessions, ({ one }) => ({
|
|
user: one(users, { fields: [sessions.userId], references: [users.id] }),
|
|
}));
|
|
|
|
export const verificationTokens = createTable(
|
|
"verification_token",
|
|
(d) => ({
|
|
identifier: d.varchar({ length: 255 }).notNull(),
|
|
token: d.varchar({ length: 255 }).notNull(),
|
|
expires: d.timestamp({ mode: "date" }).notNull(),
|
|
}),
|
|
(t) => [primaryKey({ columns: [t.identifier, t.token] })],
|
|
);
|