1mod areas;
4mod code;
5mod config;
6mod constraints;
7mod contract_traits;
8mod cross_owner;
9mod declarations;
10mod effects;
11mod entitlements;
12mod error;
13mod flags;
14mod gateways;
15mod gating;
16mod handlers;
17mod identity;
18mod islands;
19mod load;
20mod mails;
21mod manifest;
22mod menu;
23mod messages;
24mod metadata;
25pub mod naming;
26mod package_events;
27mod package_routes;
28pub mod permissions;
29mod posts;
30mod provisions;
31mod references;
32mod routes;
33mod shipped;
34mod sign_in;
35mod sources;
36pub mod syntax;
37mod targets;
38mod telemetry;
39#[cfg(feature = "testing")]
40pub mod testing;
41pub mod usage;
42
43use std::path::PathBuf;
44
45use usage::{Mentions, PublicItem};
46
47pub use code::{
48 Aggregate, Code, EnumDeclaration, EnumVariant, FieldDeclaration, Function, InputDeclaration,
49 KeyLiteral, RawSql, ReadModel, ScreenRender, TypeMethod, TypeName,
50};
51pub use config::{ConfigKey, DATABASE_URL, KeyKind, ModuleConfig, config_type_name};
52pub use contract_traits::{ContractMethod, ContractTrait};
53pub use cross_owner::CrossOwnerCheck;
54pub use declarations::{ModuleDeclaration, module_declaration};
55pub use effects::{Call, Effects, MethodCall, Queued, Raised};
56pub use entitlements::{EntitlementDeclaration, Entitlements};
57pub use error::ModelError;
58pub use flags::{FeatureCode, FeatureDeclaration, FeatureGate};
59pub use gateways::{Gateway, GatewayAdapter};
60pub use islands::{Island, IslandBundle, PropsDeclaration, is_island_name, island_bundles};
61pub use load::{
62 dependency_crate, files_with_extension, load, rust_files, subdirectories, workspace_crates,
63};
64pub use manifest::{MANIFEST_CONSTANT, Manifest, Tier, manifest_file};
65pub use messages::interval_seconds;
66pub use metadata::{framework_features, workspace_root};
67pub use naming::{KnownArea, WiringSide};
68pub use package_routes::{ListedRoute, PackageRoutes, RouteMount, RoutedPackage, ServedRoute};
69pub use routes::check_route_path;
70pub use shipped::{MountedScreen, ScreenRoute, ShippedScreen};
71pub use sign_in::SignInPaths;
72pub use telemetry::{ProductEvent, TelemetryCode};
73
74#[derive(Clone, Debug, PartialEq, Eq)]
75pub struct App {
76 pub root: PathBuf,
77 pub app: Crate,
78 pub modules: Vec<Module>,
79 pub identity: Option<Identity>,
80 pub package_events: Vec<EventDeclaration>,
82 pub packages: Vec<RoutedPackage>,
84 pub split: Split,
85 pub structure_ceilings: bool,
87}
88
89#[derive(Clone, Debug, Default, PartialEq, Eq)]
91pub struct Split {
92 pub serves: Vec<String>,
94 pub remote: Vec<RemoteModule>,
95}
96
97#[derive(Clone, Debug, PartialEq, Eq)]
99pub struct RemoteModule {
100 pub name: String,
101 pub contract: Crate,
102 pub defined_areas: Vec<AreaDefinition>,
103 pub exports: Vec<String>,
104 pub events: Vec<String>,
105 pub traits: Vec<ContractTrait>,
106}
107
108#[derive(Clone, Debug, Default, PartialEq, Eq)]
109pub struct Identity {
110 pub directory: PathBuf,
111 pub screens: Vec<String>,
112 pub routes: Vec<ListedRoute>,
113 pub mounts: Vec<RouteMount>,
114 pub shipped: Vec<ShippedScreen>,
115 pub features: Vec<String>,
116}
117
118#[derive(Clone, Debug, PartialEq, Eq)]
119pub struct Crate {
120 pub package: String,
121 pub crate_name: String,
122 pub path: PathBuf,
123 pub dependencies: Vec<Dependency>,
124 pub sources: Vec<Source>,
125 pub tests_and_examples: Vec<Source>,
126}
127
128#[derive(Clone, Debug, PartialEq, Eq)]
129pub struct Dependency {
130 pub package: String,
131 pub crate_name: String,
132}
133
134#[derive(Clone, Debug, PartialEq, Eq)]
135pub struct Source {
136 pub file: PathBuf,
137 pub paths: Vec<PathReference>,
138 pub macros: Vec<MacroCall>,
139 pub mentions: Mentions,
140 pub public_items: Vec<PublicItem>,
141}
142
143#[derive(Clone, Debug, PartialEq, Eq)]
144pub struct PathReference {
145 pub segments: Vec<String>,
146 pub line: usize,
147}
148
149#[derive(Clone, Debug, PartialEq, Eq)]
150pub struct MacroCall {
151 pub path: Vec<String>,
152 pub first_string: Option<String>,
153 pub line: usize,
154}
155
156impl MacroCall {
157 #[must_use]
158 pub fn name(&self) -> &str {
159 self.path.last().map_or("", String::as_str)
160 }
161}
162
163#[derive(Clone, Debug, PartialEq, Eq)]
164pub struct Module {
165 pub krate: Crate,
166 pub manifest: Option<Manifest>,
167 pub config: Option<ModuleConfig>,
168 pub contract: Option<Crate>,
169 pub defined_areas: Vec<AreaDefinition>,
170 pub contract_declares_gen: bool,
171 pub contract_exports: Vec<String>,
172 pub contract_traits: Vec<ContractTrait>,
173 pub migrations: Vec<PathBuf>,
174 pub sqlite_migrations: Vec<PathBuf>,
176 pub areas: Vec<AreaContribution>,
177 pub unrouted_areas: Vec<PathBuf>,
179 pub listeners: Vec<Listener>,
180 pub schedules: Vec<Schedule>,
181 pub events: Vec<String>,
182 pub module_events: Vec<EventDeclaration>,
183 pub jobs: Vec<Job>,
184 pub tasks: Vec<Task>,
185 pub implementations: Vec<Provision>,
186 pub extensions: Vec<Provision>,
187 pub gateways: Vec<Gateway>,
188 pub islands: Vec<Island>,
189 pub components: Vec<PathBuf>,
191 pub languages: Vec<PathBuf>,
193 pub mails: Vec<MailTemplate>,
194 pub plans: Option<PathBuf>,
196 pub private_items: Vec<PrivateItem>,
197 pub code: Code,
198}
199
200#[derive(Clone, Debug, PartialEq, Eq)]
202pub struct PrivateItem {
203 pub path: Vec<String>,
204 pub file: PathBuf,
205 pub line: usize,
206 pub crate_visible: bool,
208}
209
210#[derive(Clone, Debug, PartialEq, Eq)]
213pub struct MailTemplate {
214 pub key: String,
215 pub file: PathBuf,
216}
217
218#[derive(Clone, Debug, PartialEq, Eq)]
219pub struct AreaDefinition {
220 pub name: String,
221 pub type_path: Vec<String>,
222 pub prefix: Option<String>,
223 pub client: AreaClient,
224 pub principal: Vec<String>,
225 pub implements_member_area: bool,
226 pub opens_sign_up: bool,
228 pub file: PathBuf,
229 pub line: usize,
230}
231
232#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
235pub enum AreaClient {
236 #[default]
237 Html,
238 Svelte,
239}
240
241#[derive(Clone, Debug, PartialEq, Eq)]
242pub struct Job {
243 pub file: PathBuf,
244 pub line: usize,
245 pub function: Vec<String>,
246}
247
248#[derive(Clone, Debug, PartialEq, Eq)]
250pub struct Task {
251 pub file: PathBuf,
252 pub line: usize,
253 pub function: Vec<String>,
254}
255
256#[derive(Clone, Debug, PartialEq, Eq)]
257pub struct Provision {
258 pub contract: Vec<String>,
259 pub ty: Vec<String>,
260 pub unit: bool,
262 pub file: PathBuf,
263 pub line: usize,
264}
265
266#[derive(Clone, Debug, PartialEq, Eq)]
267pub struct EventDeclaration {
268 pub name: String,
269 pub file: PathBuf,
270 pub line: usize,
271}
272
273#[derive(Clone, Debug, PartialEq, Eq)]
274pub struct Listener {
275 pub file: PathBuf,
276 pub line: usize,
277 pub function: Vec<String>,
278 pub event: Vec<String>,
279}
280
281#[derive(Clone, Debug, PartialEq, Eq)]
282pub struct Schedule {
283 pub file: PathBuf,
284 pub line: usize,
285 pub function: Vec<String>,
286 pub cadence: Cadence,
287 pub each: Option<Vec<String>>,
288}
289
290#[derive(Clone, Debug, PartialEq, Eq)]
293pub enum Cadence {
294 Interval(String),
296 WallClock(WallClock),
297}
298
299#[derive(Clone, Debug, PartialEq, Eq)]
300pub struct WallClock {
301 pub daily_at: String,
302 pub weekly_on: Option<String>,
303 pub zone: String,
304}
305
306impl std::fmt::Display for Cadence {
307 fn fmt(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
308 match self {
309 Self::Interval(interval) => write!(formatter, "every {interval}"),
310 Self::WallClock(WallClock {
311 daily_at,
312 weekly_on: None,
313 zone,
314 }) => write!(formatter, "daily at {daily_at} {zone}"),
315 Self::WallClock(WallClock {
316 daily_at,
317 weekly_on: Some(weekday),
318 zone,
319 }) => write!(formatter, "weekly on {weekday} at {daily_at} {zone}"),
320 }
321 }
322}
323
324#[derive(Clone, Debug, PartialEq, Eq)]
325pub struct AreaContribution {
326 pub area: String,
327 pub routes_file: PathBuf,
328 pub declared: bool,
330 pub routes: Vec<Route>,
331 pub screens: Vec<PathBuf>,
332 pub overrides: Vec<ScreenOverride>,
333 pub menu: Option<MenuFile>,
334}
335
336#[derive(Clone, Debug, PartialEq, Eq)]
337pub struct MenuFile {
338 pub file: PathBuf,
339 pub declared: bool,
340 pub entries: Vec<MenuEntry>,
341}
342
343#[derive(Clone, Debug, PartialEq, Eq)]
344pub struct MenuEntry {
345 pub label: String,
346 pub feature: Option<String>,
347 pub line: usize,
348}
349
350#[derive(Clone, Debug, PartialEq, Eq)]
351pub struct ScreenOverride {
352 pub module: String,
353 pub file: PathBuf,
354}
355
356#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
357pub enum Method {
358 Get,
359 Post,
360 Put,
361 Patch,
362 Delete,
363}
364
365impl Method {
366 const ALL: [Self; 5] = [Self::Get, Self::Post, Self::Put, Self::Patch, Self::Delete];
367
368 #[must_use]
369 pub fn name(self) -> &'static str {
370 match self {
371 Self::Get => "GET",
372 Self::Post => "POST",
373 Self::Put => "PUT",
374 Self::Patch => "PATCH",
375 Self::Delete => "DELETE",
376 }
377 }
378
379 #[must_use]
380 pub fn from_routes_method(name: &str) -> Option<Self> {
381 Self::ALL
382 .into_iter()
383 .find(|method| method.name().to_ascii_lowercase() == name)
384 }
385}
386
387#[derive(Clone, Debug, PartialEq, Eq)]
388pub struct Route {
389 pub method: Method,
390 pub path: String,
391 pub handler: Vec<String>,
392 pub screen: Option<String>,
393 pub island: Option<String>,
394 pub then: Option<Then>,
395 pub modifiers: Vec<Modifier>,
396 pub webhook: Option<String>,
397 pub line: usize,
398}
399
400#[derive(Clone, Debug, PartialEq, Eq)]
401pub enum Modifier {
402 Throttle(String),
403 Signed,
404 Idempotent,
405 BodyLimit(String),
406 Feature(String),
407 Entitled(String),
409 Live(String),
411 Cached(String),
413 Queued,
415 Document(String),
417 FileLimit(String),
419}
420
421#[derive(Clone, Debug, PartialEq, Eq)]
422pub enum Then {
423 Screen {
424 screen: String,
425 fragment: String,
426 },
427 Redirect(String),
428 Follow,
430 RedirectOrFollow(String),
432}