CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-msw

Seamless REST/GraphQL API mocking library for browser and Node.js.

Pending
Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

SecuritybySnyk

Pending

The risk profile of this skill

Overview
Eval results
Files

response-creation.mddocs/

Response Creation

Response creation provides an enhanced Response class with convenience methods for creating various response types with proper headers and content handling.

Capabilities

HttpResponse Class

Enhanced Response class that extends the standard Response with additional features for mocking.

/**
 * Enhanced Response class with additional mocking features
 * Drop-in replacement for standard Response with MSW-specific enhancements
 */
class HttpResponse<BodyType extends DefaultBodyType> extends Response {
  /** Response body type marker for TypeScript */
  readonly [bodyType]: BodyType;
  
  /**
   * Create an HttpResponse instance
   * @param body - Response body content
   * @param init - Response initialization options
   */
  constructor(body?: NoInfer<BodyType> | null, init?: HttpResponseInit);
  
  /** Create network error response */
  static error(): HttpResponse<any>;
}

interface HttpResponseInit extends ResponseInit {
  /** Response type (basic, cors, error, opaque, opaqueredirect) */
  type?: ResponseType;
}

type DefaultBodyType = 
  | string 
  | number 
  | boolean 
  | null 
  | undefined 
  | ArrayBuffer 
  | Blob 
  | FormData 
  | ReadableStream;

Usage Examples:

import { HttpResponse, http } from "msw";

// Basic HttpResponse with string body
http.get('/api/message', () => {
  return new HttpResponse('Hello, world!', {
    status: 200,
    headers: {
      'Content-Type': 'text/plain'
    }
  });
});

// HttpResponse with custom headers and status
http.post('/api/data', () => {
  return new HttpResponse(JSON.stringify({ success: true }), {
    status: 201,
    statusText: 'Created',
    headers: {
      'Content-Type': 'application/json',
      'X-Custom-Header': 'custom-value'
    }
  });
});

// Network error response
http.get('/api/network-error', () => {
  return HttpResponse.error();
});

Text Response Creation

Create text responses with proper Content-Type headers.

/**
 * Create a Response with Content-Type: "text/plain" body
 * @param body - Text content for the response body
 * @param init - Response initialization options
 * @returns HttpResponse with text/plain content type
 */
static text<BodyType extends string>(
  body?: NoInfer<BodyType> | null,
  init?: HttpResponseInit
): HttpResponse<BodyType>;

Usage Examples:

// Simple text response
http.get('/api/message', () => {
  return HttpResponse.text('Hello, world!');
});

// Text response with custom status
http.get('/api/error-message', () => {
  return HttpResponse.text('Something went wrong', {
    status: 500
  });
});

// Text response with custom headers
http.get('/api/plain-text', () => {
  return HttpResponse.text('Plain text content', {
    headers: {
      'Cache-Control': 'no-cache',
      'X-Source': 'mock'
    }
  });
});

// Empty text response
http.delete('/api/resource', () => {
  return HttpResponse.text(null, { status: 204 });
});

// Multiline text response
http.get('/api/readme', () => {
  return HttpResponse.text(`
# README

This is a multiline text response
with proper formatting.

## Features
- Feature 1
- Feature 2
  `.trim());
});

JSON Response Creation

Create JSON responses with proper Content-Type headers and automatic serialization.

/**
 * Create a Response with Content-Type: "application/json" body
 * @param body - JavaScript object/array to serialize as JSON
 * @param init - Response initialization options
 * @returns HttpResponse with application/json content type
 */
static json<BodyType extends JsonBodyType>(
  body?: NoInfer<BodyType> | null | undefined,
  init?: HttpResponseInit
): HttpResponse<BodyType>;

type JsonBodyType = Record<string, any> | any[];

Usage Examples:

// Simple JSON object response
http.get('/api/user', () => {
  return HttpResponse.json({
    id: 1,
    name: 'John Doe',
    email: 'john@example.com'
  });
});

// JSON array response
http.get('/api/users', () => {
  return HttpResponse.json([
    { id: 1, name: 'John Doe' },
    { id: 2, name: 'Jane Smith' }
  ]);
});

// JSON response with custom status
http.post('/api/users', () => {
  return HttpResponse.json(
    { id: 3, name: 'New User', created: true },
    { status: 201 }
  );
});

// Error JSON response
http.get('/api/protected', () => {
  return HttpResponse.json(
    { 
      error: 'Unauthorized',
      code: 'AUTH_REQUIRED',
      message: 'Please provide valid authentication'
    },
    { status: 401 }
  );
});

// Complex nested JSON
http.get('/api/dashboard', () => {
  return HttpResponse.json({
    user: {
      id: 1,
      profile: { name: 'John', avatar: 'avatar.jpg' }
    },
    stats: {
      views: 1234,
      likes: 567,
      comments: 89
    },
    posts: [
      { id: 1, title: 'First Post', published: true },
      { id: 2, title: 'Second Post', published: false }
    ]
  });
});

// Empty JSON response
http.delete('/api/user/1', () => {
  return HttpResponse.json(null, { status: 204 });
});

// JSON response with custom headers
http.get('/api/data', () => {
  return HttpResponse.json(
    { data: 'example' },
    {
      headers: {
        'X-Total-Count': '1',
        'Cache-Control': 'max-age=300'
      }
    }
  );
});

XML Response Creation

Create XML responses with proper Content-Type headers.

/**
 * Create a Response with Content-Type: "application/xml" body
 * @param body - XML string content
 * @param init - Response initialization options
 * @returns HttpResponse with text/xml content type
 */
static xml<BodyType extends string>(
  body?: BodyType | null,
  init?: HttpResponseInit
): HttpResponse<BodyType>;

Usage Examples:

// Simple XML response
http.get('/api/data.xml', () => {
  return HttpResponse.xml(`
    <?xml version="1.0" encoding="UTF-8"?>
    <user>
      <id>1</id>
      <name>John Doe</name>
      <email>john@example.com</email>
    </user>
  `);
});

// XML response with custom status
http.post('/api/soap', () => {
  return HttpResponse.xml(`
    <?xml version="1.0" encoding="UTF-8"?>
    <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
      <soap:Body>
        <response>Success</response>
      </soap:Body>
    </soap:Envelope>
  `, { status: 201 });
});

// RSS feed response
http.get('/api/feed', () => {
  return HttpResponse.xml(`
    <?xml version="1.0" encoding="UTF-8"?>
    <rss version="2.0">
      <channel>
        <title>My Blog</title>
        <description>Latest posts</description>
        <item>
          <title>First Post</title>
          <description>Content of first post</description>
        </item>
      </channel>
    </rss>
  `);
});

// XML error response
http.get('/api/error.xml', () => {
  return HttpResponse.xml(`
    <?xml version="1.0" encoding="UTF-8"?>
    <error>
      <code>404</code>
      <message>Resource not found</message>
    </error>
  `, { status: 404 });
});

HTML Response Creation

Create HTML responses with proper Content-Type headers.

/**
 * Create a Response with Content-Type: "text/html" body
 * @param body - HTML string content
 * @param init - Response initialization options
 * @returns HttpResponse with text/html content type
 */
static html<BodyType extends string>(
  body?: BodyType | null,
  init?: HttpResponseInit
): HttpResponse<BodyType>;

Usage Examples:

// Simple HTML page
http.get('/login', () => {
  return HttpResponse.html(`
    <!DOCTYPE html>
    <html>
      <head><title>Login</title></head>
      <body>
        <form>
          <input type="text" placeholder="Username" />
          <input type="password" placeholder="Password" />
          <button type="submit">Login</button>
        </form>
      </body>
    </html>
  `);
});

// HTML fragment
http.get('/api/widget', () => {
  return HttpResponse.html(`
    <div class="widget">
      <h3>Dynamic Widget</h3>
      <p>This content was generated by MSW</p>
    </div>
  `);
});

// HTML error page
http.get('/not-found', () => {
  return HttpResponse.html(`
    <!DOCTYPE html>
    <html>
      <head><title>404 - Not Found</title></head>
      <body>
        <h1>Page Not Found</h1>
        <p>The requested page could not be found.</p>
      </body>
    </html>
  `, { status: 404 });
});

// Server-side rendered component
http.get('/ssr-component', () => {
  return HttpResponse.html(`
    <div id="app">
      <header>
        <h1>Server Rendered</h1>
      </header>
      <main>
        <p>This HTML was "rendered" by MSW</p>
      </main>
    </div>
  `);
});

Binary Response Creation

Create responses with binary data using ArrayBuffer.

/**
 * Create a Response with an ArrayBuffer body
 * @param body - ArrayBuffer or SharedArrayBuffer content
 * @param init - Response initialization options
 * @returns HttpResponse with application/octet-stream content type
 */
static arrayBuffer<BodyType extends ArrayBuffer | SharedArrayBuffer>(
  body?: BodyType,
  init?: HttpResponseInit
): HttpResponse<BodyType>;

Usage Examples:

// Binary file response
http.get('/api/file.bin', () => {
  const buffer = new ArrayBuffer(16);
  const view = new Uint8Array(buffer);
  
  // Fill with sample binary data
  for (let i = 0; i < view.length; i++) {
    view[i] = i * 2;
  }
  
  return HttpResponse.arrayBuffer(buffer);
});

// Image response (simulated)
http.get('/api/image.png', () => {
  // Create a minimal PNG-like binary structure
  const buffer = new ArrayBuffer(100);
  const view = new Uint8Array(buffer);
  
  // PNG signature (not a real PNG, just for demo)
  view.set([0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A]);
  
  return HttpResponse.arrayBuffer(buffer, {
    headers: {
      'Content-Type': 'image/png'
    }
  });
});

// Binary data with custom content type
http.get('/api/data.custom', () => {
  const buffer = new ArrayBuffer(64);
  const view = new Float32Array(buffer);
  
  // Fill with float data
  for (let i = 0; i < view.length; i++) {
    view[i] = Math.random();
  }
  
  return HttpResponse.arrayBuffer(buffer, {
    headers: {
      'Content-Type': 'application/x-custom-binary'
    }
  });
});

// Download response
http.get('/api/download/:filename', ({ params }) => {
  const buffer = new ArrayBuffer(1024);
  // ... fill buffer with file content
  
  return HttpResponse.arrayBuffer(buffer, {
    headers: {
      'Content-Disposition': `attachment; filename="${params.filename}"`,
      'Content-Type': 'application/octet-stream'
    }
  });
});

Form Data Response Creation

Create responses with FormData bodies.

/**
 * Create a Response with a FormData body
 * @param body - FormData instance
 * @param init - Response initialization options
 * @returns HttpResponse with FormData body
 */
static formData(
  body?: FormData,
  init?: HttpResponseInit
): HttpResponse<FormData>;

Usage Examples:

// Form data response
http.get('/api/form-data', () => {
  const formData = new FormData();
  formData.append('name', 'John Doe');
  formData.append('email', 'john@example.com');
  formData.append('age', '30');
  
  return HttpResponse.formData(formData);
});

// File upload simulation
http.post('/api/upload', () => {
  const formData = new FormData();
  formData.append('status', 'success');
  formData.append('fileId', '12345');
  formData.append('filename', 'uploaded-file.txt');
  
  return HttpResponse.formData(formData, {
    status: 201
  });
});

// Multi-part response with files
http.get('/api/export', () => {
  const formData = new FormData();
  
  // Simulate file content
  const blob = new Blob(['CSV data content'], { type: 'text/csv' });
  formData.append('file', blob, 'export.csv');
  formData.append('format', 'csv');
  formData.append('records', '1000');
  
  return HttpResponse.formData(formData);
});

Custom Response Headers

Set custom headers for enhanced response simulation.

// Response with caching headers
http.get('/api/cached-data', () => {
  return HttpResponse.json(
    { data: 'cached content' },
    {
      headers: {
        'Cache-Control': 'public, max-age=3600',
        'ETag': '"abc123"',
        'Last-Modified': 'Wed, 21 Oct 2015 07:28:00 GMT'
      }
    }
  );
});

// CORS headers
http.options('/api/cors-endpoint', () => {
  return new HttpResponse(null, {
    status: 204,
    headers: {
      'Access-Control-Allow-Origin': '*',
      'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE',
      'Access-Control-Allow-Headers': 'Content-Type, Authorization',
      'Access-Control-Max-Age': '86400'
    }
  });
});

// Security headers
http.get('/api/secure-data', () => {
  return HttpResponse.json(
    { sensitiveData: 'protected' },
    {
      headers: {
        'X-Content-Type-Options': 'nosniff',
        'X-Frame-Options': 'DENY',
        'X-XSS-Protection': '1; mode=block',
        'Strict-Transport-Security': 'max-age=31536000'
      }
    }
  );
});

// Custom API headers
http.get('/api/data', () => {
  return HttpResponse.json(
    { results: [] },
    {
      headers: {
        'X-Total-Count': '0',
        'X-Page': '1',
        'X-Per-Page': '20',
        'X-Rate-Limit-Remaining': '99'
      }
    }
  );
});

Response Status Codes

Handle various HTTP status codes appropriately.

// Success responses
http.get('/api/data', () => {
  return HttpResponse.json({ data: 'ok' }); // 200 OK (default)
});

http.post('/api/resource', () => {
  return HttpResponse.json(
    { id: 1, created: true },
    { status: 201 } // 201 Created
  );
});

http.put('/api/resource/1', () => {
  return HttpResponse.json(
    { id: 1, updated: true },
    { status: 200 } // 200 OK for updates
  );
});

http.delete('/api/resource/1', () => {
  return new HttpResponse(null, { status: 204 }); // 204 No Content
});

// Client error responses
http.get('/api/unauthorized', () => {
  return HttpResponse.json(
    { error: 'Unauthorized' },
    { status: 401 }
  );
});

http.get('/api/forbidden', () => {
  return HttpResponse.json(
    { error: 'Forbidden' },
    { status: 403 }
  );
});

http.get('/api/not-found', () => {
  return HttpResponse.json(
    { error: 'Not found' },
    { status: 404 }
  );
});

http.post('/api/invalid-data', () => {
  return HttpResponse.json(
    { 
      error: 'Validation failed',
      details: { name: 'Required field' }
    },
    { status: 422 }
  );
});

// Server error responses
http.get('/api/server-error', () => {
  return HttpResponse.json(
    { error: 'Internal server error' },
    { status: 500 }
  );
});

http.get('/api/service-unavailable', () => {
  return HttpResponse.json(
    { error: 'Service temporarily unavailable' },
    { status: 503 }
  );
});

// Redirect responses
http.get('/api/redirect', () => {
  return new HttpResponse(null, {
    status: 302,
    headers: {
      'Location': '/api/new-location'
    }
  });
});

Types

// Response class types
class HttpResponse<BodyType extends DefaultBodyType> extends Response {
  readonly [bodyType]: BodyType;
  constructor(body?: NoInfer<BodyType> | null, init?: HttpResponseInit);
  
  static error(): HttpResponse<any>;
  static text<T extends string>(body?: T | null, init?: HttpResponseInit): HttpResponse<T>;
  static json<T extends JsonBodyType>(body?: T | null, init?: HttpResponseInit): HttpResponse<T>;
  static xml<T extends string>(body?: T | null, init?: HttpResponseInit): HttpResponse<T>;
  static html<T extends string>(body?: T | null, init?: HttpResponseInit): HttpResponse<T>;
  static arrayBuffer<T extends ArrayBuffer | SharedArrayBuffer>(body?: T, init?: HttpResponseInit): HttpResponse<T>;
  static formData(body?: FormData, init?: HttpResponseInit): HttpResponse<FormData>;
}

// Body types
type DefaultBodyType = 
  | string 
  | number 
  | boolean 
  | null 
  | undefined 
  | ArrayBuffer 
  | Blob 
  | FormData 
  | ReadableStream;

type JsonBodyType = Record<string, any> | any[];

// Response initialization
interface HttpResponseInit extends ResponseInit {
  status?: number;
  statusText?: string;
  headers?: HeadersInit;
  type?: ResponseType;
}

// Utility types
type NoInfer<T> = [T][T extends any ? 0 : never];

// Symbol for body type tracking
declare const bodyType: unique symbol;

docs

browser-setup.md

cli.md

graphql-handlers.md

http-handlers.md

index.md

nodejs-setup.md

react-native-setup.md

response-creation.md

utilities.md

websocket-handlers.md

tile.json