1use camino::Utf8PathBuf;
2use rustex_diagnostics::Diagnostic;
3use serde::{Deserialize, Serialize};
4
5#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
6pub struct IrPackage {
7 pub project: ProjectInfo,
8 #[serde(default)]
9 pub tables: Vec<Table>,
10 #[serde(default)]
11 pub functions: Vec<Function>,
12 #[serde(default)]
13 pub named_types: Vec<NamedType>,
14 #[serde(default)]
15 pub constraints: Vec<Constraint>,
16 pub capabilities: CapabilityFlags,
17 #[serde(default)]
18 pub source_inventory: Vec<SourceInventoryItem>,
19 #[serde(default)]
20 pub diagnostics: Vec<Diagnostic>,
21 pub manifest_meta: ManifestMeta,
22}
23
24#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
25pub struct ProjectInfo {
26 pub name: String,
27 pub root: Utf8PathBuf,
28 pub convex_root: Utf8PathBuf,
29 pub convex_version: Option<String>,
30 pub generated_metadata_present: bool,
31 #[serde(default)]
32 pub discovered_convex_roots: Vec<Utf8PathBuf>,
33 #[serde(default)]
34 pub component_roots: Vec<Utf8PathBuf>,
35}
36
37#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
38pub struct ManifestMeta {
39 pub rustex_version: String,
40 pub manifest_version: u32,
41 pub input_hash: String,
42}
43
44#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
45pub struct Table {
46 pub name: String,
47 pub doc_name: String,
48 pub document_type: TypeNode,
49 pub source: Option<Origin>,
50}
51
52#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
53pub struct Field {
54 pub name: String,
55 pub required: bool,
56 pub r#type: TypeNode,
57 pub doc: Option<String>,
58 pub source: Option<Origin>,
59}
60
61#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
62pub struct Function {
63 pub canonical_path: String,
64 pub module_path: String,
65 pub export_name: String,
66 pub component_path: Option<String>,
67 pub visibility: Visibility,
68 pub kind: FunctionKind,
69 pub args_type: Option<TypeNode>,
70 pub returns_type: Option<TypeNode>,
71 pub contract_provenance: ContractProvenance,
72 pub source: Option<Origin>,
73}
74
75#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
76#[serde(rename_all = "snake_case")]
77pub enum Visibility {
78 Public,
79 Internal,
80}
81
82#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
83#[serde(rename_all = "snake_case")]
84pub enum FunctionKind {
85 Query,
86 Mutation,
87 Action,
88}
89
90#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
91#[serde(rename_all = "snake_case")]
92pub enum ContractProvenance {
93 Validator,
94 GeneratedTs,
95 Inferred,
96 Missing,
97}
98
99#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
100pub struct Origin {
101 pub file: Utf8PathBuf,
102 pub line: usize,
103 pub column: usize,
104}
105
106#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
107pub struct NamedType {
108 pub key: String,
109 pub suggested_name: String,
110 pub origin_symbol: String,
111 pub node: TypeNode,
112 pub source: Option<Origin>,
113}
114
115#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
116#[serde(rename_all = "snake_case")]
117pub enum ConstraintKind {
118 Literal,
119 Optional,
120 RecordValue,
121 Discriminant,
122 IdentifierTable,
123}
124
125#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
126pub struct Constraint {
127 pub path: String,
128 pub kind: ConstraintKind,
129 pub detail: String,
130}
131
132#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Default)]
133pub struct CapabilityFlags {
134 pub generated_metadata_present: bool,
135 pub inferred_returns_used: bool,
136 pub internal_functions_present: bool,
137 pub public_functions_present: bool,
138 pub http_actions_present: bool,
139 pub components_present: bool,
140}
141
142#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
143#[serde(rename_all = "snake_case")]
144pub enum SourceKind {
145 Schema,
146 FunctionModule,
147 GeneratedMetadata,
148 ComponentModule,
149}
150
151#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
152pub struct SourceInventoryItem {
153 pub path: Utf8PathBuf,
154 pub kind: SourceKind,
155}
156
157#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
158#[serde(tag = "kind", rename_all = "snake_case")]
159pub enum TypeNode {
160 String,
161 Float64,
162 Int64,
163 Boolean,
164 Null,
165 Bytes,
166 Any,
167 LiteralString { value: String },
168 LiteralNumber { value: f64 },
169 LiteralBoolean { value: bool },
170 Id { table: String },
171 Array { element: Box<TypeNode> },
172 Record { value: Box<TypeNode> },
173 Object { fields: Vec<Field>, open: bool },
174 Union { members: Vec<TypeNode> },
175 Unknown { reason: String, confidence: f32 },
176}
177
178impl TypeNode {
179 pub fn object(fields: Vec<Field>) -> Self {
180 Self::Object {
181 fields,
182 open: false,
183 }
184 }
185}