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
// adminx-storage/src/lib.rs
//
// File attachments for adminx. Register it and any resource can declare
// `file_fields()`; the panel then shows an upload widget on the detail page and
// the web adapters expose attach / serve / detach routes. Leave it out and
// adminx behaves exactly as before.
//
// Two layers, both swappable:
// - `BlobStore` holds the bytes. The MVP ships `LocalFsStore` (local disk); an
// S3 / object-store backend can slot in behind it later.
// - the `adminx_attachments` table holds the metadata, written through
// adminx-core's `Storage`, so it works over SeaORM (SQL) or MongoDB.
//
// ## Startup order
//
// ```ignore
// adminx_seaorm::init(&db_url).await?; // 1. storage
// adminx_core::seed(adminx_storage::migrate_sql()).await?; // 2. SQL table (SQL backends only)
// adminx_storage::init_local("./adminx_uploads"); // 3. register a local-disk backend
// configure_auth(AuthConfig { /* ... */ }); // 4. auth
// register_resource(Box::new(MyResource)); // declares file_fields()
// ```
//
// A resource opts in by returning fields from `file_fields()`:
//
// ```ignore
// fn file_fields(&self) -> Vec<adminx_core::attach::FileField> {
// vec![adminx_core::attach::FileField::new("avatar", "Avatar").images()]
// }
// ```
//
// ## What is stored where
//
// The bytes go to the `BlobStore` under an opaque key; the row in
// `adminx_attachments` records the original filename, content type, size and
// that key. Serving reads the row, then the bytes. Deleting a record purges its
// attachments (see `adminx_core::crud::delete`).
pub use ;
pub use ;
/// Register a backend built from any [`BlobStore`]. Use this to supply a custom
/// store; most apps want [`init_local`] instead.
/// Register a local-filesystem backend rooted at `dir` (created on first write).
/// The simplest way to turn attachments on; swap for an object-store backend in
/// production.
/// SQL `CREATE TABLE IF NOT EXISTS` + index for the attachment table. Run once on
/// a SQL backend via `adminx_core::seed(adminx_storage::migrate_sql())`. Mongo
/// needs nothing.