Skip to main content

mockforge_core/
lib.rs

1//! # MockForge Core
2//!
3//! Core functionality and shared logic for the MockForge mocking framework.
4//!
5//! This crate provides the foundational building blocks used across all MockForge protocols
6//! (HTTP, WebSocket, gRPC, GraphQL). It can be used as a library to programmatically create
7//! and manage mock servers, or to build custom mocking solutions.
8//!
9//! ## Overview
10//!
11//! MockForge Core includes:
12//!
13//! - **Routing & Validation**: OpenAPI-based route registration and request validation
14//! - **Request/Response Processing**: Template expansion, data generation, and transformation
15//! - **Chaos Engineering**: Latency injection, failure simulation, and traffic shaping
16//! - **Proxy & Hybrid Mode**: Forward requests to real backends with intelligent fallback
17//! - **Request Chaining**: Multi-step request workflows with context passing
18//! - **Workspace Management**: Organize and persist mock configurations
19//! - **Observability**: Request logging, metrics collection, and tracing
20//!
21//! ## Quick Start: Embedding MockForge
22//!
23//! ### Creating a Simple HTTP Mock Server
24//!
25//! NOTE: marked `ignore` (not `no_run`) — the example references types
26//! that moved out of `mockforge-core` during the workspace splits in
27//! commits 2ec7625a (openapi) and b75e243c (foundation):
28//! `OpenApiSpec`, `OpenApiRouteRegistry`, and `ValidationOptions` now
29//! live in `mockforge_openapi`; `LatencyProfile` is in
30//! `mockforge_foundation`. Until the example is rewritten using only
31//! symbols still re-exported from `mockforge_core`, marking it `ignore`
32//! keeps it visible as docs without breaking `cargo test --doc`.
33//!
34//! ```rust,ignore
35//! use mockforge_core::{
36//!     Config, LatencyProfile, OpenApiRouteRegistry, OpenApiSpec, Result, ValidationOptions,
37//! };
38//!
39//! #[tokio::main]
40//! async fn main() -> Result<()> {
41//!     // Load OpenAPI specification
42//!     let spec = OpenApiSpec::from_file("api.json").await?;
43//!
44//!     // Create route registry with validation
45//!     let registry = OpenApiRouteRegistry::new_with_options(spec, ValidationOptions::default());
46//!
47//!     // Configure core features
48//!     let config = Config {
49//!         latency_enabled: true,
50//!         failures_enabled: false,
51//!         default_latency: LatencyProfile::with_normal_distribution(400, 120.0),
52//!         ..Default::default()
53//!     };
54//!
55//!     // Build your HTTP server with the registry
56//!     // (See mockforge-http crate for router building)
57//!
58//!     Ok(())
59//! }
60//! ```
61//!
62//! ### Request Chaining
63//!
64//! Chain multiple requests together with shared context:
65//!
66//! ```rust,no_run
67//! use mockforge_core::{
68//!     ChainConfig, ChainDefinition, ChainLink, ChainRequest, RequestChainRegistry, Result,
69//! };
70//! use mockforge_core::request_chaining::RequestBody;
71//! use serde_json::json;
72//! use std::collections::HashMap;
73//!
74//! # async fn example() -> Result<()> {
75//! let registry = RequestChainRegistry::new(ChainConfig::default());
76//!
77//! // Define a chain: create user → add to group → verify membership
78//! let chain = ChainDefinition {
79//!     id: "user_onboarding".to_string(),
80//!     name: "User Onboarding".to_string(),
81//!     description: Some("Create user → add to group".to_string()),
82//!     config: ChainConfig {
83//!         enabled: true,
84//!         ..ChainConfig::default()
85//!     },
86//!     links: vec![
87//!         ChainLink {
88//!             request: ChainRequest {
89//!                 id: "create_user".to_string(),
90//!                 method: "POST".to_string(),
91//!                 url: "https://api.example.com/users".to_string(),
92//!                 headers: HashMap::new(),
93//!                 body: Some(RequestBody::json(json!({"name": "{{faker.name}}"}))),
94//!                 depends_on: Vec::new(),
95//!                 timeout_secs: None,
96//!                 expected_status: None,
97//!                 scripting: None,
98//!             },
99//!             extract: HashMap::from([("user_id".to_string(), "create_user.body.id".to_string())]),
100//!             store_as: Some("create_user_response".to_string()),
101//!         },
102//!         ChainLink {
103//!             request: ChainRequest {
104//!                 id: "add_to_group".to_string(),
105//!                 method: "POST".to_string(),
106//!                 url: "https://api.example.com/groups/{{user_id}}/members".to_string(),
107//!                 headers: HashMap::new(),
108//!                 body: None,
109//!                 depends_on: vec!["create_user".to_string()],
110//!                 timeout_secs: None,
111//!                 expected_status: None,
112//!                 scripting: None,
113//!             },
114//!             extract: HashMap::new(),
115//!             store_as: None,
116//!         },
117//!     ],
118//!     variables: HashMap::new(),
119//!     tags: vec!["onboarding".to_string()],
120//! };
121//!
122//! registry.store().register_chain(chain).await?;
123//! # Ok(())
124//! # }
125//! ```
126//!
127//! ### Latency & Failure Injection
128//!
129//! Simulate realistic network conditions and errors:
130//!
131//! NOTE: also marked `ignore` for the same reason as the Quick Start
132//! example above — `LatencyProfile`, `FailureConfig`, and
133//! `create_failure_injector` no longer live in `mockforge_core` after
134//! the foundation/openapi extraction. Rewrite to use the actual hosting
135//! crates when this section is updated.
136//!
137//! ```rust,ignore
138//! use mockforge_core::{LatencyProfile, FailureConfig, create_failure_injector};
139//!
140//! // Configure latency simulation
141//! let latency = LatencyProfile::with_normal_distribution(400, 120.0)
142//!     .with_min_ms(100)
143//!     .with_max_ms(800);
144//!
145//! // Configure failure injection
146//! let failure_config = FailureConfig {
147//!     global_error_rate: 0.05, // 5% of requests fail
148//!     default_status_codes: vec![500, 502, 503],
149//!     ..Default::default()
150//! };
151//!
152//! let injector = create_failure_injector(true, Some(failure_config));
153//! ```
154//!
155//! ## Key Modules
156//!
157//! ### OpenAPI Support
158//! - [`openapi`]: Parse and work with OpenAPI specifications
159//! - [`openapi_routes`]: Register routes from OpenAPI specs with validation
160//! - [`validation`]: Request/response validation against schemas
161//!
162//! ### Request Processing
163//! - [`routing`]: Route matching and registration
164//! - [`templating`]: Template variable expansion ({{uuid}}, {{now}}, etc.)
165//! - [`request_chaining`]: Multi-step request workflows
166//! - [`overrides`]: Dynamic request/response modifications
167//!
168//! ### Chaos Engineering
169//! - [`latency`]: Latency injection with configurable profiles
170//! - [`failure_injection`]: Simulate service failures and errors
171//! - [`traffic_shaping`]: Bandwidth limiting and packet loss
172//!
173//! ### Proxy & Hybrid
174//! - [`proxy`]: Forward requests to upstream services
175//! - [`ws_proxy`]: WebSocket proxy with message transformation
176//!
177//! ### Persistence & Import
178//! - [`workspace`]: Workspace management for organizing mocks
179//! - [`workspace_import`]: Import from Postman, Insomnia, cURL, HAR
180//! - [`record_replay`]: Record real requests and replay as fixtures
181//!
182//! ### Observability
183//! - [`request_logger`]: Centralized request logging
184//! - [`performance`]: Performance metrics and profiling
185//!
186//! ## Feature Flags
187//!
188//! This crate supports several optional features:
189//!
190//! - `openapi`: OpenAPI specification support (enabled by default)
191//! - `validation`: Request/response validation (enabled by default)
192//! - `templating`: Template expansion (enabled by default)
193//! - `chaos`: Chaos engineering features (enabled by default)
194//! - `proxy`: Proxy and hybrid mode (enabled by default)
195//! - `workspace`: Workspace management (enabled by default)
196//!
197//! ## Examples
198//!
199//! See the [examples directory](https://github.com/SaaSy-Solutions/mockforge/tree/main/examples)
200//! for complete working examples.
201//!
202//! ## Related Crates
203//!
204//! - [`mockforge-http`](https://docs.rs/mockforge-http): HTTP/REST mock server
205//! - [`mockforge-grpc`](https://docs.rs/mockforge-grpc): gRPC mock server
206//! - [`mockforge-ws`](https://docs.rs/mockforge-ws): WebSocket mock server
207//! - [`mockforge-graphql`](https://docs.rs/mockforge-graphql): GraphQL mock server
208//! - [`mockforge-plugin-core`](https://docs.rs/mockforge-plugin-core): Plugin development
209//! - [`mockforge-data`](https://docs.rs/mockforge-data): Synthetic data generation
210//!
211//! ## Documentation
212//!
213//! - [MockForge Book](https://docs.mockforge.dev/)
214//! - [API Reference](https://docs.rs/mockforge-core)
215//! - [GitHub Repository](https://github.com/SaaSy-Solutions/mockforge)
216
217#![allow(deprecated)]
218
219#[cfg(feature = "advanced")]
220pub mod ab_testing;
221#[cfg(feature = "ai")]
222// Data types moved to mockforge-foundation (A15/A19);
223// ContractDiffAnalyzer stays here as it is LLM-bound.
224pub mod ai_contract_diff;
225#[cfg(feature = "ai")]
226#[deprecated(note = "Will be extracted to mockforge-intelligence crate")]
227pub mod ai_response;
228/// AI Studio - Unified AI Copilot for all AI-powered features.
229/// Data types moved to mockforge-foundation (A20); engines
230/// (ApiCritiqueEngine, SystemGenerator, BehavioralSimulator,
231/// ArtifactFreezer) stay here as they hold LlmClient + do I/O.
232#[cfg(feature = "ai")]
233pub mod ai_studio;
234/// Behavioral cloning of backends - learn from recorded traffic to create realistic mock behavior
235#[cfg(feature = "ai")]
236#[deprecated(note = "Will be extracted to mockforge-intelligence crate")]
237pub mod behavioral_cloning;
238#[cfg(feature = "advanced")]
239// behavioral_economics depends on priority_handler + core internals; staying in core.
240pub mod behavioral_economics;
241#[allow(dead_code)]
242pub(crate) mod cache;
243pub mod chain_execution;
244pub mod chaos_utilities;
245#[cfg(feature = "advanced")]
246#[deprecated(note = "Will be extracted to mockforge-import crate")]
247pub mod codegen;
248/// Collection export utilities for exporting mock data in various formats
249#[allow(dead_code)]
250pub(crate) mod collection_export;
251pub mod conditions;
252pub mod config;
253/// Connection pooling for HTTP clients with health checks and idle management
254#[allow(dead_code)]
255pub(crate) mod connection_pool;
256/// Cross-protocol consistency engine for unified state across all protocols
257#[cfg(feature = "advanced")]
258pub mod consistency;
259#[cfg(feature = "contracts")]
260#[deprecated(note = "Will be extracted to mockforge-contracts crate")]
261/// Consumer-driven contracts for tracking usage and detecting consumer-specific breaking changes
262pub mod consumer_contracts;
263#[cfg(feature = "contracts")]
264/// Contract drift detection. Data types moved to mockforge-foundation
265/// (A13–A21); engines (DriftBudgetEngine, ThreatAnalyzer,
266/// ProtocolContractRegistry, WebSocket/MQTT/Kafka contract impls) stay
267/// here because they depend on OpenApiSpec and jsonschema validators.
268pub mod contract_drift;
269#[cfg(feature = "contracts")]
270/// Contract validation for ensuring API contracts match specifications.
271/// Depends on OpenApiSpec; stays in core.
272pub mod contract_validation;
273/// Contract webhooks for notifying external systems about contract changes
274#[cfg(feature = "contracts")]
275#[allow(dead_code)]
276pub(crate) mod contract_webhooks;
277/// `custom_fixture` was promoted to [`mockforge_openapi::custom_fixture`];
278/// re-exported here for backwards compatibility.
279pub(crate) use mockforge_openapi::custom_fixture;
280/// Data source abstraction for loading test data from multiple sources
281pub mod data_source;
282/// Deceptive canary mode for routing team traffic to deceptive deploys
283pub mod deceptive_canary;
284/// Docker Compose integration for containerized mock deployments
285#[allow(dead_code)]
286pub(crate) mod docker_compose;
287#[cfg(feature = "contracts")]
288/// GitOps integration for drift budget violations. Depends on core
289/// incidents + contract_drift; stays in core.
290pub mod drift_gitops;
291// Encryption utility; stays in core (small, widely used).
292pub mod encryption;
293pub mod error;
294pub mod failure_analysis;
295/// `failure_injection` was promoted to [`mockforge_foundation::failure_injection`];
296/// re-exported here for backwards compatibility.
297pub(crate) use mockforge_foundation::failure_injection;
298pub mod fidelity;
299/// Generic fixture loading utilities shared across protocol crates
300pub mod fixture_store;
301pub mod generate_config;
302#[allow(dead_code)]
303pub(crate) mod generative_schema;
304#[deprecated(note = "Will be extracted to mockforge-workspace crate")]
305pub mod git_watch;
306#[cfg(feature = "advanced")]
307pub mod graph;
308#[cfg(feature = "workspace-mgmt")]
309#[deprecated(note = "Will be extracted to mockforge-import crate")]
310pub mod import;
311#[cfg(feature = "contracts")]
312pub mod incidents;
313#[cfg(feature = "ai")]
314// Data types moved to mockforge-foundation (A12/A17);
315// MockAI, RuleGenerator, OpenApiSpecGenerator stay here (LLM-bound).
316pub mod intelligent_behavior;
317/// `latency` was promoted to [`mockforge_foundation::latency`]; re-exported
318/// here so the legacy `mockforge_core::latency::*` path continues to resolve.
319pub(crate) use mockforge_foundation::latency;
320pub mod lifecycle;
321#[cfg(feature = "advanced")]
322// Config types moved to mockforge-foundation (A14);
323// MultiTenantWorkspaceRegistry + WorkspaceRouter stay here (hold Workspace).
324pub mod multi_tenant;
325pub mod network_profiles;
326/// OData function call URI rewrite middleware
327pub mod odata_rewrite;
328pub mod openapi;
329/// Core's concrete [`mockforge_openapi::response_rewriter::ResponseRewriter`]
330/// implementation wrapping core's `templating::expand_tokens` +
331/// [`overrides::Overrides`]. Used by the OpenAPI router internally; consumer
332/// code rarely constructs this directly.
333pub mod openapi_rewriter;
334/// `openapi_routes` was moved to [`mockforge_openapi::openapi_routes`];
335/// re-exported here so every existing
336/// `mockforge_core::openapi_routes::{OpenApiRouteRegistry, ValidationOptions,
337/// create_registry_from_file, create_registry_from_json, ...}` path
338/// keeps resolving.
339pub(crate) use mockforge_openapi::openapi_routes;
340pub mod output_control;
341pub mod overrides;
342pub mod performance;
343/// Pillar usage tracking utilities
344pub mod pillar_tracking;
345/// Pillar metadata system for compile-time pillar tagging
346pub mod pillars;
347/// PR generation lives in `mockforge_intelligence::pr_generation` (Issue #562
348/// phase 1); re-exported here so existing `crate::pr_generation::*` call sites
349/// and external users that imported `mockforge_core::pr_generation::*` keep
350/// compiling without churn.
351pub use mockforge_intelligence::pr_generation;
352pub mod priority_handler;
353pub mod protocol_abstraction;
354/// Protocol server lifecycle trait for uniform server startup and shutdown
355pub mod protocol_server;
356/// Proxy module — migrating to `mockforge-proxy` crate.
357/// Import from `mockforge_proxy` instead of `mockforge_core::proxy`.
358#[deprecated(note = "Use mockforge_proxy crate directly")]
359pub mod proxy;
360pub mod reality;
361#[cfg(feature = "advanced")]
362pub mod reality_continuum;
363pub mod record_replay;
364pub mod request_capture;
365pub mod request_chaining;
366/// `request_fingerprint` was promoted to [`mockforge_openapi::request_fingerprint`];
367/// re-exported here for backwards compatibility.
368pub(crate) use mockforge_openapi::request_fingerprint;
369pub mod request_logger;
370#[cfg(feature = "scripting")]
371pub(crate) mod request_scripting;
372// Route chaos has been moved to mockforge-route-chaos crate to avoid Send issues
373// Import directly from mockforge-route-chaos crate instead of re-exporting here
374// to avoid circular dependency (mockforge-route-chaos depends on mockforge-core for config types)
375#[allow(dead_code)]
376pub(crate) mod persona_lifecycle_time;
377pub mod routing;
378/// Runtime validation for SDKs (request/response validation at runtime)
379pub mod runtime_validation;
380/// Scenario Studio - Visual editor for co-editing business flows
381#[cfg(feature = "advanced")]
382pub mod scenario_studio;
383#[cfg(feature = "advanced")]
384pub mod scenarios;
385/// `schema_diff` was promoted to [`mockforge_foundation::schema_diff`] so that
386/// leaf crates can use its `ValidationError` + diff helpers without depending
387/// on `mockforge-core`. Re-exported here for backwards compatibility.
388pub(crate) use mockforge_foundation::schema_diff;
389pub mod security;
390pub mod server_utils;
391/// Time travel and snapshot functionality for saving and restoring system states
392#[cfg(feature = "advanced")]
393pub mod snapshots;
394/// Re-export of the extracted [`mockforge_openapi::spec_parser`] module.
395pub(crate) use mockforge_openapi::spec_parser;
396pub mod stateful_handler;
397// sync_watcher stays in core.
398pub mod sync_watcher;
399/// Template expansion utilities (Send-safe, isolated from templating module)
400pub mod template_expansion;
401/// Template library system for shared templates, versioning, and marketplace
402pub mod template_library;
403pub mod templating;
404#[cfg(feature = "advanced")]
405pub mod time_travel;
406#[cfg(feature = "advanced")]
407pub mod time_travel_handler;
408/// Shared TLS utilities for building rustls server and client configurations.
409pub mod tls;
410pub mod traffic_shaping;
411pub mod validation;
412pub mod verification;
413#[cfg(feature = "voice")]
414pub mod voice;
415#[cfg(feature = "workspace-mgmt")]
416// Workspace family (Workspace, WorkspaceConfig, WorkspaceRegistry, etc.) —
417// 11k+ LoC surface area. Staying in core; future extraction would need
418// its own dedicated planning.
419pub mod workspace;
420#[cfg(feature = "workspace-mgmt")]
421pub mod workspace_import;
422#[cfg(feature = "workspace-mgmt")]
423pub mod workspace_persistence;
424pub mod ws_proxy;
425
426#[cfg(feature = "advanced")]
427pub use ab_testing::{
428    apply_variant_to_response, select_variant, ABTestConfig, ABTestReport,
429    ABTestingMiddlewareState, MockVariant, VariantAllocation, VariantAnalytics, VariantComparison,
430    VariantManager, VariantSelectionStrategy,
431};
432#[cfg(feature = "ai")]
433#[deprecated(note = "Will be extracted to mockforge-intelligence crate")]
434pub use behavioral_cloning::{
435    AmplificationScope, BehavioralSequence, EdgeAmplificationConfig, EdgeAmplifier,
436    EndpointProbabilityModel, ErrorPattern, LatencyDistribution, PayloadVariation,
437    ProbabilisticModel, SequenceLearner, SequenceStep,
438};
439pub use chain_execution::{ChainExecutionEngine, ChainExecutionResult, ChainExecutionStatus};
440#[deprecated(note = "Use mockforge_chaos::core_chaos_utilities instead")]
441pub use chaos_utilities::{ChaosConfig, ChaosEngine, ChaosResult, ChaosStatistics};
442pub use conditions::{evaluate_condition, ConditionContext, ConditionError};
443pub use config::{
444    apply_env_overrides, load_config, load_config_with_fallback, save_config, ApiKeyConfig,
445    AuthConfig, ServerConfig,
446};
447#[cfg(feature = "advanced")]
448pub use consistency::{
449    ConsistencyEngine, EntityState, ProtocolState, SessionInfo, StateChangeEvent, UnifiedState,
450};
451pub(crate) use custom_fixture::CustomFixtureLoader;
452pub use data_source::{
453    DataSource, DataSourceConfig, DataSourceContent, DataSourceFactory, DataSourceManager,
454    DataSourceType, GitDataSource, HttpDataSource, LocalDataSource,
455};
456pub use deceptive_canary::{
457    CanaryRoutingStrategy, CanaryStats, DeceptiveCanaryConfig, DeceptiveCanaryRouter,
458    TeamIdentifiers,
459};
460pub use error::{Error, Result};
461pub use failure_analysis::{
462    ContributingFactor, FailureContext, FailureContextCollector, FailureNarrative,
463    FailureNarrativeGenerator, NarrativeFrame,
464};
465#[deprecated(note = "Use mockforge_chaos::core_failure_injection instead")]
466pub(crate) use failure_injection::FailureInjector;
467pub use fidelity::{FidelityCalculator, FidelityScore, SampleComparator, SchemaComparator};
468pub use generate_config::{
469    discover_config_file, load_generate_config, load_generate_config_with_fallback,
470    save_generate_config, BarrelType, GenerateConfig, GenerateOptions, InputConfig, OutputConfig,
471    PluginConfig,
472};
473#[deprecated(note = "Will be extracted to mockforge-workspace crate")]
474pub use git_watch::{GitWatchConfig, GitWatchService};
475#[cfg(feature = "advanced")]
476pub use graph::{
477    builder::GraphBuilder, relationships, ClusterType, EdgeType, GraphCluster, GraphData,
478    GraphEdge, GraphNode, NodeType, Protocol as GraphProtocol,
479};
480pub(crate) use latency::LatencyProfile;
481pub use lifecycle::{
482    LifecycleHook, LifecycleHookRegistry, MockLifecycleEvent, RequestContext, ResponseContext,
483    ServerLifecycleEvent,
484};
485#[cfg(feature = "advanced")]
486pub use multi_tenant::{
487    MultiTenantConfig, MultiTenantWorkspaceRegistry, RoutingStrategy, TenantWorkspace,
488    WorkspaceContext, WorkspaceRouter, WorkspaceStats,
489};
490#[deprecated(note = "Use mockforge_chaos::core_network_profiles instead")]
491pub use network_profiles::{NetworkProfile, NetworkProfileCatalog};
492pub(crate) use openapi::OpenApiSpec;
493pub use output_control::{
494    apply_banner, apply_extension, apply_file_naming_template, build_file_naming_context,
495    process_generated_file, BarrelGenerator, FileNamingContext, GeneratedFile,
496};
497pub use overrides::{OverrideMode, OverrideRule, Overrides, PatchOp};
498pub use pillars::{Pillar, PillarMetadata};
499pub use priority_handler::{
500    CustomFixtureStep, FailureInjectionStep, GenerationResult, MockGenerator, MockResponse,
501    PriorityHttpHandler, PriorityRequest, PriorityResponse, PriorityStep, SimpleMockGenerator,
502};
503pub use protocol_abstraction::{
504    MessagePattern, MiddlewareAction, MiddlewareChain, Protocol, ProtocolMiddleware,
505    ProtocolRequest, ProtocolResponse, RequestMatcher, ResponseStatus, SpecOperation, SpecRegistry,
506    ValidationError as ProtocolValidationError, ValidationResult as ProtocolValidationResult,
507};
508#[deprecated(note = "Will be extracted to mockforge-proxy crate")]
509pub use proxy::{ProxyConfig, ProxyHandler, ProxyResponse};
510pub use reality::{PresetMetadata, RealityConfig, RealityEngine, RealityLevel, RealityPreset};
511#[cfg(feature = "advanced")]
512pub use reality_continuum::{
513    ContinuumConfig, ContinuumRule, MergeStrategy, RealityContinuumEngine, ResponseBlender,
514    TimeSchedule, TransitionCurve, TransitionMode,
515};
516pub use record_replay::{
517    clean_old_fixtures, list_fixtures, list_ready_fixtures, list_smoke_endpoints, RecordHandler,
518    RecordReplayHandler, RecordedRequest, ReplayHandler,
519};
520pub use request_chaining::{
521    ChainConfig, ChainContext, ChainDefinition, ChainExecutionContext, ChainLink, ChainRequest,
522    ChainResponse, ChainStore, ChainTemplatingContext, RequestChainRegistry,
523};
524pub(crate) use request_fingerprint::{RequestFingerprint, ResponsePriority, ResponseSource};
525pub use request_logger::{
526    create_grpc_log_entry, create_http_log_entry, create_http_log_entry_with_query,
527    create_websocket_log_entry, get_global_logger, init_global_logger, log_request_global,
528    CentralizedRequestLogger, RequestLogEntry,
529};
530// Route chaos types moved to mockforge-route-chaos crate
531// Import directly: use mockforge_route_chaos::{RouteChaosInjector, RouteFaultResponse, RouteMatcher};
532pub use routing::{HttpMethod, Route, RouteRegistry};
533pub use runtime_validation::{
534    RuntimeValidationError, RuntimeValidationResult, RuntimeValidatorConfig, SchemaMetadata,
535};
536#[cfg(feature = "advanced")]
537pub use scenario_studio::{
538    ConditionOperator, FlowCondition, FlowConnection, FlowDefinition, FlowExecutionResult,
539    FlowExecutor, FlowPosition, FlowStep, FlowStepResult, FlowType, FlowVariant, StepType,
540};
541#[cfg(feature = "advanced")]
542pub use scenarios::types::StepResult;
543#[cfg(feature = "advanced")]
544pub use scenarios::{
545    ScenarioDefinition, ScenarioExecutor, ScenarioParameter, ScenarioRegistry, ScenarioResult,
546    ScenarioStep,
547};
548pub use server_utils::errors::{json_error, json_success};
549pub use server_utils::{create_socket_addr, localhost_socket_addr, wildcard_socket_addr};
550#[cfg(feature = "advanced")]
551pub use snapshots::{SnapshotComponents, SnapshotManager, SnapshotManifest, SnapshotMetadata};
552pub use stateful_handler::{
553    ResourceIdExtract, StateInfo, StateResponse, StatefulConfig, StatefulResponse,
554    StatefulResponseHandler, TransitionTrigger,
555};
556#[cfg(feature = "workspace-mgmt")]
557pub use sync_watcher::{FileChange, SyncEvent, SyncService, SyncWatcher};
558pub use template_library::{
559    TemplateLibrary, TemplateLibraryEntry, TemplateLibraryManager, TemplateMarketplace,
560    TemplateMetadata, TemplateVersion,
561};
562pub use templating::{expand_str, expand_tokens};
563#[cfg(feature = "advanced")]
564pub use time_travel::{
565    cron::{CronJob, CronJobAction, CronScheduler},
566    get_global_clock, is_time_travel_enabled, now as time_travel_now, register_global_clock,
567    unregister_global_clock, RepeatConfig, ResponseScheduler, ScheduledResponse, TimeScenario,
568    TimeTravelConfig, TimeTravelManager, TimeTravelStatus, VirtualClock,
569};
570#[cfg(feature = "advanced")]
571pub use time_travel_handler::{
572    time_travel_middleware, ScheduledResponseWrapper, TimeTravelHandler,
573};
574#[deprecated(note = "Use mockforge_chaos::core_traffic_shaping instead")]
575pub use traffic_shaping::{BandwidthConfig, BurstLossConfig, TrafficShaper, TrafficShapingConfig};
576pub use uuid::Uuid;
577pub use validation::{validate_openapi_operation_security, validate_openapi_security, Validator};
578pub use verification::{
579    matches_verification_pattern, verify_at_least, verify_never, verify_requests, verify_sequence,
580    VerificationCount, VerificationRequest, VerificationResult,
581};
582#[cfg(feature = "voice")]
583pub use voice::{
584    ConversationContext, ConversationManager, ConversationState, GeneratedWorkspaceScenario,
585    HookTranspiler, ParsedCommand, ParsedWorkspaceScenario, VoiceCommandParser, VoiceSpecGenerator,
586    WorkspaceConfigSummary, WorkspaceScenarioGenerator,
587};
588#[cfg(feature = "workspace-mgmt")]
589pub use workspace::promotion_trait::PromotionService;
590#[cfg(feature = "workspace-mgmt")]
591pub use workspace::{EntityId, Folder, MockRequest, Workspace, WorkspaceConfig, WorkspaceRegistry};
592#[cfg(feature = "workspace-mgmt")]
593pub use workspace_import::{
594    create_workspace_from_curl, create_workspace_from_har, create_workspace_from_insomnia,
595    create_workspace_from_postman, import_postman_to_existing_workspace,
596    import_postman_to_workspace, WorkspaceImportConfig, WorkspaceImportResult,
597};
598#[cfg(feature = "workspace-mgmt")]
599pub use workspace_persistence::WorkspacePersistence;
600pub use ws_proxy::{WsProxyConfig, WsProxyHandler, WsProxyRule};
601// Note: ValidationError and ValidationResult from spec_parser conflict with schema_diff::ValidationError
602// Use qualified paths: spec_parser::ValidationError, spec_parser::ValidationResult
603
604// ── Organized module facades (R10) ───────────────────────────────────────────
605// These provide a namespaced access path for new code. Existing flat re-exports
606// above remain for backward compatibility. Prefer these for new imports.
607
608/// Routing, route matching, and OpenAPI route generation
609pub mod routes {
610    pub use crate::openapi::{
611        OpenApiOperation, OpenApiRoute, OpenApiSchema, OpenApiSecurityRequirement, OpenApiSpec,
612    };
613    pub use crate::openapi_routes::{
614        create_registry_from_file, create_registry_from_json, OpenApiRouteRegistry,
615        ValidationOptions,
616    };
617    pub use crate::routing::{HttpMethod, Route, RouteRegistry};
618}
619
620/// Middleware, protocol abstractions, and request processing
621pub mod middleware {
622    pub use crate::latency::LatencyInjector;
623    pub use crate::overrides::{OverrideMode, OverrideRule, Overrides, PatchOp};
624    pub use crate::protocol_abstraction::{
625        MessagePattern, MiddlewareAction, MiddlewareChain, Protocol, ProtocolMiddleware,
626        ProtocolRequest, ProtocolResponse, RequestMatcher, ResponseStatus, SpecOperation,
627        SpecRegistry,
628    };
629}
630
631/// Mock response generation and priority handling
632pub mod generation {
633    pub use crate::priority_handler::{
634        CustomFixtureStep, FailureInjectionStep, GenerationResult, MockGenerator, MockResponse,
635        PriorityHttpHandler, PriorityRequest, PriorityResponse, PriorityStep, SimpleMockGenerator,
636    };
637    pub use crate::stateful_handler::{StatefulConfig, StatefulResponse, StatefulResponseHandler};
638}
639
640/// Request/response validation
641pub mod validate {
642    pub use crate::runtime_validation::{
643        RuntimeValidationError, RuntimeValidationResult, RuntimeValidatorConfig, SchemaMetadata,
644    };
645    pub use crate::spec_parser::{GraphQLValidator, OpenApiValidator, SpecFormat};
646    pub use crate::validation::{
647        validate_openapi_operation_security, validate_openapi_security, Validator,
648    };
649    pub use crate::verification::{
650        matches_verification_pattern, verify_at_least, verify_never, verify_requests,
651        verify_sequence, VerificationCount, VerificationRequest, VerificationResult,
652    };
653}
654
655/// Fixture loading utilities
656pub mod fixtures {
657    pub use crate::custom_fixture::{CustomFixture, CustomFixtureLoader, NestedFixture};
658    pub use crate::fixture_store::{
659        load_fixtures_from_dir, FixtureFileFormat, FixtureFileGranularity, FixtureLoadErrorMode,
660        FixtureLoadOptions,
661    };
662    pub use crate::record_replay::{
663        RecordHandler, RecordReplayHandler, RecordedRequest, ReplayHandler,
664    };
665}
666
667/// Core configuration for MockForge
668#[derive(Debug, Clone, serde::Deserialize, serde::Serialize)]
669#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
670#[serde(default)]
671pub struct Config {
672    /// Enable latency simulation
673    pub latency_enabled: bool,
674    /// Enable failure simulation
675    pub failures_enabled: bool,
676    /// Enable response overrides
677    pub overrides_enabled: bool,
678    /// Enable traffic shaping (bandwidth + burst loss)
679    pub traffic_shaping_enabled: bool,
680    /// Failure injection configuration
681    pub failure_config: Option<failure_injection::FailureConfig>,
682    /// Proxy configuration
683    pub proxy: Option<ProxyConfig>,
684    /// Default latency profile
685    pub default_latency: LatencyProfile,
686    /// Traffic shaping configuration
687    pub traffic_shaping: TrafficShapingConfig,
688    /// Random chaos configuration
689    pub chaos_random: Option<ChaosConfig>,
690    /// Maximum number of request logs to keep in memory (default: 1000)
691    /// Helps prevent unbounded memory growth from request logging
692    pub max_request_logs: usize,
693    /// Time travel configuration for temporal testing
694    pub time_travel: TimeTravelConfig,
695}
696
697/// Default configuration
698impl Default for Config {
699    fn default() -> Self {
700        Self {
701            latency_enabled: true,
702            failures_enabled: false,
703            overrides_enabled: true,
704            traffic_shaping_enabled: false,
705            failure_config: None,
706            proxy: None,
707            default_latency: LatencyProfile::default(),
708            traffic_shaping: TrafficShapingConfig::default(),
709            chaos_random: None,
710            max_request_logs: 1000, // Default: keep last 1000 requests
711            time_travel: TimeTravelConfig::default(),
712        }
713    }
714}
715
716impl Config {
717    /// Create a ChaosEngine from the chaos_random configuration if enabled
718    pub fn create_chaos_engine(&self) -> Option<ChaosEngine> {
719        self.chaos_random.as_ref().map(|config| ChaosEngine::new(config.clone()))
720    }
721
722    /// Check if random chaos mode is enabled
723    pub fn is_chaos_random_enabled(&self) -> bool {
724        self.chaos_random.as_ref().map(|c| c.enabled).unwrap_or(false)
725    }
726}
727
728#[cfg(test)]
729mod tests {
730    use super::*;
731
732    #[test]
733    fn test_config_default() {
734        let config = Config::default();
735        assert!(config.latency_enabled);
736        assert!(!config.failures_enabled);
737        assert!(config.overrides_enabled);
738        assert!(!config.traffic_shaping_enabled);
739        assert!(config.failure_config.is_none());
740        assert!(config.proxy.is_none());
741    }
742
743    #[test]
744    fn test_config_serialization() {
745        let config = Config::default();
746        let json = serde_json::to_string(&config).unwrap();
747        assert!(json.contains("latency_enabled"));
748        assert!(json.contains("failures_enabled"));
749    }
750
751    #[test]
752    fn test_config_deserialization() {
753        // Use default config and modify
754        let config = Config {
755            latency_enabled: false,
756            failures_enabled: true,
757            ..Default::default()
758        };
759
760        // Serialize and deserialize
761        let json = serde_json::to_string(&config).unwrap();
762        let deserialized: Config = serde_json::from_str(&json).unwrap();
763
764        assert!(!deserialized.latency_enabled);
765        assert!(deserialized.failures_enabled);
766        assert!(deserialized.overrides_enabled);
767    }
768
769    #[test]
770    fn test_config_with_custom_values() {
771        let config = Config {
772            latency_enabled: false,
773            failures_enabled: true,
774            ..Default::default()
775        };
776
777        assert!(!config.latency_enabled);
778        assert!(config.failures_enabled);
779    }
780}