@ agentuity/schema (英语)
用于Agentuity平台的轻量级,型式安全的Schema验证库. 支持 标准计划 规格.
特征
- QQ 类型安全计划验证
- 零运行时间依赖的轻量级
- 符合标准Schema v1
- 在浏览器和服务器环境中工作(Node.js, Bun)
- 简单而流利的API
安装
bun add @agentuity/schema
使用量
import { s, ValidationError } from '@agentuity/schema';
// Define a schema
const userSchema = s.object({
name: s.string(),
age: s.number(),
email: s.string(),
isActive: s.boolean(),
});
// Extract the inferred type (like zod's z.infer)
type User = s.infer<typeof userSchema>;
// Parse with validation (throws on error)
try {
const user: User = userSchema.parse({
name: 'John',
age: 30,
email: '[email protected]',
isActive: true,
});
console.log('Valid user:', user);
} catch (error) {
if (error instanceof ValidationError) {
console.error('Validation failed:', error.message);
console.error('Issues:', error.issues);
}
}
// Safe parse (returns result object)
const result = userSchema.safeParse(data);
if (result.success) {
console.log('Valid data:', result.data);
} else {
console.error('Validation failed:', result.error.message);
}
// Optional and nullable
const optionalSchema = s.object({
name: s.string(),
nickname: s.optional(s.string()),
age: s.nullable(s.number()),
});
// Arrays
const stringArraySchema = s.array(s.string());
const userArraySchema = s.array(userSchema);
// Unions
const statusSchema = s.union(s.literal('active'), s.literal('inactive'), s.literal('pending'));
// Enums (shorthand for union of literals)
const roleSchema = s.enum(['admin', 'user', 'guest']);
const prioritySchema = s.enum([1, 2, 3, 4, 5]);
// Literal values
const roleSchema = s.literal('admin');
API 密码
基本类型
s.string()- 字符串验证s.number()- 数量验证s.boolean()- 布尔验证s.null()- 无效验证s.undefined()- 未定义的验证
复杂类型
s.object(shape)- 有打字属性的物件验证s.array(schema)- 有输入元素的矩阵验证
工具类型
s.optional(schema)- 做一个可以选择的策略s.nullable(schema)- 使计划无效s.union(...schemas)- 多种计划的联合s.literal(value)- 精确值匹配s.enum([...values])- Enum类型(文字结合)
// Enum (shorthand for union of literals)
const roleSchema = s.enum(['admin', 'user', 'guest']);
const role = roleSchema.parse('admin'); // 'admin'
// Equivalent to:
const roleSchema2 = s.union(s.literal('admin'), s.literal('user'), s.literal('guest'));
胁迫
自动将值转换为正确的类型( 如 zod.coerce) :
s.coerce.string()- 强迫使用字符串String(value)s.coerce.number()- 强迫使用数字Number(value)s.coerce.boolean()- 强迫布尔使用Boolean(value)s.coerce.date()- 使用强迫至今new Date(value)
// Parse form data where everything is a string
const formSchema = s.object({
name: s.string(),
age: s.coerce.number(), // "30" → 30
newsletter: s.coerce.boolean(), // "on" → true
createdAt: s.coerce.date(), // "2025-01-01" → Date
});
const formData = formSchema.parse({
name: 'John',
age: '30', // String coerced to number
newsletter: 'on', // String coerced to boolean
createdAt: '2025-01-01', // String coerced to Date
});
// Query parameters (always strings)
const querySchema = s.object({
page: s.coerce.number(),
limit: s.coerce.number(),
});
const params = querySchema.parse({
page: '1', // "1" → 1
limit: '20', // "20" → 20
});
文档
所有计划都支持a .describe(description: string) 添加文档的方法:
const userSchema = s
.object({
id: s.string().describe('The unique identifier'),
name: s.string().describe('The user full name'),
age: s.number().describe('Age in years'),
})
.describe('User profile');
JSON Schema 转换
将计划转换为 JSON Schema 格式 :
const schema = s.object({
name: s.string().describe('User name'),
age: s.number().describe('User age'),
});
const jsonSchema = s.toJSONSchema(schema);
// {
// "type": "object",
// "properties": {
// "name": { "type": "string", "description": "User name" },
// "age": { "type": "number", "description": "User age" }
// },
// "required": ["name", "age"]
// }
将 JSON Schema 转换为计划 :
const jsonSchema = {
type: 'object',
properties: {
firstName: {
type: 'string',
description: 'First name',
},
lastName: {
type: 'string',
description: 'Last name',
},
age: {
type: 'number',
description: 'Age',
},
hobbies: {
type: 'array',
items: { type: 'string' },
},
},
required: ['firstName', 'lastName', 'age', 'hobbies'],
};
const schema = s.fromJSONSchema(jsonSchema);
// Now you can use schema for validation
const result = schema['~standard'].validate(data);
支持圆通转换 :
const original = s.object({ name: s.string() });
const json = s.toJSONSchema(original);
const reconstructed = s.fromJSONSchema(json);
// reconstructed works exactly like original
分析与验证
.parse(value) - 抛出验证错误
try {
const user = userSchema.parse(data);
// user is typed and validated
} catch (error) {
if (error instanceof ValidationError) {
console.error(error.message); // Human-readable error
console.error(error.issues); // Detailed issue array with paths
}
}
.safeParse(value) - 返回结果对象
const result = userSchema.safeParse(data);
if (result.success) {
console.log(result.data); // Typed data
} else {
console.error(result.error); // ValidationError instance
}
类型推论
使用 s.infer 从图中提取类型( 如 Zod ) z.infer:
import { s } from '@agentuity/schema';
const Player = s.object({
username: s.string(),
xp: s.number(),
inventory: s.array(s.string()),
});
// Extract the inferred type (like zod's z.infer)
type Player = s.infer<typeof Player>;
// { username: string; xp: number; inventory: string[] }
const player: Player = Player.parse(data);
您也可以导入 Infer 如果选中的话, 直接键入 :
import { s, type Infer } from '@agentuity/schema';
type Player = Infer<typeof Player>; // Alternative syntax
处理错误
校验错误结构化, 包括失败字段的路径 :
const profileSchema = s.object({
user: s.object({
name: s.string(),
age: s.number(),
}),
});
try {
profileSchema.parse({ user: { name: 'John', age: 'thirty' } });
} catch (error) {
if (error instanceof ValidationError) {
console.log(error.message);
// "[user.age]: Expected number, got string"
console.log(error.issues);
// [{ message: "Expected number, got string", path: ["user", "age"] }]
}
}
标准计划支持
所有计划执行标准Schema v1接口:
interface StandardSchemaV1<Input, Output> {
readonly '~standard': {
readonly version: 1;
readonly vendor: string;
readonly validate: (value: unknown) => Result<Output>;
readonly types?: { input: Input; output: Output };
};
}
许可证
阿帕奇 - 2.0