1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
//! # adminx
//!
//! A framework-neutral admin-panel framework. This crate is a **facade**: it
//! re-exports the neutral [`adminx_core`] plus whichever framework and storage
//! adapters you enable via Cargo features, so you depend on a single crate.
//!
//! ```toml
//! # Axum + PostgreSQL/MySQL/SQLite:
//! adminx = { version = "2", features = ["axum", "seaorm"] }
//! # Actix + MongoDB:
//! adminx = { version = "2", features = ["actix", "mongo"] }
//! ```
//!
//! ## Usage
//!
//! ```ignore
//! use adminx::prelude::*; // Resource, ReqCtx, ApiResponse, auth, ...
//!
//! # #[derive(Clone)] struct UserResource;
//! # #[async_trait::async_trait] impl Resource for UserResource {
//! # fn resource_name(&self)->&'static str {"Users"}
//! # fn base_path(&self)->&'static str {"users"}
//! # fn table_name(&self)->&'static str {"users"}
//! # fn clone_box(&self)->Box<dyn Resource>{Box::new(self.clone())}
//! # }
//! #[tokio::main]
//! async fn main() -> Result<(), Box<dyn std::error::Error>> {
//! adminx::seaorm::init("postgres://localhost/mydb").await?; // storage adapter
//! register_resource(Box::new(UserResource));
//!
//! let app = axum::Router::new().nest("/adminx", adminx::axum::router());
//! let l = tokio::net::TcpListener::bind("0.0.0.0:8080").await?;
//! axum::serve(l, app).await?;
//! Ok(())
//! }
//! ```
//!
//! The framework/storage integrations live under [`self::actix`] / [`self::axum`]
//! and [`self::seaorm`] / [`self::mongo`], each present only when its feature is
//! enabled. Everything else (the [`Resource`] trait, [`prelude`], auth, UI) comes
//! straight from the core.
// Pick exactly one web framework. Both adapters register the same routes, so
// enabling both is almost always a mistake in Cargo features. (Both *storage*
// backends together is fine — the `cli` feature bundles them on purpose.)
compile_error!;
// Re-export the entire neutral core at the crate root, including its `prelude`,
// `auth`, `ui`, `storage`, etc. modules and the `Resource` trait.
pub use *;
/// The neutral core, also reachable explicitly as `adminx::core`.
pub use adminx_core as core;
/// Actix Web integration (`adminx::actix::scope()`). Requires feature `actix`.
pub use adminx_actix as actix;
/// Axum integration (`adminx::axum::router()`). Requires feature `axum`.
pub use adminx_axum as axum;
/// SeaORM storage (`adminx::seaorm::init(url)`). Requires feature `seaorm`.
pub use adminx_seaorm as seaorm;
/// MongoDB storage (`adminx::mongo::init(uri, db)`). Requires feature `mongo`.
pub use adminx_mongo as mongo;
/// DB-backed RBAC (`adminx::rbac::init(abilities)`). Requires feature `rbac`.
/// The `Action`, `Authorizer`, and `set_authorizer` items come through the core
/// re-export above; this adds the `DbAuthorizer` backend and `Ability` builder.
pub use adminx_rbac as rbac;
/// Audit logging (`adminx::audit::init(AuditConfig::default())`). Requires
/// feature `audit`. The `Auditor` trait and `set_auditor` come through the core
/// re-export above; this adds the storage-backed sink and the in-panel viewer.
pub use adminx_audit as audit;
/// File attachments (`adminx::attachments::init_local(dir)`). Requires feature
/// `attachments`. The `Attachments`/`FileField`/`UploadedFile` types come
/// through the core re-export (`adminx::attach`); this adds the backend and the
/// local-disk store.
pub use adminx_attachments as attachments;
/// Full-text search (`adminx::search::init_memory()`). Requires the `search`
/// feature (or `search-meilisearch` for the Meilisearch backend). Powered by the
/// standalone `searchez` crate; resources opt in with `search_fields()`.
pub use adminx_search as search;
/// Cloud attachment backends — AWS S3, GCS, Azure Blob (`adminx::cloud::s3_from_env(..)`).
/// Requires one of the `cloud-aws` / `cloud-gcp` / `cloud-azure` features. Hand
/// the result to `adminx::attachments::init(..)`.
pub use adminx_cloud as cloud;