junobuild_storage/
types.rs

1pub mod state {
2    use crate::types::config::StorageConfig;
3    use crate::types::store::Asset;
4    use candid::{CandidType, Deserialize};
5    use junobuild_collections::types::rules::Rules;
6    use junobuild_shared::types::core::Key;
7    use junobuild_shared::types::domain::CustomDomains;
8    use serde::Serialize;
9    use std::collections::HashMap;
10
11    /// Represents the relative path of an asset in the storage.
12    ///
13    /// This type, `FullPath`, is an alias for `Key`, indicating the relative path of an asset within the storage system.
14    ///
15    /// `FullPath` is commonly used to identify the location of assets within a storage system.
16    pub type FullPath = Key;
17
18    pub type AssetsHeap = HashMap<FullPath, Asset>;
19
20    #[derive(CandidType, Serialize, Deserialize, Clone)]
21    pub struct StorageHeapState {
22        pub assets: AssetsHeap,
23        pub rules: Rules,
24        pub config: StorageConfig,
25        pub custom_domains: CustomDomains,
26    }
27}
28
29pub mod runtime_state {
30    use crate::certification::types::certified::CertifiedAssetHashes;
31    use crate::types::store::{Batch, Chunk};
32    use junobuild_shared::rate::types::RateTokenStore;
33    use serde::{Deserialize, Serialize};
34    use std::collections::HashMap;
35
36    pub type Batches = HashMap<BatchId, Batch>;
37    pub type Chunks = HashMap<ChunkId, Chunk>;
38
39    pub type BatchId = u128;
40    pub type ChunkId = u128;
41
42    #[derive(Default, Serialize, Deserialize)]
43    pub struct State {
44        // Unstable state: State that resides only on the heap, that’s lost after an upgrade.
45        #[serde(skip, default)]
46        pub runtime: RuntimeState,
47    }
48
49    #[derive(Default, Clone)]
50    pub struct RuntimeState {
51        pub storage: StorageRuntimeState,
52    }
53
54    #[derive(Default, Clone)]
55    pub struct StorageRuntimeState {
56        pub batches: Batches,
57        pub chunks: Chunks,
58        pub asset_hashes: CertifiedAssetHashes,
59        pub rate_tokens: RateTokenStore,
60    }
61}
62
63pub mod store {
64    use crate::http::types::HeaderField;
65    use crate::types::interface::CommitBatch;
66    use crate::types::runtime_state::BatchId;
67    use crate::types::state::FullPath;
68    use candid::CandidType;
69    use ic_certification::Hash;
70    use junobuild_collections::types::core::CollectionKey;
71    use junobuild_shared::types::core::Blob;
72    use junobuild_shared::types::state::{Timestamp, UserId, Version};
73    use serde::{Deserialize, Serialize};
74    use std::clone::Clone;
75    use std::collections::HashMap;
76
77    #[derive(CandidType, Deserialize, Clone)]
78    pub struct Chunk {
79        pub batch_id: BatchId,
80        pub order_id: u128,
81        pub content: Blob,
82    }
83
84    // When stable memory is used, chunks are saved within a StableBTreeMap and their keys - StableEncodingChunkKey - are saved for reference as serialized values
85    pub type BlobOrKey = Blob;
86
87    #[derive(CandidType, Serialize, Deserialize, Clone)]
88    pub struct AssetEncoding {
89        pub modified: Timestamp,
90        pub content_chunks: Vec<BlobOrKey>,
91        pub total_length: u128,
92        pub sha256: Hash,
93    }
94
95    #[derive(CandidType, Serialize, Deserialize, Clone)]
96    pub struct AssetKey {
97        // myimage.jpg
98        pub name: String,
99        // /images/myimage.jpg
100        pub full_path: FullPath,
101        // ?token=1223-3345-5564-3333
102        pub token: Option<String>,
103        // Assets are prefixed with full_path because these are unique. Collection is there for read (list) and write but all assets are available through http_request (that's why we use the token).
104        pub collection: CollectionKey,
105        // For security check purpose
106        pub owner: UserId,
107        // A description field which can be useful for search purpose
108        pub description: Option<String>,
109    }
110
111    pub type EncodingType = String;
112
113    #[derive(CandidType, Serialize, Deserialize, Clone)]
114    pub struct Asset {
115        pub key: AssetKey,
116        pub headers: Vec<HeaderField>,
117        pub encodings: HashMap<EncodingType, AssetEncoding>,
118        pub created_at: Timestamp,
119        pub updated_at: Timestamp,
120        pub version: Option<Version>,
121    }
122
123    pub trait BatchExpiry {
124        fn expires_at(&self) -> Timestamp;
125    }
126
127    pub type ReferenceId = u128;
128
129    #[derive(CandidType, Serialize, Deserialize, Clone)]
130    pub struct Batch {
131        pub key: AssetKey,
132        pub reference_id: Option<ReferenceId>,
133        pub expires_at: Timestamp,
134        pub encoding_type: Option<EncodingType>,
135    }
136
137    #[derive(CandidType, Serialize, Deserialize, Clone)]
138    pub struct AssetAssertUpload {
139        pub current: Option<Asset>,
140        pub batch: Batch,
141        pub commit_batch: CommitBatch,
142    }
143}
144
145pub mod interface {
146    use candid::{CandidType, Deserialize};
147    use ic_certification::Hash;
148    use junobuild_collections::types::core::CollectionKey;
149    use junobuild_shared::types::core::Blob;
150    use junobuild_shared::types::state::{Timestamp, Version};
151    use serde::Serialize;
152
153    use crate::http::types::HeaderField;
154    use crate::types::runtime_state::{BatchId, ChunkId};
155    use crate::types::state::FullPath;
156    use crate::types::store::{AssetKey, EncodingType};
157
158    #[derive(CandidType, Deserialize)]
159    pub struct InitAssetKey {
160        pub name: String,
161        pub full_path: FullPath,
162        pub token: Option<String>,
163        pub collection: CollectionKey,
164        pub encoding_type: Option<EncodingType>,
165        pub description: Option<String>,
166    }
167
168    #[derive(CandidType)]
169    pub struct InitUploadResult {
170        pub batch_id: BatchId,
171    }
172
173    #[derive(CandidType, Deserialize)]
174    pub struct UploadChunk {
175        pub batch_id: BatchId,
176        pub content: Blob,
177        pub order_id: Option<u128>,
178    }
179
180    #[derive(CandidType)]
181    pub struct UploadChunkResult {
182        pub chunk_id: ChunkId,
183    }
184
185    #[derive(CandidType, Serialize, Deserialize, Clone)]
186    pub struct CommitBatch {
187        pub batch_id: BatchId,
188        pub headers: Vec<HeaderField>,
189        pub chunk_ids: Vec<ChunkId>,
190    }
191
192    #[derive(CandidType, Deserialize, Clone)]
193    pub struct AssetNoContent {
194        pub key: AssetKey,
195        pub headers: Vec<HeaderField>,
196        pub encodings: Vec<(EncodingType, AssetEncodingNoContent)>,
197        pub created_at: Timestamp,
198        pub updated_at: Timestamp,
199        pub version: Option<Version>,
200    }
201
202    #[derive(CandidType, Deserialize, Clone)]
203    pub struct AssetEncodingNoContent {
204        pub modified: Timestamp,
205        pub total_length: u128,
206        pub sha256: Hash,
207    }
208}
209
210pub mod config {
211    use crate::http::types::{HeaderField, StatusCode};
212    use candid::CandidType;
213    use junobuild_shared::types::config::ConfigMaxMemorySize;
214    use serde::{Deserialize, Serialize};
215    use std::collections::HashMap;
216
217    pub type StorageConfigHeaders = HashMap<String, Vec<HeaderField>>;
218    pub type StorageConfigRewrites = HashMap<String, String>;
219    pub type StorageConfigRedirects = HashMap<String, StorageConfigRedirect>;
220
221    #[derive(CandidType, Serialize, Deserialize, Clone)]
222    pub enum StorageConfigIFrame {
223        Deny,
224        SameOrigin,
225        AllowAny,
226    }
227
228    #[derive(CandidType, Serialize, Deserialize, Clone)]
229    pub enum StorageConfigRawAccess {
230        Deny,
231        Allow,
232    }
233
234    pub type StorageConfigMaxMemorySize = ConfigMaxMemorySize;
235
236    #[derive(Default, CandidType, Serialize, Deserialize, Clone)]
237    pub struct StorageConfig {
238        pub headers: StorageConfigHeaders,
239        pub rewrites: StorageConfigRewrites,
240        pub redirects: Option<StorageConfigRedirects>,
241        pub iframe: Option<StorageConfigIFrame>,
242        pub raw_access: Option<StorageConfigRawAccess>,
243        pub max_memory_size: Option<StorageConfigMaxMemorySize>,
244    }
245
246    #[derive(Default, CandidType, Serialize, Deserialize, Clone)]
247    pub struct StorageConfigRedirect {
248        pub location: String,
249        pub status_code: StatusCode,
250    }
251}
252
253pub mod http_request {
254    use crate::http::types::StatusCode;
255    use crate::types::config::{StorageConfigIFrame, StorageConfigRedirect};
256    use crate::types::store::Asset;
257    use candid::{CandidType, Deserialize};
258    use junobuild_collections::types::rules::Memory;
259
260    #[derive(CandidType, Deserialize, Clone)]
261    pub struct MapUrl {
262        pub path: String,
263        pub token: Option<String>,
264    }
265
266    #[derive(CandidType, Deserialize, Clone)]
267    pub enum Routing {
268        Default(RoutingDefault),
269        Rewrite(RoutingRewrite),
270        Redirect(RoutingRedirect),
271        RedirectRaw(RoutingRedirectRaw),
272    }
273
274    #[derive(CandidType, Deserialize, Clone)]
275    pub struct RoutingDefault {
276        pub url: String,
277        pub asset: Option<(Asset, Memory)>,
278    }
279
280    #[derive(CandidType, Deserialize, Clone)]
281    pub struct RoutingRewrite {
282        pub url: String,
283        pub asset: Option<(Asset, Memory)>,
284        pub source: String,
285        pub status_code: StatusCode,
286    }
287
288    #[derive(CandidType, Deserialize, Clone)]
289    pub struct RoutingRedirect {
290        pub url: String,
291        pub redirect: StorageConfigRedirect,
292        pub iframe: StorageConfigIFrame,
293    }
294
295    #[derive(CandidType, Deserialize, Clone)]
296    pub struct RoutingRedirectRaw {
297        pub redirect_url: String,
298        pub iframe: StorageConfigIFrame,
299    }
300}