@amritk/adapters

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

从外部库(TypeBox, Zod, Avro,...)中将 schema 转换为 JSON Schema 为 mjst.

中文使用文档
文档目录17 节
  1. 概览
  2. 安装
  3. 同伴依赖关系
  4. 使用量
  5. 类型框
  6. 佐德语Name
  7. 维利博特
  8. 效果
  9. 阿芙罗
  10. 这个 x-mjst 扩展
  11. 名义品牌
  12. 丢失构造并扩展警告
  13. 洞穴
  14. 扩展类型( TypeBox)
  15. 效果编码 有线 任职人数
  16. 相关软件包
  17. 许可证

@amritk/ 适应器

将TypeBox,Zod,Valibot,Effect,或Apache Avro中编写的计划转换为Draft 2020-12 JSON Schema——单输入会塑造mjst生成器的理解.

status  version  license  JSON Schema  node  vibe coded


概览

mjst的发电机——解析器,验证器,类型,docs,测试数据——全部取用 一个 a 2020-12 JSON Schema草案。 这个软件包让你在别的地方写出这个计划。 它能转换一个 类型框, (中文(简体) ), 佐德语Name, (中文(简体) ), 维利博特,或 效果 计划——或 阿帕奇·阿夫罗 .avsc 然后将结果直接交给发电机.

这个 mjst CLI 电线在后面 --input <format> 旗帜( n)typebox, (中文(简体) ), zod, (中文(简体) ), valibot, (中文(简体) ), effect, (中文(简体) ), avro) (中文(简体) ). 对于图书馆格式 --schema jS/TS的路径点 模块 出口一个计划而不是一个 .json 文件; 用于 avro 它指着 .avsc 文档本身,它被读作数据,从未被导入。 也可以直接调用适配器——每个适配器都是一种小而纯的功能.

图书馆适配器依靠源代码库自己的JSON Schema出口商(Zod 4's) toJSONSchema, (中文(简体) ), @valibot/to-json-schema,效果为 JSONSchema.make; TypeBox schemas 在运行时已经是JSON Schema了),然后使结果正常化. Avro是例外——它没有这种出口商,因此在这里完全实行转换(不需要依赖,因为Avro schema本身就是JSON). 正常化 :

  • 将方言标记剥去( r)$schema发电机不需要,
  • 重写构造 JSON Schema 无法表达——运行时间 Date, (中文(简体) ), bigint ——进入共享 x-mjst 提示发电机读取,以及
  • 警告和继续 因此一个没有支持的字段从不阻挡生成(通过) { strict: true } 来做一个损失的构造抛出.

安装

npm install --save-dev @amritk/adapters
# or: pnpm add -D / yarn add -D / bun add -d

同伴依赖关系

源代码库是 可选同伴依赖关系 – 每个适配器在运行时动态导入其库,所以您只安装实际使用的库. TypeBox 根本不需要对等依赖(它的chemas是普通的 JSON Schema 对象;适配器从不导入 TypeBox ).

输入格式安装
typebox(无-见下文)
zodzod@>=4, (中文(简体) ), 或者说 zod@3 加号 zod-to-json-schema@>=3
valibotvalibot@>=1 财务报告和审定财务报表 @valibot/to-json-schema@>=1
effecteffect@>=3
avro(没什么——一个Avro计划是普通的JSON)

如果缺少所需的软件包,适配器会抛出一个清晰,可操作的错误来命名要安装什么——例如. "Zod适配器要求要么'zod' v4+(对于它的原生到JSONSchema),要么"zod-to-json-schema"包(Zod 3的倒置). 也没有找到——在你的项目中安装一个"

[注] TypeBox 适配器故意这样做 没有 导入 TypeBox 。 其作用纯粹是用在 schema 的平面对象外形上(通过一个 JSON 的回转),因此 TypeBox 保持了您的 schema 模块的依赖性,从来没有mjst.


使用量

每个适配器是一个函数 (source: unknown, options?: { strict?: boolean }) => Promise<JSONSchema> (TypeBox 和 Avro 适配器是同步的,但通过 getAdapter 具有相同签名的统一性 await 当你通过它. strict: true (Zod, Valibot, Avro)。 通过子路径导入它们 :

import { avroToJsonSchema } from '@amritk/adapters/avro-to-json-schema'
import { typeboxToJsonSchema } from '@amritk/adapters/typebox-to-json-schema'
import { zodToJsonSchema } from '@amritk/adapters/zod-to-json-schema'
import { valibotToJsonSchema } from '@amritk/adapters/valibot-to-json-schema'
import { effectToJsonSchema } from '@amritk/adapters/effect-to-json-schema'

或按名称解决一个问题——匹配CLI的 --input 旗帜 :

import { getAdapter } from '@amritk/adapters/get-adapter'

const adapter = getAdapter('zod') // throws for an unimplemented / unknown format
const jsonSchema = await adapter.toJSONSchema(mySchema)

适配器接收 已装入 schema值(一个导入的模块导出),而不是一个文件路径——加载模块是呼叫者的工作,它使适配器保持了纯度和微不足道的测试.

类型框

import { Type } from '@sinclair/typebox'
import { typeboxToJsonSchema } from '@amritk/adapters/typebox-to-json-schema'

const User = Type.Object({
  id: Type.Integer(),
  name: Type.String({ minLength: 1 }),
  createdAt: Type.Date(),
})

const jsonSchema = await typeboxToJsonSchema(User)

一个TypeBox schema在运行时已经是一个JSON Schema对象——它只是携带了不可假设的符号键(Kind, (中文(简体) ), Optional,.)用于TypeBox自己的机械. JSON 将这些(和任何 undefined 值),留下了干净的平地方案. 适配器然后重写类型框 扩展类型 输入 x-mjst 暗示.

佐德语Name

[大 Zod 4更喜欢. 适配器依赖Zod的本土 toJSONSchema,在Zod 4之前不存在(见 src/zod-to-json-schema.ts) (中文(简体) ). 在Zod 3上,它回到可选的 zod-to-json-schema 软件包 —— 与 Zod 3 一起安装 —— 并且如果没有可用的软件包, 你就会得到一个明显的错误而不是一个沉默的错失.

import { z } from 'zod'
import { zodToJsonSchema } from '@amritk/adapters/zod-to-json-schema'

const User = z.object({
  id: z.number().int(),
  name: z.string().min(1),
  createdAt: z.date(),
})

const jsonSchema = await zodToJsonSchema(User)

z.date() 财务报告和审定财务报表 z.bigint() 没有 JSON Schema 代理, 并且会让 Zod 的出口商丢出; 适配器会用 unrepresentable: 'any' 并使用 override 钩去救他们 x-mjst 暗示。 它还沿途修理了两道Zod 4克:它恢复了固定拖带上被捆绑的长度(Zod发出一个赤裸的,没有捆绑的) prefixItems),它合并了一个对象 相交点 佐德发泄为不满足 allOf 联 合 国 additionalProperties: false 分支变成一个单独的封闭对象.

维利博特

import * as v from 'valibot'
import { valibotToJsonSchema } from '@amritk/adapters/valibot-to-json-schema'

const User = v.object({
  id: v.pipe(v.number(), v.integer()),
  name: v.pipe(v.string(), v.minLength(1)),
  createdAt: v.date(),
})

const jsonSchema = await valibotToJsonSchema(User)

需要两者 valibot 财务报告和审定财务报表 @valibot/to-json-schema就像Zod一样, v.date() 编号 : v.bigint() 被救进 x-mjst 通过转换器提示 overrideSchema 钩. 转换器运行在 errorMode: 'ignore' (2020-12年目标草案),因此任何其他无支持的构造都降解为开放式计划;mjst收集并分批报告 [mjst] Valibot adapter: … 警告,不要扔东西.

效果

import { Schema } from 'effect'
import { effectToJsonSchema } from '@amritk/adapters/effect-to-json-schema'

const User = Schema.Struct({
  id: Schema.Number,
  name: Schema.String,
  createdAt: Schema.DateFromSelf, // runtime Date — see the caveat below
})

const jsonSchema = await effectToJsonSchema(User)

要求数 effect@>=3A级 Schema.BigIntFromSelf 编号 : Schema.DateFromSelf 树上的任何地方 ——顶层或嵌入于结构、阵列或结合中——被救入 x-mjst 提示; 每个子树 JSONSchema.make 接受从它逐字取出. 读取 编码代表说明 在选择之间之前 Schema.Date 财务报告和审定财务报表 Schema.DateFromSelf - 它改变你是否得到一个 string 或运行时间 Date。 。 。 .

阿芙罗

import { readFile } from 'node:fs/promises'
import { avroToJsonSchema } from '@amritk/adapters/avro-to-json-schema'

const avro = JSON.parse(await readFile('user.avsc', 'utf-8'))
const jsonSchema = avroToJsonSchema(avro)

没有对等依赖性:一个Avro schema是JSON文档,因此适配器直接读取. 每个被命名的类型—— record, (中文(简体) ), enum, (中文(简体) ), fixed - 在其定义下界定一次 全名 内 $defs 参考文献 $ref 随处可见,所以递归型保持有限度 com.example.User 生成一个 ComExampleUser 类型而不是每个使用站点重复的内线形状.

选择编码其实是指

Avro 是一个二进制格式,带有 单独指定 JSON编码,而"JSON for this schema"的两种读取,则真正有分歧. 适配器让你选择:

encoding说明工会bytes带 a 的字段 default
'json' (默认)您的应用程序代码查看的对象简单 anyOf· ; ["null", T] 崩溃为无效 T基础64 字符串选项
'avro-json'spec's JSON编码——什么是旅行 application/vnd.apache.avro+json用分支的全名标记的单键包装对象密码点/ 字节字符串所需经费
// Generating TypeScript types and parsers? You want the idiomatic shape.
avroToJsonSchema(avro)

// Validating an AsyncAPI examples.payload? You want the wire shape.
avroToJsonSchema(avro, { encoding: 'avro-json' })

这个 default 栏不是结构选择。 阿芙罗有 无可选字段 编码中包含每个已申报的字段,a default 仅在计程解析时查阅,读取对一 不同 计划 这么说吧 'avro-json' 标出每个需要的字段, 因为那是线上的东西,同时 'json' 将默认字段视为可选的,因为这就是处理的形状应用程序代码.

默认 价值 因为Avro不是用编码来写的 Avro宣称工会违约 赤线 工会价值 第一个 分支,所以在 'avro-json' 它被包裹,以匹配数据使用的分支标记(null 保持赤裸,在两个 "null" 财务报告和审定财务报表 {"type": "null"} )),拼写. 下 'json' a字节默认在错误的字母表中——Avro写作"latin-1",平面形状为"base64"——所以它被抛出而不是被误译. 这两种规则都适用于任何深度:在记录、阵列或地图默认内嵌入的结合值都以同样的方式被标记,默认内任何地方的字节值都会降低整个情况,因为半翻译的默认比无更糟糕。 这比错误的说明更重要,因为 @amritk/validation 胁迫 default。 。 。 .

故意不修炼的东西

两幅地图看起来像是遗漏,不是:

  • A 类 long 没有界限. 其范围为±2^63,没有JSON数字能够代表——一个已声明的 maximum 将转至2^63, 既错误又无法到达。 (单位:千美元) A 类 long 过去2^53将无法生存 JSON.parse 不论计划如何, 一个 int 实值 绑定,因为±2^31 降落在正双.
  • 日期和时间逻辑类型保持整数. Avro 编码 timestamp-millis 作为 long 在它的JSON编码 和二进制一样多,所以 format: 'date-time' 将描述一个从未到达的字符串。 仅 uuid 将基础类型真正缩小到 { type: 'string', format: 'uuid' }。 。 。 .

decimal 财务报告和审定财务报表 duration 承载结构 JSON Schema 无法表达(精度/分级;以12字节表示3个未署名的32位英寸),因此它们会降解为基型并被通过通常的拓宽警告报告. 一个未识别 logicalType avro谱系要求的、悄悄地进入其基准类型——正如在它没有界定的基数上申报的基数一样(Avro谱系)decimal 编号 record因此,它被忽略了,而不是报告. aliases 和外地 order 描述如何 两个 策略在解析期间相关,在单一文档的形状上没有位置,因此被忽略. 名称 为: 校正: 正写成 $defs 键和 $ref 指着它,所以一个非法的名字会默默地产生不同的,破碎的JSON指针而不是错误.


这个 x-mjst 扩展

JSON Schema 的核心词汇没有运行时间的关键词 Date页:1 bigint或者名义上的品牌 mjst携带这些作为供应商延伸, x-mjst,使生成器读取出正确的类型脚本和运行时间检查。 同一对象带有文档设置 @amritk/generate-markdown (单位:千美元)hidden,所有东西在 markdown发电机忽略了它

x-mjst 提示生成处理
{ instanceOf: 'Date' }类型为 Date,已选中 instanceof
{ primitive: 'bigint' }类型为 bigint,已选中 typeof
{ brand: 'UserId' }类型为 Base & { readonly __brand: 'UserId' }; 验证为 Base 运行时间

instanceOf 编号 : primitive 由适配器发射(适配器地图) 不变 提示由图书馆编写,所以 Date 生成在任何地方都相同的数据). brand 实值 手写 ——没有适配器在今天发出——而且纯粹是类型级别:运行时间值仍然验证为它的基础JSON Schema类型,但生成的TypeScript类型与一个独特的品牌相交,所以是一个 UserId 无法与平原相替换 string。见 名义品牌 见下文.

每个图书馆 Date 编号 : bigint 资料来源:

Date → instanceOf: 'Date'bigint → primitive: 'bigint'
类型框Type.Date()Type.BigInt()
佐德语Namez.date()z.bigint()
维利博特v.date()v.bigint()
效果Schema.DateFromSelfSchema.BigIntFromSelf

名义品牌

{ brand: 'Name' } 给一个计划 名义 (品牌)类型不作更改 它接受在运行时间。 附加到任何计划和生成的类型脚本 与唯一标记相交的碱基类型 :

{ "type": "string", "format": "uuid", "x-mjst": { "brand": "UserId" } }
// generated type: (string & { readonly __brand: 'UserId' })
// runtime check:  still just "a string" (plus the uuid format check)

因为品牌只生活在类型中,两个有不同品牌的ID不是 互相分配,所以你不能通过一个 OrderId 其中a UserId 实值 - 同样的保护 Drizzle's .$type<UserId>() 现在给一列 由计划携带。 名称必须匹配 ^[\w$ -]+$ (它嵌入于一个 生成输出中的字符串字元; 一个不安全的名称被忽略 .

两种模式都以相同的方式尊重品牌:

  • 页:1 代码生成器 (单位:千美元)@amritk/validation (等等) 把它放进去 .d.ts· ;
  • 类型级别 FromSchema 读它,所以任何东西 从活的图文中打出——最出名的是 @amritk/api 路径 params 编号 : query 编号 : body - 把牌子放在你的处理器里 宣布一个 路由参数 { type: 'string', 'x-mjst': { brand: 'UserId' } } 制造 params.id (单位:千美元) UserId,不是一个平地 string,端对端(处理器) 财务报告和审定财务报表 页:1 生成的打字客户端). 写入内含图案或 as const 所以,字义 生存的推断.

品牌形状是 { readonly __brand: 'UserId' }如果你想成为 不变 键入为 Drizzle-branded id, 定义该 id 到此形状( 或标记 Drizzle专栏匹配; mjst 校正一个会场, 它不重复 Drizzle 的 拥有品牌符号.


丢失构造并扩展警告

一些来源类型没有忠实的JSON Schema代表,而且 没有 被救进一个 x-mjst 指点 适配器不但没有辜负整个转换,反而拓宽了这些,以"接受任何东西"({}()——这意味着 生成类型比源计划宽 - 并发出一个 [mjst] 警告,所以扩张是可见的,绝不沉默。 每个库的行为 :

  • 赵德. 这些Zod类型成为"接受任何东西": symbol, (中文(简体) ), nan, (中文(简体) ), void, (中文(简体) ), undefined, (中文(简体) ), never, (中文(简体) ), map, (中文(简体) ), set, (中文(简体) ), promise, (中文(简体) ), function。当出现时,适配器记录,例如: "[妙. Zod适配器:功能,符号没有完整的JSON Schema代表并被拓宽. 生成的型号将比"Zod schema"更宽"
  • 维利博特. 转换器运行在 errorMode: 'ignore': 不支持的构造会降解为开放的 schema, 适配器会从转换器的覆盖钩中收集每一个这样的构造, 并将其报告在一个 [mjst] Valibot adapter: … 警告与Zod的形状相同.
  • 类型框. 扩展 type 没有映射的字符串(见下文)没有变化,但有警告: "[mjst] TypeBox type"..."没有JSON Schema或x-mjst映射;没有更改"
  • 阿维罗. 只有 decimal 财务报告和审定财务报表 duration 逻辑类型扩大,每个缩小到其基类型: "[妙. Avro适配器:十进制逻辑类型(精度/尺度)没有完整的JSON Schema代表并被拓宽. 生成的型号将比"阿夫罗"(Avro schema)更宽" Avro地图上的其他所有内容都准确无误,或者被直接拒绝——重复名称,提及未定义名称,或者不正确 record编号 :enum编号 :fixed 抛出而不是转换成错误的东西.
  • 影响. 效果没有扩大——它更严格. JSONSchema.make 扔在任何无法代表的类型, 无论它坐在哪里。 适配器在结构上捕捉并下降,重建容器(结构、阵列、结合、精炼.),并拯救每一个 BigIntFromSelf 编号 : DateFromSelf 叶子会伸入 x-mjst 指点 只有一朵叶子,它不能拯救它 symbol,说)是致命的,然后它扔出一个可操作的信息而不是Effect的不透明信息:将类型替换为JSON的可代表信息,或者添加一个 jsonSchema 该领域的说明.

如果在您的计划上有任何这些问题, 则选择一个具有代表性的替代方案( 如将一组模型作为数组) , 或者添加库本身的 JSON Schema 注释 .


洞穴

扩展类型( TypeBox)

类型框释放出非标准 type 用于运行时类的字符串(例如:. Type.Date() 生产 { type: 'Date' }) (中文(简体) ). 适配器识别出7个核心JSON Schema类型,并处理其他任何东西 type 作为类型框的槽 扩展类型。它理解的扩展类型图目前覆盖 仅限 Date 财务报告和审定财务报表 bigint (见 src/typebox-to-json-schema.ts:11-19:

扩展类型框 type绘制到
Datex-mjst instanceOf: 'Date'
bigintx-mjst primitive: 'bigint'

任何其他扩展类型(Uint8Array, (中文(简体) ), Symbol, (中文(简体) ), Undefined,.)与上面的正在扩大的警告没有关系;随着发电机获得更多类型的处理,通过扩展该地图而增加了支持.

效果编码 有线 任职人数

效果模型作为值 解码/编码对,以及 JSONSchema.make 描述 编码 (有线)代表——不是运行时间类型. 这是最让你惊讶的警告:

  • Schema.Date 解码 a Date 从字符串,所以它转换为 string 计划——不是运行时间 Date。适配器通过这个没有改变,因为它准确地反映了Effect对电线的期望.
  • 只有 *FromSelf 变式 - Schema.DateFromSelf, (中文(简体) ), Schema.BigIntFromSelf ——描述运行时间值本身,这些是被救入的 x-mjst 运行时类型提示(参见 src/effect-to-json-schema.ts:121-122) (中文(简体) ).

因此:想要生成 Date作者 Schema.DateFromSelf。想要一个字符串,将效果描述为 Date作者 Schema.Date 并期望 string 在生成的输出中。 同样的区别适用于: Schema.BigInt (-) string对 Schema.BigIntFromSelf (-) bigint) (中文(简体) ).



许可证

麻省理工学院

版本与发布记录

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

版本发布日期距今
0.6.10latest2026/10/2314 天前
0.6.92026/10/1027 天前
0.6.82026/09/261 个月前
0.6.72026/09/241 个月前
0.6.62026/09/231 个月前
0.6.52026/09/221 个月前

关于 @amritk/adapters 的常见问题

@amritk/adapters 是什么?

从外部库(TypeBox, Zod, Avro,...)中将 schema 转换为 JSON Schema 为 mjst.

如何安装 @amritk/adapters?

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

@amritk/adapters 支持 TypeScript 吗?

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

@amritk/adapters 支持 ESM 还是 CommonJS?

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

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

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

@amritk/adapters 可以商用吗?

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

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

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

@amritk/adapters 还在维护吗?

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