mcpField
C
custom-format-validators

custom-format-validators

github.com/zaggino开发349172 次安装5 天前更新
代码仓库

关于 custom-format-validators

面向开发者的 z-schema 技能,介绍如何配置内置及自定义 JSON Schema 格式验证器。内容涵盖同步与异步注册、不同草案的格式行为及验证器管理。

主要功能

  1. 01内置 JSON Schema 格式
  2. 02注册同步和异步格式
  3. 03全局及实例级格式
  4. 04配置各草案的格式断言
  5. 05列出和注销格式

适用场景

  1. 01验证应用专用字符串格式
  2. 02根据外部数据检查值
  3. 03禁用内置格式检查
  4. 04查看已注册的格式

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/zaggino/z-schema --skill custom-format-validators

安装后在 Claude Code 中输入/custom-format-validators确认已加载。

详细介绍

z-schema 中的自定义格式验证器

JSON Schema 的 format 除了基本类型检查外,还会约束字符串(或其他)值。z-schema 内置了验证器,并支持注册自定义验证器,包括同步和异步验证器。

内置格式

z-schema 为所有标准 JSON Schema 格式提供了验证器:

格式验证内容
dateRFC 3339 完整日期(2024-01-15)
date-timeRFC 3339 日期时间(2024-01-15T09:30:00Z)
timeRFC 3339 时间(09:30:00Z)
emailRFC 5321 电子邮件地址
idn-email国际化电子邮件
hostnameRFC 1123 主机名
host-namehostname 的别名
idn-hostname国际化主机名
ipv4IPv4 地址
ipv6IPv6 地址
uriRFC 3986 URI
strict-uri经过严格验证的 RFC 3986 URI(也是 strictUris: true 时替换 uri 的格式)
uri-referenceURI 或相对引用
uri-templateRFC 6570 URI 模板(完整 ABNF,Errata 6937)
iri国际化 URI
iri-reference国际化 URI 引用
json-pointerRFC 6901 JSON Pointer
relative-json-pointer相对 JSON Pointer
regexECMA-262 正则表达式
durationISO 8601 时长
uuidRFC 4122 UUID

注册同步格式

格式验证器是一个函数 (input: unknown) => boolean。有效时返回 true,无效时返回 false。对于不适用的类型(例如,输入不是字符串),请返回 true——z-schema 会对任何值类型调用格式验证器。

全局注册(所有实例共享)
import ZSchema from 'z-schema';

ZSchema.registerFormat('postal-code', (value) => {
  if (typeof value !== 'string') return true; // skip non-strings
  return /^\d{5}(-\d{4})?$/.test(value);
});
实例级注册
const validator = ZSchema.create();
validator.registerFormat('postal-code', (value) => {
  if (typeof value !== 'string') return true;
  return /^\d{5}(-\d{4})?$/.test(value);
});

实例格式会覆盖同名的全局格式。

创建时通过选项注册
const validator = ZSchema.create({
  customFormats: {
    'postal-code': (value) => typeof value === 'string' && /^\d{5}(-\d{4})?$/.test(value),
    'always-valid': () => true,
    'disable-email': null, // disable the built-in email validator
  },
});

传入 null 可禁用内置格式或全局注册的格式。

注册异步格式

返回 Promise<boolean>。验证器必须使用 { async: true } 创建。

const validator = ZSchema.create({ async: true });

validator.registerFormat('user-exists', async (value) => {
  if (typeof value !== 'number') return true;
  const user = await db.findUser(value);
  return user != null;
});

// Validate (returns Promise)
try {
  await validator.validate(data, schema);
} catch (err) {
  console.log(err.details);
}
超时

异步格式验证器会在 asyncTimeout 毫秒后超时(默认值:2000)。对于耗时较长的操作,请增大此值:

const validator = ZSchema.create({
  async: true,
  asyncTimeout: 10000, // 10 seconds
});

验证器超时会产生 ASYNC_TIMEOUT 错误。

不同草案中的格式断言行为

JSON Schema 规范在较新草案中更改了 format 的工作方式:

草案默认行为启用 formatAssertions: true 时
draft-04/06/07始终断言(不匹配时失败)始终断言
draft-2019-09始终断言(z-schema 默认行为)仅注解,除非启用了词汇
draft-2020-12始终断言(z-schema 默认行为)仅注解,除非启用了词汇

z-schema 默认将 formatAssertions: null(旧版行为——始终断言)。若要遵循现代草案中与词汇相关的规范行为:

const validator = ZSchema.create({ formatAssertions: true });

若要禁用所有格式断言(仅注解):

const validator = ZSchema.create({ formatAssertions: false });

未知格式

默认情况下,z-schema 会针对 draft-04/06/07 中无法识别的格式名称报告 UNKNOWN_FORMAT。现代草案(2019-09、2020-12)则始终静默忽略未知格式。

若要在较旧的草案中抑制未知格式错误:

const validator = ZSchema.create({ ignoreUnknownFormats: true });

注销格式

// Global
ZSchema.unregisterFormat('postal-code');

// Instance
validator.unregisterFormat('postal-code');

列出格式

// List globally registered custom formats
const customFormats = ZSchema.getRegisteredFormats();

// List all supported formats (built-in + custom) on an instance
const allFormats = validator.getSupportedFormats();

// Check if a specific format is supported
const supported = validator.isFormatSupported('postal-code');

实际应用模式

电话号码验证
ZSchema.registerFormat('phone', (value) => {
  if (typeof value !== 'string') return true;
  return /^\+?[1-9]\d{1,14}$/.test(value); // E.164 format
});
ISO 8601 日期(严格)
ZSchema.registerFormat('iso-date', (value) => {
  if (typeof value !== 'string') return true;
  const d = new Date(value);
  return !isNaN(d.getTime()) && value === d.toISOString().split('T')[0];
});
业务规则:值来自外部列表
const validator = ZSchema.create({ async: true });

validator.registerFormat('valid-country', async (value) => {
  if (typeof value !== 'string') return true;
  const countries = await fetchValidCountries();
  return countries.includes(value.toUpperCase());
});
副作用:预填默认值

格式验证器可以修改对象(请谨慎使用):

ZSchema.registerFormat('fill-defaults', (obj) => {
  if (typeof obj === 'object' && obj !== null) {
    (obj as Record<string, unknown>).createdAt ??= new Date().toISOString();
  }
  return true;
});

Schema 用法

{
  "type": "object",
  "properties": {
    "phone": { "type": "string", "format": "phone" },
    "country": { "type": "string", "format": "valid-country" },
    "zipCode": { "type": "string", "format": "postal-code" }
  }
}

评论

支持 Markdown