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/)
This commit is contained in:
@@ -0,0 +1,33 @@
|
||||
/**
|
||||
* 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);
|
||||
@@ -4,19 +4,11 @@
|
||||
*/
|
||||
import { z } from "zod";
|
||||
import { PersonalityTraitsSchema, PERSONALITY_TRAITS_DEFAULTS } from "./personality_traits";
|
||||
|
||||
/**
|
||||
* 防御性解析:后端对 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` 声明不会破)
|
||||
*
|
||||
* 这是前端防御性解析(不要求后端修改)—— 和后端对齐更稳。
|
||||
*/
|
||||
const stringOrEmpty = z.string().nullable().transform((v) => v ?? "").default("");
|
||||
const numberOrZero = z.number().nullable().transform((v) => v ?? 0).default(0);
|
||||
const booleanOrFalse = z.boolean().nullable().transform((v) => v ?? false).default(false);
|
||||
import {
|
||||
booleanOrFalse,
|
||||
numberOrZero,
|
||||
stringOrEmpty,
|
||||
} from "../nullable-defaults";
|
||||
|
||||
export const UserSchema = z.object({
|
||||
id: stringOrEmpty, // 兜底:理论 id 不会 null,但保持防御
|
||||
|
||||
Reference in New Issue
Block a user