Monorepo for wisp.place. A static site hosting service built on top of the AT Protocol. wisp.place
at main 27 kB view raw
1// @generated by jacquard-lexicon. DO NOT EDIT. 2// 3// Lexicon: place.wisp.settings 4// 5// This file was automatically generated from Lexicon schemas. 6// Any manual changes will be overwritten on the next regeneration. 7 8/// Custom HTTP header configuration 9#[jacquard_derive::lexicon] 10#[derive( 11 serde::Serialize, 12 serde::Deserialize, 13 Debug, 14 Clone, 15 PartialEq, 16 Eq, 17 jacquard_derive::IntoStatic, 18 Default 19)] 20#[serde(rename_all = "camelCase")] 21pub struct CustomHeader<'a> { 22 /// HTTP header name (e.g., 'Cache-Control', 'X-Frame-Options') 23 #[serde(borrow)] 24 pub name: jacquard_common::CowStr<'a>, 25 /// Optional glob pattern to apply this header to specific paths (e.g., '*.html', '/assets/*'). If not specified, applies to all paths. 26 #[serde(skip_serializing_if = "std::option::Option::is_none")] 27 #[serde(borrow)] 28 pub path: std::option::Option<jacquard_common::CowStr<'a>>, 29 /// HTTP header value 30 #[serde(borrow)] 31 pub value: jacquard_common::CowStr<'a>, 32} 33 34fn lexicon_doc_place_wisp_settings() -> ::jacquard_lexicon::lexicon::LexiconDoc< 35 'static, 36> { 37 ::jacquard_lexicon::lexicon::LexiconDoc { 38 lexicon: ::jacquard_lexicon::lexicon::Lexicon::Lexicon1, 39 id: ::jacquard_common::CowStr::new_static("place.wisp.settings"), 40 revision: None, 41 description: None, 42 defs: { 43 let mut map = ::std::collections::BTreeMap::new(); 44 map.insert( 45 ::jacquard_common::smol_str::SmolStr::new_static("customHeader"), 46 ::jacquard_lexicon::lexicon::LexUserType::Object(::jacquard_lexicon::lexicon::LexObject { 47 description: Some( 48 ::jacquard_common::CowStr::new_static( 49 "Custom HTTP header configuration", 50 ), 51 ), 52 required: Some( 53 vec![ 54 ::jacquard_common::smol_str::SmolStr::new_static("name"), 55 ::jacquard_common::smol_str::SmolStr::new_static("value") 56 ], 57 ), 58 nullable: None, 59 properties: { 60 #[allow(unused_mut)] 61 let mut map = ::std::collections::BTreeMap::new(); 62 map.insert( 63 ::jacquard_common::smol_str::SmolStr::new_static("name"), 64 ::jacquard_lexicon::lexicon::LexObjectProperty::String(::jacquard_lexicon::lexicon::LexString { 65 description: Some( 66 ::jacquard_common::CowStr::new_static( 67 "HTTP header name (e.g., 'Cache-Control', 'X-Frame-Options')", 68 ), 69 ), 70 format: None, 71 default: None, 72 min_length: None, 73 max_length: Some(100usize), 74 min_graphemes: None, 75 max_graphemes: None, 76 r#enum: None, 77 r#const: None, 78 known_values: None, 79 }), 80 ); 81 map.insert( 82 ::jacquard_common::smol_str::SmolStr::new_static("path"), 83 ::jacquard_lexicon::lexicon::LexObjectProperty::String(::jacquard_lexicon::lexicon::LexString { 84 description: Some( 85 ::jacquard_common::CowStr::new_static( 86 "Optional glob pattern to apply this header to specific paths (e.g., '*.html', '/assets/*'). If not specified, applies to all paths.", 87 ), 88 ), 89 format: None, 90 default: None, 91 min_length: None, 92 max_length: Some(500usize), 93 min_graphemes: None, 94 max_graphemes: None, 95 r#enum: None, 96 r#const: None, 97 known_values: None, 98 }), 99 ); 100 map.insert( 101 ::jacquard_common::smol_str::SmolStr::new_static("value"), 102 ::jacquard_lexicon::lexicon::LexObjectProperty::String(::jacquard_lexicon::lexicon::LexString { 103 description: Some( 104 ::jacquard_common::CowStr::new_static("HTTP header value"), 105 ), 106 format: None, 107 default: None, 108 min_length: None, 109 max_length: Some(1000usize), 110 min_graphemes: None, 111 max_graphemes: None, 112 r#enum: None, 113 r#const: None, 114 known_values: None, 115 }), 116 ); 117 map 118 }, 119 }), 120 ); 121 map.insert( 122 ::jacquard_common::smol_str::SmolStr::new_static("main"), 123 ::jacquard_lexicon::lexicon::LexUserType::Record(::jacquard_lexicon::lexicon::LexRecord { 124 description: Some( 125 ::jacquard_common::CowStr::new_static( 126 "Configuration settings for a static site hosted on wisp.place", 127 ), 128 ), 129 key: Some(::jacquard_common::CowStr::new_static("any")), 130 record: ::jacquard_lexicon::lexicon::LexRecordRecord::Object(::jacquard_lexicon::lexicon::LexObject { 131 description: None, 132 required: None, 133 nullable: None, 134 properties: { 135 #[allow(unused_mut)] 136 let mut map = ::std::collections::BTreeMap::new(); 137 map.insert( 138 ::jacquard_common::smol_str::SmolStr::new_static( 139 "cleanUrls", 140 ), 141 ::jacquard_lexicon::lexicon::LexObjectProperty::Boolean(::jacquard_lexicon::lexicon::LexBoolean { 142 description: None, 143 default: None, 144 r#const: None, 145 }), 146 ); 147 map.insert( 148 ::jacquard_common::smol_str::SmolStr::new_static( 149 "custom404", 150 ), 151 ::jacquard_lexicon::lexicon::LexObjectProperty::String(::jacquard_lexicon::lexicon::LexString { 152 description: Some( 153 ::jacquard_common::CowStr::new_static( 154 "Custom 404 error page file path. Incompatible with directoryListing and spaMode.", 155 ), 156 ), 157 format: None, 158 default: None, 159 min_length: None, 160 max_length: Some(500usize), 161 min_graphemes: None, 162 max_graphemes: None, 163 r#enum: None, 164 r#const: None, 165 known_values: None, 166 }), 167 ); 168 map.insert( 169 ::jacquard_common::smol_str::SmolStr::new_static( 170 "directoryListing", 171 ), 172 ::jacquard_lexicon::lexicon::LexObjectProperty::Boolean(::jacquard_lexicon::lexicon::LexBoolean { 173 description: None, 174 default: None, 175 r#const: None, 176 }), 177 ); 178 map.insert( 179 ::jacquard_common::smol_str::SmolStr::new_static("headers"), 180 ::jacquard_lexicon::lexicon::LexObjectProperty::Array(::jacquard_lexicon::lexicon::LexArray { 181 description: Some( 182 ::jacquard_common::CowStr::new_static( 183 "Custom HTTP headers to set on responses", 184 ), 185 ), 186 items: ::jacquard_lexicon::lexicon::LexArrayItem::Ref(::jacquard_lexicon::lexicon::LexRef { 187 description: None, 188 r#ref: ::jacquard_common::CowStr::new_static( 189 "#customHeader", 190 ), 191 }), 192 min_length: None, 193 max_length: Some(50usize), 194 }), 195 ); 196 map.insert( 197 ::jacquard_common::smol_str::SmolStr::new_static( 198 "indexFiles", 199 ), 200 ::jacquard_lexicon::lexicon::LexObjectProperty::Array(::jacquard_lexicon::lexicon::LexArray { 201 description: Some( 202 ::jacquard_common::CowStr::new_static( 203 "Ordered list of files to try when serving a directory. Defaults to ['index.html'] if not specified.", 204 ), 205 ), 206 items: ::jacquard_lexicon::lexicon::LexArrayItem::String(::jacquard_lexicon::lexicon::LexString { 207 description: None, 208 format: None, 209 default: None, 210 min_length: None, 211 max_length: Some(255usize), 212 min_graphemes: None, 213 max_graphemes: None, 214 r#enum: None, 215 r#const: None, 216 known_values: None, 217 }), 218 min_length: None, 219 max_length: Some(10usize), 220 }), 221 ); 222 map.insert( 223 ::jacquard_common::smol_str::SmolStr::new_static("spaMode"), 224 ::jacquard_lexicon::lexicon::LexObjectProperty::String(::jacquard_lexicon::lexicon::LexString { 225 description: Some( 226 ::jacquard_common::CowStr::new_static( 227 "File to serve for all routes (e.g., 'index.html'). When set, enables SPA mode where all non-file requests are routed to this file. Incompatible with directoryListing and custom404.", 228 ), 229 ), 230 format: None, 231 default: None, 232 min_length: None, 233 max_length: Some(500usize), 234 min_graphemes: None, 235 max_graphemes: None, 236 r#enum: None, 237 r#const: None, 238 known_values: None, 239 }), 240 ); 241 map 242 }, 243 }), 244 }), 245 ); 246 map 247 }, 248 } 249} 250 251impl<'a> ::jacquard_lexicon::schema::LexiconSchema for CustomHeader<'a> { 252 fn nsid() -> &'static str { 253 "place.wisp.settings" 254 } 255 fn def_name() -> &'static str { 256 "customHeader" 257 } 258 fn lexicon_doc() -> ::jacquard_lexicon::lexicon::LexiconDoc<'static> { 259 lexicon_doc_place_wisp_settings() 260 } 261 fn validate( 262 &self, 263 ) -> ::std::result::Result<(), ::jacquard_lexicon::validation::ConstraintError> { 264 { 265 let value = &self.name; 266 #[allow(unused_comparisons)] 267 if <str>::len(value.as_ref()) > 100usize { 268 return Err(::jacquard_lexicon::validation::ConstraintError::MaxLength { 269 path: ::jacquard_lexicon::validation::ValidationPath::from_field( 270 "name", 271 ), 272 max: 100usize, 273 actual: <str>::len(value.as_ref()), 274 }); 275 } 276 } 277 if let Some(ref value) = self.path { 278 #[allow(unused_comparisons)] 279 if <str>::len(value.as_ref()) > 500usize { 280 return Err(::jacquard_lexicon::validation::ConstraintError::MaxLength { 281 path: ::jacquard_lexicon::validation::ValidationPath::from_field( 282 "path", 283 ), 284 max: 500usize, 285 actual: <str>::len(value.as_ref()), 286 }); 287 } 288 } 289 { 290 let value = &self.value; 291 #[allow(unused_comparisons)] 292 if <str>::len(value.as_ref()) > 1000usize { 293 return Err(::jacquard_lexicon::validation::ConstraintError::MaxLength { 294 path: ::jacquard_lexicon::validation::ValidationPath::from_field( 295 "value", 296 ), 297 max: 1000usize, 298 actual: <str>::len(value.as_ref()), 299 }); 300 } 301 } 302 Ok(()) 303 } 304} 305 306/// Configuration settings for a static site hosted on wisp.place 307#[jacquard_derive::lexicon] 308#[derive( 309 serde::Serialize, 310 serde::Deserialize, 311 Debug, 312 Clone, 313 PartialEq, 314 Eq, 315 jacquard_derive::IntoStatic 316)] 317#[serde(rename_all = "camelCase")] 318pub struct Settings<'a> { 319 /// Enable clean URL routing. When enabled, '/about' will attempt to serve '/about.html' or '/about/index.html' automatically. 320 #[serde(skip_serializing_if = "std::option::Option::is_none")] 321 pub clean_urls: std::option::Option<bool>, 322 /// Custom 404 error page file path. Incompatible with directoryListing and spaMode. 323 #[serde(skip_serializing_if = "std::option::Option::is_none")] 324 #[serde(borrow)] 325 pub custom404: std::option::Option<jacquard_common::CowStr<'a>>, 326 /// Enable directory listing mode for paths that resolve to directories without an index file. Incompatible with spaMode. 327 #[serde(skip_serializing_if = "std::option::Option::is_none")] 328 pub directory_listing: std::option::Option<bool>, 329 /// Custom HTTP headers to set on responses 330 #[serde(skip_serializing_if = "std::option::Option::is_none")] 331 #[serde(borrow)] 332 pub headers: std::option::Option<Vec<crate::place_wisp::settings::CustomHeader<'a>>>, 333 /// Ordered list of files to try when serving a directory. Defaults to ['index.html'] if not specified. 334 #[serde(skip_serializing_if = "std::option::Option::is_none")] 335 #[serde(borrow)] 336 pub index_files: std::option::Option<Vec<jacquard_common::CowStr<'a>>>, 337 /// File to serve for all routes (e.g., 'index.html'). When set, enables SPA mode where all non-file requests are routed to this file. Incompatible with directoryListing and custom404. 338 #[serde(skip_serializing_if = "std::option::Option::is_none")] 339 #[serde(borrow)] 340 pub spa_mode: std::option::Option<jacquard_common::CowStr<'a>>, 341} 342 343pub mod settings_state { 344 345 pub use crate::builder_types::{Set, Unset, IsSet, IsUnset}; 346 #[allow(unused)] 347 use ::core::marker::PhantomData; 348 mod sealed { 349 pub trait Sealed {} 350 } 351 /// State trait tracking which required fields have been set 352 pub trait State: sealed::Sealed {} 353 /// Empty state - all required fields are unset 354 pub struct Empty(()); 355 impl sealed::Sealed for Empty {} 356 impl State for Empty {} 357 /// Marker types for field names 358 #[allow(non_camel_case_types)] 359 pub mod members {} 360} 361 362/// Builder for constructing an instance of this type 363pub struct SettingsBuilder<'a, S: settings_state::State> { 364 _phantom_state: ::core::marker::PhantomData<fn() -> S>, 365 __unsafe_private_named: ( 366 ::core::option::Option<bool>, 367 ::core::option::Option<jacquard_common::CowStr<'a>>, 368 ::core::option::Option<bool>, 369 ::core::option::Option<Vec<crate::place_wisp::settings::CustomHeader<'a>>>, 370 ::core::option::Option<Vec<jacquard_common::CowStr<'a>>>, 371 ::core::option::Option<jacquard_common::CowStr<'a>>, 372 ), 373 _phantom: ::core::marker::PhantomData<&'a ()>, 374} 375 376impl<'a> Settings<'a> { 377 /// Create a new builder for this type 378 pub fn new() -> SettingsBuilder<'a, settings_state::Empty> { 379 SettingsBuilder::new() 380 } 381} 382 383impl<'a> SettingsBuilder<'a, settings_state::Empty> { 384 /// Create a new builder with all fields unset 385 pub fn new() -> Self { 386 SettingsBuilder { 387 _phantom_state: ::core::marker::PhantomData, 388 __unsafe_private_named: (None, None, None, None, None, None), 389 _phantom: ::core::marker::PhantomData, 390 } 391 } 392} 393 394impl<'a, S: settings_state::State> SettingsBuilder<'a, S> { 395 /// Set the `cleanUrls` field (optional) 396 pub fn clean_urls(mut self, value: impl Into<Option<bool>>) -> Self { 397 self.__unsafe_private_named.0 = value.into(); 398 self 399 } 400 /// Set the `cleanUrls` field to an Option value (optional) 401 pub fn maybe_clean_urls(mut self, value: Option<bool>) -> Self { 402 self.__unsafe_private_named.0 = value; 403 self 404 } 405} 406 407impl<'a, S: settings_state::State> SettingsBuilder<'a, S> { 408 /// Set the `custom404` field (optional) 409 pub fn custom404( 410 mut self, 411 value: impl Into<Option<jacquard_common::CowStr<'a>>>, 412 ) -> Self { 413 self.__unsafe_private_named.1 = value.into(); 414 self 415 } 416 /// Set the `custom404` field to an Option value (optional) 417 pub fn maybe_custom404( 418 mut self, 419 value: Option<jacquard_common::CowStr<'a>>, 420 ) -> Self { 421 self.__unsafe_private_named.1 = value; 422 self 423 } 424} 425 426impl<'a, S: settings_state::State> SettingsBuilder<'a, S> { 427 /// Set the `directoryListing` field (optional) 428 pub fn directory_listing(mut self, value: impl Into<Option<bool>>) -> Self { 429 self.__unsafe_private_named.2 = value.into(); 430 self 431 } 432 /// Set the `directoryListing` field to an Option value (optional) 433 pub fn maybe_directory_listing(mut self, value: Option<bool>) -> Self { 434 self.__unsafe_private_named.2 = value; 435 self 436 } 437} 438 439impl<'a, S: settings_state::State> SettingsBuilder<'a, S> { 440 /// Set the `headers` field (optional) 441 pub fn headers( 442 mut self, 443 value: impl Into<Option<Vec<crate::place_wisp::settings::CustomHeader<'a>>>>, 444 ) -> Self { 445 self.__unsafe_private_named.3 = value.into(); 446 self 447 } 448 /// Set the `headers` field to an Option value (optional) 449 pub fn maybe_headers( 450 mut self, 451 value: Option<Vec<crate::place_wisp::settings::CustomHeader<'a>>>, 452 ) -> Self { 453 self.__unsafe_private_named.3 = value; 454 self 455 } 456} 457 458impl<'a, S: settings_state::State> SettingsBuilder<'a, S> { 459 /// Set the `indexFiles` field (optional) 460 pub fn index_files( 461 mut self, 462 value: impl Into<Option<Vec<jacquard_common::CowStr<'a>>>>, 463 ) -> Self { 464 self.__unsafe_private_named.4 = value.into(); 465 self 466 } 467 /// Set the `indexFiles` field to an Option value (optional) 468 pub fn maybe_index_files( 469 mut self, 470 value: Option<Vec<jacquard_common::CowStr<'a>>>, 471 ) -> Self { 472 self.__unsafe_private_named.4 = value; 473 self 474 } 475} 476 477impl<'a, S: settings_state::State> SettingsBuilder<'a, S> { 478 /// Set the `spaMode` field (optional) 479 pub fn spa_mode( 480 mut self, 481 value: impl Into<Option<jacquard_common::CowStr<'a>>>, 482 ) -> Self { 483 self.__unsafe_private_named.5 = value.into(); 484 self 485 } 486 /// Set the `spaMode` field to an Option value (optional) 487 pub fn maybe_spa_mode(mut self, value: Option<jacquard_common::CowStr<'a>>) -> Self { 488 self.__unsafe_private_named.5 = value; 489 self 490 } 491} 492 493impl<'a, S> SettingsBuilder<'a, S> 494where 495 S: settings_state::State, 496{ 497 /// Build the final struct 498 pub fn build(self) -> Settings<'a> { 499 Settings { 500 clean_urls: self.__unsafe_private_named.0, 501 custom404: self.__unsafe_private_named.1, 502 directory_listing: self.__unsafe_private_named.2, 503 headers: self.__unsafe_private_named.3, 504 index_files: self.__unsafe_private_named.4, 505 spa_mode: self.__unsafe_private_named.5, 506 extra_data: Default::default(), 507 } 508 } 509 /// Build the final struct with custom extra_data 510 pub fn build_with_data( 511 self, 512 extra_data: std::collections::BTreeMap< 513 jacquard_common::smol_str::SmolStr, 514 jacquard_common::types::value::Data<'a>, 515 >, 516 ) -> Settings<'a> { 517 Settings { 518 clean_urls: self.__unsafe_private_named.0, 519 custom404: self.__unsafe_private_named.1, 520 directory_listing: self.__unsafe_private_named.2, 521 headers: self.__unsafe_private_named.3, 522 index_files: self.__unsafe_private_named.4, 523 spa_mode: self.__unsafe_private_named.5, 524 extra_data: Some(extra_data), 525 } 526 } 527} 528 529impl<'a> Settings<'a> { 530 pub fn uri( 531 uri: impl Into<jacquard_common::CowStr<'a>>, 532 ) -> Result< 533 jacquard_common::types::uri::RecordUri<'a, SettingsRecord>, 534 jacquard_common::types::uri::UriError, 535 > { 536 jacquard_common::types::uri::RecordUri::try_from_uri( 537 jacquard_common::types::string::AtUri::new_cow(uri.into())?, 538 ) 539 } 540} 541 542/// Typed wrapper for GetRecord response with this collection's record type. 543#[derive( 544 serde::Serialize, 545 serde::Deserialize, 546 Debug, 547 Clone, 548 PartialEq, 549 Eq, 550 jacquard_derive::IntoStatic 551)] 552#[serde(rename_all = "camelCase")] 553pub struct SettingsGetRecordOutput<'a> { 554 #[serde(skip_serializing_if = "std::option::Option::is_none")] 555 #[serde(borrow)] 556 pub cid: std::option::Option<jacquard_common::types::string::Cid<'a>>, 557 #[serde(borrow)] 558 pub uri: jacquard_common::types::string::AtUri<'a>, 559 #[serde(borrow)] 560 pub value: Settings<'a>, 561} 562 563impl From<SettingsGetRecordOutput<'_>> for Settings<'_> { 564 fn from(output: SettingsGetRecordOutput<'_>) -> Self { 565 use jacquard_common::IntoStatic; 566 output.value.into_static() 567 } 568} 569 570impl jacquard_common::types::collection::Collection for Settings<'_> { 571 const NSID: &'static str = "place.wisp.settings"; 572 type Record = SettingsRecord; 573} 574 575/// Marker type for deserializing records from this collection. 576#[derive(Debug, serde::Serialize, serde::Deserialize)] 577pub struct SettingsRecord; 578impl jacquard_common::xrpc::XrpcResp for SettingsRecord { 579 const NSID: &'static str = "place.wisp.settings"; 580 const ENCODING: &'static str = "application/json"; 581 type Output<'de> = SettingsGetRecordOutput<'de>; 582 type Err<'de> = jacquard_common::types::collection::RecordError<'de>; 583} 584 585impl jacquard_common::types::collection::Collection for SettingsRecord { 586 const NSID: &'static str = "place.wisp.settings"; 587 type Record = SettingsRecord; 588} 589 590impl<'a> ::jacquard_lexicon::schema::LexiconSchema for Settings<'a> { 591 fn nsid() -> &'static str { 592 "place.wisp.settings" 593 } 594 fn def_name() -> &'static str { 595 "main" 596 } 597 fn lexicon_doc() -> ::jacquard_lexicon::lexicon::LexiconDoc<'static> { 598 lexicon_doc_place_wisp_settings() 599 } 600 fn validate( 601 &self, 602 ) -> ::std::result::Result<(), ::jacquard_lexicon::validation::ConstraintError> { 603 if let Some(ref value) = self.custom404 { 604 #[allow(unused_comparisons)] 605 if <str>::len(value.as_ref()) > 500usize { 606 return Err(::jacquard_lexicon::validation::ConstraintError::MaxLength { 607 path: ::jacquard_lexicon::validation::ValidationPath::from_field( 608 "custom404", 609 ), 610 max: 500usize, 611 actual: <str>::len(value.as_ref()), 612 }); 613 } 614 } 615 if let Some(ref value) = self.headers { 616 #[allow(unused_comparisons)] 617 if value.len() > 50usize { 618 return Err(::jacquard_lexicon::validation::ConstraintError::MaxLength { 619 path: ::jacquard_lexicon::validation::ValidationPath::from_field( 620 "headers", 621 ), 622 max: 50usize, 623 actual: value.len(), 624 }); 625 } 626 } 627 if let Some(ref value) = self.index_files { 628 #[allow(unused_comparisons)] 629 if value.len() > 10usize { 630 return Err(::jacquard_lexicon::validation::ConstraintError::MaxLength { 631 path: ::jacquard_lexicon::validation::ValidationPath::from_field( 632 "index_files", 633 ), 634 max: 10usize, 635 actual: value.len(), 636 }); 637 } 638 } 639 if let Some(ref value) = self.spa_mode { 640 #[allow(unused_comparisons)] 641 if <str>::len(value.as_ref()) > 500usize { 642 return Err(::jacquard_lexicon::validation::ConstraintError::MaxLength { 643 path: ::jacquard_lexicon::validation::ValidationPath::from_field( 644 "spa_mode", 645 ), 646 max: 500usize, 647 actual: <str>::len(value.as_ref()), 648 }); 649 } 650 } 651 Ok(()) 652 } 653}