Monorepo for wisp.place. A static site hosting service built on top of the AT Protocol.
wisp.place
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}