# @codewithagents/openapi-msw 中文文档

规范地址：https://npmcn.com/package/%40codewithagents/openapi-msw/

版本：0\.3\.0
npm 元数据更新时间：2026-11-03T09:41:45.059Z
中文译文更新时间：2026-11-10T08:26:25.209Z
软件包许可：MIT

本文由上游 README 翻译，可能存在偏差，请结合原文核对 API、命令与配置。版权与许可归原作者所有。

原始 npm 页面：https://www.npmjs.com/package/%40codewithagents/openapi-msw
原文对照：https://npmcn.com/package/%40codewithagents/openapi-msw/?lang=original
项目主页：https://openapi.codewithagents.de/openapi-msw
源码仓库：https://github.com/codewithagents/openapi-zod-ts

## 关键信息（来自 npm 元数据）

- 包体积（解压后）：836 kB，35 个文件
- 模块格式：ES Module
- TypeScript 类型：包内自带
- Node.js 要求：\>=22\.19\.0
- 运行依赖：3 个
- peer 依赖：msw ^2\.0\.0 \|\| ^3\.0\.0，@faker-js/faker ^10\.5\.0
- 首次发布：2026-06-05T20:26:31.349Z
- 最新版本发布：2026-11-03T09:41:43.857Z
- 近 30 天下载量：3226（2026-10-10 至 2026-11-08，npm 官方下载统计）
- 已发布版本数：5（近 12 个月 5 个）

## 中文简介

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

## 安装

```sh
npm install @codewithagents/openapi-msw
```

也可以使用：`pnpm add @codewithagents/openapi-msw`、`yarn add @codewithagents/openapi-msw`、`bun add @codewithagents/openapi-msw`

## README

# @ codewits/ openapi- msw

[![npm](https://img.shields.io/npm/v/@codewithagents/openapi-msw.svg)](https://npmjs.com/package/@codewithagents/openapi-msw) [![CI](https://github.com/codewithagents/openapi-zod-ts/actions/workflows/ci.yml/badge.svg)](https://github.com/codewithagents/openapi-zod-ts/actions/workflows/ci.yml) [![codecov](https://codecov.io/gh/codewithagents/openapi-zod-ts/graph/badge.svg?flag=openapi-msw)](https://codecov.io/gh/codewithagents/openapi-zod-ts) [![CodeQL](https://github.com/codewithagents/openapi-zod-ts/actions/workflows/codeql.yml/badge.svg)](https://github.com/codewithagents/openapi-zod-ts/actions/workflows/codeql.yml)

📖 **[完整文档](https://openapi.codewithagents.de/openapi-msw)**

`@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?)` 内置,每个测试处理器每个组件的构建器。 见 [固定建筑工](https://npmcn.com/package/%40codewithagents/openapi-msw/#readme-fixture-builders-fixtures-true)。 。 。 .
-   **高级清洁输出**: 生成 `handlers.ts` 通过 `prettier --check` 从盒子里出来.
-   **打开API 3.x**:3.1.x是首要目标;3.0x在实践中得到支持(13个显示规格中的8个是3.0.x,全部编译在下) `tsc --strict`) (中文(简体) ).

* * *

## 安装

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

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

```bash
pnpm add msw @faker-js/faker
```

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

此软件包取决于 [`openapi-zod-ts`](https://npmcn.com/package/%40codewithagents/openapi-zod-ts) 用于 spec 解析和共享配置管道,但不要求您生成模型或客户端。 单独运行 或与其余的套房.

* * *

## 快开始

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

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

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

**2\. 运行生成器:**

```bash
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:

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

export const worker = setupWorker(...handlers)
```

```ts
// 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` 看起来像这样:

```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`](https://npmcn.com/package/%40codewithagents/integration/generated/handlers.ts)从 [`packages/integration/spec/api.json`](https://npmcn.com/package/%40codewithagents/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` | 没有 | `30` | Schema 重现深度后再跳出 `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` 掷出.

```json
{
  "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`数字 :

```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` 生成器会发出 :

```ts
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)]`。 。 。 .
-   **尼斯特德计划再利用他们的建造者.** 一个财产 `$ref`s 另外一个组件计划称为 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`,格式 `email` | `faker.internet.email()` |
| `string`,格式 `uuid` | `faker.string.uuid()` |
| `string`,格式 `date-time` | `faker.date.recent().toISOString()` |
| `string`,格式 `date` | `faker.date.recent().toISOString().slice(0, 10)` |
| `string`,格式 `uri` 编号 : `url` | `faker.internet.url()` |
| `string` (其他部分) | `faker.lorem.word()` |
| `integer`, (中文(简体) ), `int32`, (中文(简体) ), `int64` | `faker.number.int({ min: 1, max: 1000 })` |
| `number` (其他部分) | `faker.number.float({ min: 0, max: 1000, fractionDigits: 2 })` |
| `boolean` | `faker.datatype.boolean()` |
| `enum` | `faker.helpers.arrayElement([...literals])` |
| `array` | `Array.from({ length: max_array_items }, () => item)` |
| 对象为 `additionalProperties` | `Object.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

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

```ts
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](https://github.com/codewithagents/openapi-zod-ts) 单相机 4个生成器从一个 OpenAPI spec 中发送文件,还有一个运行时的帮助者在应用代码中映射 API 错误 :

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

见 [完整存储参考应用](https://github.com/codewithagents/openapi-zod-ts/tree/main/packages/petstore-fastify) (Fastify + React + reaction-query,有浏览器e2e套件),用于这些包一起工作到结束.

* * *

## 许可证

麻省理工学院

## 常见问题

### @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 和提交记录判断。

