{"version":3,"sources":["../../src/test/convert-array-to-async-iterable.ts","../../src/test/convert-array-to-readable-stream.ts","../../src/test/convert-async-iterable-to-array.ts","../../src/test/convert-readable-stream-to-array.ts","../../src/test/convert-response-stream-to-array.ts","../../src/test/is-node-version.ts","../../src/test/mock-id.ts","../../src/test/test-server.ts"],"sourcesContent":["export function convertArrayToAsyncIterable<T>(values: T[]): AsyncIterable<T> {\n  return {\n    async *[Symbol.asyncIterator]() {\n      for (const value of values) {\n        yield value;\n      }\n    },\n  };\n}\n","export function convertArrayToReadableStream<T>(\n  values: T[],\n): ReadableStream<T> {\n  return new ReadableStream({\n    start(controller) {\n      try {\n        for (const value of values) {\n          controller.enqueue(value);\n        }\n      } finally {\n        controller.close();\n      }\n    },\n  });\n}\n","export async function convertAsyncIterableToArray<T>(\n  iterable: AsyncIterable<T>,\n): Promise<T[]> {\n  const result: T[] = [];\n  for await (const item of iterable) {\n    result.push(item);\n  }\n  return result;\n}\n","export async function convertReadableStreamToArray<T>(\n  stream: ReadableStream<T>,\n): Promise<T[]> {\n  const reader = stream.getReader();\n  const result: T[] = [];\n\n  while (true) {\n    const { done, value } = await reader.read();\n    if (done) break;\n    result.push(value);\n  }\n\n  return result;\n}\n","import { convertReadableStreamToArray } from './convert-readable-stream-to-array';\n\nexport async function convertResponseStreamToArray(\n  response: Response,\n): Promise<string[]> {\n  return convertReadableStreamToArray(\n    response.body!.pipeThrough(new TextDecoderStream()),\n  );\n}\n","export function isNodeVersion(version: number) {\n  const nodeMajorVersion = parseInt(process.version.slice(1).split('.')[0], 10);\n  return nodeMajorVersion === version;\n}\n","export function mockId({\n  prefix = 'id',\n}: {\n  prefix?: string;\n} = {}): () => string {\n  let counter = 0;\n  return () => `${prefix}-${counter++}`;\n}\n","import { http, HttpResponse, JsonBodyType } from 'msw';\nimport { setupServer } from 'msw/node';\nimport { convertArrayToReadableStream } from './convert-array-to-readable-stream';\nimport { beforeAll, beforeEach, afterAll } from 'vitest';\n\nexport type UrlResponse =\n  | {\n      type: 'json-value';\n      headers?: Record<string, string>;\n      body: JsonBodyType;\n    }\n  | {\n      type: 'stream-chunks';\n      headers?: Record<string, string>;\n      chunks: Array<string>;\n    }\n  | {\n      type: 'binary';\n      headers?: Record<string, string>;\n      body: Buffer;\n    }\n  | {\n      type: 'empty';\n      headers?: Record<string, string>;\n      status?: number;\n    }\n  | {\n      type: 'error';\n      headers?: Record<string, string>;\n      status?: number;\n      body?: string;\n    }\n  | {\n      type: 'controlled-stream';\n      headers?: Record<string, string>;\n      controller: TestResponseController;\n    }\n  | undefined;\n\ntype UrlResponseParameter =\n  | UrlResponse\n  | UrlResponse[]\n  | ((options: { callNumber: number }) => UrlResponse);\n\nexport type UrlHandler = {\n  response: UrlResponseParameter;\n};\n\nexport type UrlHandlers<\n  URLS extends {\n    [url: string]: {\n      response?: UrlResponseParameter;\n    };\n  },\n> = {\n  [url in keyof URLS]: UrlHandler;\n};\n\nclass TestServerCall {\n  constructor(private request: Request) {}\n\n  get requestBodyJson() {\n    return this.request!.text().then(JSON.parse);\n  }\n\n  get requestBodyMultipart() {\n    return this.request!.headers.get('content-type')?.startsWith(\n      'multipart/form-data',\n    )\n      ? // For multipart/form-data, return the form data entries as an object\n        this.request!.formData().then(formData => {\n          const entries: Record<string, any> = {};\n          formData.forEach((value, key) => {\n            entries[key] = value;\n          });\n          return entries;\n        })\n      : null;\n  }\n\n  get requestCredentials() {\n    return this.request!.credentials;\n  }\n\n  get requestHeaders() {\n    const requestHeaders = this.request!.headers;\n\n    // convert headers to object for easier comparison\n    const headersObject: Record<string, string> = {};\n    requestHeaders.forEach((value, key) => {\n      if (key.toLowerCase() === 'user-agent') return;\n      headersObject[key] = value;\n    });\n\n    return headersObject;\n  }\n\n  get requestUserAgent(): string | undefined {\n    return this.request!.headers.get('user-agent') ?? undefined;\n  }\n\n  get requestUrlSearchParams() {\n    return new URL(this.request!.url).searchParams;\n  }\n\n  get requestUrl() {\n    return this.request!.url;\n  }\n\n  get requestMethod() {\n    return this.request!.method;\n  }\n}\n\nexport function createTestServer<\n  URLS extends {\n    [url: string]: {\n      response?: UrlResponseParameter;\n    };\n  },\n>(\n  routes: URLS,\n): {\n  urls: UrlHandlers<URLS>;\n  calls: TestServerCall[];\n} {\n  const originalRoutes = structuredClone(routes); // deep copy\n\n  const mswServer = setupServer(\n    ...Object.entries(routes).map(([url, handler]) => {\n      return http.all(url, ({ request }) => {\n        const callNumber = calls.length;\n\n        calls.push(new TestServerCall(request));\n\n        const response =\n          typeof handler.response === 'function'\n            ? handler.response({ callNumber })\n            : Array.isArray(handler.response)\n              ? handler.response[callNumber]\n              : handler.response;\n\n        if (response === undefined) {\n          return HttpResponse.json({ error: 'Not Found' }, { status: 404 });\n        }\n\n        const handlerType = response.type;\n\n        switch (handlerType) {\n          case 'json-value':\n            return HttpResponse.json(response.body, {\n              status: 200,\n              headers: {\n                'Content-Type': 'application/json',\n                ...response.headers,\n              },\n            });\n\n          case 'stream-chunks':\n            return new HttpResponse(\n              convertArrayToReadableStream(response.chunks).pipeThrough(\n                new TextEncoderStream(),\n              ),\n              {\n                status: 200,\n                headers: {\n                  'Content-Type': 'text/event-stream',\n                  'Cache-Control': 'no-cache',\n                  Connection: 'keep-alive',\n                  ...response.headers,\n                },\n              },\n            );\n\n          case 'controlled-stream': {\n            if (request.signal) {\n              request.signal.addEventListener('abort', () => {\n                response.controller.error(\n                  new DOMException('Aborted', 'AbortError'),\n                );\n              });\n            }\n\n            return new HttpResponse(\n              response.controller.stream.pipeThrough(new TextEncoderStream()),\n              {\n                status: 200,\n                headers: {\n                  'Content-Type': 'text/event-stream',\n                  'Cache-Control': 'no-cache',\n                  Connection: 'keep-alive',\n                  ...response.headers,\n                },\n              },\n            );\n          }\n\n          case 'binary': {\n            return HttpResponse.arrayBuffer(response.body, {\n              status: 200,\n              headers: response.headers,\n            });\n          }\n\n          case 'error':\n            return HttpResponse.text(response.body ?? 'Error', {\n              status: response.status ?? 500,\n              headers: response.headers,\n            });\n\n          case 'empty':\n            return new HttpResponse(null, {\n              status: response.status ?? 200,\n            });\n\n          default: {\n            const _exhaustiveCheck: never = handlerType;\n            throw new Error(`Unknown response type: ${_exhaustiveCheck}`);\n          }\n        }\n      });\n    }),\n  );\n\n  let calls: TestServerCall[] = [];\n\n  beforeAll(() => {\n    mswServer.listen();\n  });\n\n  beforeEach(() => {\n    mswServer.resetHandlers();\n\n    // set the responses back to the original values\n    Object.entries(originalRoutes).forEach(([url, handler]) => {\n      routes[url].response = handler.response;\n    });\n\n    calls = [];\n  });\n\n  afterAll(() => {\n    mswServer.close();\n  });\n\n  return {\n    urls: routes as UrlHandlers<URLS>,\n    get calls() {\n      return calls;\n    },\n  };\n}\n\nexport class TestResponseController {\n  private readonly transformStream: TransformStream;\n  private readonly writer: WritableStreamDefaultWriter;\n\n  constructor() {\n    this.transformStream = new TransformStream();\n    this.writer = this.transformStream.writable.getWriter();\n  }\n\n  get stream(): ReadableStream {\n    return this.transformStream.readable;\n  }\n\n  async write(chunk: string): Promise<void> {\n    await this.writer.write(chunk);\n  }\n\n  async error(error: Error): Promise<void> {\n    await this.writer.abort(error);\n  }\n\n  async close(): Promise<void> {\n    await this.writer.close();\n  }\n}\n"],"mappings":"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","names":[]}