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, ActiveValue, ColumnTrait, EntityTrait, IntoActiveModel, ModelTrait,
124 PaginatorTrait, QueryFilter, QueryOrder, QuerySelect,
125};
126pub use session::{
127 invalidate_all_for_user, session, session_mut, with_test_session, DatabaseSessionDriver,
128 SessionConfig, 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, TenantScoped,
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, BaseContext, Cardinality, DataType,
259 Error as ProjectionsError, FieldDef, FieldMeaning, GuardDef, InputDef, Intent, IntentHint,
260 IntentScore, NavigationHint, RelationshipDef, RenderHint, Renderer, ServiceDef, StateDef,
261 StateMachine, Transition, Verbosity, Warning as ProjectionsWarning,
262};
263#[cfg(feature = "projections")]
265pub use ferro_json_ui::{JsonUiRenderer, RenderMode, VisualContext};
266#[cfg(feature = "projections")]
268pub use ferro_text::TextRenderer;
269
270pub use async_trait::async_trait;
272
273#[doc(hidden)]
275pub use inventory;
276
277#[doc(hidden)]
279pub use serde_json;
280
281pub use serde;
283
284pub use validator;
286pub use validator::Validate;
287
288pub use validation::{
290 accepted,
292 alpha,
293 alpha_dash,
294 alpha_num,
295 array,
296 between,
297 boolean,
298 confirmed,
299 date,
300 different,
301 email,
302 in_array,
303 integer,
304 max,
305 min,
306 not_in,
307 nullable,
308 numeric,
309 regex,
310 register_validation_translator,
312 required,
313 required_if,
314 same,
315 string,
316 unique,
317 url,
318 validate,
319 AsyncRule,
320 AsyncValidationError,
321 AsyncValidator,
322 ConstraintMap,
323 MapConstraintExt,
324 Rule,
325 TranslatorFn,
326 Validatable,
327 ValidationError,
328 Validator,
329};
330
331pub use ferro_macros::action;
333pub use ferro_macros::domain_error;
334pub use ferro_macros::ferro_test;
335pub use ferro_macros::handler;
336pub use ferro_macros::inertia_response;
337pub use ferro_macros::injectable;
338pub use ferro_macros::redirect;
339pub use ferro_macros::request;
340pub use ferro_macros::resource_get;
341pub use ferro_macros::resource_post;
342pub use ferro_macros::service;
343pub use ferro_macros::ApiResource;
344pub use ferro_macros::FerroModel;
345pub use ferro_macros::FormRequest as FormRequestDerive;
346pub use ferro_macros::InertiaProps;
347pub use ferro_macros::ValidateRules;
348
349pub use ferro_macros::describe;
351pub use ferro_macros::test;
352
353pub use testing::{
355 Factory, FactoryBuilder, Fake, Sequence, TestClient, TestContainer, TestContainerGuard,
356 TestDatabase, TestRequestBuilder, TestResponse,
357};
358
359#[macro_export]
371macro_rules! json_response {
372 ($($json:tt)+) => {
373 Ok($crate::HttpResponse::json($crate::serde_json::json!($($json)+)))
374 };
375}
376
377#[macro_export]
389macro_rules! text_response {
390 ($text:expr) => {
391 Ok($crate::HttpResponse::text($text))
392 };
393}
394
395#[macro_export]
409macro_rules! error_response {
410 ($status:expr, $msg:expr) => {
411 $crate::HttpResponse::json($crate::serde_json::json!({ "message": ($msg).to_string() }))
412 .status($status as u16)
413 };
414}
415
416#[macro_export]
434macro_rules! global_middleware {
435 ($middleware:expr) => {
436 $crate::register_global_middleware($middleware)
437 };
438}
439
440#[macro_export]
454macro_rules! pre_route_middleware {
455 ($middleware:expr) => {
456 $crate::register_pre_route_middleware($middleware)
457 };
458}
459
460#[macro_export]
483macro_rules! expect {
484 ($value:expr) => {
485 $crate::testing::Expect::new($value, concat!(file!(), ":", line!()))
486 };
487}