将next-auth替换为better-auth
This commit is contained in:
43
src/lib/actions/auth.ts
Normal file
43
src/lib/actions/auth.ts
Normal file
@@ -0,0 +1,43 @@
|
||||
"use server";
|
||||
|
||||
import { auth } from "@/auth";
|
||||
import { headers } from "next/headers";
|
||||
import { redirect } from "next/navigation";
|
||||
|
||||
export async function signUpAction(formData: FormData) {
|
||||
const email = formData.get("email") as string;
|
||||
const name = formData.get("name") as string;
|
||||
const password = formData.get("password") as string;
|
||||
|
||||
await auth.api.signUpEmail({
|
||||
body: {
|
||||
email,
|
||||
password,
|
||||
name
|
||||
}
|
||||
});
|
||||
|
||||
redirect("/");
|
||||
}
|
||||
|
||||
export async function signInAction(formData: FormData) {
|
||||
const email = formData.get("email") as string;
|
||||
const password = formData.get("password") as string;
|
||||
|
||||
await auth.api.signInEmail({
|
||||
body: {
|
||||
email,
|
||||
password,
|
||||
}
|
||||
});
|
||||
|
||||
redirect("/");
|
||||
}
|
||||
|
||||
export async function signOutAction() {
|
||||
await auth.api.signOut({
|
||||
headers: await headers()
|
||||
});
|
||||
|
||||
redirect("/login");
|
||||
}
|
||||
5
src/lib/auth-client.ts
Normal file
5
src/lib/auth-client.ts
Normal file
@@ -0,0 +1,5 @@
|
||||
import { createAuthClient } from "better-auth/react";
|
||||
|
||||
export const authClient = createAuthClient({
|
||||
baseURL: process.env.BETTER_AUTH_URL as string
|
||||
});
|
||||
@@ -16,7 +16,7 @@ export const getLocalStorageOperator = <T extends z.ZodTypeAny>(
|
||||
try {
|
||||
const item = globalThis.localStorage.getItem(key);
|
||||
|
||||
if (!item) return [];
|
||||
if (!item) return [] as z.infer<T>;
|
||||
|
||||
const rawData = JSON.parse(item) as z.infer<T>;
|
||||
const result = schema.safeParse(rawData);
|
||||
@@ -28,11 +28,11 @@ export const getLocalStorageOperator = <T extends z.ZodTypeAny>(
|
||||
"Invalid data structure in localStorage:",
|
||||
result.error,
|
||||
);
|
||||
return [];
|
||||
return [] as z.infer<T>;
|
||||
}
|
||||
} catch (e) {
|
||||
console.error(`Failed to parse ${key} data:`, e);
|
||||
return [];
|
||||
return [] as z.infer<T>;
|
||||
}
|
||||
},
|
||||
set: (data: z.infer<T>) => {
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
import { FolderCreateInput, FolderUpdateInput } from "../../../../generated/prisma/models";
|
||||
import prisma from "../../db";
|
||||
|
||||
export async function getFoldersByUserId(userId: number) {
|
||||
export async function getFoldersByUserId(userId: string) {
|
||||
const folders = await prisma.folder.findMany({
|
||||
where: {
|
||||
userId: userId,
|
||||
@@ -23,7 +23,7 @@ export async function renameFolderById(id: number, newName: string) {
|
||||
});
|
||||
}
|
||||
|
||||
export async function getFoldersWithTotalPairsByUserId(userId: number) {
|
||||
export async function getFoldersWithTotalPairsByUserId(userId: string) {
|
||||
const folders = await prisma.folder.findMany({
|
||||
where: { userId },
|
||||
include: {
|
||||
127
src/lib/utils.ts
127
src/lib/utils.ts
@@ -20,3 +20,130 @@ export function shallowEqual<T extends object>(obj1: T, obj2: T): boolean {
|
||||
|
||||
return true;
|
||||
}
|
||||
export class SeededRandom {
|
||||
private seed: number;
|
||||
private readonly m: number = 0x80000000; // 2^31
|
||||
private readonly a: number = 1103515245;
|
||||
private readonly c: number = 12345;
|
||||
|
||||
constructor(seed?: number) {
|
||||
this.seed = seed || Date.now();
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成0-1之间的随机数
|
||||
* @returns 0到1之间的随机浮点数
|
||||
*/
|
||||
next(): number {
|
||||
this.seed = (this.a * this.seed + this.c) % this.m;
|
||||
return this.seed / (this.m - 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成指定范围的随机整数
|
||||
* @param min 最小值(包含)
|
||||
* @param max 最大值(包含)
|
||||
* @returns [min, max] 范围内的随机整数
|
||||
*/
|
||||
nextInt(min: number, max: number): number {
|
||||
if (min > max) {
|
||||
throw new Error('min must be less than or equal to max');
|
||||
}
|
||||
return Math.floor(this.next() * (max - min + 1)) + min;
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成指定范围的随机浮点数
|
||||
* @param min 最小值(包含)
|
||||
* @param max 最大值(不包含)
|
||||
* @returns [min, max) 范围内的随机浮点数
|
||||
*/
|
||||
nextFloat(min: number, max: number): number {
|
||||
if (min >= max) {
|
||||
throw new Error('min must be less than max');
|
||||
}
|
||||
return this.next() * (max - min) + min;
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成固定长度的随机数序列
|
||||
* @param length 序列长度
|
||||
* @param min 最小值
|
||||
* @param max 最大值
|
||||
* @param type 生成类型:'integer' 或 'float'
|
||||
* @returns 随机数数组
|
||||
*/
|
||||
generateSequence(
|
||||
length: number,
|
||||
min: number = 0,
|
||||
max: number = 1,
|
||||
type: 'integer' | 'float' = 'integer'
|
||||
): number[] {
|
||||
const sequence: number[] = [];
|
||||
|
||||
for (let i = 0; i < length; i++) {
|
||||
if (type === 'integer') {
|
||||
sequence.push(this.nextInt(min, max));
|
||||
} else {
|
||||
sequence.push(this.nextFloat(min, max));
|
||||
}
|
||||
}
|
||||
|
||||
return sequence;
|
||||
}
|
||||
|
||||
/**
|
||||
* 重置种子
|
||||
* @param newSeed 新的种子值
|
||||
*/
|
||||
reset(newSeed?: number): void {
|
||||
this.seed = newSeed || Date.now();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前种子值
|
||||
* @returns 当前种子
|
||||
*/
|
||||
getSeed(): number {
|
||||
return this.seed;
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成随机布尔值
|
||||
* @param probability 为 true 的概率,默认 0.5
|
||||
* @returns 随机布尔值
|
||||
*/
|
||||
nextBoolean(probability: number = 0.5): boolean {
|
||||
if (probability < 0 || probability > 1) {
|
||||
throw new Error('probability must be between 0 and 1');
|
||||
}
|
||||
return this.next() < probability;
|
||||
}
|
||||
|
||||
/**
|
||||
* 从数组中随机选择元素
|
||||
* @param array 源数组
|
||||
* @returns 随机选择的元素
|
||||
*/
|
||||
choice<T>(array: T[]): T {
|
||||
if (array.length === 0) {
|
||||
throw new Error('array cannot be empty');
|
||||
}
|
||||
const index = this.nextInt(0, array.length - 1);
|
||||
return array[index];
|
||||
}
|
||||
|
||||
/**
|
||||
* 打乱数组(Fisher-Yates 洗牌算法)
|
||||
* @param array 要打乱的数组
|
||||
* @returns 打乱后的新数组
|
||||
*/
|
||||
shuffle<T>(array: T[]): T[] {
|
||||
const shuffled = [...array];
|
||||
for (let i = shuffled.length - 1; i > 0; i--) {
|
||||
const j = this.nextInt(0, i);
|
||||
[shuffled[i], shuffled[j]] = [shuffled[j], shuffled[i]];
|
||||
}
|
||||
return shuffled;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user