1#![warn(missing_docs)]
7
8pub mod api;
10pub mod app;
11pub mod auth;
12pub mod authorization;
13pub mod broadcast;
14pub mod cache;
15pub mod config;
16pub mod container;
17pub mod csrf;
18pub mod database;
19pub mod debug;
20pub mod error;
21pub mod hashing;
22pub mod http;
24#[cfg(feature = "inertia")]
25pub mod inertia;
26#[cfg(feature = "json-ui")]
27pub mod json_ui;
28pub mod lang;
29pub mod metrics;
30pub mod middleware;
31pub mod routing;
33pub mod schedule;
34pub mod seeder;
35pub mod server;
37pub mod session;
38pub(crate) mod static_files;
39pub mod telemetry;
42pub mod tenant;
43pub mod testing;
44#[cfg(feature = "theme")]
45pub mod theme;
46pub mod validation;
47mod websocket;
48#[cfg(feature = "projections")]
51pub mod write;
52
53pub use api::api_key::{
54 generate_api_key, hash_api_key, verify_api_key_hash, ApiKeyInfo, ApiKeyMiddleware,
55 ApiKeyProvider, GeneratedApiKey,
56};
57pub use api::openapi::{
58 build_openapi_spec, openapi_docs_response, openapi_json_response, OpenApiConfig,
59};
60
61pub use app::Application;
62pub use auth::{
63 Auth, AuthMiddleware, AuthUser, Authenticatable, GuestMiddleware, OptionalUser, UserProvider,
64};
65pub use authorization::{AuthResponse, Authorizable, AuthorizationError, Authorize, Gate, Policy};
66pub use cache::{Cache, CacheConfig, CacheStore, InMemoryCache, RedisCache};
67pub use config::{
68 env, env_optional, env_required, AppConfig, Config, Environment, LangConfig, LangConfigBuilder,
69 ServerConfig,
70};
71pub use container::{App, Container};
72pub use csrf::{csrf_field, csrf_meta_tag, csrf_token, CsrfMiddleware};
73pub use database::{
74 AutoRouteBinding, Database, DatabaseConfig, DatabaseType, DbConnection, Model, ModelMut,
75 RouteBinding, DB,
76};
77pub use utoipa;
79pub use utoipa_redoc;
80
81pub use error::{AppError, FrameworkError, HttpError, ValidationErrors};
84#[cfg(feature = "json-ui")]
85pub use ferro_json_ui::{
86 resolve_actions, resolve_actions_strict, resolve_errors, resolve_errors_all, Action,
87 ActionCardProps, ActionCardVariant, ActionOutcome, AlertProps, AlertVariant, AvatarProps,
88 BadgeProps, BadgeVariant, BreadcrumbItem, BreadcrumbProps, ButtonProps, ButtonType,
89 ButtonVariant, CardProps, CheckboxProps, ChecklistItem, ChecklistProps, Column, ColumnFormat,
90 ConfirmDialog, DashboardLayout, DashboardLayoutConfig, DescriptionItem, DescriptionListProps,
91 DialogVariant, Element, ElementBuilder, FormProps, HeaderProps, HttpMethod, IconPosition,
92 ImageProps, InputProps, InputType, JsonUiConfig, Layout, LayoutContext, LayoutRegistry,
93 ModalProps, NavItem, NotificationDropdownProps, NotificationItem, NotifyVariant, Orientation,
94 PaginationProps, ProgressProps, SelectOption, SelectProps, SeparatorProps, SidebarGroup,
95 SidebarNavItem, SidebarProps, SidebarSection, Size, SkeletonProps, SortDirection, Spec,
96 SpecBuilder, SpecError, StatCardProps, SwitchProps, Tab, TableProps, TabsProps, TextElement,
97 TextProps, ToastProps, ToastVariant, Visibility as JsonUiVisibility, VisibilityCondition,
98 VisibilityOperator, MAX_NESTING_DEPTH, SCHEMA_VERSION,
99};
100#[cfg(feature = "stripe")]
101pub use ferro_stripe::{
102 account, checkout, refund, verify_webhook, CheckoutBuilder, CheckoutIntent,
103 Error as StripeError, LineItem, MemoryProcessedLog, Mode, ProcessStripeWebhook,
104 ProcessedEventLog, Stripe, StripeChargeDisputeCreated, StripeChargeRefunded,
105 StripeCheckoutCompleted, StripeCheckoutExpired, StripeConfig, StripeConnectAccountUpdated,
106 StripeConnectPaymentSucceeded, StripeEvent, StripeInvoicePaid, StripePaymentIntentFailed,
107 StripeSubscriptionDeleted, StripeSubscriptionUpdated, SyncDispatcher,
108};
109#[cfg(feature = "theme")]
110pub use ferro_theme::{IntentModeTemplates, IntentSlotTemplate, Theme, ThemeError, ThemeTemplates};
111pub use hashing::{hash, needs_rehash, verify, DEFAULT_COST as HASH_DEFAULT_COST};
112pub use http::action::{
113 ActionError, ActionKind, ActionResult, ActionResultExt, FlashVariant, IntoActionError,
114};
115pub use http::{
116 bytes, json, request_host, text, validate_mime, validate_size, Cookie, CookieOptions,
117 FerroBody, FormRequest, FromParam, FromRequest, HttpResponse, InertiaRedirect, MultipartForm,
118 PaginationLinks, PaginationMeta, Redirect, Request, Resource, ResourceCollection, ResourceMap,
119 Response, ResponseExt, SameSite, SseEvent, SseStream, UploadedFile,
120};
121#[cfg(feature = "inertia")]
122pub use inertia::{Inertia, InertiaConfig, InertiaResponse, InertiaShared, SavedInertiaContext};
123#[cfg(feature = "json-ui")]
124pub use json_ui::JsonUi;
125pub use lang::{lang_choice, lang_init, locale, set_locale, t, trans, LangMiddleware};
126pub use sea_orm::{
127 ActiveModelTrait, ActiveValue, ColumnTrait, EntityTrait, IntoActiveModel, ModelTrait,
128 PaginatorTrait, QueryFilter, QueryOrder, QuerySelect,
129};
130pub use session::{
131 invalidate_all_for_user, session, session_mut, with_test_session, DatabaseSessionDriver,
132 SessionConfig, SessionData, SessionMiddleware, SessionStore,
133};
134#[cfg(feature = "stripe")]
135pub use tenant::RequiresPlan;
136pub use tenant::{
137 current_tenant, DbTenantLookup, FrameworkTenantScopeProvider, HeaderResolver, JwtClaimResolver,
138 PathResolver, SubdomainResolver, TenantContext, TenantFailureMode, TenantLookup,
139 TenantMiddleware, TenantResolver, TenantScope, TenantScoped,
140};
141#[cfg(feature = "theme")]
142pub use theme::{
143 current_theme, DefaultResolver, HeaderThemeResolver, TenantThemeResolver, ThemeMiddleware,
144 ThemeResolver,
145};
146#[cfg(feature = "inertia")]
148#[allow(deprecated)]
149pub use inertia::InertiaContext;
150pub use metrics::{get_metrics, MetricsSnapshot, RouteMetrics, RouteMetricsView};
151pub use middleware::{
152 get_pre_route_middleware, register_global_middleware, register_pre_route_middleware,
153 rewrite_request_path, Cors, Limit, LimiterResponse, MetricsMiddleware, Middleware,
154 MiddlewareFuture, MiddlewareRegistry, Next, PreRouteMiddleware, PreRouteResult, RateLimiter,
155 SecurityHeaders, Throttle,
156};
157pub use routing::{
158 __box_handler,
160 __delete_impl,
161 __fallback_impl,
162 __get_impl,
163 __patch_impl,
164 __post_impl,
165 __put_impl,
166 get_registered_routes,
167 route,
168 validate_route_path,
169 FallbackDefBuilder,
170 GroupBuilder,
171 GroupDef,
172 GroupItem,
173 GroupRoute,
174 GroupRouter,
175 IntoGroupItem,
176 ResourceAction,
177 ResourceDef,
178 ResourceRoute,
179 RouteBuilder,
180 RouteDefBuilder,
181 RouteInfo,
182 Router,
183};
184pub use schedule::{CronExpression, DayOfWeek, Schedule, Task, TaskBuilder, TaskEntry, TaskResult};
185pub use seeder::{DatabaseSeeder, Seeder, SeederRegistry};
186pub use server::Server;
187pub use telemetry::{
188 inline_budget::DEFAULT_INLINE_BUDGET_THRESHOLD_BYTES, request_telemetry::RING_BUFFER_CAPACITY,
189 Decision, RequestTelemetry, Sample,
190};
191
192pub use ferro_events::{
194 dispatch as dispatch_event, dispatch_sync, Error as EventError, Event, EventDispatcher,
195 Listener, ShouldQueue,
196};
197
198pub mod queue {
200 pub use ferro_queue::{
201 dispatch, dispatch_later, dispatch_to, register_tenant_capture_hook, CreateJobsTable,
202 Error, FailedJobInfo, Job, JobInfo, JobPayload, JobState, PendingDispatch, Queue,
203 QueueConfig, QueueStats, Queueable, SingleQueueStats, TenantScopeProvider, Worker,
204 WorkerConfig, WorkerLoop,
205 };
206}
207
208pub use ferro_notifications::{
210 Channel as NotificationChannel, ChannelResult, DatabaseMessage, DatabaseNotificationStore,
211 Error as NotificationError, InAppConfig, InAppMessage, InAppSeverity, MailAttachment,
212 MailConfig, MailDriver, MailMessage, Notifiable, Notification, NotificationConfig,
213 NotificationDispatcher, PushMessage, ResendConfig, SlackAttachment, SlackField, SlackMessage,
214 SmsMessage, SmtpConfig, StoredNotification, WhatsAppMessage,
215};
216
217pub use ferro_broadcast::{
219 AuthData, Broadcast, BroadcastBuilder, BroadcastConfig, BroadcastMessage, Broadcaster,
220 ChannelAuthorizer, ChannelInfo, ChannelType, Client as BroadcastClient, ClientMessage,
221 Error as BroadcastError, PresenceMember, ServerMessage,
222};
223
224pub use broadcast::broadcasting_auth;
226
227pub use ferro_storage::{
229 Disk, DiskConfig, DiskDriver, Error as StorageError, FileMetadata, LocalDriver,
230 MemoryDriver as StorageMemoryDriver, PutOptions, Storage, StorageDriver, Visibility,
231};
232
233pub use ferro_cache::{
235 Cache as TaggableCache, CacheConfig as TaggableCacheConfig, CacheStore as TaggableCacheStore,
236 Error as TaggableCacheError, MemoryStore as TaggableCacheMemoryStore, TaggedCache,
237};
238
239pub use ferro_lang::{LangError, Translator};
241
242#[cfg(feature = "ai")]
244pub use ferro_ai::{
245 AnthropicProvider, ClassificationProvider, ClassificationResult, Classifier, ClassifierConfig,
246 ConfirmationExpired, ConfirmationStore, Error as AiError, InMemoryConfirmationStore,
247 PendingActionInfo,
248};
249
250#[cfg(feature = "whatsapp")]
252pub use ferro_whatsapp::{
253 verify_whatsapp_webhook, DeduplicationStore, DeliveryStatus, Error as WhatsAppError,
254 InMemoryDeduplicationStore, Message as WhatsAppRawMessage, ProcessWhatsAppWebhook,
255 SendResult as WhatsAppSendResult, SenderIdentity, WhatsApp, WhatsAppConfig,
256 WhatsAppStatusUpdate, WhatsAppTextReceived,
257};
258
259#[cfg(feature = "projections")]
261pub use ferro_projections::{
262 derive_intents, derive_transition_plan, infer_meaning, ActionDef, BaseContext, Cardinality,
263 DataType, Error as ProjectionsError, FieldDef, FieldMeaning, GuardDef, InputDef, Intent,
264 IntentHint, IntentScore, NavigationHint, RelationshipDef, RenderHint, Renderer, ServiceDef,
265 StateDef, StateMachine, Transition, TransitionPlan, Verbosity, Warning as ProjectionsWarning,
266};
267#[cfg(feature = "projections")]
269pub use ferro_json_ui::{JsonUiRenderer, RenderMode, VisualContext};
270#[cfg(feature = "projections")]
272pub use ferro_text::TextRenderer;
273#[cfg(feature = "projections")]
275pub use write::{
276 dispatch_write, ExecutorFn, GuardEvaluatorFn, OverrideFn, WriteDispatcher, WriteError,
277 WriteResult,
278};
279
280pub use async_trait::async_trait;
282
283#[doc(hidden)]
285pub use inventory;
286
287#[doc(hidden)]
289pub use serde_json;
290
291pub use serde;
293
294pub use validator;
296pub use validator::Validate;
297
298pub use validation::{
300 accepted,
302 alpha,
303 alpha_dash,
304 alpha_num,
305 array,
306 between,
307 boolean,
308 confirmed,
309 date,
310 different,
311 email,
312 in_array,
313 integer,
314 max,
315 min,
316 not_in,
317 nullable,
318 numeric,
319 regex,
320 register_validation_translator,
322 required,
323 required_if,
324 same,
325 string,
326 unique,
327 url,
328 validate,
329 AsyncRule,
330 AsyncValidationError,
331 AsyncValidator,
332 ConstraintMap,
333 MapConstraintExt,
334 Rule,
335 TranslatorFn,
336 Validatable,
337 ValidationError,
338 Validator,
339};
340
341pub use ferro_macros::action;
343pub use ferro_macros::domain_error;
344pub use ferro_macros::ferro_test;
345pub use ferro_macros::handler;
346pub use ferro_macros::inertia_response;
347pub use ferro_macros::injectable;
348pub use ferro_macros::redirect;
349pub use ferro_macros::request;
350pub use ferro_macros::resource_get;
351pub use ferro_macros::resource_post;
352pub use ferro_macros::service;
353pub use ferro_macros::ApiResource;
354pub use ferro_macros::FerroModel;
355pub use ferro_macros::FormRequest as FormRequestDerive;
356pub use ferro_macros::InertiaProps;
357pub use ferro_macros::ValidateRules;
358
359pub use ferro_macros::describe;
361pub use ferro_macros::test;
362
363pub use testing::{
365 Factory, FactoryBuilder, Fake, Sequence, TestClient, TestContainer, TestContainerGuard,
366 TestDatabase, TestRequestBuilder, TestResponse,
367};
368
369#[macro_export]
381macro_rules! json_response {
382 ($($json:tt)+) => {
383 Ok($crate::HttpResponse::json($crate::serde_json::json!($($json)+)))
384 };
385}
386
387#[macro_export]
399macro_rules! text_response {
400 ($text:expr) => {
401 Ok($crate::HttpResponse::text($text))
402 };
403}
404
405#[macro_export]
419macro_rules! error_response {
420 ($status:expr, $msg:expr) => {
421 $crate::HttpResponse::json($crate::serde_json::json!({ "message": ($msg).to_string() }))
422 .status($status as u16)
423 };
424}
425
426#[macro_export]
444macro_rules! global_middleware {
445 ($middleware:expr) => {
446 $crate::register_global_middleware($middleware)
447 };
448}
449
450#[macro_export]
464macro_rules! pre_route_middleware {
465 ($middleware:expr) => {
466 $crate::register_pre_route_middleware($middleware)
467 };
468}
469
470#[macro_export]
493macro_rules! expect {
494 ($value:expr) => {
495 $crate::testing::Expect::new($value, concat!(file!(), ":", line!()))
496 };
497}