Skip to main content

ferro_rs/
lib.rs

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