msw-auto-handlers
v0.3.0
Published
Generate msw handlers code (in TypeScript) automatically based on the OpenAPI documentation and TypeScript interface files.
Downloads
404
Maintainers
Readme
MSW AUTO HANDLERS
Generate source codes of msw's handlers
from OpenAPI specifications and your typescript services codes.
Easy to find and modify mocks of some complicated APIs.
Join Services with Mocks together, let it to be maintained much more easily.
Features
- works with CLI, Node.js 18+, or npx
- supports OpenAPI 3.0, 3.1 specifications
- supports JSON input files
- generates handlers from
openapi-ts
oryapi-to-typescript
andopenapi specifications
- intergrates @mswjs/data, @mswjs/source
How to use
# 1. Install
npm install --save-dev msw-auto-handlers msw @mswjs/data @mswjs/source
# 2. Generate handlers
msw-auto-handlers --config msw-auto.config.js
# // msw-auto.config.js
# export default {
# type: 'openapi-ts', // or 'ytt'
# inputApiFilePath: './tests/generated/pet/services.gen', // generated by openapi-ts
# inputTypeFilePath: './tests/generated/pet/types.gen', // generated by openapi-ts
# outputFileFolderPath: './mocks',
# openapiDoc: './tests/spec/pet.json' // or url (OpenAPI specifications)
# }
Examples
// ./mocks/index.ts
import { setupWorker } from 'msw/browser';
import { combineHandlers } from 'msw-auto-handlers';
import * as generated from './generated/handlers.gen';
import * as v1 from './v1';
const handlerExports = [v1, generated];
const handlers = combineHandlers(handlerExports, {
delay: null, // random delay
baseUrl: '/api', // interface prefix
});
export const worker = setupWorker(...handlers);
// ./mocks/v1.ts
import { HttpResponse } from 'msw';
import { createHandler, http } from 'msw-auto-handlers';
import * as generated from './generated/handlers.gen';
export const handlers = [
// Create classic msw handler
http.post('/data', () => HttpResponse.json({ data: 'hello' })),
// Or create configure msw handler using createHandler
createHandler(http.put('/data'), () => HttpResponse.json({ data: 'world' }, { status: 201 })),
// Or override exsiting handler from generated codes.
createHandler(generated.updatePet, () => HttpResponse.json({ data: 'world' }, { status: 201 })),
// Or add some config for exsiting handler from generated codes.
createHandler(generated.addPet, null, {
delay: 3*1000, // easy to add some delay
timeout: 30*1000, // or timeout
disabled: true, // disabled this handler
}),
];
// We could disabled all the generated handlers here or anywhere;
generated.config.disabled = true;
// ./mocks/generated/handlers.gen.ts
import { http, HttpHandler, StrictResponse, JsonBodyType } from 'msw';
import type { UpdatePetData, UpdatePetResponse, AddPetData, AddPetResponse } from '../../src/api/client/types.gen';
import * as services from './handlerHelper.gen';
export const updatePet = http.put<RequestParams<UpdatePetData>, RequestBody<UpdatePetData>, ResponseBody<UpdatePetResponse>>(
'/pet', services.updatePet.response
);
export const addPet = http.post<RequestParams<AddPetData>, RequestBody<AddPetData>, ResponseBody<AddPetResponse>>(
'/pet', services.addPet.response
);
export const handlers = [updatePet, addPet];
// ./mocks/generated/handlerHelper.gen.ts
import { HttpHandler, HttpResponse } from 'msw';
import { sourceHandlers } from './source.gen';
import * as services from '../../src/api/client/services.gen';
export const updatePet = {
method: 'put',
url: '/pet',
request: services.updatePet,
response: (request: unknown) => resolveHandler(updatePet)(request),
} as const;
export const addPet = {
method: 'post',
url: '/pet',
request: services.addPet,
response: (request: unknown) => resolveHandler(addPet)(request),
} as const;
export const resolveHandler = (requestMeta: { method: string; url: string }) => {
const header = [requestMeta.method, requestMeta.url].map(i => i.toLowerCase()).join(' ');
return sourceHandlers.find((item: HttpHandler) => item.info.header.toLowerCase() === header).resolver;
};