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