| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970 |
- import { http, HttpResponse, HttpResponseResolver } from 'msw'
- import { setupServer } from 'msw/node'
- import type { paths } from '../../data/api'
- import { GlobalAPIMocks } from './msw-global-api-mocks'
- import { API_URL } from '@/lib/constants'
- export const mswServer = setupServer(...GlobalAPIMocks)
- mswServer.events.on('request:start', ({ request }) => {
- console.log('[MSW] Outgoing:', request.method, request.url)
- })
- // Recursively changes params in an endpoint path segment from {param}
- // format to :param format which is expected by Mock Service Worker
- type RemapParams<T extends string> = T extends `${infer Before}{${infer Param}}${infer After}`
- ? `${Before}:${Param}${RemapParams<After>}`
- : T
- type TrimQueryParams<T extends string> = T extends `${infer Endpoint}?${string}` ? Endpoint : T
- // We need to remap all keys from our openapi-typescript generated types
- // so that they follow MSW's parameter formatting
- type RemapPaths = {
- [K in keyof paths as RemapParams<K>]: paths[K]
- }
- type Endpoints = keyof RemapPaths
- type Methods = Exclude<keyof typeof http, 'all'>
- // Extract either the 200 or 201 response object
- type SuccessResponse<P extends Endpoints, M extends Methods> = RemapPaths[P][M] extends {
- responses: { 200: { content: { 'application/json': infer R200 } } }
- }
- ? R200
- : RemapPaths[P][M] extends {
- responses: { 201: { content: { 'application/json': infer R201 } } }
- }
- ? R201
- : never
- const isResponseResolver = (val: unknown): val is HttpResponseResolver => typeof val === `function`
- export const addAPIMock = <P extends Endpoints | `${Endpoints}?${string}`, M extends Methods>({
- method,
- path,
- response,
- }: SuccessResponse<TrimQueryParams<P>, M> extends never
- ? // Don't require a mocked response when the API doesn't return one
- { method: M; path: P; response?: never }
- : {
- method: M
- path: P
- response: SuccessResponse<TrimQueryParams<P>, M> | HttpResponseResolver
- }) => {
- const fullPath = `${API_URL}${path}`
- console.log('[MSW] Adding mock:', method.toUpperCase(), fullPath)
- mswServer.use(
- http[method](
- fullPath,
- isResponseResolver(response)
- ? response
- : ({ request }) => {
- console.log('[MSW] Handling request:', request.method, request.url, response)
- return HttpResponse.json(response ?? null)
- }
- )
- )
- }
|