47 lines
1.4 KiB
TypeScript
47 lines
1.4 KiB
TypeScript
"use server";
|
|
|
|
import { cookies } from "next/headers";
|
|
|
|
type RequestCookies = Awaited<ReturnType<typeof cookies>>;
|
|
|
|
const decodeValue = (value?: string) => {
|
|
if (!value) return value;
|
|
return value.startsWith("base64-") ? Buffer.from(value.slice(7), "base64").toString("utf8") : value;
|
|
};
|
|
|
|
const encodeValue = (value: string) => {
|
|
if (!value) return value;
|
|
// Next.js 会自动 base64 编码,我们只需处理已有 base64 前缀的情况
|
|
if (value.startsWith("base64-")) {
|
|
return value;
|
|
}
|
|
return value;
|
|
};
|
|
|
|
const wrapCookies = (store: RequestCookies) => {
|
|
return {
|
|
get: (name: string) => {
|
|
const cookie = store.get(name);
|
|
if (!cookie) return cookie;
|
|
return { ...cookie, value: decodeValue(cookie.value) };
|
|
},
|
|
getAll: (...args: Parameters<RequestCookies["getAll"]>) =>
|
|
store.getAll(...args).map((cookie) => ({ ...cookie, value: decodeValue(cookie.value) })),
|
|
set: (...args: Parameters<RequestCookies["set"]>) => {
|
|
const [name, value, options] = args;
|
|
if (typeof value === "string") {
|
|
store.set(name, encodeValue(value), options);
|
|
} else {
|
|
store.set(name, value);
|
|
}
|
|
},
|
|
delete: (...args: Parameters<RequestCookies["delete"]>) => store.delete(...args),
|
|
has: (...args: Parameters<RequestCookies["has"]>) => store.has(...args),
|
|
};
|
|
};
|
|
|
|
export const getDecodedCookies = async () => {
|
|
const store = await cookies();
|
|
return wrapCookies(store) as RequestCookies;
|
|
};
|