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::config::{
155        StorageConfigHeaders, StorageConfigIFrame, StorageConfigMaxMemorySize,
156        StorageConfigRawAccess, StorageConfigRedirects, StorageConfigRewrites,
157    };
158    use crate::types::runtime_state::{BatchId, ChunkId};
159    use crate::types::state::FullPath;
160    use crate::types::store::{AssetKey, EncodingType};
161
162    #[derive(CandidType, Deserialize)]
163    pub struct InitAssetKey {
164        pub name: String,
165        pub full_path: FullPath,
166        pub token: Option<String>,
167        pub collection: CollectionKey,
168        pub encoding_type: Option<EncodingType>,
169        pub description: Option<String>,
170    }
171
172    #[derive(CandidType)]
173    pub struct InitUploadResult {
174        pub batch_id: BatchId,
175    }
176
177    #[derive(CandidType, Deserialize)]
178    pub struct UploadChunk {
179        pub batch_id: BatchId,
180        pub content: Blob,
181        pub order_id: Option<u128>,
182    }
183
184    #[derive(CandidType)]
185    pub struct UploadChunkResult {
186        pub chunk_id: ChunkId,
187    }
188
189    #[derive(CandidType, Serialize, Deserialize, Clone)]
190    pub struct CommitBatch {
191        pub batch_id: BatchId,
192        pub headers: Vec<HeaderField>,
193        pub chunk_ids: Vec<ChunkId>,
194    }
195
196    #[derive(CandidType, Deserialize, Clone)]
197    pub struct AssetNoContent {
198        pub key: AssetKey,
199        pub headers: Vec<HeaderField>,
200        pub encodings: Vec<(EncodingType, AssetEncodingNoContent)>,
201        pub created_at: Timestamp,
202        pub updated_at: Timestamp,
203        pub version: Option<Version>,
204    }
205
206    #[derive(CandidType, Deserialize, Clone)]
207    pub struct AssetEncodingNoContent {
208        pub modified: Timestamp,
209        pub total_length: u128,
210        pub sha256: Hash,
211    }
212
213    #[derive(Default, CandidType, Serialize, Deserialize, Clone)]
214    pub struct SetStorageConfig {
215        pub headers: StorageConfigHeaders,
216        pub rewrites: StorageConfigRewrites,
217        pub redirects: Option<StorageConfigRedirects>,
218        pub iframe: Option<StorageConfigIFrame>,
219        pub raw_access: Option<StorageConfigRawAccess>,
220        pub max_memory_size: Option<StorageConfigMaxMemorySize>,
221        pub version: Option<Version>,
222    }
223}
224
225pub mod config {
226    use crate::http::types::{HeaderField, StatusCode};
227    use candid::CandidType;
228    use junobuild_shared::types::config::ConfigMaxMemorySize;
229    use junobuild_shared::types::state::{Timestamp, Version};
230    use serde::{Deserialize, Serialize};
231    use std::collections::HashMap;
232
233    pub type StorageConfigHeaders = HashMap<String, Vec<HeaderField>>;
234    pub type StorageConfigRewrites = HashMap<String, String>;
235    pub type StorageConfigRedirects = HashMap<String, StorageConfigRedirect>;
236
237    #[derive(CandidType, Serialize, Deserialize, Clone)]
238    pub enum StorageConfigIFrame {
239        Deny,
240        SameOrigin,
241        AllowAny,
242    }
243
244    #[derive(CandidType, Serialize, Deserialize, Clone)]
245    pub enum StorageConfigRawAccess {
246        Deny,
247        Allow,
248    }
249
250    pub type StorageConfigMaxMemorySize = ConfigMaxMemorySize;
251
252    #[derive(Default, CandidType, Serialize, Deserialize, Clone)]
253    pub struct StorageConfig {
254        pub headers: StorageConfigHeaders,
255        pub rewrites: StorageConfigRewrites,
256        pub redirects: Option<StorageConfigRedirects>,
257        pub iframe: Option<StorageConfigIFrame>,
258        pub raw_access: Option<StorageConfigRawAccess>,
259        pub max_memory_size: Option<StorageConfigMaxMemorySize>,
260        pub version: Option<Version>,
261        pub created_at: Option<Timestamp>,
262        pub updated_at: Option<Timestamp>,
263    }
264
265    #[derive(Default, CandidType, Serialize, Deserialize, Clone)]
266    pub struct StorageConfigRedirect {
267        pub location: String,
268        pub status_code: StatusCode,
269    }
270}
271
272pub mod http_request {
273    use crate::http::types::StatusCode;
274    use crate::types::config::{StorageConfigIFrame, StorageConfigRedirect};
275    use crate::types::store::Asset;
276    use candid::{CandidType, Deserialize};
277    use junobuild_collections::types::rules::Memory;
278
279    #[derive(CandidType, Deserialize, Clone)]
280    pub struct MapUrl {
281        pub path: String,
282        pub token: Option<String>,
283    }
284
285    #[derive(CandidType, Deserialize, Clone)]
286    pub enum Routing {
287        Default(RoutingDefault),
288        Rewrite(RoutingRewrite),
289        Redirect(RoutingRedirect),
290        RedirectRaw(RoutingRedirectRaw),
291    }
292
293    #[derive(CandidType, Deserialize, Clone)]
294    pub struct RoutingDefault {
295        pub url: String,
296        pub asset: Option<(Asset, Memory)>,
297    }
298
299    #[derive(CandidType, Deserialize, Clone)]
300    pub struct RoutingRewrite {
301        pub url: String,
302        pub asset: Option<(Asset, Memory)>,
303        pub source: String,
304        pub status_code: StatusCode,
305    }
306
307    #[derive(CandidType, Deserialize, Clone)]
308    pub struct RoutingRedirect {
309        pub url: String,
310        pub redirect: StorageConfigRedirect,
311        pub iframe: StorageConfigIFrame,
312    }
313
314    #[derive(CandidType, Deserialize, Clone)]
315    pub struct RoutingRedirectRaw {
316        pub redirect_url: String,
317        pub iframe: StorageConfigIFrame,
318    }
319}