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