Skip to main content

ferro_rs/
lib.rs

1pub mod app;
2pub mod auth;
3pub mod authorization;
4pub mod broadcast;
5pub mod cache;
6pub mod config;
7pub mod container;
8pub mod csrf;
9pub mod database;
10pub mod debug;
11pub mod error;
12pub mod hashing;
13pub mod http;
14#[cfg(feature = "inertia")]
15pub mod inertia;
16#[cfg(feature = "json-ui")]
17pub mod json_ui;
18pub mod lang;
19pub mod metrics;
20pub mod middleware;
21pub mod routing;
22pub mod schedule;
23pub mod seeder;
24pub mod server;
25pub mod session;
26pub(crate) mod static_files;
27pub mod testing;
28pub mod validation;
29mod websocket;
30
31pub use app::Application;
32pub use auth::{
33    Auth, AuthMiddleware, AuthUser, Authenticatable, GuestMiddleware, OptionalUser, UserProvider,
34};
35pub use authorization::{AuthResponse, Authorizable, AuthorizationError, Authorize, Gate, Policy};
36pub use cache::{Cache, CacheConfig, CacheStore, InMemoryCache, RedisCache};
37pub use config::{
38    env, env_optional, env_required, AppConfig, Config, Environment, LangConfig, LangConfigBuilder,
39    ServerConfig,
40};
41pub use container::{App, Container};
42pub use csrf::{csrf_field, csrf_meta_tag, csrf_token, CsrfMiddleware};
43pub use database::{
44    AutoRouteBinding, Database, DatabaseConfig, DatabaseType, DbConnection, Model, ModelMut,
45    RouteBinding, DB,
46};
47
48// Re-export commonly used SeaORM traits for convenience
49// This saves users from having to add `use sea_orm::*` imports
50pub use error::{AppError, FrameworkError, HttpError, ValidationErrors};
51#[cfg(feature = "json-ui")]
52pub use ferro_json_ui::{
53    footer, global_registry, navigation, register_layout, render_layout, render_to_html,
54    resolve_actions, resolve_actions_strict, resolve_errors, resolve_errors_all, resolve_path,
55    resolve_path_string, sidebar, Action, ActionOutcome, AlertProps, AlertVariant, AppLayout,
56    AuthLayout, AvatarProps, BadgeProps, BadgeVariant, BreadcrumbItem, BreadcrumbProps,
57    ButtonProps, ButtonVariant, CardProps, CheckboxProps, Column, ColumnFormat, Component,
58    ComponentNode, ConfirmDialog, DefaultLayout, DescriptionItem, DescriptionListProps,
59    DialogVariant, FormProps, HttpMethod, IconPosition, InputProps, InputType, JsonUiConfig,
60    JsonUiView, Layout, LayoutContext, LayoutRegistry, ModalProps, NavItem, NotifyVariant,
61    Orientation, PaginationProps, ProgressProps, SelectOption, SelectProps, SeparatorProps,
62    SidebarSection, Size, SkeletonProps, SortDirection, SwitchProps, Tab, TableProps, TabsProps,
63    TextElement, TextProps, Visibility as JsonUiVisibility, VisibilityCondition,
64    VisibilityOperator, SCHEMA_VERSION,
65};
66pub use hashing::{hash, needs_rehash, verify, DEFAULT_COST as HASH_DEFAULT_COST};
67pub use http::{
68    json, text, Cookie, CookieOptions, FormRequest, FromParam, FromRequest, HttpResponse,
69    InertiaRedirect, PaginationLinks, PaginationMeta, Redirect, Request, Resource,
70    ResourceCollection, ResourceMap, Response, ResponseExt, SameSite,
71};
72#[cfg(feature = "inertia")]
73pub use inertia::{Inertia, InertiaConfig, InertiaResponse, InertiaShared, SavedInertiaContext};
74#[cfg(feature = "json-ui")]
75pub use json_ui::JsonUi;
76pub use lang::{lang_choice, lang_init, locale, set_locale, t, trans, LangMiddleware};
77pub use sea_orm::{
78    ActiveModelTrait, ColumnTrait, EntityTrait, IntoActiveModel, ModelTrait, PaginatorTrait,
79    QueryFilter, QueryOrder, QuerySelect,
80};
81pub use session::{
82    session, session_mut, SessionConfig, SessionData, SessionMiddleware, SessionStore,
83};
84// Deprecated - kept for backward compatibility
85#[cfg(feature = "inertia")]
86#[allow(deprecated)]
87pub use inertia::InertiaContext;
88pub use metrics::{get_metrics, MetricsSnapshot, RouteMetrics, RouteMetricsView};
89pub use middleware::{
90    register_global_middleware, Limit, LimiterResponse, MetricsMiddleware, Middleware,
91    MiddlewareFuture, MiddlewareRegistry, Next, RateLimiter, Throttle,
92};
93pub use routing::{
94    // Internal functions used by macros (hidden from docs)
95    __box_handler,
96    __delete_impl,
97    __fallback_impl,
98    __get_impl,
99    __patch_impl,
100    __post_impl,
101    __put_impl,
102    get_registered_routes,
103    route,
104    validate_route_path,
105    FallbackDefBuilder,
106    GroupBuilder,
107    GroupDef,
108    GroupItem,
109    GroupRoute,
110    GroupRouter,
111    IntoGroupItem,
112    ResourceAction,
113    ResourceDef,
114    ResourceRoute,
115    RouteBuilder,
116    RouteDefBuilder,
117    RouteInfo,
118    Router,
119};
120pub use schedule::{CronExpression, DayOfWeek, Schedule, Task, TaskBuilder, TaskEntry, TaskResult};
121pub use seeder::{DatabaseSeeder, Seeder, SeederRegistry};
122pub use server::Server;
123
124// Re-export ferro-events for event-driven architecture
125pub use ferro_events::{
126    dispatch as dispatch_event, dispatch_sync, Error as EventError, Event, EventDispatcher,
127    Listener, ShouldQueue,
128};
129
130// Re-export ferro-queue for background job processing
131pub use ferro_queue::{
132    dispatch as queue_dispatch, dispatch_later, dispatch_to, Error as QueueError, Job, JobPayload,
133    PendingDispatch, Queue, QueueConfig, QueueConnection, Queueable, Worker, WorkerConfig,
134};
135
136// Re-export ferro-notifications for multi-channel notifications
137pub use ferro_notifications::{
138    Channel as NotificationChannel, ChannelResult, DatabaseMessage, DatabaseNotificationStore,
139    Error as NotificationError, MailConfig, MailDriver, MailMessage, Notifiable, Notification,
140    NotificationConfig, NotificationDispatcher, ResendConfig, SlackAttachment, SlackField,
141    SlackMessage, SmtpConfig, StoredNotification,
142};
143
144// Re-export ferro-broadcast for real-time WebSocket channels
145pub use ferro_broadcast::{
146    AuthData, Broadcast, BroadcastBuilder, BroadcastConfig, BroadcastMessage, Broadcaster,
147    ChannelAuthorizer, ChannelInfo, ChannelType, Client as BroadcastClient, ClientMessage,
148    Error as BroadcastError, PresenceMember, ServerMessage,
149};
150
151// Re-export broadcasting auth handler
152pub use broadcast::broadcasting_auth;
153
154// Re-export ferro-storage for file storage abstraction
155pub use ferro_storage::{
156    Disk, DiskConfig, DiskDriver, Error as StorageError, FileMetadata, LocalDriver,
157    MemoryDriver as StorageMemoryDriver, PutOptions, Storage, StorageDriver, Visibility,
158};
159
160// Re-export ferro-cache for caching with tags
161pub use ferro_cache::{
162    Cache as TaggableCache, CacheConfig as TaggableCacheConfig, CacheStore as TaggableCacheStore,
163    Error as TaggableCacheError, MemoryStore as TaggableCacheMemoryStore, TaggedCache,
164};
165
166// Re-export ferro-lang for localization
167pub use ferro_lang::{LangError, Translator};
168
169// Re-export async_trait for middleware implementations
170pub use async_trait::async_trait;
171
172// Re-export inventory for #[service(ConcreteType)] macro
173#[doc(hidden)]
174pub use inventory;
175
176// Re-export for macro usage
177#[doc(hidden)]
178pub use serde_json;
179
180// Re-export serde for InertiaProps derive macro
181pub use serde;
182
183// Re-export validator crate for derive-based validation
184pub use validator;
185pub use validator::Validate;
186
187// Re-export our Laravel-style validation module
188pub use validation::{
189    // Rules
190    accepted,
191    alpha,
192    alpha_dash,
193    alpha_num,
194    array,
195    between,
196    boolean,
197    confirmed,
198    date,
199    different,
200    email,
201    in_array,
202    integer,
203    max,
204    min,
205    not_in,
206    nullable,
207    numeric,
208    regex,
209    // Bridge
210    register_validation_translator,
211    required,
212    required_if,
213    same,
214    string,
215    url,
216    validate,
217    Rule,
218    TranslatorFn,
219    Validatable,
220    ValidationError,
221    Validator,
222};
223
224// Re-export the proc-macros for compile-time component validation and type safety
225pub use ferro_macros::domain_error;
226pub use ferro_macros::ferro_test;
227pub use ferro_macros::handler;
228pub use ferro_macros::inertia_response;
229pub use ferro_macros::injectable;
230pub use ferro_macros::redirect;
231pub use ferro_macros::request;
232pub use ferro_macros::service;
233pub use ferro_macros::ApiResource;
234pub use ferro_macros::FerroModel;
235pub use ferro_macros::FormRequest as FormRequestDerive;
236pub use ferro_macros::InertiaProps;
237pub use ferro_macros::ValidateRules;
238
239// Re-export Jest-like testing macros
240pub use ferro_macros::describe;
241pub use ferro_macros::test;
242
243// Re-export testing utilities
244pub use testing::{
245    Factory, FactoryBuilder, Fake, Sequence, TestClient, TestContainer, TestContainerGuard,
246    TestDatabase, TestRequestBuilder, TestResponse,
247};
248
249#[macro_export]
250macro_rules! json_response {
251    ($($json:tt)+) => {
252        Ok($crate::HttpResponse::json($crate::serde_json::json!($($json)+)))
253    };
254}
255
256#[macro_export]
257macro_rules! text_response {
258    ($text:expr) => {
259        Ok($crate::HttpResponse::text($text))
260    };
261}
262
263/// Register global middleware that runs on every request
264///
265/// Global middleware is registered in `bootstrap.rs` and runs in registration order,
266/// before any route-specific middleware.
267///
268/// # Example
269///
270/// ```rust,ignore
271/// // In bootstrap.rs
272/// use ferro_rs::global_middleware;
273/// use ferro_rs::middleware;
274///
275/// pub fn register() {
276///     global_middleware!(middleware::LoggingMiddleware);
277///     global_middleware!(middleware::CorsMiddleware);
278/// }
279/// ```
280#[macro_export]
281macro_rules! global_middleware {
282    ($middleware:expr) => {
283        $crate::register_global_middleware($middleware)
284    };
285}
286
287/// Create an expectation for fluent assertions
288///
289/// # Example
290///
291/// ```rust,ignore
292/// use ferro_rs::expect;
293///
294/// expect!(actual).to_equal(expected);
295/// expect!(result).to_be_ok();
296/// expect!(vec).to_have_length(3);
297/// ```
298///
299/// On failure, shows clear output:
300/// ```text
301/// Test: "returns all todos"
302///   at src/actions/todo_action.rs:25
303///
304///   expect!(actual).to_equal(expected)
305///
306///   Expected: 0
307///   Received: 3
308/// ```
309#[macro_export]
310macro_rules! expect {
311    ($value:expr) => {
312        $crate::testing::Expect::new($value, concat!(file!(), ":", line!()))
313    };
314}