Skip to content

mashabow/mswpida

Repository files navigation

mswpida npm version

A wrapper to use MSW in a type-safe manner for aspida users.

  • Simple
  • Type safe
  • Aspida-like interface

English / 日本語

Installation

npm install mswpida --save-dev

Usage

// 1. Create `typedHttp` from the `api` function generated by aspida.

import { createTypedHttp } from 'mswpida';
import api from './awesome/store/$api';

const typedHttp = createTypedHttp(api);

// 2. Write MSW's request handler using `typedHttp`.

import { HttpResponse } from 'msw';

const handlers = [
  typedHttp.products._productId.images.$post(({ request, params }) => {
    console.log(`Add an image to product ${params.productId}`); // Path parameter is typed ✅

    const reqBody = await request.json();
    console.log(`Image description: ${reqBody.description}`); // Request body is typed ✅

    return HttpResponse.json(
      { id: 123, ...reqBody }, // Response body is also typed ✅
      { status: 201 },
    );
  }),
  // ...
];

// 3. Subsequent usage is the same as the regular MSW usage.

import { setupWorker } from 'msw/browser';
// or
// import { setupServer } from 'msw/node';

await setupWorker(...handlers).start();

createTypedHttp(api, options?)

Creates a typedHttp object based on the api function generated by aspida. This typedHttp is a wrapper to write MSW's request handler.

Options

  • baseURL (optional): Specifies the base URL for the API. Works the same as aspida's baseURL option.
createTypedHttp(api, { baseURL: 'https://staging.example.com' });

typedHttp

An object for writing MSW's request handler. Essentially, it is a thin wrapper for MSW's http. The usage is almost identical to http, but paths and methods are expressed in an aspida-like format.

const handler = typedHttp.products._productId.images.$post(({ request, params }) => ...);

// This is equivalent to:
const handler = http.post('https://example.com/products/:productId/images', ({ request, params }) => ...);

Path

Paths are expressed as properties. While path parameters are expressed with function calls like ._productId('abc123') in aspida, note that in typedRest, they are simply expressed as properties like ._productId.

Use .$path() to get the path of that endpoint as a string.

const path = typedHttp.products._productId.images.$path();
// -> 'https://example.com/products/:productId/images'

Method

Expressed as the $-prefixed HTTP method function, like .$get(resolver) or .$post(resolver). The argument is MSW's response resolver. The following three are typed from aspida's api, so no type annotations are required:

const handler = typedHttp.products._productId.images.$post(
  ({ request, params }) => {
    console.log(`Add an image to product ${params.productId}`); // Path parameter is typed ✅

    const reqBody = await request.json();
    console.log(`Image description: ${reqBody.description}`); // Request body is typed ✅

    return HttpResponse.json(
      { id: 123, ...reqBody }, // Response body is also typed ✅
      { status: 201 },
    );
  },
);

FAQ

How can I return an error response without getting a type error?

By using method with a type parameter like .$get<T>() or .$post<T>(), you can return T as the response body without getting a type error.

type ErrorResponseBody = { errorCode: string };

const handler = typedHttp.products._productId.images.$post<ErrorResponseBody>(
  ({ request, params }) => {
    if (params.productId === 'bad_id') {
      return HttpResponse.json(
        { errorCode: 'product_not_found' },
        { status: 404 },
      );
    }
    const reqBody = await request.json();
    return HttpResponse.json({ id: 123, ...reqBody }, { status: 201 });
  },
);

Can I use it with MSW v1?

Please use mswpida v1 for MSW v1.

License

MIT