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.
This commit is contained in:
手瓜一十雪
2026-03-06 10:23:01 +08:00
parent 8aec6aec1b
commit 3ba1bd9565
9 changed files with 12 additions and 23 deletions
+2 -4
View File
@@ -46,8 +46,7 @@ export abstract class ConfigBase<T> {
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<T> {
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(', '));
}
+1 -2
View File
@@ -45,8 +45,7 @@ export function loadNapcatConfig (configPath: string): NapcatConfig {
} catch {
// 读取失败时使用 schema 默认值
}
data = Value.Default(NapcatConfigSchema, data) as Record<string, unknown>;
data = Value.Convert(NapcatConfigSchema, data) as Record<string, unknown>;
data = Value.Parse(NapcatConfigSchema, data) as Record<string, unknown>;
return data as NapcatConfig;
}
@@ -69,8 +69,7 @@ export abstract class OneBotAction<PayloadType, ReturnDataType> {
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);
}
+1 -2
View File
@@ -99,8 +99,7 @@ export type NetworkConfigKey = keyof OneBotConfig['network'];
export function loadConfig (config: Partial<OneBotConfig>): OneBotConfig {
let data = config;
data = Value.Default(OneBotConfigSchema, data) as Partial<OneBotConfig>;
data = Value.Convert(OneBotConfigSchema, data) as Partial<OneBotConfig>;
data = Value.Parse(OneBotConfigSchema, data) as Partial<OneBotConfig>;
const validate = TypeCompiler.Compile(OneBotConfigSchema);
const valid = validate.Check(data);
if (!valid) {
+1 -2
View File
@@ -58,8 +58,7 @@ export type NetworkConfigKey = keyof NapCatProtocolConfig['network'];
export function loadConfig (config: Partial<NapCatProtocolConfig>): NapCatProtocolConfig {
let data = config;
data = Value.Default(NapCatProtocolConfigSchema, data) as Partial<NapCatProtocolConfig>;
data = Value.Convert(NapCatProtocolConfigSchema, data) as Partial<NapCatProtocolConfig>;
data = Value.Parse(NapCatProtocolConfigSchema, data) as Partial<NapCatProtocolConfig>;
const validate = TypeCompiler.Compile(NapCatProtocolConfigSchema);
const valid = validate.Check(data);
if (!valid) {
+3 -6
View File
@@ -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<string, unknown>;
@@ -12,7 +12,7 @@ import { NapcatConfigSchema } from '@/napcat-core/helper/config';
// 动态获取 NapCat 配置默认值
function getDefaultNapcatConfig (): Record<string, unknown> {
const data = {};
return Value.Default(NapcatConfigSchema, data) as Record<string, unknown>;
return Value.Parse(NapcatConfigSchema, data) as Record<string, unknown>;
}
/**
@@ -43,8 +43,7 @@ export class WebUiConfigWrapper {
private validateAndApplyDefaults (config: Partial<WebUiConfigType>): WebUiConfigType {
let data = config;
data = Value.Default(WebUiConfigSchema, data) as Partial<WebUiConfigType>;
data = Value.Convert(WebUiConfigSchema, data) as Partial<WebUiConfigType>;
data = Value.Parse(WebUiConfigSchema, data) as Partial<WebUiConfigType>;
const validate = TypeCompiler.Compile(WebUiConfigSchema);
if (!validate.Check(data)) {
// Return original if validation failed, or throw
@@ -99,8 +99,7 @@ export type NetworkConfigKey = keyof OneBotConfig['network'];
export function loadConfig (config: Partial<OneBotConfig>): OneBotConfig {
let data = config;
data = Value.Default(OneBotConfigSchema, data) as Partial<OneBotConfig>;
data = Value.Convert(OneBotConfigSchema, data) as Partial<OneBotConfig>;
data = Value.Parse(OneBotConfigSchema, data) as Partial<OneBotConfig>;
const validate = TypeCompiler.Compile(OneBotConfigSchema);
const valid = validate.Check(data);
if (!valid) {