|
| 1 | +use spacetimedb_lib::db::raw_def::v9::TableAccess; |
1 | 2 | use spacetimedb_schema::def::{ModuleDef, ProcedureDef, ReducerDef, TableDef, TypeDef, ViewDef}; |
2 | 3 | use spacetimedb_schema::schema::{Schema, TableSchema}; |
3 | 4 | mod code_indenter; |
@@ -33,10 +34,34 @@ pub fn generate(module: &ModuleDef, lang: &dyn Lang, options: &CodegenOptions) - |
33 | 34 | itertools::chain!( |
34 | 35 | util::iter_tables(module, options.visibility).map(|tbl| lang.generate_table_file(module, tbl)), |
35 | 36 | module.views().map(|view| lang.generate_view_file(module, view)), |
| 37 | + // Public tables from mounted submodules |
| 38 | + module |
| 39 | + .all_tables_with_prefix() |
| 40 | + .into_iter() |
| 41 | + .filter(|(prefix, _, table)| !prefix.is_empty() && table.table_access == TableAccess::Public) |
| 42 | + .map(|(prefix, owning_def, table)| lang.generate_mounted_table_file(owning_def, &prefix, table)), |
| 43 | + // Views from mounted submodules (views are currently always public) |
| 44 | + module |
| 45 | + .all_views_with_prefix() |
| 46 | + .into_iter() |
| 47 | + .filter(|(prefix, _, _)| !prefix.is_empty()) |
| 48 | + .map(|(prefix, owning_def, view)| lang.generate_mounted_view_file(owning_def, &prefix, view)), |
36 | 49 | module.types().flat_map(|typ| lang.generate_type_files(module, typ)), |
37 | 50 | util::iter_reducers(module, options.visibility).map(|reducer| lang.generate_reducer_file(module, reducer)), |
38 | 51 | util::iter_procedures(module, options.visibility) |
39 | 52 | .map(|procedure| lang.generate_procedure_file(module, procedure)), |
| 53 | + // Reducers from mounted submodules |
| 54 | + module |
| 55 | + .all_reducers_with_prefix() |
| 56 | + .into_iter() |
| 57 | + .filter(|(prefix, _, reducer)| !prefix.is_empty() && !reducer.visibility.is_private()) |
| 58 | + .map(|(prefix, owning_def, reducer)| lang.generate_mounted_reducer_file(owning_def, &prefix, reducer)), |
| 59 | + // Procedures from mounted submodules |
| 60 | + module |
| 61 | + .all_procedures_with_prefix() |
| 62 | + .into_iter() |
| 63 | + .filter(|(prefix, _, procedure)| !prefix.is_empty() && !procedure.visibility.is_private()) |
| 64 | + .map(|(prefix, owning_def, procedure)| lang.generate_mounted_procedure_file(owning_def, &prefix, procedure)), |
40 | 65 | lang.generate_global_files(module, options), |
41 | 66 | ) |
42 | 67 | .collect() |
@@ -68,4 +93,48 @@ pub trait Lang { |
68 | 93 | .expect("Failed to generate table due to validation errors"); |
69 | 94 | self.generate_table_file_from_schema(module, &tbl, schema) |
70 | 95 | } |
| 96 | + |
| 97 | + /// Generate a row-type file for a public table from a mounted submodule. |
| 98 | + /// Uses `owning_def`'s typespace for type resolution. |
| 99 | + /// Filename goes in a subdirectory named after the namespace: |
| 100 | + /// e.g. `alias/table_name_table.ts` for namespace `"alias."`, table `tableName`. |
| 101 | + fn generate_mounted_table_file(&self, owning_def: &ModuleDef, namespace: &str, table: &TableDef) -> OutputFile { |
| 102 | + let schema = TableSchema::from_module_def(owning_def, table, (), 0.into()) |
| 103 | + .validated() |
| 104 | + .expect("Failed to generate mounted table file"); |
| 105 | + let mut file = self.generate_table_file_from_schema(owning_def, table, schema); |
| 106 | + let ns_path = namespace.trim_end_matches('.').replace('.', "/"); |
| 107 | + file.filename = format!("{}/{}", ns_path, file.filename); |
| 108 | + file |
| 109 | + } |
| 110 | + |
| 111 | + /// Generate a row-type file for a view from a mounted submodule. |
| 112 | + fn generate_mounted_view_file(&self, owning_def: &ModuleDef, namespace: &str, view: &ViewDef) -> OutputFile { |
| 113 | + let tbl = TableDef::from(view.clone()); |
| 114 | + let schema = TableSchema::from_view_def_for_codegen(owning_def, view) |
| 115 | + .validated() |
| 116 | + .expect("Failed to generate mounted view file"); |
| 117 | + let mut file = self.generate_table_file_from_schema(owning_def, &tbl, schema); |
| 118 | + let ns_path = namespace.trim_end_matches('.').replace('.', "/"); |
| 119 | + file.filename = format!("{}/{}", ns_path, file.filename); |
| 120 | + file |
| 121 | + } |
| 122 | + |
| 123 | + /// Generate an arg-schema file for a reducer from a mounted submodule. |
| 124 | + /// Filename goes in a subdirectory named after the namespace prefix: |
| 125 | + /// e.g. `lib/library_reducer_reducer.ts` for prefix `"lib/"`. |
| 126 | + fn generate_mounted_reducer_file(&self, owning_def: &ModuleDef, prefix: &str, reducer: &ReducerDef) -> OutputFile { |
| 127 | + let mut file = self.generate_reducer_file(owning_def, reducer); |
| 128 | + let ns_path = prefix.trim_end_matches('/').replace('/', "/"); |
| 129 | + file.filename = format!("{}/{}", ns_path, file.filename); |
| 130 | + file |
| 131 | + } |
| 132 | + |
| 133 | + /// Generate an arg-schema file for a procedure from a mounted submodule. |
| 134 | + fn generate_mounted_procedure_file(&self, owning_def: &ModuleDef, prefix: &str, procedure: &ProcedureDef) -> OutputFile { |
| 135 | + let mut file = self.generate_procedure_file(owning_def, procedure); |
| 136 | + let ns_path = prefix.trim_end_matches('/').replace('/', "/"); |
| 137 | + file.filename = format!("{}/{}", ns_path, file.filename); |
| 138 | + file |
| 139 | + } |
71 | 140 | } |
0 commit comments