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#[cfg(feature = "contracts")]
348pub mod pr_generation;
349pub mod priority_handler;
350pub mod protocol_abstraction;
351/// Protocol server lifecycle trait for uniform server startup and shutdown
352pub mod protocol_server;
353/// Proxy module — migrating to `mockforge-proxy` crate.
354/// Import from `mockforge_proxy` instead of `mockforge_core::proxy`.
355#[deprecated(note = "Use mockforge_proxy crate directly")]
356pub mod proxy;
357pub mod reality;
358#[cfg(feature = "advanced")]
359pub mod reality_continuum;
360pub mod record_replay;
361pub mod request_capture;
362pub mod request_chaining;
363/// `request_fingerprint` was promoted to [`mockforge_openapi::request_fingerprint`];
364/// re-exported here for backwards compatibility.
365pub(crate) use mockforge_openapi::request_fingerprint;
366pub mod request_logger;
367#[cfg(feature = "scripting")]
368pub(crate) mod request_scripting;
369// Route chaos has been moved to mockforge-route-chaos crate to avoid Send issues
370// Import directly from mockforge-route-chaos crate instead of re-exporting here
371// to avoid circular dependency (mockforge-route-chaos depends on mockforge-core for config types)
372#[allow(dead_code)]
373pub(crate) mod persona_lifecycle_time;
374pub mod routing;
375/// Runtime validation for SDKs (request/response validation at runtime)
376pub mod runtime_validation;
377/// Scenario Studio - Visual editor for co-editing business flows
378#[cfg(feature = "advanced")]
379pub mod scenario_studio;
380#[cfg(feature = "advanced")]
381pub mod scenarios;
382/// `schema_diff` was promoted to [`mockforge_foundation::schema_diff`] so that
383/// leaf crates can use its `ValidationError` + diff helpers without depending
384/// on `mockforge-core`. Re-exported here for backwards compatibility.
385pub(crate) use mockforge_foundation::schema_diff;
386pub mod security;
387pub mod server_utils;
388/// Time travel and snapshot functionality for saving and restoring system states
389#[cfg(feature = "advanced")]
390pub mod snapshots;
391/// Re-export of the extracted [`mockforge_openapi::spec_parser`] module.
392pub(crate) use mockforge_openapi::spec_parser;
393pub mod stateful_handler;
394// sync_watcher stays in core.
395pub mod sync_watcher;
396/// Template expansion utilities (Send-safe, isolated from templating module)
397pub mod template_expansion;
398/// Template library system for shared templates, versioning, and marketplace
399pub mod template_library;
400pub mod templating;
401#[cfg(feature = "advanced")]
402pub mod time_travel;
403#[cfg(feature = "advanced")]
404pub mod time_travel_handler;
405/// Shared TLS utilities for building rustls server and client configurations.
406pub mod tls;
407pub mod traffic_shaping;
408pub mod validation;
409pub mod verification;
410#[cfg(feature = "voice")]
411pub mod voice;
412#[cfg(feature = "workspace-mgmt")]
413// Workspace family (Workspace, WorkspaceConfig, WorkspaceRegistry, etc.) —
414// 11k+ LoC surface area. Staying in core; future extraction would need
415// its own dedicated planning.
416pub mod workspace;
417#[cfg(feature = "workspace-mgmt")]
418pub mod workspace_import;
419#[cfg(feature = "workspace-mgmt")]
420pub mod workspace_persistence;
421pub mod ws_proxy;
422
423#[cfg(feature = "advanced")]
424pub use ab_testing::{
425    apply_variant_to_response, select_variant, ABTestConfig, ABTestReport,
426    ABTestingMiddlewareState, MockVariant, VariantAllocation, VariantAnalytics, VariantComparison,
427    VariantManager, VariantSelectionStrategy,
428};
429#[cfg(feature = "ai")]
430#[deprecated(note = "Will be extracted to mockforge-intelligence crate")]
431pub use behavioral_cloning::{
432    AmplificationScope, BehavioralSequence, EdgeAmplificationConfig, EdgeAmplifier,
433    EndpointProbabilityModel, ErrorPattern, LatencyDistribution, PayloadVariation,
434    ProbabilisticModel, SequenceLearner, SequenceStep,
435};
436pub use chain_execution::{ChainExecutionEngine, ChainExecutionResult, ChainExecutionStatus};
437#[deprecated(note = "Use mockforge_chaos::core_chaos_utilities instead")]
438pub use chaos_utilities::{ChaosConfig, ChaosEngine, ChaosResult, ChaosStatistics};
439pub use conditions::{evaluate_condition, ConditionContext, ConditionError};
440pub use config::{
441    apply_env_overrides, load_config, load_config_with_fallback, save_config, ApiKeyConfig,
442    AuthConfig, ServerConfig,
443};
444#[cfg(feature = "advanced")]
445pub use consistency::{
446    ConsistencyEngine, EntityState, ProtocolState, SessionInfo, StateChangeEvent, UnifiedState,
447};
448pub(crate) use custom_fixture::CustomFixtureLoader;
449pub use data_source::{
450    DataSource, DataSourceConfig, DataSourceContent, DataSourceFactory, DataSourceManager,
451    DataSourceType, GitDataSource, HttpDataSource, LocalDataSource,
452};
453pub use deceptive_canary::{
454    CanaryRoutingStrategy, CanaryStats, DeceptiveCanaryConfig, DeceptiveCanaryRouter,
455    TeamIdentifiers,
456};
457pub use error::{Error, Result};
458pub use failure_analysis::{
459    ContributingFactor, FailureContext, FailureContextCollector, FailureNarrative,
460    FailureNarrativeGenerator, NarrativeFrame,
461};
462#[deprecated(note = "Use mockforge_chaos::core_failure_injection instead")]
463pub(crate) use failure_injection::FailureInjector;
464pub use fidelity::{FidelityCalculator, FidelityScore, SampleComparator, SchemaComparator};
465pub use generate_config::{
466    discover_config_file, load_generate_config, load_generate_config_with_fallback,
467    save_generate_config, BarrelType, GenerateConfig, GenerateOptions, InputConfig, OutputConfig,
468    PluginConfig,
469};
470#[deprecated(note = "Will be extracted to mockforge-workspace crate")]
471pub use git_watch::{GitWatchConfig, GitWatchService};
472#[cfg(feature = "advanced")]
473pub use graph::{
474    builder::GraphBuilder, relationships, ClusterType, EdgeType, GraphCluster, GraphData,
475    GraphEdge, GraphNode, NodeType, Protocol as GraphProtocol,
476};
477pub(crate) use latency::LatencyProfile;
478pub use lifecycle::{
479    LifecycleHook, LifecycleHookRegistry, MockLifecycleEvent, RequestContext, ResponseContext,
480    ServerLifecycleEvent,
481};
482#[cfg(feature = "advanced")]
483pub use multi_tenant::{
484    MultiTenantConfig, MultiTenantWorkspaceRegistry, RoutingStrategy, TenantWorkspace,
485    WorkspaceContext, WorkspaceRouter, WorkspaceStats,
486};
487#[deprecated(note = "Use mockforge_chaos::core_network_profiles instead")]
488pub use network_profiles::{NetworkProfile, NetworkProfileCatalog};
489pub(crate) use openapi::OpenApiSpec;
490pub use output_control::{
491    apply_banner, apply_extension, apply_file_naming_template, build_file_naming_context,
492    process_generated_file, BarrelGenerator, FileNamingContext, GeneratedFile,
493};
494pub use overrides::{OverrideMode, OverrideRule, Overrides, PatchOp};
495pub use pillars::{Pillar, PillarMetadata};
496pub use priority_handler::{
497    CustomFixtureStep, FailureInjectionStep, GenerationResult, MockGenerator, MockResponse,
498    PriorityHttpHandler, PriorityRequest, PriorityResponse, PriorityStep, SimpleMockGenerator,
499};
500pub use protocol_abstraction::{
501    MessagePattern, MiddlewareAction, MiddlewareChain, Protocol, ProtocolMiddleware,
502    ProtocolRequest, ProtocolResponse, RequestMatcher, ResponseStatus, SpecOperation, SpecRegistry,
503    ValidationError as ProtocolValidationError, ValidationResult as ProtocolValidationResult,
504};
505#[deprecated(note = "Will be extracted to mockforge-proxy crate")]
506pub use proxy::{ProxyConfig, ProxyHandler, ProxyResponse};
507pub use reality::{PresetMetadata, RealityConfig, RealityEngine, RealityLevel, RealityPreset};
508#[cfg(feature = "advanced")]
509pub use reality_continuum::{
510    ContinuumConfig, ContinuumRule, MergeStrategy, RealityContinuumEngine, ResponseBlender,
511    TimeSchedule, TransitionCurve, TransitionMode,
512};
513pub use record_replay::{
514    clean_old_fixtures, list_fixtures, list_ready_fixtures, list_smoke_endpoints, RecordHandler,
515    RecordReplayHandler, RecordedRequest, ReplayHandler,
516};
517pub use request_chaining::{
518    ChainConfig, ChainContext, ChainDefinition, ChainExecutionContext, ChainLink, ChainRequest,
519    ChainResponse, ChainStore, ChainTemplatingContext, RequestChainRegistry,
520};
521pub(crate) use request_fingerprint::{RequestFingerprint, ResponsePriority, ResponseSource};
522pub use request_logger::{
523    create_grpc_log_entry, create_http_log_entry, create_http_log_entry_with_query,
524    create_websocket_log_entry, get_global_logger, init_global_logger, log_request_global,
525    CentralizedRequestLogger, RequestLogEntry,
526};
527// Route chaos types moved to mockforge-route-chaos crate
528// Import directly: use mockforge_route_chaos::{RouteChaosInjector, RouteFaultResponse, RouteMatcher};
529pub use routing::{HttpMethod, Route, RouteRegistry};
530pub use runtime_validation::{
531    RuntimeValidationError, RuntimeValidationResult, RuntimeValidatorConfig, SchemaMetadata,
532};
533#[cfg(feature = "advanced")]
534pub use scenario_studio::{
535    ConditionOperator, FlowCondition, FlowConnection, FlowDefinition, FlowExecutionResult,
536    FlowExecutor, FlowPosition, FlowStep, FlowStepResult, FlowType, FlowVariant, StepType,
537};
538#[cfg(feature = "advanced")]
539pub use scenarios::types::StepResult;
540#[cfg(feature = "advanced")]
541pub use scenarios::{
542    ScenarioDefinition, ScenarioExecutor, ScenarioParameter, ScenarioRegistry, ScenarioResult,
543    ScenarioStep,
544};
545pub use server_utils::errors::{json_error, json_success};
546pub use server_utils::{create_socket_addr, localhost_socket_addr, wildcard_socket_addr};
547#[cfg(feature = "advanced")]
548pub use snapshots::{SnapshotComponents, SnapshotManager, SnapshotManifest, SnapshotMetadata};
549pub use stateful_handler::{
550    ResourceIdExtract, StateInfo, StateResponse, StatefulConfig, StatefulResponse,
551    StatefulResponseHandler, TransitionTrigger,
552};
553#[cfg(feature = "workspace-mgmt")]
554pub use sync_watcher::{FileChange, SyncEvent, SyncService, SyncWatcher};
555pub use template_library::{
556    TemplateLibrary, TemplateLibraryEntry, TemplateLibraryManager, TemplateMarketplace,
557    TemplateMetadata, TemplateVersion,
558};
559pub use templating::{expand_str, expand_tokens};
560#[cfg(feature = "advanced")]
561pub use time_travel::{
562    cron::{CronJob, CronJobAction, CronScheduler},
563    get_global_clock, is_time_travel_enabled, now as time_travel_now, register_global_clock,
564    unregister_global_clock, RepeatConfig, ResponseScheduler, ScheduledResponse, TimeScenario,
565    TimeTravelConfig, TimeTravelManager, TimeTravelStatus, VirtualClock,
566};
567#[cfg(feature = "advanced")]
568pub use time_travel_handler::{
569    time_travel_middleware, ScheduledResponseWrapper, TimeTravelHandler,
570};
571#[deprecated(note = "Use mockforge_chaos::core_traffic_shaping instead")]
572pub use traffic_shaping::{BandwidthConfig, BurstLossConfig, TrafficShaper, TrafficShapingConfig};
573pub use uuid::Uuid;
574pub use validation::{validate_openapi_operation_security, validate_openapi_security, Validator};
575pub use verification::{
576    matches_verification_pattern, verify_at_least, verify_never, verify_requests, verify_sequence,
577    VerificationCount, VerificationRequest, VerificationResult,
578};
579#[cfg(feature = "voice")]
580pub use voice::{
581    ConversationContext, ConversationManager, ConversationState, GeneratedWorkspaceScenario,
582    HookTranspiler, ParsedCommand, ParsedWorkspaceScenario, VoiceCommandParser, VoiceSpecGenerator,
583    WorkspaceConfigSummary, WorkspaceScenarioGenerator,
584};
585#[cfg(feature = "workspace-mgmt")]
586pub use workspace::promotion_trait::PromotionService;
587#[cfg(feature = "workspace-mgmt")]
588pub use workspace::{EntityId, Folder, MockRequest, Workspace, WorkspaceConfig, WorkspaceRegistry};
589#[cfg(feature = "workspace-mgmt")]
590pub use workspace_import::{
591    create_workspace_from_curl, create_workspace_from_har, create_workspace_from_insomnia,
592    create_workspace_from_postman, import_postman_to_existing_workspace,
593    import_postman_to_workspace, WorkspaceImportConfig, WorkspaceImportResult,
594};
595#[cfg(feature = "workspace-mgmt")]
596pub use workspace_persistence::WorkspacePersistence;
597pub use ws_proxy::{WsProxyConfig, WsProxyHandler, WsProxyRule};
598// Note: ValidationError and ValidationResult from spec_parser conflict with schema_diff::ValidationError
599// Use qualified paths: spec_parser::ValidationError, spec_parser::ValidationResult
600
601// ── Organized module facades (R10) ───────────────────────────────────────────
602// These provide a namespaced access path for new code. Existing flat re-exports
603// above remain for backward compatibility. Prefer these for new imports.
604
605/// Routing, route matching, and OpenAPI route generation
606pub mod routes {
607    pub use crate::openapi::{
608        OpenApiOperation, OpenApiRoute, OpenApiSchema, OpenApiSecurityRequirement, OpenApiSpec,
609    };
610    pub use crate::openapi_routes::{
611        create_registry_from_file, create_registry_from_json, OpenApiRouteRegistry,
612        ValidationOptions,
613    };
614    pub use crate::routing::{HttpMethod, Route, RouteRegistry};
615}
616
617/// Middleware, protocol abstractions, and request processing
618pub mod middleware {
619    pub use crate::latency::LatencyInjector;
620    pub use crate::overrides::{OverrideMode, OverrideRule, Overrides, PatchOp};
621    pub use crate::protocol_abstraction::{
622        MessagePattern, MiddlewareAction, MiddlewareChain, Protocol, ProtocolMiddleware,
623        ProtocolRequest, ProtocolResponse, RequestMatcher, ResponseStatus, SpecOperation,
624        SpecRegistry,
625    };
626}
627
628/// Mock response generation and priority handling
629pub mod generation {
630    pub use crate::priority_handler::{
631        CustomFixtureStep, FailureInjectionStep, GenerationResult, MockGenerator, MockResponse,
632        PriorityHttpHandler, PriorityRequest, PriorityResponse, PriorityStep, SimpleMockGenerator,
633    };
634    pub use crate::stateful_handler::{StatefulConfig, StatefulResponse, StatefulResponseHandler};
635}
636
637/// Request/response validation
638pub mod validate {
639    pub use crate::runtime_validation::{
640        RuntimeValidationError, RuntimeValidationResult, RuntimeValidatorConfig, SchemaMetadata,
641    };
642    pub use crate::spec_parser::{GraphQLValidator, OpenApiValidator, SpecFormat};
643    pub use crate::validation::{
644        validate_openapi_operation_security, validate_openapi_security, Validator,
645    };
646    pub use crate::verification::{
647        matches_verification_pattern, verify_at_least, verify_never, verify_requests,
648        verify_sequence, VerificationCount, VerificationRequest, VerificationResult,
649    };
650}
651
652/// Fixture loading utilities
653pub mod fixtures {
654    pub use crate::custom_fixture::{CustomFixture, CustomFixtureLoader, NestedFixture};
655    pub use crate::fixture_store::{
656        load_fixtures_from_dir, FixtureFileFormat, FixtureFileGranularity, FixtureLoadErrorMode,
657        FixtureLoadOptions,
658    };
659    pub use crate::record_replay::{
660        RecordHandler, RecordReplayHandler, RecordedRequest, ReplayHandler,
661    };
662}
663
664/// Core configuration for MockForge
665#[derive(Debug, Clone, serde::Deserialize, serde::Serialize)]
666#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
667#[serde(default)]
668pub struct Config {
669    /// Enable latency simulation
670    pub latency_enabled: bool,
671    /// Enable failure simulation
672    pub failures_enabled: bool,
673    /// Enable response overrides
674    pub overrides_enabled: bool,
675    /// Enable traffic shaping (bandwidth + burst loss)
676    pub traffic_shaping_enabled: bool,
677    /// Failure injection configuration
678    pub failure_config: Option<failure_injection::FailureConfig>,
679    /// Proxy configuration
680    pub proxy: Option<ProxyConfig>,
681    /// Default latency profile
682    pub default_latency: LatencyProfile,
683    /// Traffic shaping configuration
684    pub traffic_shaping: TrafficShapingConfig,
685    /// Random chaos configuration
686    pub chaos_random: Option<ChaosConfig>,
687    /// Maximum number of request logs to keep in memory (default: 1000)
688    /// Helps prevent unbounded memory growth from request logging
689    pub max_request_logs: usize,
690    /// Time travel configuration for temporal testing
691    pub time_travel: TimeTravelConfig,
692}
693
694/// Default configuration
695impl Default for Config {
696    fn default() -> Self {
697        Self {
698            latency_enabled: true,
699            failures_enabled: false,
700            overrides_enabled: true,
701            traffic_shaping_enabled: false,
702            failure_config: None,
703            proxy: None,
704            default_latency: LatencyProfile::default(),
705            traffic_shaping: TrafficShapingConfig::default(),
706            chaos_random: None,
707            max_request_logs: 1000, // Default: keep last 1000 requests
708            time_travel: TimeTravelConfig::default(),
709        }
710    }
711}
712
713impl Config {
714    /// Create a ChaosEngine from the chaos_random configuration if enabled
715    pub fn create_chaos_engine(&self) -> Option<ChaosEngine> {
716        self.chaos_random.as_ref().map(|config| ChaosEngine::new(config.clone()))
717    }
718
719    /// Check if random chaos mode is enabled
720    pub fn is_chaos_random_enabled(&self) -> bool {
721        self.chaos_random.as_ref().map(|c| c.enabled).unwrap_or(false)
722    }
723}
724
725#[cfg(test)]
726mod tests {
727    use super::*;
728
729    #[test]
730    fn test_config_default() {
731        let config = Config::default();
732        assert!(config.latency_enabled);
733        assert!(!config.failures_enabled);
734        assert!(config.overrides_enabled);
735        assert!(!config.traffic_shaping_enabled);
736        assert!(config.failure_config.is_none());
737        assert!(config.proxy.is_none());
738    }
739
740    #[test]
741    fn test_config_serialization() {
742        let config = Config::default();
743        let json = serde_json::to_string(&config).unwrap();
744        assert!(json.contains("latency_enabled"));
745        assert!(json.contains("failures_enabled"));
746    }
747
748    #[test]
749    fn test_config_deserialization() {
750        // Use default config and modify
751        let config = Config {
752            latency_enabled: false,
753            failures_enabled: true,
754            ..Default::default()
755        };
756
757        // Serialize and deserialize
758        let json = serde_json::to_string(&config).unwrap();
759        let deserialized: Config = serde_json::from_str(&json).unwrap();
760
761        assert!(!deserialized.latency_enabled);
762        assert!(deserialized.failures_enabled);
763        assert!(deserialized.overrides_enabled);
764    }
765
766    #[test]
767    fn test_config_with_custom_values() {
768        let config = Config {
769            latency_enabled: false,
770            failures_enabled: true,
771            ..Default::default()
772        };
773
774        assert!(!config.latency_enabled);
775        assert!(config.failures_enabled);
776    }
777}