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 register_layout, resolve_actions, resolve_actions_strict, resolve_errors, resolve_errors_all,
87 Action, ActionCardProps, ActionOutcome, AlertProps, AvatarProps, BadgeProps, BreadcrumbItem,
88 BreadcrumbProps, ButtonProps, ButtonType, CardAppearance, CardProps, CheckboxProps,
89 ChecklistItem, ChecklistProps, Column, ColumnFormat, ConfirmDialog, DashboardLayout,
90 DashboardLayoutConfig, DescriptionItem, DescriptionListProps, Element, ElementBuilder,
91 FormProps, HeaderProps, HttpMethod, IconPosition, ImageProps, InputProps, InputType,
92 JsonUiConfig, Layout, LayoutContext, LayoutRegistry, ModalProps, NavItem,
93 NotificationDropdownProps, NotificationItem, Orientation, PaginationProps, ProgressProps,
94 SelectOption, SelectProps, SeparatorProps, SidebarGroup, SidebarNavItem, SidebarProps,
95 SidebarSection, Size, SkeletonProps, SortDirection, Spec, SpecBuilder, SpecError,
96 StatCardProps, SwitchProps, Tab, TableProps, TabsProps, TextElement, TextProps, ToastProps,
97 Tone, Variant, Visibility as JsonUiVisibility, VisibilityCondition, VisibilityOperator,
98 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::{
270 default_template, register_template, JsonUiRenderer, RenderMode, VisualContext,
271};
272#[cfg(feature = "projections")]
274pub use ferro_text::TextRenderer;
275#[cfg(feature = "projections")]
277pub use write::{
278 dispatch_write, ExecutorFn, GuardEvaluatorFn, OverrideFn, WriteDispatcher, WriteError,
279 WriteResult,
280};
281
282pub use async_trait::async_trait;
284
285#[doc(hidden)]
287pub use inventory;
288
289#[doc(hidden)]
291pub use serde_json;
292
293pub use serde;
295
296pub use validator;
298pub use validator::Validate;
299
300pub use validation::{
302 accepted,
304 alpha,
305 alpha_dash,
306 alpha_num,
307 array,
308 between,
309 boolean,
310 confirmed,
311 date,
312 different,
313 email,
314 in_array,
315 integer,
316 max,
317 min,
318 not_in,
319 nullable,
320 numeric,
321 regex,
322 register_validation_translator,
324 required,
325 required_if,
326 same,
327 string,
328 unique,
329 url,
330 validate,
331 AsyncRule,
332 AsyncValidationError,
333 AsyncValidator,
334 ConstraintMap,
335 MapConstraintExt,
336 Rule,
337 TranslatorFn,
338 Validatable,
339 ValidationError,
340 Validator,
341};
342
343pub use ferro_macros::action;
345pub use ferro_macros::domain_error;
346pub use ferro_macros::ferro_test;
347pub use ferro_macros::handler;
348pub use ferro_macros::inertia_response;
349pub use ferro_macros::injectable;
350pub use ferro_macros::redirect;
351pub use ferro_macros::request;
352pub use ferro_macros::resource_get;
353pub use ferro_macros::resource_post;
354pub use ferro_macros::service;
355pub use ferro_macros::ApiResource;
356pub use ferro_macros::FerroModel;
357pub use ferro_macros::FormRequest as FormRequestDerive;
358pub use ferro_macros::InertiaProps;
359pub use ferro_macros::ValidateRules;
360
361pub use ferro_macros::describe;
363pub use ferro_macros::test;
364
365pub use testing::{
367 Factory, FactoryBuilder, Fake, Sequence, TestClient, TestContainer, TestContainerGuard,
368 TestDatabase, TestRequestBuilder, TestResponse,
369};
370
371#[macro_export]
383macro_rules! json_response {
384 ($($json:tt)+) => {
385 Ok($crate::HttpResponse::json($crate::serde_json::json!($($json)+)))
386 };
387}
388
389#[macro_export]
401macro_rules! text_response {
402 ($text:expr) => {
403 Ok($crate::HttpResponse::text($text))
404 };
405}
406
407#[macro_export]
421macro_rules! error_response {
422 ($status:expr, $msg:expr) => {
423 $crate::HttpResponse::json($crate::serde_json::json!({ "message": ($msg).to_string() }))
424 .status($status as u16)
425 };
426}
427
428#[macro_export]
446macro_rules! global_middleware {
447 ($middleware:expr) => {
448 $crate::register_global_middleware($middleware)
449 };
450}
451
452#[macro_export]
466macro_rules! pre_route_middleware {
467 ($middleware:expr) => {
468 $crate::register_pre_route_middleware($middleware)
469 };
470}
471
472#[macro_export]
495macro_rules! expect {
496 ($value:expr) => {
497 $crate::testing::Expect::new($value, concat!(file!(), ":", line!()))
498 };
499}