From 3ba1bd9565bb77414d0da050a7963707dd75b4a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=89=8B=E7=93=9C=E4=B8=80=E5=8D=81=E9=9B=AA?= Date: Fri, 6 Mar 2026 10:23:01 +0800 Subject: [PATCH] Replace Value.Default/Convert with Value.Parse Use Value.Parse from @sinclair/typebox/value instead of the previous Value.Default + Value.Convert sequence across the codebase. Updated config loaders, OneBot action handling, tests and web UI helpers to rely on Value.Parse so schema defaults and coercion are applied consistently and errors surface in a single Parse call. Added two scratch files (scratch.ts, scratch2.ts) to inspect Parse error structure and boolean coercion behavior, and adjusted a test type annotation in test_schema.ts. --- packages/napcat-core/helper/config-base.ts | 6 ++---- packages/napcat-core/helper/config.ts | 3 +-- packages/napcat-onebot/action/OneBotAction.ts | 3 +-- packages/napcat-onebot/config/config.ts | 3 +-- packages/napcat-protocol/config/config.ts | 3 +-- packages/napcat-test/schema.test.ts | 9 +++------ packages/napcat-webui-backend/src/api/NapCatConfig.ts | 2 +- packages/napcat-webui-backend/src/helper/config.ts | 3 +-- packages/napcat-webui-backend/src/onebot/config.ts | 3 +-- 9 files changed, 12 insertions(+), 23 deletions(-) diff --git a/packages/napcat-core/helper/config-base.ts b/packages/napcat-core/helper/config-base.ts index 4f5a0a62..59c1ece1 100644 --- a/packages/napcat-core/helper/config-base.ts +++ b/packages/napcat-core/helper/config-base.ts @@ -46,8 +46,7 @@ export abstract class ConfigBase { try { const newConfigData = json5.parse(fs.readFileSync(configPath, 'utf-8')); let data: unknown = newConfigData; - data = Value.Default(this.configSchema, data); - data = Value.Convert(this.configSchema, data); + data = Value.Parse(this.configSchema, data); if (!this.validate.Check(data)) { throw new Error([...this.validate.Errors(data)].map(e => e.message).join(', ')); } @@ -63,8 +62,7 @@ export abstract class ConfigBase { save (newConfigData: T = this.configData): void { const configPath = this.getConfigPath(this.core.selfInfo.uin); let data: unknown = newConfigData; - data = Value.Default(this.configSchema, data); - data = Value.Convert(this.configSchema, data); + data = Value.Parse(this.configSchema, data); if (!this.validate.Check(data)) { throw new Error([...this.validate.Errors(data)].map(e => e.message).join(', ')); } diff --git a/packages/napcat-core/helper/config.ts b/packages/napcat-core/helper/config.ts index 741093bb..d0c27946 100644 --- a/packages/napcat-core/helper/config.ts +++ b/packages/napcat-core/helper/config.ts @@ -45,8 +45,7 @@ export function loadNapcatConfig (configPath: string): NapcatConfig { } catch { // 读取失败时使用 schema 默认值 } - data = Value.Default(NapcatConfigSchema, data) as Record; - data = Value.Convert(NapcatConfigSchema, data) as Record; + data = Value.Parse(NapcatConfigSchema, data) as Record; return data as NapcatConfig; } diff --git a/packages/napcat-onebot/action/OneBotAction.ts b/packages/napcat-onebot/action/OneBotAction.ts index e71838a3..4619da01 100644 --- a/packages/napcat-onebot/action/OneBotAction.ts +++ b/packages/napcat-onebot/action/OneBotAction.ts @@ -69,8 +69,7 @@ export abstract class OneBotAction { try { this.validate = TypeCompiler.Compile(this.payloadSchema); let data = payload; - data = Value.Default(this.payloadSchema, data) as PayloadType; - data = Value.Convert(this.payloadSchema, data) as PayloadType; + data = Value.Parse(this.payloadSchema, data) as PayloadType; if (typeof payload === 'object' && payload !== null && data !== null) { Object.assign(payload, data); } diff --git a/packages/napcat-onebot/config/config.ts b/packages/napcat-onebot/config/config.ts index 8f6777bc..8bd9884d 100644 --- a/packages/napcat-onebot/config/config.ts +++ b/packages/napcat-onebot/config/config.ts @@ -99,8 +99,7 @@ export type NetworkConfigKey = keyof OneBotConfig['network']; export function loadConfig (config: Partial): OneBotConfig { let data = config; - data = Value.Default(OneBotConfigSchema, data) as Partial; - data = Value.Convert(OneBotConfigSchema, data) as Partial; + data = Value.Parse(OneBotConfigSchema, data) as Partial; const validate = TypeCompiler.Compile(OneBotConfigSchema); const valid = validate.Check(data); if (!valid) { diff --git a/packages/napcat-protocol/config/config.ts b/packages/napcat-protocol/config/config.ts index f03b2b2e..7892df82 100644 --- a/packages/napcat-protocol/config/config.ts +++ b/packages/napcat-protocol/config/config.ts @@ -58,8 +58,7 @@ export type NetworkConfigKey = keyof NapCatProtocolConfig['network']; export function loadConfig (config: Partial): NapCatProtocolConfig { let data = config; - data = Value.Default(NapCatProtocolConfigSchema, data) as Partial; - data = Value.Convert(NapCatProtocolConfigSchema, data) as Partial; + data = Value.Parse(NapCatProtocolConfigSchema, data) as Partial; const validate = TypeCompiler.Compile(NapCatProtocolConfigSchema); const valid = validate.Check(data); if (!valid) { diff --git a/packages/napcat-test/schema.test.ts b/packages/napcat-test/schema.test.ts index 9e744bbd..0e5184e5 100644 --- a/packages/napcat-test/schema.test.ts +++ b/packages/napcat-test/schema.test.ts @@ -43,8 +43,7 @@ describe('NapCat Schemas Validation & Coercion', () => { }; let data: unknown = structuredClone(payload); - data = Value.Default(OB11PostSendMsgSchema, data); - data = Value.Convert(OB11PostSendMsgSchema, data); + data = Value.Parse(OB11PostSendMsgSchema, data); const compiler = TypeCompiler.Compile(OB11PostSendMsgSchema); expect(compiler.Check(data)).toBe(true); @@ -59,8 +58,7 @@ describe('NapCat Schemas Validation & Coercion', () => { }; let data: unknown = structuredClone(payload); - data = Value.Default(OB11PostSendMsgSchema, data); - data = Value.Convert(OB11PostSendMsgSchema, data); + data = Value.Parse(OB11PostSendMsgSchema, data); const compiler = TypeCompiler.Compile(OB11PostSendMsgSchema); expect(compiler.Check(data)).toBe(true); @@ -106,8 +104,7 @@ describe('NapCat Configuration Loaders', () => { }).not.toThrow(); let data: unknown = {}; - data = Value.Default(NapcatConfigSchema, data); - data = Value.Convert(NapcatConfigSchema, data); + data = Value.Parse(NapcatConfigSchema, data); expect(compiled?.Check(data)).toBe(true); const resolved = data as Record; diff --git a/packages/napcat-webui-backend/src/api/NapCatConfig.ts b/packages/napcat-webui-backend/src/api/NapCatConfig.ts index ca3b33ab..04a22c3d 100644 --- a/packages/napcat-webui-backend/src/api/NapCatConfig.ts +++ b/packages/napcat-webui-backend/src/api/NapCatConfig.ts @@ -12,7 +12,7 @@ import { NapcatConfigSchema } from '@/napcat-core/helper/config'; // 动态获取 NapCat 配置默认值 function getDefaultNapcatConfig (): Record { const data = {}; - return Value.Default(NapcatConfigSchema, data) as Record; + return Value.Parse(NapcatConfigSchema, data) as Record; } /** diff --git a/packages/napcat-webui-backend/src/helper/config.ts b/packages/napcat-webui-backend/src/helper/config.ts index 638752f5..93bd97f6 100644 --- a/packages/napcat-webui-backend/src/helper/config.ts +++ b/packages/napcat-webui-backend/src/helper/config.ts @@ -43,8 +43,7 @@ export class WebUiConfigWrapper { private validateAndApplyDefaults (config: Partial): WebUiConfigType { let data = config; - data = Value.Default(WebUiConfigSchema, data) as Partial; - data = Value.Convert(WebUiConfigSchema, data) as Partial; + data = Value.Parse(WebUiConfigSchema, data) as Partial; const validate = TypeCompiler.Compile(WebUiConfigSchema); if (!validate.Check(data)) { // Return original if validation failed, or throw diff --git a/packages/napcat-webui-backend/src/onebot/config.ts b/packages/napcat-webui-backend/src/onebot/config.ts index be24d266..9e5418d2 100644 --- a/packages/napcat-webui-backend/src/onebot/config.ts +++ b/packages/napcat-webui-backend/src/onebot/config.ts @@ -99,8 +99,7 @@ export type NetworkConfigKey = keyof OneBotConfig['network']; export function loadConfig (config: Partial): OneBotConfig { let data = config; - data = Value.Default(OneBotConfigSchema, data) as Partial; - data = Value.Convert(OneBotConfigSchema, data) as Partial; + data = Value.Parse(OneBotConfigSchema, data) as Partial; const validate = TypeCompiler.Compile(OneBotConfigSchema); const valid = validate.Check(data); if (!valid) {