/** * 掩码哨兵辅助(Phase 3 Task 3) * * 契约对齐后端 app/platform/routes/config_routes.py: * - 密钥字段 GET 响应:库中非空 → `__SET__`(MASKED 哨兵);空/缺省 → 原样 * - PUT 提交:密钥字段传 `__SET__` = 保持库值(后端还原,哨兵字面量绝不落库) * * 本模块提供哨兵 ↔ 表单语义的纯函数转换,配置中心(Task 7)与 * 平台设置(Task 9)的凭据表单消费: * - secretPlaceholder:GET 掩码值 → 输入框占位文案("已设置,输入新值覆盖") * - secretToSubmit:用户输入 + 原掩码状态 → 提交值(未改动回哨兵保持库值) */ /** 后端密钥掩码哨兵(config_routes.MASKED) */ export const MASKED_SENTINEL = '__SET__' /** 表单侧"已设置"展示语义 */ export const MASKED_DISPLAY = '已设置' /** 值是否为掩码哨兵 */ export function isMaskedSentinel(value: unknown): value is typeof MASKED_SENTINEL { return value === MASKED_SENTINEL } /** * GET 掩码值 → 表单占位文案 * * @param maskedValue 后端下发的密钥字段值(哨兵=已设置;空串/null/undefined=未设置) */ export function secretPlaceholder(maskedValue: string | null | undefined): string { return isMaskedSentinel(maskedValue) ? '已设置,输入新值覆盖' : '未设置,输入新值' } /** * 表单输入 → 提交值 * * @param input 用户输入(空串=未改动/清空) * @param originalMasked GET 时的掩码值(哨兵=库中已有值;否则=未设置) * @returns 提交值:输入非空 → 新值;输入空且已设置 → 哨兵(保持库值);输入空且未设置 → 空串 */ export function secretToSubmit(input: string, originalMasked: string | null | undefined): string { if (input !== '') return input return isMaskedSentinel(originalMasked) ? MASKED_SENTINEL : '' }