@amritk/resolve-refs (英语)
解析并内置 JSON Schema / OpenAPI $refs- 内部指针,交叉文件
参考文献和远程(http/https)文件——作为单一参考文件.
- 单行道,缓存. 每个独特的裁判都解决一次,结果总是
有限。 参考文献 周期 递归分支为 保留,而不是丢失:
周期点保持a
$ref在输出文档中解决的(a) 跨文件周期目标被升入根$defs),所以递归性 计谋在完全不参考的情况下得以幸存. - 锁定器+动态反射器,
$id- 扫描过了. 超越 JSON 指针$refs, (中文(简体) ), 普通名称$anchor参考文献(#node, (中文(简体) ),$dynamicRef编号 :$dynamicAnchor(2020-12) (中文(简体) )$recursiveRef编号 :$recursiveAnchor(2019-09) 被贬为 我也一样.$id基准URI范围界定为捆绑文件的模型:参考文献 其 URI 匹配嵌入式资源$id决心不这样做 取取并锚于所申报的资源中 返回到文档-全局搜索。 见$id范围界定 准确数字如下 子集. - 交叉文件 + 远程. 相对裁判对所显示的文件作出决断 在(远程文件内部的参考文献保持远程,本地文件内部的参考文献保持远程) (当地)。 为会话缓存已获取的远程文档, 按 URL 键 财务报告和审定财务报表 以他们所拿的证书盟誓.
- 默认的SSRF守卫. 远程回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回回
云-元数据主机——由IP(
169.254.169.254(中文(简体) ) 财务报告和审定财务报表 按名称 (单位:千美元)metadata.google.internal,任何东西下.internal——除非 你选择加入。 主机名被额外解决, 当地址出现时拒绝 他们指的是不公开的,所以127.0.0.1.nip.io不要滑过. - 默认本地读取 . 当地人
$ref可能只解决 树根下 文档目录。 。 。 .{"$ref": "../../../secrets.env"}拒绝; 拓宽 与allowedRoots当您的光谱合法地覆盖文件夹时. - OpenAPI 参考对象. A 类
$ref他们唯一的兄弟姐妹是summary编号 :description将目标与以上说明相接 OpenAPI 3.1 参考对象语义,其中allOf包装是 无效。 任何其他兄弟关键字都保持光谱校正allOf组合.
使用量
import { resolveRefs, resolveRefsFromFile } from '@amritk/resolve-refs'
// In-memory, internal (#/...) refs only. External refs (another file or an
// http(s) URL) are left in place and reported on `errors`, since this resolver
// can't load other documents — use resolveRefsFromFile for those:
const { resolved, errors } = resolveRefs(myDocument)
// From disk or a URL, including cross-file and remote refs:
const result = await resolveRefsFromFile('./schema.json')
const remote = await resolveRefsFromFile('https://api.example.com/schema.json', {
allowedHosts: ['api.example.com'],
})
选项( E)resolveRefsFromFile(中文(简体) )
| 选项 | 默认 | 说明 |
|---|---|---|
remote | true | 是否可获取 http( s) refs . |
localRefs | true | 是否为 $refs 到磁盘上的其他文件可被读取. false 仍然读取你命名的根部文件——它拒绝任何参考文献. |
allowedRoots | [dirname(root)] | 本地目录 $ref 必须在内部解决问题。 默认限制对持有根文档的文件夹进行对比;对于从 URL 中加载的根,默认为 [],所以完全不读取本地文件. |
allowedHosts | [] | 如果不是空的,则只能获取这些主机 。 匹配的大小写不敏感;没有端口的条目匹配任何端口,有端口的条目必须匹配(省略端口的URL计为协议默认值). 一个明确的条目绕过私人宿主和DNS的守卫. |
allowPrivateHosts | false | 允许回放/私人/链接-局部目标. 别管了,这些被拒为安全局警卫. |
verifyDns | true | 解决每个远程主机,并在任何地址决定不公开时拒绝. 过 false 名称以 egress 代理解决而不是本地解决. |
headers | —— 说 | 远程请求(记录,或 (url) => headers (每个东道主的证书)。 从来没有通过一个跨源方向. |
fetch | 全球 fetch | 自定义获取执行 。 SSRF的后卫仍然在呼叫前评价每一次跳. |
timeoutMs | 30_000 | 在这多毫秒后中止未响应的远程获取 . |
totalTimeoutMs | 60_000 | 整个决心的预算,每个文件都有. |
maxDocuments | 500 | 单项决议(包括根)可能装入文件. |
maxRedirects | 5 | 重定向跳接每个远程文档(每个跳接会重跑SSF后卫). |
maxBytes | 16 小贝 | 拒绝缓冲比此更大的远程文档 . |
maxDepth | 512 | 在离开未解决的子树并记录出出错之前,行走有多深. |
cache | true | 过 false 以绕过此调用的全过程会话缓存 —— 每件事物都是被重置的, 没有被存储 . |
parse | JSON.parse | 自定义内容解析器( 如 YAML- aware) . |
rootDocument | —— 说 | 根已分出值相. 命名文件不读也不解析;其位置仍然锁定相对 refs, allowedRoots,以及 origins。该值仅被读取、从未被写出或被化名输入结果. |
trackOrigins | false | 在结果上记录一个每个节点的起源地图. |
bundle | false | 捆绑而不是内衬: 从另一个文档中将每个目标提升到根的 $defs 一次并在那里指针, 将指针按写在根上。 输出是一个只有内部 refs的文件——代码生成器想要的,因为共享的计程器在每次使用时都会保留一个定义而不是一个副本. 一个绝对的文件 $id 被嵌入其整体 $id,并用该 URI 来校正嵌入式资源名称中的任何内容; 具有相对的文档 $id 已内置. |
出错( 缺少文件、 拒绝主机、 拒绝路径、 错误 URL、 文档也)
被收集起来 result.errors 而不是抛出
参考节点留作 $ref (什么都没有是内在的) 所以其余的
中文本无需改动.
每个错误都带有 path 引文使用过时
文档,以关键词结尾(['properties', 'pet', '$ref']这样
来电者可以把诊断定位在 $ref 读者必须修补。 这是空的
当无处可言时:预算、整个决心或
其它文件中的参考文献.
clearRemoteCache() 丢弃每个缓存的远程文档——用于测试或
远程计划可能改变的长寿命会议。 通过一个 URL
(单位:千美元)clearRemoteCache(url)) 掉掉一个。 缓存在
10分钟后就把最近使用最少的256个文件 赶走了,所以很长一段时间
过程不会累积它见过的每一个计划.
安全态势
远程路径总是默认- 拒绝; 本地路径现在匹配 .
- 本地读取被限制 改为
dirname(rootLocation)除非你通过allowedRoots。这是故意的严格:像../common/schemas.json——普通的分谱布局——在您选择加入之前被拒绝,因为相同的 形状是读取/etc/passwd您没有写入文档中。 两者 逻辑学和共解路径必须在根内降落,所以共解 植入树上不能用来逃避它。 根文档本身是 免责:这是您明确命名的文件 . - 会话缓存是证书范围 . 它的密钥覆盖了请求标题,
页:1
fetch编号 :parse回调、调用限制和主机警卫 (单位:千美元)allowPrivateHosts, (中文(简体) ),allowedHosts, (中文(简体) ),verifyDns),因此获取文档 一个租户的代号是隐形的 与不同(或没有)的电话 证书——没有传呼者继承他人的fetch. 飞行集成 使用相同的密钥. - SSRF的警卫分两道经过.
isPrivateHost同步并读取 只有URL(每个IPv4编码,IPv4-in-IPv6嵌入,ULA/link-local/) site-local IPv6,外加云-元数据端点名称否定列表.assertPublicHost然后确定名称,并在地址是 非公开的。 都运行在每个方向跳. - 已知残缺:DNS再装订. 检查之间有变化的记录
连接仍然获胜;关闭时需要将套接字接上
经核实的地址, 节点所在
fetch不让我们这样做。 什么DNS通过 买的是名字 静态 指向私人地址被拒绝—— 事实就是如此. - 决心是注定的 以
maxDocuments, (中文(简体) ),totalTimeoutMs,以及maxDepth这样 敌对文档不能使用解析器作为外向放大器,持有 进程持续数小时,或以筑巢方式崩溃.
$id 范围界定
所支持的子集,用于捆绑文件现实而不是 全谱 :
- 带有
$id是一个 嵌入式资源页:1$id(已解决) 成为它内部一切事物的URI基础. - 被告的URI——解决了包围基地的问题—— 匹配嵌入的
资源
$id决心不获取资源。 指针或 此类参考文献的锚片适用 在内部 资源. - 锁定 在首先宣布它们的资源内绑定; 不锁定 在范围中找到的返回到文档-全局搜索(兼容 参考跨兄弟资源的文件.
- 一个平地
#/pointer碎片解析 在资源范围内 首先, 并返回到文档根, 当它与文档根不匹配时—— 这就是 所依赖的行为捆绑现实世界文档(捆绑的 OpenAPI 文件点) 时间#/components/schemas/…从内部$id范围。 当两者可以匹配时, 资源胜出,这是光谱要求的命令. $dynamicRef喜欢一个$dynamicAnchor,然后降解为$ref语义; 指向形式$dynamicRef(单位:千美元)#/$defs/items解决的完全一样 (单位:千美元)$ref,这是Spec说它是什么。 完整的动态瞄准镜算法 (在运行时间参考链上最远的锚)不是模拟的,而且 无法通过一个内在的解析器——看到 达标,计量。 。 。 .- 文档 检索不受影响: 哪个文件/ URL 一个外部 ref 加载
源自参考文件 地点从不
$id—— 说 一个根$id命名远程 URL 无法将本地的兄弟姐妹文件 ref 变成 网络获取 .
达标,计量
插入文件时不得改变其接受的内容,并对照
一、导 言 $ref 形状 .
src/conformance.test.ts 处理官员的每个参考案件
JSON Schema 测试套件
(需要2020-12年测试草案),通过
@amritk/runtime-validators - 一次通过原件
计划,一次通过已解决的计划——要求双方同意这一规定:
170例/170例通过(100%).
委托书是翻译已经回答的参考文件 正确的 在此之前 因此,一个分歧是 解决者与 没有人是.
获得最后十个意味着 没有 回答:a $dynamicRef 谁
$dynamicAnchor 名称在评价时多次被宣布为约束,并且
将它倒塌到一个目标上 通过建造。 这些现在保存在
与它们所需要的脚手架进行输出,正像参考周期一样——见
$id 范围界定 页:1 预期失败列表为空并保存在
位置,所以建构名称是第一个倒退而不是让一个
百分数 。 案发地点是
fixtures/json-schema-test-suite; 无
现予公布.
文档
每个文档——本地文件或远程文件——被解析为 贾森 默认,所以
解析器不依赖。 其他格式插入通过 parse 选项 :
mjst lint 传出一个YAML意识的解析器 .lint.yaml
文档的交叉文件 $refs 解析不包含此包, 取决于 YAML
par.
基准
resolveRefs 回忆:每个独特的 $ref 字符串每个范围解决一次,
通过保持参考节点来打破循环的哨兵。 不过
已经不再 仅限 在解决任何问题之前
建立资源登记册的完整文件一次$id编号 :$anchor 范围界定,保留
循环周期完整无缺,记录每个外推员的诊断结果. 这个
bench/ 套房把它与一个 赤裸裸的天真无邪的内线 无关,不
登记册,没有范围界定,没有诊断——并重新解决每个参考文件上的每个参考文件
所以差距是生产解析器的 共计 按召用费用计算
最便宜的东西 产生相同的内衬形状。 他们都声称:
生成字节-等同的输出,在两个输出之前进行定时。 运行它 bun run bench
(本)或(本) bun run bench:node (节点);形状很长 $ref → $ref
链条,许多反射重用一个定义,一个循环树, 和许多不同的
每个定义都使用了一次。 邦德和节点在每一个形状上都靠近,
这才是你所期望的 解决者的成本是一份文件
而不是一个热的内环.
感化会超越天真的行走 链式 形状,其中长
间接路径重解成本很高 缓存崩溃到一个
通过。 登记前行走的固定费用(已支付)
每一次通话,无论复用率如何高 都比记忆省得多少
赤裸的内线比较快 这些是小计划 在一个文件行走的地方
统治者。 外卖是实用的 解决器的每层楼是完整的
文档 traversal, 因此在热回路中解析文档 一次 和再利用
而不是重新解决。 这个 reuse-heavy, (中文(简体) ), cyclic,以及 wide-distinct
形状被保留在长凳上 恰恰是为了表明贸易诚实而不是
樱桃选取一个形状 缓存获胜.
选择进入 trackOrigins (记录每个内含值的来源)
在这些小计划上,无论运行时间如何,成本都无法衡量:
差异为零,即运行中的噪音而不是价格.