@dynamic-mock-server/mocks-manager
v0.1.0-beta
Published
Mocks manager for Dynamic Mock Server — hot-reload file loading, route handling, and response management
Downloads
95
Maintainers
Readme
@dynamic-mock-server/mocks-manager
Mock management engine for the Dynamic Mock Server
Central manager for all mocks in the Dynamic Mock Server. Manages routes, responses, and routes suites with support for multiple response options per route, hierarchical suite organization, per-route overrides, and hot-reload file watching.
Features
- 🎯 Route Management: Add, update, remove, and query routes with multiple response options
- 🔄 Response Variants: Define multiple responses per route (success, error, loading, etc.)
- 🗂️ Routes Suites: Named collections mapping routes to specific responses
- 📂 Nested Suites: Hierarchical organization with namespace support
- ⭐ Active Suite: Set which suite controls default route responses
- 🔧 Per-Route Overrides: Override specific routes independently of active suite
- ⚡ Fastify Integration: Automatic HTTP request handling via RoutesHandler
- 📁 File Loading: Load routes and suites from JavaScript files with FilesLoader
- 🔥 Hot Reload: Watch mode automatically reloads files on changes (via chokidar)
- 📊 Statistics: Get real-time stats on routes, responses, and suites
Installation
pnpm add @dynamic-mock-server/mocks-managerQuick Start
Basic Usage
import { MocksManager } from "@dynamic-mock-server/mocks-manager";
import Fastify from "fastify";
// Create manager and Fastify app
const mocksManager = new MocksManager();
const app = Fastify();
mocksManager.setApp(app);
// Add a route with multiple response options
mocksManager.addRoute({
id: "get-users",
url: "/api/users",
method: "GET",
responses: [
{
id: "success",
status: 200,
body: [
{ id: 1, name: "John Doe" },
{ id: 2, name: "Jane Smith" },
],
},
{
id: "empty",
status: 200,
body: [],
},
{
id: "error",
status: 500,
body: { error: "Internal server error" },
},
{
id: "slow",
status: 200,
body: [{ id: 1, name: "John" }],
delay: 3000, // Simulate slow response
},
],
});
// Add a routes suite
mocksManager.addSuite({
id: "happy-path",
routes: {
"get-users": "success", // Map route to response
},
});
// Set the active suite
mocksManager.setActiveSuite("happy-path");
// Start server
await app.listen({ port: 3000 });
// GET /api/users now returns "success" responsePer-Route Overrides
// Override a specific route without changing the suite
mocksManager.setRouteResponse("get-users", "error");
// GET /api/users now returns "error" response
// Clear override to return to suite default
mocksManager.setRouteResponse("get-users", null);
// GET /api/users returns "success" again (from suite)Nested Suites Organization
// Organize suites hierarchically
const apiSuites = mocksManager.routesSuites.collection("api");
apiSuites.set("v1", {
id: "api-v1",
routes: { "get-users": "success" },
});
apiSuites.set("v2", {
id: "api-v2",
routes: { "get-users": "empty" },
});
// Access nested suite
const v1Suite = apiSuites.get("v1");Constructor Options
import { MocksManager } from "@dynamic-mock-server/mocks-manager";
import { Config } from "@dynamic-mock-server/config";
import { Logger } from "@dynamic-mock-server/logger";
import { Alerts } from "@dynamic-mock-server/alerts";
const mocksManager = new MocksManager({
// Optional: Enable file loading with hot-reload
config: new Config(),
logger: new Logger(),
alerts: new Alerts(),
// Optional: Initial routes
routes: [
{ id: "route1", url: "/test", method: "GET", responses: [...] }
],
// Optional: Initial suites
suites: [
{ id: "suite1", routes: { "route1": "response1" } }
],
// Optional: Set active suite immediately
activeSuite: "suite1",
});
// Initialize and start file watching
await mocksManager.init();
await mocksManager.start();API Reference
MocksManager
Main class that orchestrates all mock management functionality.
Constructor
constructor(options?: MocksManagerOptions)MocksManagerOptions:
config?: Config- Configuration instance (enables file loading)logger?: Logger- Logger instance (enables file loading)alerts?: Alerts- Alerts instance (enables file loading)routes?: RouteConfig[]- Initial routes to addsuites?: RoutesSuite[]- Initial suites to addactiveSuite?: string- Initial active suite ID
Methods
Route Management
addRoute(config: RouteConfig): void- Add or update a route with its responsesremoveRoute(routeId: string): void- Remove a route by IDaddResponse(routeId: string, response: RouteResponse): void- Add/update a response for a routeremoveResponse(routeId: string, responseId: string): void- Remove a response from a routegetRoutes(): RouteConfig[]- Get all routesgetRoute(routeId: string): RouteConfig | undefined- Get a specific routefindRoute(method: string, url: string): RouteConfig | null- Find route by method and URL
Suite Management
addSuite(suite: RoutesSuite): void- Add or update a routes suiteremoveSuite(suiteId: string): void- Remove a routes suitesetActiveSuite(suiteId: string | null): void- Set the active suite (null to clear)getActiveSuite(): string | null- Get current active suite IDgetSuites(): RoutesSuite[]- Get all routes suitesgetSuite(suiteId: string): RoutesSuite | undefined- Get a specific suite
Response Resolution
setRouteResponse(routeId: string, responseId: string | null): void- Override route responseresolveResponse(routeId: string): RouteResponse | null- Resolve the active response for a route
Lifecycle
async init(): Promise<void>- Initialize FilesLoader if configuredasync start(): Promise<void>- Start file watchingasync stop(): Promise<void>- Stop file watching
Fastify Integration
setApp(app: FastifyInstance): void- Set Fastify instance for HTTP handlinggetApp(): FastifyInstance | undefined- Get the Fastify instance
Utilities
clear(): void- Clear all routes and suitesgetStats(): MocksStats- Get statistics about current state
Properties
routesSuites: NestedRoutesSuites- Access nested routes suitesroutesHandler: RoutesHandler- Access routes handler
Types
RouteConfig
interface RouteConfig {
id: string; // Unique route identifier
url: string; // Route URL (supports Fastify params)
method: HttpMethod; // HTTP method (GET, POST, etc.)
responses: RouteResponse[]; // Array of response options
}RouteResponse
interface RouteResponse {
id: string; // Unique response identifier
status: number; // HTTP status code
body?: any; // Response body (JSON)
headers?: Record<string, string>; // Response headers
delay?: number; // Delay in milliseconds
}RoutesSuite
interface RoutesSuite {
id: string; // Unique suite identifier
routes: Record<string, string>; // Map of routeId -> responseId
}MocksStats
interface MocksStats {
totalRoutes: number; // Total number of routes
totalResponses: number; // Total number of responses
totalSuites: number; // Total number of suites
activeSuite: string | null; // Currently active suite
routeOverrides: number; // Number of per-route overrides
}FilesLoader
Manages loading of mock files with hot-reload support.
Automatically initialized when MocksManager is created with config, logger, and alerts.
File Structure
mocks/
├── routes/ # Route definitions (.js files)
│ ├── users.js
│ └── products.js
└── routesSuites/ # Suite definitions (.js files)
├── base.js
└── errors.jsRoute File Example
// mocks/routes/users.js
export default {
id: "get-users",
url: "/api/users",
method: "GET",
responses: [
{ id: "success", status: 200, body: [{ id: 1, name: "John" }] },
{ id: "error", status: 500, body: { error: "Server Error" } },
],
};Suite File Example
// mocks/routesSuites/base.js
export default {
id: "base",
routes: {
"get-users": "success",
"get-products": "success",
},
};Complete Example
import { MocksManager } from "@dynamic-mock-server/mocks-manager";
import { Config } from "@dynamic-mock-server/config";
import { Logger } from "@dynamic-mock-server/logger";
import { Alerts } from "@dynamic-mock-server/alerts";
import Fastify from "fastify";
// Create MocksManager with file loading
const mocksManager = new MocksManager({
config: new Config(),
logger: new Logger(),
alerts: new Alerts(),
});
// Initialize file loading
await mocksManager.init();
// Add programmatic routes (in addition to file-based ones)
mocksManager.addRoute({
id: "health",
url: "/health",
method: "GET",
responses: [{ id: "ok", status: 200, body: { status: "ok" } }],
});
// Create and configure Fastify
const app = Fastify();
mocksManager.setApp(app);
// Set active suite
mocksManager.setActiveSuite("base");
// Start file watching
await mocksManager.start();
// Start server
await app.listen({ port: 3000 });
console.log("Server running at http://localhost:3000");
console.log("Stats:", mocksManager.getStats());
// Later: stop file watching
await mocksManager.stop();Architecture
MocksManager
├── RoutesHandler (Fastify integration)
│ └── ResponsesHandler (response resolution)
├── NestedRoutesSuites (hierarchical organization)
└── FilesLoader (file loading with chokidar)Dependencies
fastify- HTTP server frameworkchokidar- File watching for hot-reloadfast-glob- File discovery@dynamic-mock-server/config- Configuration management (optional)@dynamic-mock-server/logger- Logging (optional)@dynamic-mock-server/alerts- Alerts system (optional)
Related Packages
- @dynamic-mock-server/core - Core orchestrator
- @dynamic-mock-server/config - Configuration management
- @dynamic-mock-server/logger - Logging utilities
License
Apache-2.0 © Miguel Martínez
