Files
cozsweet-frontend-nextjs/src/data/schemas/nullable-defaults.ts
T
admin d41b3c4473 refactor(schemas): extract nullable-default helpers to shared file
The three defensive Zod helpers (stringOrEmpty, numberOrZero,
booleanOrFalse) used by user.ts are general-purpose Zod utilities
that any schema may need — they're not user-specific. The original
inline declaration in user.ts had two downsides:

1. Any new schema (chat, auth, metrics, etc.) that needs the same
   'null | undefined → default scalar' pattern would have to
   duplicate the helper.

2. The long defensive-parse comment block (11 lines) lived inside
   user.ts and didn't explain the helpers' general purpose.

Move them to src/data/schemas/nullable-defaults.ts (top-level
sibling of auth/, chat/, metrics/, user/ subdirs) so any schema
can import them. Keep the original explanation verbatim at the
top of the new file.

Bundled in this commit:
- user.ts imports the helpers from the new file (drops 11 lines
  of comment + 3 const declarations)
- 3 auto-generated barrel index files regenerated by barrelsby
  to pick up the new exports (chat/, subscription/, stores/user/)
2026-06-17 12:05:09 +08:00

33 lines
1.1 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* Zod 默认值辅助器(处理 `null | undefined` → 标量默认)
*
* 防御性解析:后端对 Facebook / Apple 等 OAuth 用户可能返回 `null`(如 `email: null`),
* Zod 默认的 `.default("")` 只接受 `undefined`,遇到 `null` 会抛 ZodError → 登录静默失败。
* 用 `z.string().nullable().transform(v => v ?? "").default("")` 模式:
* - input 接受 `string | null | undefined`(保持 optional
* - output 永远是 `string`User 类的 `email: string` 声明不会破)
*
* 这是前端防御性解析(不要求后端修改)—— 和后端对齐更稳。
*/
import { z } from "zod";
/** `string | null | undefined` → `string`(默认空串) */
export const stringOrEmpty = z
.string()
.nullable()
.transform((v) => v ?? "")
.default("");
/** `number | null | undefined` → `number`(默认 0 */
export const numberOrZero = z
.number()
.nullable()
.transform((v) => v ?? 0)
.default(0);
/** `boolean | null | undefined` → `boolean`(默认 false */
export const booleanOrFalse = z
.boolean()
.nullable()
.transform((v) => v ?? false)
.default(false);