Monorepo for wisp.place. A static site hosting service built on top of the AT Protocol. wisp.place
at main 3.0 kB view raw
1use jacquard_common::types::blob::BlobRef; 2use jacquard_common::IntoStatic; 3use std::collections::HashMap; 4 5use crate::place_wisp::fs::{Directory, EntryNode}; 6 7/// Extract blob information from a directory tree 8/// Returns a map of file paths to their blob refs and CIDs 9/// 10/// This mirrors the TypeScript implementation in src/lib/wisp-utils.ts lines 275-302 11pub fn extract_blob_map( 12 directory: &Directory, 13) -> HashMap<String, (BlobRef<'static>, String)> { 14 extract_blob_map_recursive(directory, String::new()) 15} 16 17fn extract_blob_map_recursive( 18 directory: &Directory, 19 current_path: String, 20) -> HashMap<String, (BlobRef<'static>, String)> { 21 let mut blob_map = HashMap::new(); 22 23 for entry in &directory.entries { 24 let full_path = if current_path.is_empty() { 25 entry.name.to_string() 26 } else { 27 format!("{}/{}", current_path, entry.name) 28 }; 29 30 match &entry.node { 31 EntryNode::File(file_node) => { 32 // Extract CID from blob ref 33 // BlobRef is an enum with Blob variant, which has a ref field (CidLink) 34 let blob_ref = &file_node.blob; 35 let cid_string = blob_ref.blob().r#ref.to_string(); 36 37 // Store with full path (mirrors TypeScript implementation) 38 blob_map.insert( 39 full_path, 40 (blob_ref.clone().into_static(), cid_string) 41 ); 42 } 43 EntryNode::Directory(subdir) => { 44 let sub_map = extract_blob_map_recursive(subdir, full_path); 45 blob_map.extend(sub_map); 46 } 47 EntryNode::Subfs(_) => { 48 // Subfs nodes don't contain blobs directly - they reference other records 49 // Skip them in blob map extraction 50 } 51 EntryNode::Unknown(_) => { 52 // Skip unknown node types 53 } 54 } 55 } 56 57 blob_map 58} 59 60/// Normalize file path by removing base folder prefix 61/// Example: "cobblemon/index.html" -> "index.html" 62/// 63/// Note: This function is kept for reference but is no longer used in production code. 64/// The TypeScript server has a similar normalization (src/routes/wisp.ts line 291) to handle 65/// uploads that include a base folder prefix, but our CLI doesn't need this since we 66/// track full paths consistently. 67#[allow(dead_code)] 68pub fn normalize_path(path: &str) -> String { 69 // Remove base folder prefix (everything before first /) 70 if let Some(idx) = path.find('/') { 71 path[idx + 1..].to_string() 72 } else { 73 path.to_string() 74 } 75} 76 77#[cfg(test)] 78mod tests { 79 use super::*; 80 81 #[test] 82 fn test_normalize_path() { 83 assert_eq!(normalize_path("index.html"), "index.html"); 84 assert_eq!(normalize_path("cobblemon/index.html"), "index.html"); 85 assert_eq!(normalize_path("folder/subfolder/file.txt"), "subfolder/file.txt"); 86 assert_eq!(normalize_path("a/b/c/d.txt"), "b/c/d.txt"); 87 } 88} 89