npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@jjades/msw-auto-mock

v0.1.4

Published

Generate random mock data from OpenAPI descriptions for msw.

Downloads

96

Readme

🎯 msw-auto-mock

OpenAPI 스펙을 기반으로 MSW(Mock Service Worker) 핸들러를 자동으로 생성해주는 라이브러리입니다.

✨ 주요 기능

  • 🚀 OpenAPI 스펙 기반 자동 핸들러 생성
  • 📁 엔티티별 핸들러 파일 분리
  • 🎮 프로그래밍 방식 API 지원
  • 🛠 커스텀 컨트롤러를 통한 응답 커스터마이징 (controllers 타입 추론 지원)
  • 🔄 다양한 응답 타입 지원 (JSON, Event Stream 등)

📦 설치 방법

npm registry에 배포 전이므로, portal 방식으로 link합니다.

1️⃣ 프로젝트 구조 설정

먼저 my-projectmsw-auto-mock을 같은 최상위 디렉토리에 위치시킵니다:

/workspace
├── my-project/    # 구현 프로젝트
└── msw-auto-mock/ # 라이브러리

2️⃣ msw-auto-mock 설정

msw-auto-mock 디렉토리에서:

cd msw-auto-mock
pnpm install
pnpm build

3️⃣ my-project 설정

my-project 디렉토리에서:

  1. package.json에 다음 설정을 추가:
{
  "scripts": {
    "generate-msw-mock": "tsx src/app/mocks/mock-generator.ts"
  },
  "devDependencies": {
    "@dhlab/msw-auto-mock": "^0.31.0"
  },
  "resolutions": {
    "@dhlab/msw-auto-mock": "portal:../msw-auto-mock"
  }
}
  1. 의존성 설치:
cd my-project
yarn

4️⃣ my-project에 mock-generator 스크립트 추가

my-project/src/app/mocks/mock-generator.ts 파일을 생성:

import { type TOptions, generateMocks } from '@dhlab/msw-auto-mock';
import type { TControllers } from './__types__/index';
import { controllers } from './controllers/index';

async function autoGenerateMocks() {
  try {
    console.log('[MSW] 목 파일 생성 시작...');

    const options: TOptions<TControllers> = {
      controllers,
      input: './swagger/openapi.yml',
      outputDir: './src/app/mocks',
      environment: 'react',
      baseUrl: 'https://api.example.com/api/v1',
    };

    const result = await generateMocks(options);

    console.log('[MSW] 목 파일 생성 완료!');
    console.log('[MSW] 생성된 파일 경로:', result.targetFolder);

    return result;
  } catch (error) {
    console.error('[MSW] 목 파일 생성 중 오류 발생:', error);
    throw error;
  }
}

autoGenerateMocks();

5️⃣ MSW 핸들러 생성

my-project 디렉토리에서:

yarn generate-msw-mock

🔧 사용 방법

기본 설정

const options: ProgrammaticOptions = {
  /**
   * OpenAPI 스펙 파일 경로
   * YAML 또는 JSON 형식 지원
   * @required
   */
  input: './swagger/openapi.yml',

  /**
   * 생성된 핸들러 파일이 저장될 디렉토리
   * @optional
   * @default 'src/app/mocks'
   */
  outputDir: './src/app/mocks',

  /**
   * API 기본 URL
   * @optional
   * - string: 지정된 URL을 기본 URL로 사용
   * - true: OpenAPI 스펙의 servers[0].url을 기본 URL로 사용
   */
  baseUrl: 'https://api.example.com',

  /**
   * 생성할 mock 파일의 환경 설정
   * @optional
   * @default 'react'
   * - next: Node.js와 브라우저 환경을 위한 mock 파일 생성
   * - react: 브라우저 환경을 위한 mock 파일 생성
   * - react-native: React Native 환경을 위한 mock 파일 생성
   */
  environment: 'react',

  /**
   * 배열 응답의 최대 길이
   * @optional
   * @default 3
   * faker.js로 생성되는 배열 응답의 최대 아이템 개수를 제한합니다.
   * 예: users 배열이 100개의 아이템을 가질 수 있더라도, maxArrayLength: 3으로 설정하면
   *     최대 3개의 사용자 데이터만 생성됩니다.
   */
  maxArrayLength: 3,

  /**
   * 포함할 API 경로 패턴
   * @optional
   * 예: '/api/v1/*' - /api/v1/로 시작하는 경로만 포함
   */
  includes: '/api/v1/*',

  /**
   * 제외할 API 경로 패턴
   * @optional
   * 예: '/api/v1/health' - /api/v1/health 경로 제외
   */
  excludes: '/api/v1/health',

  /**
   * HTTP 상태 코드
   * @optional
   * 예: '200,201' - 200과 201 상태 코드만 사용
   */
  codes: '200,201',

  /**
   * 정적 응답 사용 여부
   * @optional
   * @default false
   * true: faker.js를 사용하지 않고 정적 응답 생성
   */
  static: false,

  /**
   * 사용자 정의 응답 컨트롤러
   * @optional
   * faker.js를 사용하지 않고 API 엔드포인트별 커스텀 응답 생성
   */
  controllers: {
    getGetUsersUsersGet200Response: () => userList,
    ...
  },

  /**
   * 컨트롤러 import 경로
   * @optional
   * @default '@/app/mocks/controllers'
   */
  controllerPath: '@/app/mocks/controllers',

  /**
   * DTO 타입 import 경로
   * @optional
   * @default '@/shared/api/dto'
   * FSD(Feature-Sliced Design) 패러다임에 따라 기본값이 @/shared/api/dto로 설정됩니다.
   */
  dtoImportPath: '@/shared/api/dto',
};

📁 생성되는 파일 구조

src/app/mocks/
├── __types__/
│   ├── users.type.ts
│   ├── chats.type.ts
│   ├── ...
│   ├── index.ts
├── __handlers__/
│   ├── users.handlers.ts
│   ├── chats.handlers.ts
│   └── ...
│   └── index.ts
└── browser.ts

🔄 지원하는 환경

  • 🌐 React (Browser)
  • ⚡ Next.js (Node.js + Browser)
  • 📱 React Native

🚀 ESM 지원 및 기술적 해결 방안

Node.js 전용 기능이 CommonJS인 이유

generateMocks 함수는 다음과 같은 이유로 CommonJS로만 빌드됩니다:

  1. 의존성 제약: @apidevtools/swagger-parser, swagger2openapi 등의 핵심 의존성이 ESM을 지원하지 않음
  2. 파일 시스템 접근: Node.js의 fs, path 모듈을 직접 사용하여 파일 생성 작업 수행
  3. 안정성: CommonJS 환경에서 검증된 라이브러리들과의 호환성 보장

React 프로젝트에서 ESM 사용 가능

React 프로젝트에서는 다음과 같은 방식으로 ESM을 완전히 지원합니다:

// ✅ React 환경에서 ESM 사용 가능
import { selectResponseByScenario, transformJSONSchemaToFakerCode } from '@dhlab/msw-auto-mock';

// ✅ Node.js 빌드 스크립트에서 CommonJS 사용
// (예: React 프로젝트의 scripts/mock-generator.ts)
import { generateMocks } from '@dhlab/msw-auto-mock/node';

이중 패키지 구조의 장점

@dhlab/msw-auto-mock
├── dist/
│   ├── index.js      # ESM (브라우저, React 등)
│   ├── index.cjs     # CommonJS (Node.js 호환)
│   └── node/
│       └── node.cjs  # Node.js 전용 CommonJS

이 구조를 통해:

  • 브라우저 환경: 가벼운 ESM 번들 사용
  • Node.js 환경: 안정적인 CommonJS 사용
  • React 프로젝트: ESM으로 런타임 기능 사용, 빌드 스크립트는 CommonJS로 파일 생성

설치

npm install @dhlab/msw-auto-mock
# 또는
yarn add @dhlab/msw-auto-mock
# 또는
pnpm add @dhlab/msw-auto-mock

환경별 사용법

기본 사용법 (환경 상관없이)

환경에 상관없이 사용할 수 있는 기능들입니다.

// 타입 정의, 시나리오 선택, 가짜 데이터 생성 등
import { 
  selectResponseByScenario, 
  transformJSONSchemaToFakerCode,
  type TOptions,
  type TScenarioConfig,
  type ResponseObject
} from '@dhlab/msw-auto-mock';

Node.js 환경 (코드 생성)

Node.js 환경에서는 OpenAPI 스키마를 기반으로 MSW 핸들러 파일을 생성할 수 있습니다.

// Node.js 전용 기능
import { generateMocks } from '@dhlab/msw-auto-mock/node';

// 환경 상관없이 사용 가능한 기능들 (필요시 별도 import)
import { 
  selectResponseByScenario, 
  transformJSONSchemaToFakerCode,
  type TOptions 
} from '@dhlab/msw-auto-mock';

await generateMocks({
  input: 'path/to/openapi.json',
  outputDir: 'src/mocks',
  environment: 'react' // 'react', 'next', 'react-native'
});

React 컴포넌트에서 사용 예제

import React, { useState, useEffect } from 'react';
import { http, HttpResponse } from 'msw';
import { selectResponseByScenario, transformJSONSchemaToFakerCode } from '@dhlab/msw-auto-mock';

const MyComponent: React.FC = () => {
  const [mockData, setMockData] = useState(null);

  useEffect(() => {
    // 시나리오 설정
    const scenarios = {
      'user-error': {
        description: '사용자 오류 시나리오',
        api: {
          '/api/users': {
            'GET': { status: 400 }
          }
        }
      },
      'success': {
        description: '성공 시나리오',
        api: {
          '/api/users': {
            'GET': { status: 200 }
          }
        }
      },
      'custom-error': {
        description: '커스텀 에러 시나리오',
        api: {
          '/api/users': {
            'GET': { status: 418, allowCustomStatus: true }
          }
        }
      }
    };

    // MSW 핸들러 설정
    const handler = http.get('/api/users', (info) => {
      const responses = [
        { status: 200, responseType: 'application/json', body: JSON.stringify({ users: [] }) },
        { status: 400, responseType: 'application/json', body: JSON.stringify({ error: 'Bad Request' }) },
        { status: 500, responseType: 'application/json', body: JSON.stringify({ error: 'Server Error' }) }
      ];

      const selectedResponse = selectResponseByScenario('GET', '/api/users', responses, info, scenarios);
      
      return HttpResponse.json(
        JSON.parse(selectedResponse.body || '{}'),
        { status: selectedResponse.status }
      );
    });

    // 가짜 데이터 생성 예제
    const userSchema = {
      type: 'object',
      properties: {
        id: { type: 'string', format: 'uuid' },
        name: { type: 'string' },
        email: { type: 'string', format: 'email' },
        age: { type: 'integer', minimum: 18, maximum: 100 }
      }
    };

    const fakerCode = transformJSONSchemaToFakerCode(userSchema);
    console.log('Generated faker code:', fakerCode);

  }, []);

  return (
    <div>
      <h1>MSW Auto Mock React Example</h1>
      {/* 컴포넌트 내용 */}
    </div>
  );
};

Next.js에서 사용 예제

// pages/api/mocks/setup.ts 또는 app/api/mocks/setup/route.ts
import { generateMocks } from '@dhlab/msw-auto-mock/node';
import type { TOptions } from '@dhlab/msw-auto-mock';

export default async function handler(req: any, res: any) {
  if (process.env.NODE_ENV === 'development') {
    const options: TOptions = {
      input: './public/openapi.json',
      outputDir: './src/mocks',
      environment: 'next'
    };
    
    await generateMocks(options);
    
    res.status(200).json({ message: 'Mocks generated successfully' });
  } else {
    res.status(404).json({ message: 'Not found' });
  }
}
// components/MockProvider.tsx
import React from 'react';
import { selectResponseByScenario } from '@dhlab/msw-auto-mock';

export const MockProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => {
  // 브라우저 환경에서 MSW 설정
  React.useEffect(() => {
    if (typeof window !== 'undefined') {
      import('../mocks/browser').then(({ worker }) => {
        worker.start();
      });
    }
  }, []);

  return <>{children}</>;
};

API 문서

환경 상관없이 사용 가능한 API

selectResponseByScenario

시나리오 기반으로 응답을 선택하는 함수입니다. 헤더 x-scenario를 통해 특정 시나리오를 활성화할 수 있습니다.

function selectResponseByScenario(
  verb: string,
  path: string,
  resultArray: ResponseObject[],
  info: Parameters<HttpResponseResolver<Record<string, never>, null>>[0],
  scenarios?: TScenarioConfig
): ResponseObject

allowCustomStatus 기능

기본적으로 시나리오에서는 OpenAPI 명세에 정의된 status 코드만 사용할 수 있습니다. 하지만 allowCustomStatus: true를 설정하면 명세에 없는 임의의 status 코드도 사용할 수 있습니다.

  • 기본 동작: OpenAPI 명세에 정의된 status 코드만 허용 (타입 안전성 보장)
  • allowCustomStatus: true: 임의의 status 코드 사용 가능 (동적 에러 응답 생성)

사용 예시:

// 시나리오 설정
const scenarios = {
  'success': {
    description: '성공 시나리오',
    api: {
      '/api/users': { 'GET': { status: 200 } }
    }
  },
  'error': {
    description: '에러 시나리오',
    api: {
      '/api/users': { 'GET': { status: 500 } }
    }
  },
  'custom-error': {
    description: '커스텀 에러 시나리오',
    api: {
      '/api/users': { 
        'GET': { 
          status: 418, // "I'm a teapot" - OpenAPI 명세에 없는 status
          allowCustomStatus: true 
        } 
      }
    }
  }
};

// MSW 핸들러에서 사용
const handler = http.get('/api/users', (info) => {
  const responses = [
    { status: 200, responseType: 'application/json', body: '{"users": []}' },
    { status: 500, responseType: 'application/json', body: '{"error": "Server Error"}' }
  ];
  
  // 헤더 기반 시나리오 선택 - 이제 ResponseObject를 직접 반환
  const selectedResponse = selectResponseByScenario('GET', '/api/users', responses, info, scenarios);
  
  return HttpResponse.json(JSON.parse(selectedResponse.body || '{}'), {
    status: selectedResponse.status
  });
});

테스트 시나리오 제어:

# 성공 시나리오 테스트
curl -H "x-scenario: success" http://localhost:3000/api/users

# 에러 시나리오 테스트  
curl -H "x-scenario: error" http://localhost:3000/api/users

# 커스텀 에러 시나리오 테스트 (OpenAPI 명세에 없는 418 status)
curl -H "x-scenario: custom-error" http://localhost:3000/api/users

# 기본 시나리오 (헤더 없음 - 성공 응답 우선)
curl http://localhost:3000/api/users

transformJSONSchemaToFakerCode

OpenAPI 스키마를 Faker.js 코드로 변환하는 함수입니다.

function transformJSONSchemaToFakerCode(
  jsonSchema?: OpenAPIV3.SchemaObject,
  key?: string
): string

🎯 allowCustomStatus 기능 상세 가이드

사용 시나리오

allowCustomStatus: true 기능은 다음과 같은 상황에서 유용합니다:

  1. 테스트 전용 에러 코드: 특정 테스트 시나리오에서만 사용하는 에러 코드
  2. OpenAPI 명세 미정의 응답: 명세에는 없지만 실제 서버에서 발생할 수 있는 응답
  3. 프로토타이핑: 새로운 API 응답을 실험하기 위한 임시 응답

동작 방식

// OpenAPI 명세에 200, 400, 500만 정의되어 있다고 가정
const scenarios = {
  'teapot-error': {
    description: '티팟 에러 테스트',
    api: {
      '/api/users': {
        'GET': { 
          status: 418, // 명세에 없는 status
          allowCustomStatus: true // 허용 플래그
        }
      }
    }
  }
};

생성되는 응답

allowCustomStatus: true로 설정된 시나리오가 활성화되면:

{
  "error": "Client Error", // 400-499는 "Client Error"
  "status": 418
}

또는

{
  "error": "Internal Server Error", // 500+는 "Internal Server Error"  
  "status": 503
}

타입 안전성

TypeScript를 사용하는 경우:

// ❌ 컴파일 에러 - 명세에 없는 status
const badScenario = {
  api: {
    '/api/users': {
      'GET': { status: 418 } // allowCustomStatus 없이는 사용 불가
    }
  }
};

// ✅ 정상 - allowCustomStatus로 명시적 허용
const goodScenario = {
  api: {
    '/api/users': {
      'GET': { status: 418, allowCustomStatus: true }
    }
  }
};

주의사항

  • 명세 일치성: allowCustomStatus는 명세와 목업 간의 일치성을 일부 포기하는 트레이드오프입니다
  • 테스트 전용: 프로덕션 환경이 아닌 테스트/개발 환경에서만 사용하는 것을 권장합니다
  • 문서화: 커스텀 status를 사용하는 경우 팀 내에서 충분한 문서화가 필요합니다

타입 정의

export type TScenarioConfig = {
  [scenarioId: string]: {
    description: string;
    api: Record<string, Record<string, {
      status: number;
      allowCustomStatus?: boolean;
    }>>;
  };
};

export type ResponseObject = {
  status: number;
  responseType: string | undefined;
  body: string | undefined;
};

패키지 구조

이 라이브러리는 기능별로 분리된 패키지로 제공됩니다:

  • 기본 (메인 엔트리): 환경 상관없이 사용 가능한 기능들
  • Node.js 전용: 파일 시스템 접근이 필요한 코드 생성 기능
@dhlab/msw-auto-mock
├── dist/
│   ├── index.js      # 기본 ESM (환경 상관없이)
│   ├── index.cjs     # 기본 CommonJS (환경 상관없이)
│   └── node/
│       ├── node.js   # Node.js 전용 ESM
│       └── node.cjs  # Node.js 전용 CommonJS

사용법 요약

  • 환경 상관없이 사용 가능: import { ... } from '@dhlab/msw-auto-mock'
  • Node.js 전용 기능: import { generateMocks } from '@dhlab/msw-auto-mock/node'

실제 사용 예시

// React/Vue/Angular 등 모든 환경에서
import { selectResponseByScenario, transformJSONSchemaToFakerCode } from '@dhlab/msw-auto-mock';

// Node.js에서 파일 생성 기능이 필요한 경우
import { generateMocks } from '@dhlab/msw-auto-mock/node';

// 둘 다 필요하면 각각 import
import { selectResponseByScenario } from '@dhlab/msw-auto-mock';
import { generateMocks } from '@dhlab/msw-auto-mock/node';

라이선스

MIT