1#[cfg(all(feature = "resolver", feature = "fs"))]
7mod bench;
8#[cfg(feature = "fs")]
9mod code_cache;
10mod compression;
11#[cfg(all(feature = "resolver", feature = "fs"))]
12mod coverage;
13mod declare;
14mod diff;
15mod error;
16#[cfg(feature = "fs")]
17mod extractor;
18mod file_lock;
19#[cfg(feature = "fs")]
20mod init;
21mod manifest;
22mod matcher;
23pub mod meta;
24#[cfg(feature = "resolver")]
25mod navigate;
26mod paths;
27mod pattern;
28#[cfg(all(feature = "resolver", feature = "fs"))]
29mod pipeline;
30#[cfg(all(feature = "resolver", feature = "fs"))]
31mod query;
32mod query_options;
33mod repair;
34#[cfg(feature = "resolver")]
35mod resolver;
36mod selector;
37mod sidecar;
38#[cfg(all(feature = "resolver", feature = "fs"))]
39mod stats;
40mod store;
41mod sync;
42mod transact;
43mod types;
44mod validator;
45#[cfg(feature = "wasm")]
46mod index;
47mod xml;
48
49#[cfg(all(feature = "resolver", feature = "fs"))]
50pub use bench::{
51 auto_detect_cases, count_source_files, execute_bench_request, format_bench_table,
52 parse_bench_config, project_name, run_bench, AqlDef, BaselineDef, BenchCase, BenchConfig,
53 BenchRequest, BenchResponse, BenchResult, MeasuredOutput,
54};
55#[cfg(feature = "fs")]
56pub use code_cache::{glob_source_files, CodeCache};
57pub use compression::{measure_compression, CompressionResult, FileCompression, SourceEntry};
58#[cfg(all(feature = "resolver", feature = "fs"))]
59pub use coverage::{
60 diff_file_coverage, file_coverage, file_summary, spot_check_bindings, FileCoverage,
61 FileDiffCoverage, FileSummary, SpotCheckFailure, SpotCheckResult,
62};
63pub use declare::{declare_config, DeclareAttr, DeclareConfig, DeclareExtractor, DeclareTag};
64pub use diff::{diff_annotations, DiffChange, DiffEntry, DiffResult};
65pub use error::AqlError;
66#[cfg(feature = "fs")]
67pub use extractor::{run_all_extractors, run_extractor, ExtractorResult};
68#[cfg(feature = "fs")]
69pub use extractor::{BuiltinExtractor, ExtractorRegistry};
70#[cfg(all(feature = "fs", feature = "resolver"))]
71pub use extractor::{
72 ExpressExtractor, GoHttpExtractor, GoStructureExtractor, GoTestExtractor, ReactExtractor,
73 RustStructureExtractor, TestExtractor, TypeScriptStructureExtractor,
74};
75pub use file_lock::FileLockManager;
76#[cfg(feature = "fs")]
77pub use init::init_project;
78#[cfg(feature = "fs")]
79pub use init::{detect_stacks, generate_schema, DetectedStacks, Stack};
80pub use manifest::ExtractorConfig;
81#[cfg(feature = "fs")]
82pub use manifest::{find_project_root, load_manifest};
83pub use manifest::{
84 parse_manifest, AttrDefinition, AttrType, Manifest, TagDefinition, BUILTIN_ATTRS,
85 NON_GENERATED_BUILTINS, SCHEMA_VERSION,
86};
87pub use matcher::{filter_by_selector, filter_by_selector_indexed, matches_compound, Matchable};
88#[cfg(feature = "resolver")]
89pub use navigate::{
90 batch_mutate,
91 expand,
92 expand_node,
93 insert,
94 insert_source,
95 move_node,
96 move_node_in_source,
97 next,
98 next_node,
99 prev,
100 prev_node,
101 read_source,
102 remove,
103 remove_node,
104 replace,
105 replace_node,
106 select as nav_select,
107 select_nodes,
109 shrink,
110 shrink_node,
111 BatchMutationResult,
112 InsertPosition,
113 MutationOp,
114 MutationRequest,
115 MutationResult,
116 NavResult,
117 NodeRef,
118};
119pub use pattern::{
120 diff_from_pattern, extract_pattern, pattern_with_deltas, AttrSummary, Delta, Pattern,
121 PatternResult,
122};
123#[cfg(all(feature = "resolver", feature = "fs"))]
124pub use pipeline::{QueryContext, QueryMiddleware, QueryPipeline, QueryPipelineBuilder};
125#[cfg(all(feature = "resolver", feature = "fs"))]
126pub use query::{batch_query, unified_query, AnnotationSummary, CodeElementSummary, QueryResult};
127pub use query_options::QueryOptions;
128pub use repair::{suggest_repairs, suggest_repairs_from_annotations, RepairSuggestion};
129#[cfg(feature = "resolver")]
130pub use resolver::{
131 CodeElement, CodeResolver, GoResolver, ResolverRegistry, RustResolver, SourceLocation,
132 TypeScriptResolver,
133};
134pub use selector::{
135 parse_selector, AttrOp, AttrPredicate, Combinator, CompoundSelector, Predicate, PredicateOp,
136 PredicateValue, SelectorAst,
137};
138pub use sidecar::{
139 extract_aql_symbols, extract_bind_from_line, resolve_bind_name, sidecar_for_colocated,
140 source_candidates, AqlSymbol, SidecarLocator, SOURCE_EXTENSIONS,
141};
142#[cfg(feature = "fs")]
143pub use sidecar::{ColocatedLocator, DirectoryLocator};
144#[cfg(all(feature = "resolver", feature = "fs"))]
145pub use stats::{project_stats, ProjectStats};
146#[cfg(feature = "fs")]
147pub use store::{glob_annotation_files, glob_aql_files};
148pub use store::{Annotation, AnnotationStore, FileEntry};
149pub use sync::{apply_edits, sync_sidecar, SidecarEdit};
150pub use transact::{execute_transaction, TransactionCondition, TransactionOp, TransactionResult};
151pub use types::{
152 AttrName, Binding, CodeElementName, NodeKind, ProjectRoot, RelativePath, Scope, SelectorStr,
153 TagName,
154};
155pub use validator::{validate, ValidationLevel, ValidationResult};
156
157pub use rustc_hash::FxHashMap;
158
159pub const SURFACE: &[&str] = &[
165 "bench",
166 "diff",
167 "extract",
168 "init",
169 "locate",
170 "nav_insert",
171 "nav_read",
172 "nav_remove",
173 "nav_replace",
174 "nav_select",
175 "query",
176 "repair",
177 "schema",
178 "select",
179 "stats",
180 "transact",
181 "validate",
182];
183
184pub const CLI_ONLY: &[&str] = &["mcp"];
187
188pub const MCP_ONLY: &[&str] = &[
191 "batch_mutate",
192 "batch_query",
193 "coverage",
194 "diff_coverage",
195 "file_summary",
196 "nav_expand",
197 "nav_move",
198 "nav_next",
199 "nav_prev",
200 "nav_shrink",
201 "pattern",
202 "refresh",
203 "spot_check",
204];
205
206use serde_json::Value as JsonValue;
207use std::borrow::Cow;
208
209pub fn json_value_to_string(v: &JsonValue) -> Cow<'_, str> {
212 match v {
213 JsonValue::String(s) => Cow::Borrowed(s.as_str()),
214 JsonValue::Bool(b) => Cow::Owned(b.to_string()),
215 JsonValue::Number(n) => Cow::Owned(n.to_string()),
216 JsonValue::Null => Cow::Borrowed(""),
217 other => Cow::Owned(other.to_string()),
218 }
219}
220
221#[cfg(all(test, feature = "codegen"))]
226mod ts_codegen {
227 use wasm_js_bridge::{generate_index_dts, generate_index_flow, OpaqueType, TypeAlias, WasmFn};
228
229 macro_rules! collect_decls {
232 ($ts_cfg:expr, $flow_cfg:expr, [ $($ty:ty),* $(,)? ]) => {{
233 use ts_rs::TS;
234 use flowjs_rs::Flow;
235 let ts: Vec<String> = vec![ $( <$ty as TS>::decl($ts_cfg) ),* ];
236 let flow: Vec<String> = vec![ $( <$ty as Flow>::decl($flow_cfg) ),* ];
237 (ts, flow)
238 }};
239 }
240
241 const ALIASES: &[TypeAlias] = &[
242 TypeAlias {
243 name: "AttrPredicate",
244 target: "Predicate",
245 },
246 TypeAlias {
247 name: "AttrOp",
248 target: "PredicateOp",
249 },
250 ];
251
252 const WASM_FNS: &[WasmFn] = &[
254 crate::index::_WASM_JS_BRIDGE_DECLARE,
255 crate::index::_WASM_JS_BRIDGE_PARSE_MANIFEST,
256 crate::index::_WASM_JS_BRIDGE_PARSE_SELECTOR,
257 crate::index::_WASM_JS_BRIDGE_SELECT,
258 crate::index::_WASM_JS_BRIDGE_VALIDATE,
259 crate::index::_WASM_JS_BRIDGE_DIFF_ANNOTATIONS,
260 crate::index::_WASM_JS_BRIDGE_EXTRACT_PATTERN,
261 crate::index::_WASM_JS_BRIDGE_SUGGEST_REPAIRS,
262 crate::index::_WASM_JS_BRIDGE_SIDECAR_FOR,
263 crate::index::_WASM_JS_BRIDGE_SOURCE_CANDIDATES,
264 crate::index::_WASM_JS_BRIDGE_EXTRACT_BIND,
265 crate::index::_WASM_JS_BRIDGE_RESOLVE_BIND_NAME,
266 crate::index::_WASM_JS_BRIDGE_EXTRACT_AQL_SYMBOLS,
267 crate::index::_WASM_JS_BRIDGE_MEASURE_COMPRESSION,
268 ];
269
270 #[test]
271 fn generate_npm_files() {
272 let dir = std::path::Path::new(env!("CARGO_MANIFEST_DIR"));
273 let ts_cfg = ts_rs::Config::default();
274 let flow_cfg = flowjs_rs::Config::default();
275
276 let (ts_decls, flow_decls) = collect_decls!(
278 &ts_cfg,
279 &flow_cfg,
280 [
281 amql_selector::TagName,
283 amql_selector::AttrName,
284 amql_mutate::NodeKind,
285 amql_mutate::RelativePath,
286 crate::Binding,
287 crate::Scope,
288 crate::CodeElementName,
289 crate::SelectorStr,
290 serde_json::Value,
292 amql_predicates::PredicateOp,
294 amql_predicates::PredicateValue,
295 amql_predicates::Predicate,
296 amql_predicates::Token,
297 amql_selector::Combinator,
299 amql_selector::CompoundSelector,
300 amql_selector::SelectorAst,
301 amql_mutate::NodeRef,
303 amql_mutate::InsertPosition,
304 amql_mutate::MutationResult,
305 amql_mutate::RemoveResult,
306 crate::Annotation,
308 crate::FileEntry,
309 crate::DeclareConfig,
310 crate::DeclareTag,
311 crate::DeclareAttr,
312 crate::DeclareExtractor,
313 crate::Manifest,
314 crate::TagDefinition,
315 crate::AttrDefinition,
316 crate::AttrType,
317 crate::ExtractorConfig,
318 crate::DiffResult,
319 crate::DiffEntry,
320 crate::DiffChange,
321 crate::Pattern,
322 crate::PatternResult,
323 crate::AttrSummary,
324 crate::Delta,
325 crate::ValidationResult,
326 crate::ValidationLevel,
327 crate::RepairSuggestion,
328 crate::CompressionResult,
329 crate::FileCompression,
330 crate::SourceEntry,
331 crate::AqlSymbol,
332 ]
333 );
334
335 let stem = wasm_js_bridge::file_to_stem(WASM_FNS[0].file);
337
338 let dts = generate_index_dts(&ts_decls, ALIASES, &[], WASM_FNS);
339 std::fs::write(dir.join(format!("{stem}.d.ts")), dts)
340 .expect("Failed to write .d.ts");
341
342 let opaque = &[
343 OpaqueType { name: "TagName", bound: Some("string") },
344 OpaqueType { name: "AttrName", bound: Some("string") },
345 OpaqueType { name: "NodeKind", bound: Some("string") },
346 OpaqueType { name: "RelativePath", bound: Some("string") },
347 OpaqueType { name: "Binding", bound: Some("string") },
348 OpaqueType { name: "Scope", bound: Some("string") },
349 OpaqueType { name: "CodeElementName", bound: Some("string") },
350 OpaqueType { name: "SelectorStr", bound: Some("string") },
351 OpaqueType { name: "Manifest", bound: None },
352 ];
353 let flow = generate_index_flow(&flow_decls, ALIASES, &[], WASM_FNS, opaque);
354 std::fs::write(dir.join(format!("{stem}.js.flow")), flow)
355 .expect("Failed to write .js.flow");
356 }
357}