ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

深入解析 @scalar/openapi-parser:用 TypeScript 完成 OpenAPI 文档的校验、引用解析与自动升级

深入解析 @scalar/openapi-parser:用 TypeScript 完成 OpenAPI 文档的校验、引用解析与自动升级 深入解析 scalar/openapi-parser用 TypeScript 完成 OpenAPI 文档的校验、引用解析与自动升级【免费下载链接】scalarScalar is an open-source API platform: Modern REST API Client Beautiful API References ✨ 1st-Class OpenAPI/Swagger Support项目地址: https://gitcode.com/GitHub_Trending/sc/scalarscalar/openapi-parser 是 Scalar 开源 API 平台中负责解析与转换 OpenAPI/Swagger 文档的核心包支持 OpenAPI 3.2、3.1、3.0 与 Swagger 2.0 四种规范版本。本文以该包的官方 README 为主线结合仓库内真实源码与测试系统讲解 validate、dereference、filter、upgrade、sanitize 等核心 API 的用法、返回结构与底层实现帮助你在 CI、CLI 或运行时环境中可靠地处理 API 定义文件。包定位一个现代 TypeScript 编写的 OpenAPI 解析器scalar/openapi-parser是 Scalar 技术栈中面向 OpenAPI 文档处理的基础库官方定位为 Modern OpenAPI parser written in TypeScript支持 OpenAPI 3.2、3.1、3.0 与 Swagger 2.0 四种规范。它并非孤立组件而是与仓库内多个包协同工作scalar/openapi-validator负责 schema 与语义校验见 validate.ts 中的委托调用scalar/openapi-types提供 OpenAPI 2.0/3.0/3.1/3.2 的 TypeScript 类型定义scalar/openapi-upgrader负责低版本文档向新版本升级见 upgrade.tsscalar/json-magic提供跨文件 bundle、URL 拉取与 YAML/JSON 解析能力用于多文件引用场景。从包的 package.json 可以看到当前版本为 0.29.1要求 Node.js 22纯 ESM 模块type: module并且依赖apidevtools/swagger-parser作为 devDependency —— 官方在 README 中也提到该包可以被视为apidevtools/swagger-parser的现代继任者甚至专门测试保证两者在预期场景下输出一致。包的完整对外 API 定义在 src/index.ts除本文重点讲解的validate、dereference、filter、upgrade、sanitize之外还导出了load、normalize、join、traverse、toJson、toYaml、isJson、isYaml、unescapeJsonPointer等一批实用工具。安装npm add scalar/openapi-parser安装后即可在 Node.js 22或打包工具链Vite 等中直接使用。如果只想使用官方提供的 OpenAPI TypeScript 类型可以额外安装npm add scalar/openapi-types校验文档validate()validate()用于检查一个 OpenAPI/Swagger 文档是否符合对应版本的规范。它接受字符串JSON/YAML、对象或文件系统对象filesystem作为输入import { validate } from scalar/openapi-parser const file { openapi: 3.1.0, info: { title: Hello World, version: 1.0.0 }, paths: {} } const { valid, errors } await validate(file) console.log(valid) if (!valid) { console.log(errors) }返回结构validate()返回一个 Promise结果为ValidateResult对象包含以下字段valid: boolean文档是否通过全部校验errors: ErrorObject[]schema 错误、引用解析错误与语义错误的合并结果schema解析后的严格类型文档仅当通过 schema 校验时存在specification规范化的文档对象version识别出的 OpenAPI/Swagger 版本。源码级实现细节阅读 validate.ts 可以发现几个重要的行为约定自动补全缺失的info.version当文档缺少info.version时解析器不会直接判失败而是默认补为0.1.0再进入校验源码注释解释了这是遵循 semver 对初始开发版本的建议值历史上曾用0.0.1后已修正。两阶段校验先对未解析unresolved的文档做 schema 与版本校验通过后再解析$ref引用并把引用解析错误合并进结果路径参数path parameter语义校验则运行在解析后的文档上这样通过$ref声明的路径参数也能被正确识别避免误报缺少参数。throwOnError选项默认返回结果对象开启throwOnError: true后空文档或无有效入口时会直接抛出错误错误文案定义在 configuration/index.ts 的ERRORS常量中如Cant find JSON, YAML or filename in data.。空/无效输入的处理当输入无法构成有效入口例如顶层是一个数组时返回{ valid: false, errors: [{ message: ERRORS.EMPTY_OR_INVALID }] }。解析引用dereference()OpenAPI 文档大量使用$ref引用如#/components/schemas/User。dereference()会把整个文档包括跨文件引用解析成一张展开后的 schema 图返回{ specification, schema, errors }import { dereference } from scalar/openapi-parser const specification { openapi: 3.1.0, info: { title: Hello World, version: 1.0.0 }, paths: {} } const { schema, errors } await dereference(specification)从源码看dereference.ts该函数会先把输入统一转换为 filesystem内部数据结构见 make-filesystem.ts找到入口文档后调用resolveReferences完成引用解析。追踪引用过程onDereference 回调dereference接受一个onDereference回调选项每当一个引用被解析时触发可用于追踪哪些 schema 正在被解析、统计引用数量或做日志输出import { dereference } from scalar/openapi-parser const { schema, errors } await dereference(specification, { onDereference: ({ schema, ref, resolved }) { // schema: 当前被解析的 schema // ref: 引用路径 // resolved: 解析结果 }, })解析过程中可能产生的引用错误如外部引用找不到、自引用、JSON Pointer 无法解析会汇总到返回的errors数组中对应的错误文案同样定义在 configuration/index.tsINVALID_REFERENCE、EXTERNAL_REFERENCE_NOT_FOUND、SELF_REFERENCE等。修改文档filter()filter()允许你通过回调函数对文档中的每个 schema 进行筛选返回回调结果为false或返回undefined的节点会被从文档中剔除。典型用途是剥离内部接口、x-internal标记的扩展字段等import { filter } from scalar/openapi-parser const specification { openapi: 3.1.0, info: { title: Hello World, version: 1.0.0 }, paths: {} } const { specification: filtered } filter( specification, (schema) !schema?.[x-internal], )其实现filter.ts基于traverse工具回调返回原对象则保留返回undefined则该节点被删除非常适合发布对外版本前移除内部标记这类场景。升级文档upgrade()OpenAPI 生态中存量文档散落在 Swagger 2.0、OpenAPI 3.0、3.1 等不同版本。upgrade()会把低版本文档统一升级到 OpenAPI 3.1已是 3.1/3.2 的文档则保持不变import { upgrade } from scalar/openapi-parser const { specification } upgrade({ swagger: 2.0, info: { title: Hello World, version: 1.0.0, }, paths: {}, }) console.log(specification.openapi) // Output: 3.1.0从 upgrade.ts 的源码看该函数内部委托给scalar/openapi-upgrader的upgrade方法目标版本固定为3.1同时返回{ specification, version }其中version仅在结果确认为 3.1 或 3.2 时才填充。若输入为空则返回{ specification: null, version: undefined }。如果你只需要单向转换能力也可以直接使用包内导出的upgradeFromTwoToThree、upgradeFromThreeToThreeOne注意这两个导出在当前版本已标记为 deprecated建议改用upgrade或直接使用scalar/openapi-upgrader。规范化文档sanitize()sanitize()是一个尽力而为的规范修正器帮助文档尽可能符合 OpenAPI 规范要求。它自动补齐缺失的必填属性、收集操作标签并写入全局tags数组、归一化 security scheme 类型让文档以最小的改动变得合规。⚠️注意sanitize()不支持 Swagger 2.0 文档传入 Swagger 2.0 文档会被直接拒绝。import { sanitize } from scalar/openapi-parser const result sanitize({ info: { title: Hello World, }, }) console.log(result)背后的 transformer 流水线transform/sanitize.ts 将其实现为一系列 transformer 的流水线按顺序执行rejectSwaggerDocuments拒绝 Swagger 2.0 文档addLatestOpenApiVersion缺省时补上openapi: 3.1.1DEFAULT_OPENAPI_VERSION见 addLatestOpenApiVersion.tsaddInfoObject缺省时补info.title API、info.version 1.0见 addInfoObject.tsaddMissingTags遍历所有 path 上的 operation收集tags中出现的标签凡是没有在顶层tags数组中声明的自动追加为{ name }对象见 addMissingTags.tsnormalizeSecuritySchemes将 security scheme 的type归一化为规范大小写apikey→apiKey、oauth2、http、mutualtls→mutualTLS、openidconnect→openIdConnect并把 oauth2 flow 中数组形式的 scopes 转换为{ scope: }对象形式见 normalizeSecuritySchemes.ts。提示源码注释显示该函数计划从包中移除标记为deprecated在引入到新项目前建议评估其长期可用性。Promise 风格then/catch 语法所有返回 Promise 的 API如validate都同时支持await与then/catch两种写法方便习惯回调式/链式风格的开发者import { validate } from scalar/openapi-parser const specification … validate(specification, { throwOnError: true, }) .then(result { // Success }) .catch(error { // Failure })TypeScript 类型scalar/openapi-types如果你只需要 OpenAPI 的完整类型定义而不想引入解析器可以单独安装类型包npm add scalar/openapi-typesimport type { OpenAPI } from scalar/openapi-types const file: OpenAPI.Document { openapi: 3.1.0, info: { title: Hello World, version: 1.0.0, }, paths: {}, }scalar/openapi-types按版本划分了目录2.0、3.0、3.1、3.2在仓库中位于 packages/openapi-types编写类型安全的解析、转换逻辑时非常有用。进阶跨文件与远程 URL 引用生产环境的 OpenAPI 文档常常拆分成多个 YAML/JSON 文件并通过相对路径或 URL 互相引用。此时解析器需要知道磁盘上或网络上有哪些文件可用。官方推荐使用scalar/json-magic的bundle()配合插件完成加载再把打包结果交给dereferenceimport { bundle } from scalar/json-magic/bundle import { fetchUrls } from scalar/json-magic/bundle/plugins/browser import { readFiles } from scalar/json-magic/bundle/plugins/node import { dereference } from scalar/openapi-parser // Load a file and all referenced files const data await bundle(./openapi.yaml, { plugins: [ readFiles(), fetchUrls({ limit: 5, }), ], }) // Instead of just passing a single specification, pass the whole data object const result await dereference(data)bundle()支持插件机制readFiles负责读取本地文件fetchUrls负责拉取远程 URL。你完全可以仿照readFiles的源码编写自定义插件例如从数据库或内部配置中心加载 API 定义插件实现与测试见 plugins。直接加载 URL启用fetchUrls插件后甚至可以只传一个 URL配合parseYaml/parseJson插件完成解析import { bundle } from scalar/json-magic/bundle import { fetchUrls, parseJson, parseYaml } from scalar/json-magic/bundle/plugins/browser import { readFiles } from scalar/json-magic/bundle/plugins/node import { dereference } from scalar/openapi-parser const data await bundle( https://registry.scalar.com/scalar/apis/galaxy?formatyaml, { plugins: [readFiles(), fetchUrls(), parseYaml(), parseJson()], }, )拦截 HTTP 请求浏览器 CORS 场景在浏览器环境从 URL 拉取远端定义时可能遇到 CORS 限制。fetchUrls插件允许你注入自定义fetch实现将请求重定向到代理或 CDNimport { bundle } from scalar/json-magic/bundle import { fetchUrls, parseJson, parseYaml } from scalar/json-magic/bundle/plugins/browser import { readFiles } from scalar/json-magic/bundle/plugins/node import { dereference } from scalar/openapi-parser const result await bundle( https://registry.scalar.com/scalar/apis/galaxy?formatyaml, { plugins: [ fetchUrls({ fetch: (url) fetch(url.replace(BANANA.net, jsdelivr.net)), }).get(https://cdn.BANANA.net/npm/scalar/galaxy/dist/latest.yaml), ], }, )这里的.get(url)显式声明要预取的具体 URLfetch选项则接管实际的网络请求。从 load() 迁移到 bundle()早期版本通过load()方法加载多文件文档最新推荐方式已迁移到bundle()。官方给出的迁移 diff 如下-import { dereference, load } from scalar/openapi-parser -import { fetchUrls } from scalar/openapi-parser/plugins/fetch-urls import { bundle } from scalar/json-magic/bundle import { fetchUrls, parseJson, parseYaml } from scalar/json-magic/bundle/plugins/browser import { readFiles } from scalar/json-magic/bundle/plugins/node import { dereference } from scalar/openapi-parser // Load a file and all referenced files -const { filesystem } await load( const result await bundle( https://registry.scalar.com/scalar/apis/galaxy?formatyaml, { plugins: [ fetchUrls({ fetch: (url) fetch(url.replace(BANANA.net, jsdelivr.net)), }).get(https://cdn.BANANA.net/npm/scalar/galaxy/dist/latest.yaml), ], }, )核心变化是插件体系从解析器内置的plugins/fetch-urls子路径统一迁移到scalar/json-magic的 bundle 插件体系相应地load()返回的filesystem由bundle()的打包结果取代。仓库内仍保留load、join等工具导出并配套了 migration-layer.test.ts 等测试来保障迁移期的兼容行为。其他实用导出工具除上述核心 API 外src/index.ts 还导出了一系列处理 OpenAPI 文档的辅助函数normalize将字符串JSON/YAML或对象统一规范化为对象traverse深度遍历文档中的每个 schema 节点是filter的底层实现toJson/toYaml在 JSON 与 YAML 格式之间转换isJson/isYaml判断输入格式join合并多个文档/文件系统unescapeJsonPointer/escapeJsonPointerJSON Pointer 转义工具其中escapeJsonPointer与upgradeFromTwoToThree、upgradeFromThreeToThreeOne已标记为 deprecated建议按包内提示迁移到scalar/json-magic与scalar/openapi-upgrader对应入口。测试与基准解析器在仓库中配有完善的测试与基准体系可作为理解行为边界的参考单元/集成测试覆盖validate、dereference、upgrade、sanitize、traverse、resolve-references、normalize等见 src/utils 下各*.test.ts多文件引用、循环引用、外部 PathItem 引用等复杂场景有专门用例见 tests/openapi3-examples 与 tests/references基准测试对无引用、单引用及完整 petstore 文档等场景做了性能测量见 tests/benchmark并同时基于新旧解析路径对比结果。使用建议与注意事项版本支持边界解析器支持 OpenAPI 3.2、3.1、3.0 与 Swagger 2.0但sanitize()明确拒绝 Swagger 2.0 文档Node 版本要求包要求 Node.js 22见 package.json部署到旧版本 Node 环境前请先确认运行时版本宽松校验策略validate()会为缺失的info.version默认补0.1.0这是解析器相对严格校验器的有意取舍若你的 CI 需要严格把关可在上层自行检查原始文档多文件场景处理跨文件/远程引用时优先使用scalar/json-magic的bundle()插件体系而非直接传单一字符串升级链路upgrade()是 OpenAPI 2.0/3.0 → 3.1 的推荐入口底层由scalar/openapi-upgrader实现单文件场景无需额外配置。scalar/openapi-parser作为 Scalar 开放平台的基础解析层把校验、解析引用、过滤、升级、规范化这五类高频操作收敛成一组简洁的异步 API配合scalar/openapi-validator与scalar/openapi-types即可在任意 TypeScript 项目中搭建一条完整的 OpenAPI 文档处理流水线。【免费下载链接】scalarScalar is an open-source API platform: Modern REST API Client Beautiful API References ✨ 1st-Class OpenAPI/Swagger Support项目地址: https://gitcode.com/GitHub_Trending/sc/scalar创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表