@amritk/validation

中文文档
0.6.1发布于 2026/10/23MITTypeScriptES Module构建来源已验证近 30 天下载 5.9万

一个发电机表面超过Mjst的种类,验证器,胁迫器,修理器和剖析器.

中文使用文档
文档目录11 节
  1. 概览
  2. 安装
  3. 使用量
  4. 模式
  5. 离开Ajv
  6. API 密码
  7. generate(rootSchema, rootTypeName, options?)
  8. 输出布局
  9. 更快吗?
  10. 相关软件包
  11. 许可证

@ amritk/ 验证

一个发电机表面超过Mjst的种类,守卫,验证者,胁迫者,修理者和剖析器.


概览

@amritk/validation 是前门 由于一个JSON Schema(2020-12草案),它喷出 包含任意运行时间切入点的一组一致类型脚本文件 要求——从赤裸裸的型号,通过布林警卫和完整的出错报告,到 胁迫者,修理者 和全剖析器.

在下面,这是 两个 发电机引擎,不是一台:验证器、强制器和 修理机引擎,以及解析器和类型引擎。 他们分别作为 @amritk/generate-validators 财务报告和审定财务报表 @amritk/generate-parsers 直到此软件包 吸收了它们 保留它们都是故意的 他们真的不同 生成值模式的代码: 以 检查它,而且速度是它的多倍;验证员保存通行证 分开,因此可以报告什么是错的。 把它们折叠成一个发射器 这意味着放弃其中之一财产.

使得一个输出目录成为可能的是,两者都获得 TypeScript 类型 从同 @amritk/helpers/generate-type-definition,所以该类型被宣布 一次 输出中的每一个功能都涉及到它.


安装

bun add @amritk/validation

使用量

import { generate } from '@amritk/validation'
import type { JSONSchema } from 'json-schema-typed/draft-2020-12'

const schema: JSONSchema = {
  type: 'object',
  properties: {
    retries: { type: 'integer', minimum: 0, maximum: 10, default: 3 },
    name: { type: 'string', minLength: 3 },
  },
  required: ['retries', 'name'],
}

const files = await generate(schema, 'Config', {
  modes: ['types', 'guard', 'validate', 'coerce', 'repair', 'parse'],
})

for (const file of files) await Bun.write(`./generated/${file.filename}`, file.content)

模式

每种模式对 这会对我的文件造成多大影响 有人告诉我。它们会编曲: 要求多个功能,然后您会得到多个功能 一种类型, 每一个判断一个价值 它以同样的判断 validateX, (中文(简体) ), 因此,对于一个文件是否有效,没有两人可以持不同意见.

模式函数返回值告诉你停下来
types—— 说—— 说—— 说—— 说
guardisX(input): input is X—— 说布尔第一个问题
validatevalidateX(input)—— 说每个错误结束
checkcheckX(input)—— 说第一个错误第一个问题
coercecoerceX(input)被胁迫每个错误结束
repairrepairX(input)已修复维修 财务报告和审定财务报表 错误结束
parseparseX(input)已修复无从不失败
parseStrictparseX(input)给定的丢出第一个第一个问题

只验证、 快速失败或找到每个错误 . guard 失败的快取: 它在第一件事上停止错误, 没有构建错误对象, 它在无效时 投入比报告便宜得多. validate 是另一半: 每一个 错误,每个都带有 JSON 指针,关键词拒绝了该值,并且 关键词本身的值. 到达 guard 当答案是树枝 validate 当一个人类或API客户端必须被告知如何修复. check 坐着 双方: checkX 返回相同结果类型 validateX,仅持有 错误 validateX 我会先报到 再走不远了.

粗而修之,有误而有误也. coerceX 财务报告和审定财务报表 repairX 手执 返回该值 财务报告和审定财务报表 诊断; parseX 手只返回值和 从不失败。 强制移动一个已经正确但写入 类型错误; 修复还替换了一个值 : 不能被强迫, 并报告验证人自己的错误 作为修复.

也就是说 repairX 自动修正工具,而不是更严格的验证器。 它接受 文档 validateX 拒绝( 缺少所需的名称获得一个; 未知) enum 值成为第一个成员),只接受 valid 带空 repairs 给出准确的判决 coerceX 给。 一个空的 repairs 独自一人 不够:文件也无一可修复 valid: false。拒绝错误的配置,使用 coerceX交出一个固定的, 使用情况 repairX。 。 。 .

修复大型文件. repairX(input, options?) 选择 对象( 一个赤色的字符串仍然读作基础路径) :

选项默认它会做什么
path''贾森 每个报告路径的指针根植于
inPlacefalse在输入上指定和删除,而不是复制容器
coercetrue移动错误类型所写的scalar("5" 下级 integer修复前;关闭后,按计划价值修复并报告
refstrue后续实例 $refs 位于参考计划选择的位置(以下)
skipRefs[]指针前缀( e)'#/components/'其目标 根计划已经走; 仍然解决,不再走
onRef—— 说(value, path, typeId) => boolean | void,每个选择 $ref· ; false 别管它了
maxDepth512所报告位置的深度(maxDepth而不是走着
maxWork10_000_000在行走停止前参观的集装箱(maxWork(中文(简体) )
memofalse在每个计划上行走每个对象——用于带有共享或循环子树的内相图
finitefalse拒绝 NaN 和数报的无限
plainObjectsfalse只接受普通对象,并删除自己的对象 __proto__ 键

当计划中的每个定义都是从 type, (中文(简体) ), enum, (中文(简体) ), const, (中文(简体) ), properties, (中文(简体) ), required, (中文(简体) ), additionalProperties, (中文(简体) ), patternProperties, (中文(简体) ), items, (中文(简体) ), $ref, (中文(简体) ), if编号 :then编号 :else 财务报告和审定财务报表 allOf - 附加说明,和分级 例如 minLength, (中文(简体) ), pattern, (中文(简体) ), minimum, (中文(简体) ), anyOf, (中文(简体) ), oneOf 或者说 not, (中文(简体) ), 被问及验证人自己对位置的测试.. repairX 是一个 单次通行证:检查并修复每个位置的位置,一个 if 实值 根据实际值评估,将构建缺失的必需对象 与所需子女(在递归定义上达到极限深度) 错误直接进入一个阵列,只有当某物被构建时它们才会被构建路径 报告。 有效文件本身不会被复制。 在24 MB 上 捆绑的 OpenAPI 文档远远低于百毫秒(bun --conditions development scripts/bench-repair-walk.ts) (中文(简体) ). 其它关键字保存 验证和修复环路,这符合 path, (中文(简体) ), inPlace 财务报告和审定财务报表 coerce 财务报告和审定财务报表 扔出只步选项(skipRefs, (中文(简体) ), onRef, (中文(简体) ), maxDepth, (中文(简体) ), maxWork, (中文(简体) ), memo, (中文(简体) ), finite, (中文(简体) ), plainObjects而不是悄悄地放下警卫.

两份计划说明指导它. "x-repair": "drop" ——和a false 计划.. 删除一个失败位置, 而不是写入默认: 未知的密钥 additionalProperties: false,在 items: false页:1 滴入标记属性. "x-repair": "ref" 打开参考计划 实例 $ref 如下: 在写职位上 { if: { type: object, required: [$ref] }, then: Reference, else: T },则 $ref 在根文档中以 JSON 指针解决(拥有属性) 目标作为该位置的类型加以检查和修复 目标自身路径出错. 每个目标都走过一次 每一个类型,链 周期;未解决的周期报告为 unresolvedRef 从未创造过.

parseX 赞同 coerceX。 。 。 . 无论何处 coerceX 接受文档 强迫 parseX 返回非常相同的值——通过联盟,a allOf,一个 if页:1 $ref,包括复发——它只修复什么 coerceX 将 已经拒绝了。 一个差别测试针 比随机计数。 为了到那里, 一个自有树的定义 anyOf编号 :oneOf编号 :allOf编号 :if编号 :not 携带一个 准确测试( e)matchesX和强迫行走coerceXInput在它的前面 修补分解器 这样一个定义都包含着它们 A 类 没有梳理器的图案 完全照着它常做的来,一个和它们一起 发布更多 — 大约是大型 OpenAPI 文档的两倍的解析器代码 对每个定义的准确意见都花了多少时间 A 类 strict 或者说 stripUnknown 解析器没有 coerceX 同意,并且保持不变.

parse 财务报告和审定财务报表 parseStrict 在两个合同下是同一个函数名称,所以 要求两者都是错误而不是沉默的选择.

离开Ajv

coerceX 用于替换 Ajv 编译为 { allErrors: true, coerceTypes: true },每个计数都更好:答案、速度和 输入的安全.

它只接受计划所接受的. 任何东西 coerceX 手还原为 无效, validateX 刚刚接受, 和差别模糊 随机 计划 anyOf, (中文(简体) ), oneOf, (中文(简体) ), allOf 财务报告和审定财务报表 if编号 :then编号 :else 检查每个 被接受的文件反对Ajv 不胁迫。 如果两者不同,它 目的为:

  • null 从来没有被胁迫无论朝哪个方向,都是不同的 你会遇到的最多: 在一个真实的配置中, 几乎每个Ajv的案件 已接受,并 coerceX 没有。 Ajv 读到 null 作为 "", (中文(简体) ), 0 或者说 false (单位:千美元) 字符串、数字或布尔字段,并读出 nullA级 null 通常表示"没有设定",而将其变成一个真正的值会抹去这一点. 给 转到写入的验证器,验证器拒绝.

    切换前, 请检查您的呼叫者对一个被拒绝的文档做了什么 。 如果一个 将拒绝视为缺席(返回) undefined,倒回到默认, 单人 null 在一个街区的深处 让整个街区消失 错误。 Ajv的胁迫曾经隐藏这一点. 要么让计划说 null 实值 允许( e)type: ['string', 'null']),丢出 nulls 在验证前, 或有 调用者显示错误而不是丢弃值.

  • 只有干净的数字成为数字. " ", (中文(简体) ), " 1 ", (中文(简体) ), "0x10", (中文(简体) ), "Infinity" 财务报告和审定财务报表 "1." 拒绝。 Ajv把它们变成 0, (中文(简体) ), 1, (中文(简体) ), 16一个值 JSON 无法坚守,而且 1。 。 。 . "007" 财务报告和审定财务报表 "1e3" 仍然被胁迫.

  • 在工会中,一个已经匹配的分会获胜. Ajv 胁迫 首个会取值的分支. 鉴于 anyOf: [{ type: 'string' }, { const: false }],Ajv转弯 false 输入 "false"· ; coerceX 保留 false。 。 。 . 当没有分支匹配成文时,每个分支会以自己的方式强制值 并且只有在接受结果的每一个分支都同意的情况下,才会得到结果. 两种不同的读取让验证者单独报告值,所以 分行的顺序是永远不变的.

  • 一个失败的分支 留下什么. Ajv 强迫到位 尝试每个分支,所以在 oneOf: [{ type: 'integer' }, { type: 'string' }] 转了 0 输入 "0" 在尝试字符串分支时,看到两个匹配 拒绝有效文件. coerceX 接受 0 原文如上.

  • 强制令每个应用者. 斯卡拉人被胁迫通过 $ref, (中文(简体) ), allOf (每个子母依次), if编号 :then编号 :else (转入) then 当 数值匹配 if, (中文(简体) ), else 和连结的分枝.

它从来不触及输入. Ajv 强迫设置, 所以一个打电话者保持它的 文档必须先复制它. coerceX 返回共享的新值 所有它没有触及, 或输入本身 当不需要强迫.

投入必须生存的地方更快. 首先反对Ajv克隆,所以 两者都留下打电话者的证件(bun run bench:validators:coerce,或 bench:validators:coerce:node:

计划运行时间有效输入需要强制不能强迫
小( 4个字段)阿宝5.4× (中文(简体) )1.7× (中文(简体) )1.5× (中文(简体) )
小( 4个字段)节点9.9× (简体中文)2.1× (中文(简体) )2.2× (中文(简体) )
顺序( 已识别 + 数组)阿宝11× (中文(简体) )1.6× (中文(简体) )1.9× (中文(简体) )
顺序( 已识别 + 数组)节点8.4× (中文(简体) )1.8× (中文(简体) )2.2× (中文(简体) )
平发阿宝19× (中文(简体) )1.4× (中文(简体) )3.0× (中文(简体) )
平发节点36× (中文(简体) )1.6× (中文(简体) )3.1× (中文(简体) )
配置(通过 $ref(中文(简体) )阿宝7.2× (中文(简体) )1.7× (中文(简体) )3.7× (中文(简体) )
配置(通过 $ref(中文(简体) )节点5.2× (中文(简体) )1.5× (中文(简体) )4.6× (中文(简体) )

每个细胞的速度是多少倍 coerceX 比Ajv在同一输入, 每台发动机在自己的过程中定时(Bun 1.3.11,Node 22.22,Linux x64). A 类 有效文件是常见的,也是最大的空白: coerceX 用这个回答 isX 直接把输入拿回来,不要走. isX 正在建设 无事——没有错误,没有路径——在第一次失败时止步,回答: $ref 与目标自己的 isX; 它召唤 validateX 只是为了一个计划 折为常. 在有效输入时, Ajv 重写任何内容, 因此它可以 并且没有克隆人的时间; coerceX 还在前面的这些 计划,用1.2-3.3xx, 但不是每个: 在一个庞大的 工会重的文件中 呼叫者让Ajv胁迫到位,Ajv可以轻而易举地领先. 这个 上面的空白是克隆人,所以它是真实的 在那里呼叫者不能让Ajv 变异其入. 配置大小写是形状 --coerce 已存在, 用于: 每个可强制的平板 在工会内部 $ref,每个工会分支都通过 指定函数,而不是每个调用时建立的关闭.

错误不同 一种方式值得知道 如果你的关键诊断 path + keyword + params页:1 additionalProperties 出错点 地点 未申报的密钥 (单位:千美元)/readme/example_requestsAjv 指向对象的地方 拿着/readme) (中文(简体) ). params.additionalProperty 将两个键都命名.


API 密码

generate(rootSchema, rootTypeName, options?)

参数类型默认说明
rootSchemaJSONSchema—— 说取根相会. $ref 财务报告和审定财务报表 $dynamicRef 递归解决.
rootTypeNamestring—— 说根类型的名称(例如:. "Config") (中文(简体) ).
options.modesMode[]['types', 'guard', 'validate']哪个切入点可以发射. 默认为只读;任何重写文档的都是选入.
options.typeSuffixstring''每页后缀 $ref- 来源类型名称。 根名无相.
options.schemasRecord<string, unknown>—— 说您已经装入的文档, 由 URI 键入 a $ref 叫他们名字.
options.unknownKeys'count-keys' | 'count-enumerable''count-keys'闭合物体的快道如何证明它没有未申报的密钥.
options.formats'all' | string[]—— 说字符串 formats 验证符执行。 未落叶 format 一个注释.
options.branchErrorsbooleanfalse解释失败 anyOf 编号 : oneOf 和它明显意义上的分枝, 或者它接受的类型 当没有分枝取值的种类.
options.stripUnknownbooleanfalse构建每个解析结果 .
options.readonlybooleanfalse释放 readonly 类型成员.
options.caseInsensitivebooleanfalse将错误的字符串规范到一个 enum 成员它匹配.
options.helpersMode'package' | 'embedded''package'解析器的一半得到运行时间帮助的地方.
options.helpersImportPrefixstring'./'释放的帮助导入描述符的前缀, 何时 helpersMode 实值 'embedded'。 。 。 .
options.extensionsSchemaExtensions—— 说Schema 扩展,传递到剖析器的一半.
options.importExt'js' | 'ts''js'每次发射的相对导入的扩展 . 'ts' 释放上盘路径, 因此输出在节点类型剥离下运行, 没有构建步骤 .
options.logWarningsbooleanfalse打印解析器半导体对策略的警告, 例如它无法执行的关键字 .

回返情况: Promise<GeneratedFile[]> 地点 GeneratedFile = { filename: string; content: string }。 。 。 .

套件还出口 ALL_MODES (每个模式但 parseStrict来电的 和类型 Mode, (中文(简体) ), GenerateOptions, (中文(简体) ), GeneratedFile 财务报告和审定财务报表 ImportExtension。 。 。 .


输出布局

config.ts         the type, plus isX / validateX / coerceX / repairX
config.parse.ts   parseX, importing the type from ./config.js
validation-result.ts   the shared error and result types, and the runtime helpers
formats.ts        the format checks, only when `formats` enforces one the schema names
_helpers/         the parser's runtime helpers, only when `helpersMode` is 'embedded'
index.ts          a barrel over all of it

该类型生活在 config.ts 因为这是读者寻找的地方。 这个 解析器半个移动到 config.parse.ts 因为这两个生成器都命名了文件 在计划之后,他们中的一个必须让路。 只有一个 export type Config 在输出时,无论您要求的模式组合 测试套房通过汇编图案,在一系列图案中声称 结果是在这个repo自己的旗帜下.

请求不使用验证器模式, 且没有冲突, 所以解析器 既保留它自己的文件名, 也保留它已经编写过的文件类型, 也不保留 validation-result.ts 完全被释放出来 —— 仅一个解析的建筑没有 可导入其17 KiB 错误类型和运行时间帮助器.


更快吗?

比它包装的两个引擎? 不,它不应该是。 (Than Ajv,是的——见 离开Ajv. ) (中文(简体) ). 询问此软件包为一个模式, 它会发出 准确 字节 拥有该模式的引擎释放出——测试套接字针 模式,通过指纹,而不是读取输出。 无法使用同一代码 运行速度不同 所以这里没有运行时间 也没有 已经做了. bun run bench 测量它反正,三角洲徘徊在两边 运行之间为零,即进程级别差异在出现时的外观 无根本差别.

改变的只是冷淡的一面,只有你所希望的方向:

(两个引擎都直接)之后
整个矩阵的代码2.9 毫秒(秒)2.7 毫秒(秒)
已发射字节46.0基贝45.8 基贝
文件第7条6个
声明 Order2个1个
每模式代码源—— 说等于或略低
每模式字节—— 说不变

重要的是中间的最后一行 达到每个模式 曾经的意思是自己运行发电机 和运送两棵树一棵 计划,包括两个同类型的声明——结构 可互换,但两件事要保持步入正轨. 现在有一个.



许可证

麻省理工学院

版本与发布记录

@amritk/validation 共发布 9 个版本,首次发布于 2026/09/22;过去 12 个月发布了 9 个版本。最新版本附带 npm provenance 构建来源证明,可追溯到公开的 CI 构建记录。

版本发布日期距今
0.6.1latest2026/10/2314 天前
0.6.02026/10/2116 天前
0.5.02026/10/1027 天前
0.4.12026/10/0730 天前
0.4.02026/09/261 个月前
0.3.22026/09/241 个月前

关于 @amritk/validation 的常见问题

@amritk/validation 是什么?

一个发电机表面超过Mjst的种类,验证器,胁迫器,修理器和剖析器.

如何安装 @amritk/validation?

在项目目录运行 npm install @amritk/validation,或使用 pnpm add / yarn add / bun add。

@amritk/validation 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@amritk/validation 支持 ESM 还是 CommonJS?

以 ES Module 形式发布,推荐使用 import 引入。在 CommonJS 项目中,Node.js 20.19+ / 22.12+ 可以直接 require() 不含顶层 await 的 ES Module,更早的版本需要改用动态 import()。

@amritk/validation 需要什么版本的 Node.js?

package.json 的 engines 字段要求 Node.js >=20。版本不符时 npm 默认只给出警告,开启 engine-strict 后会拒绝安装。

@amritk/validation 可以商用吗?

@amritk/validation 使用 MIT 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

@amritk/validation 的下载量有多少?

根据 npm 官方下载统计,@amritk/validation 在 2026/10/06 – 2026/11/04 这 30 天内被下载 59,097 次,日均约 1,970 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@amritk/validation 还在维护吗?

最新版本 0.6.1 发布于 2026/10/23(14 天前);至今共发布 9 个版本,其中过去 12 个月发布了 9 个;首次发布于 2026/09/22。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。