@codewithagents/openapi-msw

中文文档
0.3.0发布于 2026/11/03MITTypeScriptES Module构建来源已验证近 30 天下载 3226

以来自 OpenAPI 3.1 的种子 Faker 模拟数据生成 MSW v2 处理器

中文使用文档
文档目录10 节
  1. 安装
  2. 快开始
  3. 生成输出
  4. 配置引用
  5. 固定建筑工 fixtures: true (中文(简体) )
  6. 人体如何产生
  7. 非明显行为
  8. 程序化 API
  9. Openapi-zod-ts套房的一部分
  10. 许可证

@ codewits/ openapi- msw

npm CI codecov CodeQL

📖 完整文档

@codewithagents/openapi-msw 从您的 OpenAPI 3. 1 个 spec 生成 MSW v2 模拟处理器, 并带有种子 Faker 数据: 将其指向一个 spec, 获得一个类型安全 handlers.ts 您可以立即跳入浏览器工作室或节点模拟服务器.

  • 每次行动一名操作员: 每一个 get, (中文(简体) ), post, (中文(简体) ), put, (中文(简体) ), patch,以及 delete 操作成为 http.<method>(path, resolver) 导出条目 handlers 阵列.
  • 种子、决定性的嘲弄数字 : faker.seed(<seed>) (默认) 42)被写入生成的文件,因此每个运行都具有相同的光谱和种子产生相同的模拟值. 改变种子,再生,获得一个新的但仍然稳定的数据集.
  • MSW v2 路径语法: 打开API {id} 路径参数被重写为MSW 结肠样式 :id。路径中的每个参数都会转换(/orgs/{orgId}/repos/{repoId} 变成 /orgs/:orgId/repos/:repoId) (中文(简体) ).
  • 在浏览器和节点工作: 处理器路径被固定在一个源( * 默认通配符,或您的 base_url),因此它们与绝对的URL相匹配 fetch 发送下 setupServer 和浏览器请求 setupWorker。 。 。 .
  • 知会身体:每个处理器返回一个由操作的 2xx JSON 响应计划所塑造的由 Faker 生成的正体, 荣誉字符串格式, enums, 阵列, 和嵌入对象.
  • 瞄准内置固定器数字 : fixtures: true 还写 fixtures.ts,一个键入 a<Name>(overrides?) 内置,每个测试处理器每个组件的构建器。 见 固定建筑工。 。 。 .
  • 高级清洁输出: 生成 handlers.ts 通过 prettier --check 从盒子里出来.
  • 打开API 3.x:3.1.x是首要目标;3.0x在实践中得到支持(13个显示规格中的8个是3.0.x,全部编译在下) tsc --strict) (中文(简体) ).

安装

pnpm add -D @codewithagents/openapi-msw
# or
npm install -D @codewithagents/openapi-msw

生成的 handlers.ts 从 msw 财务报告和审定财务报表 @faker-js/faker 直接,所以两者都是 同行依赖关系 你安装自己:

pnpm add msw @faker-js/faker
同伴依赖关系范围
msw^2.0.0 || ^3.0.0
@faker-js/faker^10.5.0

此软件包取决于 openapi-zod-ts 用于 spec 解析和共享配置管道,但不要求您生成模型或客户端。 单独运行 或与其余的套房.


快开始

1. 创建 openapi-msw.config.json 在您的工程根中 :

{
  "input_openapi": "./spec/api.json",
  "output": "./src/mocks",
  "seed": 42,
  "max_array_items": 3,
  "depth_cap": 30
}

仅 input_openapi 财务报告和审定财务报表 output 需要这样做。 三个数值字段是可选的并默认为上述数值.

2. 运行生成器:

npx openapi-msw
# or point at a config elsewhere:
npx openapi-msw --config ./config/openapi-msw.config.json

CLI没有立场上的论点. 可用旗帜为 --config <path>, (中文(简体) ), --help 编号 : -h,以及 --version 编号 : -v时 --config ,在配置文件目录中的配置解析度中的相对路径.

3个. handlers.ts 在输出目录中显示 :

这个 output 如果目录不存在,则以递归方式创建。 将处理器接通到MSW:

// browser worker
import { setupWorker } from 'msw/browser'
import { handlers } from './src/mocks/handlers'

export const worker = setupWorker(...handlers)
// Node / test server
import { setupServer } from 'msw/node'
import { handlers } from './src/mocks/handlers'

export const server = setupServer(...handlers)

生成输出

鉴于任务 API GET /api/v1/tasks (返回一页列表)和 DELETE /api/v1/tasks/{id} (204 无内容),生成 handlers.ts 看起来像这样:

// This file is auto-generated by @codewithagents/openapi-msw, do not edit
import { http, HttpResponse } from 'msw'
import { faker } from '@faker-js/faker'

faker.seed(42)

export const handlers = [
  http.get('*/api/v1/tasks', () =>
    HttpResponse.json({
      items: Array.from({ length: 3 }, () => ({
        id: faker.string.uuid(),
        title: faker.lorem.word(),
        status: faker.helpers.arrayElement(['pending', 'in_progress', 'done']),
        priority: faker.number.int({ min: 1, max: 1000 }),
        assigneeEmail: faker.internet.email(),
        createdAt: faker.date.recent().toISOString(),
      })),
      total: faker.number.int({ min: 1, max: 1000 }),
    })
  ),
  http.delete('*/api/v1/tasks/:id', () => HttpResponse.json(null, { status: 204 })),
]

一个承诺的,漂流检查的样本生活在 packages/integration/generated/handlers.ts从 packages/integration/spec/api.json。 。 。 .


配置引用

openapi-msw.config.json数字 :

外地需求默认说明
input_openapi对无OpenAPI 3.x spec( JSON 或 YAML) 路径
output对无要写的目录 handlers.ts (创建回转)
seed没有42传到 faker.seed() 在生成的文件中。 必须是整数 >= 0
max_array_items没有3生成模拟中的数组长度 。 必须是整数 >= 1
depth_cap没有30Schema 重现深度后再跳出 null。必须是整数 >= 1
base_url没有* 通配符来源起源(可选带基路径) 被前缀到每个处理器路径上,例如. "https://api.test" 给 https://api.test/api/v1/tasks被丢弃了 必须是非空字符串

| fixtures |无| false 时间 true,同时写入 fixtures.ts (每司马修所. 一定是布林尔的.. | models_import |无| "./models.js" 模块指定符 fixtures.ts 导入模型类型 openapi-zod-ts models.ts) (中文(简体) ). 必须是非空字符串 {}

可选密钥仅在存在时才被验证. 每个键,除了 projects 也可以设置在 a 中的每个条目 projects 阵列.

多相相相生成. 将顶级字段替换为 projects 生成一个数组 handlers.ts 光谱。 混合 a projects 带有顶级的阵列 input_openapi 编号 : output 掷出.

{
  "projects": [
    { "input_openapi": "./specs/public.json", "output": "./src/mocks/public" },
    { "input_openapi": "./specs/admin.json", "output": "./src/mocks/admin" }
  ]
}

固定建筑工fixtures: true(中文(简体) )

handlers.ts 财务报告和审定财务报表 fixtures.ts 解决两个不同的问题:

文件作用用它来
handlers.ts雾层. 一套完整的处理器,每个操作一个,有一个种子数据集Dev 工人(setupWorker,演示后端,或基线 setupServer(...handlers) 每次测试都从
fixtures.ts每测试数据. 每个组件计划一个建构器,返回完整、有效的值单项测试内置处理器(server.use(...)) 测试控制准确反应

宣告内置处理器的组件测试需要图案类型的完整对象. 手写固定装置从光谱上漂移;生成的构造器没有. 打开 "fixtures": true,以及 fixtures.ts 写在 handlers.ts数字 :

import { http, HttpResponse } from 'msw'
import { server } from './mocks/server'
import { aTask } from './mocks/fixtures.js'

it('shows the task title', async () => {
  const TASK = aTask({ title: 'Write docs', status: 'done' })
  server.use(http.get('*/api/v1/tasks/:id', () => HttpResponse.json(TASK)))
  // render, then assert on TASK.title ...
})

每一个计划 components.schemas 生成器会发出 :

export function aTask(overrides?: Partial<Task>, variant = 0): Task
aTask.full = (overrides?: Partial<Task>, variant = 0): Task => ...
  • 取名问. a<Name>,或 an<Name> 当类型名称以元音开头时(anOwner, (中文(简体) ), anUpdateTaskRequest) (中文(简体) ). <Name> 确切的类型名称 openapi-zod-ts 输出于 models.ts。 。 。 .
  • 和你的模型对打. fixtures.ts 已经 import type { ... } from './models.js' (单位:千美元) openapi-zod-ts (产出). overrides 实值 Partial<Name>,因此一个错误的值或未知的密钥是编译错误。 点 models_import 在其他地方,当模型不 住在模型旁边,例如. "models_import": "../api/models.js"。 。 。 .
  • 浅色合并. aTask({ owner }) 替换 owner 批发; 不合并为生成 owner。 。 。 .
  • 默认情况下只要求 . aTask() 只填充列表中的属性 required (复入入于巢所取之物也. aTask.full() 在对象本身和由一个筑巢者级别(在 aPet.full() 一个巢 owner 里面也满了,下面的任何东西都是必要的,所以 .full() 以大而相通的规格为界. writeOnly 属性总是被忽略,匹配读形模型类型.
  • 每个电话都要决定. 每一次呼叫都重新播音一个私人 Faker 实例(与 Global faker 那个 handlers.ts (a) 使用) (seed, builder, variant)。同一呼叫总是返回相同的值,不管在它之前是哪个建筑商运行的,还是测试在哪个顺序运行的,所以快照和断言保持稳定。 相对日期(date-time 编号 : date 字段)根据固定的参考日期计算2025-01-01T00:00:00.000Z)而不是"现在",所以它们也比较平稳地跨越了跑道和天数. 换个 variant 以获得不同的、仍然具有决定性的价值,例如,在一个清单中有两个不同的项目: [aTask({}, 0), aTask({}, 1)]。 。 。 .
  • 尼斯特德计划再利用他们的建造者. 一个财产 $refs 另外一个组件计划称为 schema 的构建者(anOwner(...),或 anOwner.full(...) 内部 .full() 由调用者的种子Faker所取出的一个变体,所以嵌入值具有确定性,但阵列项目彼此不同 fixtures.ts 在计划数中保持线性。 返回一个周期的参考文献(例如: TreeNode.children,或 A -> B -> A)是被守护的:复发会深入一个巢穴,然后产生 null,所以每个建筑工都会终止.
  • 非对象计划 (enums, 数组, 原始的) 获得一个没有覆盖的数值构建器 : aTaskStatus(variant?) 财务报告和审定财务报表 aTaskStatus.full(variant?)。 。 。 .
  • 价值观是最佳的. 生成的值遵循与 Faker 规则相同的 handlers.ts (见下文);它们被投入模型类型,而不是被证明不利于模型类型,因此,把一个测试取决于其中的值放在其中 overrides。 。 。 .

人体如何产生

每个处理器的解析器正体由操作中选择的2xx JSON响应方案来构建. 每个计划节点都选择Faker呼叫:

司马生成值
string,格式 emailfaker.internet.email()
string,格式 uuidfaker.string.uuid()
string,格式 date-timefaker.date.recent().toISOString()
string,格式 datefaker.date.recent().toISOString().slice(0, 10)
string,格式 uri 编号 : urlfaker.internet.url()
string (其他部分)faker.lorem.word()
integer, (中文(简体) ), int32, (中文(简体) ), int64faker.number.int({ min: 1, max: 1000 })
number (其他部分)faker.number.float({ min: 0, max: 1000, fractionDigits: 2 })
booleanfaker.datatype.boolean()
enumfaker.helpers.arrayElement([...literals])
arrayArray.from({ length: max_array_items }, () => item)
对象为 additionalPropertiesObject.fromEntries(...) 包含两个生成的条目
null / 无法解决null

非明显行为

  • 种子生活在输出中,而不是运行时间. faker.seed(<seed>) 是生成文件的第一个可执行行。 要改变模拟值, 需要以不同的方式重生 seed. 两跑相同的谱和种子产生字节-等同处理器.
  • Handler URL 是源代码选择. 赤裸的相亲者,如 '/api/v1/tasks' 由MSW针对 location.href,因此在节点(setupServer 从 msw/node它从不匹配 绝对要求喜欢 fetch('http://localhost/api/v1/tasks')因此,生成的处理器总是带有一种来源: '*/api/v1/tasks' 默认(MSW的通配符:任何来源、浏览器和节点都一样),或 '<base_url>/api/v1/tasks' 何时 base_url 已经设定。 设定 base_url 当您想要处理器只匹配一个来源时, 或者当您的服务器 URL 带有一个基本路径时, spec's paths 不包括(例如 "https://api.test/v2") (中文(简体) ). 在此更改之前产生的输出使用赤裸的相对路径;再生成来取回固定.
  • 2xx选取顺序. 发电机更喜欢一个 200 反应,然后 201,然后第一个宣布 application/json 躯体。 A 类 200 发射 HttpResponse.json(body) 没有状态参数; 任何其他 2xx(例如) 201发射 HttpResponse.json(body, { status: N })。 。 。 .
  • 没有JSON的尸体. 如果选中的 2xx 响应没有 application/json schema, 处理器发出 HttpResponse.json(null, { status: N }) (从第一个 2xx 代码状态,默认为 204) (中文(简体) ). 如果该答复宣布为非JSON内容类型(text/plain, (中文(简体) ), text/csv, (中文(简体) ), application/octet-stream,图像等)处理器发出 new HttpResponse(null, { status: N }) 而不是谎称 application/json。仅限 application/json 内容被假尸体所嘲弄.
  • allOf 合并; anyOf 编号 : oneOf 不属于工会. 全部属性 allOf 成员合并为一个对象及其 required 组合数组。 对于 anyOf 编号 : oneOf 生成器选择第一个混凝土(非)$ref成员,或解决第一个成员,如果所有成员都是裁判.
  • depth_cap 边界重现. 深度反增量只显示在 $ref 决议和决定的执行情况 allOf 编号 : anyOf 编号 : oneOf 决议步骤。 串联式筑巢和平地财产准入不算数。 当深度超过 depth_cap,节点发出 null /* depth cap reached */。 。 。 .
  • 通知通知 完全终止. A 类 $ref 返回到已经访问过的计划名称 null /* circular ref: depth cap reached */,不同于"深度-盖"的注释,所以自取偏好的策略不会循环.
  • 类型联盟和缺失类型. 用于 OpenAPI 3.1 type 数组,生成器使用第一个元素。 计划没有 type 不过 properties 被作为物体对待;否则会发出 null。 。 。 .
  • 道路固守的护栏. input_openapi 财务报告和审定财务报表 output 解析为系统目录的路径( e)/etc, (中文(简体) ), /usr, (中文(简体) ), /bin, (中文(简体) ), C:\Windows,和类似)作为可能的错配置而被拒绝. 这是护栏 不是安全沙盒.

程序化 API

该套件还输出一个方案面,用于围绕它建立工具:

import {
  generateHandlers,
  generateFixtures,
  generate,
  loadConfig,
  loadConfigs,
} from '@codewithagents/openapi-msw'

// Build the handlers file in memory from a parsed spec.
const { filename, content } = generateHandlers(spec, {
  seed: 42,
  maxArrayItems: 3,
  depthCap: 30,
  baseUrl: 'https://api.test', // optional; omit for the '*' wildcard origin
})
// filename === 'handlers.ts'

// Build fixtures.ts in memory.
const fixtures = generateFixtures(spec, {
  seed: 42,
  maxArrayItems: 3,
  depthCap: 30,
  modelsImport: './models.js',
})
// fixtures.filename === 'fixtures.ts'

generate 运行完整的配置驱动流程(装入配置,剖析 spec,写入文件). loadConfig 编号 : loadConfigs 读取并验证配置文件。 导出类型为 MswConfig, (中文(简体) ), HandlerGenOptions, (中文(简体) ), FixtureGenOptions,以及 GeneratedFile。 。 。 .


Openapi-zod-ts套房的一部分

openapi-msw 是其中五个已公布的软件包之一 代码与代理/openapi-zod-ts 单相机 4个生成器从一个 OpenAPI spec 中发送文件,还有一个运行时的帮助者在应用代码中映射 API 错误 :

软件包作用
openapi-zod-ts生成器: TypeScript 模型, 本地获取客户端, 和 Zod schemas
@codewithagents/openapi-server生成器:框架不可知服务接口外加可选 hono | express | fastify | none 路由器( 默认) none(中文(简体) )
@codewithagents/openapi-react-query生成器: 在生成的客户端上输入回放查询 v5 钩
@codewithagents/openapi-msw生成器: 这个包, MSW v2 处理器, 有种子 Faker 模拟数据
@codewithagents/api-errors运行时帮助器:将后端错误响应映射到窗体-字段错误

见 完整存储参考应用 (Fastify + React + reaction-query,有浏览器e2e套件),用于这些包一起工作到结束.


许可证

麻省理工学院

版本与发布记录

@codewithagents/openapi-msw 共发布 5 个版本,首次发布于 2026/06/06;过去 12 个月发布了 5 个版本。最新版本附带 npm provenance 构建来源证明,可追溯到公开的 CI 构建记录。

版本发布日期距今
0.3.0latest2026/11/036 天前
0.2.22026/11/037 天前
0.2.12026/06/224 个月前
0.2.02026/06/114 个月前
0.1.02026/06/065 个月前

关于 @codewithagents/openapi-msw 的常见问题

@codewithagents/openapi-msw 是什么?

以来自 OpenAPI 3.1 的种子 Faker 模拟数据生成 MSW v2 处理器

如何安装 @codewithagents/openapi-msw?

在项目目录运行 npm install @codewithagents/openapi-msw,或使用 pnpm add / yarn add / bun add。它还需要宿主项目提供 peer 依赖:msw(^2.0.0 || ^3.0.0)、@faker-js/faker(^10.5.0)。npm 7 及以上与 pnpm 8 及以上默认会自动安装必需的 peer 依赖,Yarn 需要手动安装。它还提供命令行工具 openapi-msw,可以用 npx openapi-msw 直接运行。

@codewithagents/openapi-msw 支持 TypeScript 吗?

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

@codewithagents/openapi-msw 支持 ESM 还是 CommonJS?

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

@codewithagents/openapi-msw 需要什么版本的 Node.js?

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

@codewithagents/openapi-msw 可以商用吗?

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

@codewithagents/openapi-msw 的下载量有多少?

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

@codewithagents/openapi-msw 还在维护吗?

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