···55if (DATABASE_URL === '') throw new Error('DATABASE_URL is not set')
6677export const db = drizzle(DATABASE_URL, { schema })
88+export type DatabaseConn = typeof db
···11+import { db } from '$server/db'
22+import { user } from '$server/db/schema.auth'
33+import { eq } from 'drizzle-orm'
44+55+function querySingle<T>(results: T[]) {
66+ return results.length === 0 ? null : results[0]
77+}
88+99+export async function getUserByUsername(username: string) {
1010+ return querySingle(await db.select().from(user).where(eq(user.username, username)).limit(1))
1111+}
1212+1313+export async function getUserByEmail(email: string) {
1414+ return querySingle(await db.select().from(user).where(eq(user.email, email)).limit(1))
1515+}
-7
app/src/lib/server/queries/getUserByUsername.ts
···11-import { db } from '$server/db'
22-import { user } from '$server/db/schema.auth'
33-import { eq } from 'drizzle-orm'
44-55-export async function getUserByUsername(username: string) {
66- return await db.select().from(user).where(eq(user.username, username)).limit(1)
77-}
···11<script lang="ts">
22import type { SvelteHTMLElements } from 'svelte/elements'
33import { cn, tv } from 'tailwind-variants'
44-import type { Proficiency } from '$lib/dnd/features'
44+import type { Proficiency } from '@starlight/types/dnd'
5566type SkillProficiencyRootElement = SvelteHTMLElements['div']
77type SkillProficiencyProps = SkillProficiencyRootElement & {
+2-2
app/src/lib/ui-patterns/skill-scores/types.ts
···11-import type { AbilityShort } from '@starlight/types/dnd'
11+import type { AbilityAbbr } from '@starlight/types/dnd'
2233export type ProficiencyKind = 'untrained' | 'halfProficient' | 'proficient' | 'expertise'
44···2828 proficiency: ProficiencyKind
2929}
30303131-export type AbilitySkill = Exclude<AbilityShort, 'CON'>
3131+export type AbilitySkill = Exclude<AbilityAbbr, 'CON'>
-1
app/src/routes/(auth)/signup/+page.server.ts
···11import { pageTitle } from '$lib/utils'
22import { auth } from '$server/auth'
33import { signUpSchema } from '$server/form/auth'
44-import { isEmailAvailable } from '$server/queries/isEmailAvailable'
54import { fail, redirect } from '@sveltejs/kit'
65import { message, superValidate } from 'sveltekit-superforms'
76import { zod4 } from 'sveltekit-superforms/adapters'
···11-import { ElementSchema, type Element } from '@starlight/types/hsr'
11+import { zElement, type Element } from '@starlight/types/hsr'
22import type { TokenStringLiteral } from './types'
3344type PredicateFn = (s: string) => boolean
···21212222// oxlint-disable-next-line typescript-eslint(no-explicit-any)
2323export function isElement(s: any): s is Element {
2424- return ElementSchema.safeParse(s).success
2424+ return zElement.safeParse(s).success
2525}
26262727// oxlint-disable-next-line typescript-eslint(no-explicit-any)
···33export * from './character-level'
44export * from './dice-roll'
55export * from './dice-range'
66+export * from './feature'
67export * from './spell-component'
88+export * from './spell-duration'
99+export * from './spell-range'
710export * from './spell-school'
1111+export * from './proficiency'
+4
packages/types/src/dnd/proficiency.ts
···11+import z from 'zod'
22+33+export const zProficiency = z.enum(['untrained', 'halfProficient', 'proficient', 'expertise'])
44+export type Proficiency = z.infer<typeof zProficiency>