mago_wasm/
lib.rs

1//! # Mago WASM Bindings
2//!
3//! This crate provides [wasm-bindgen] exports that wrap Mago’s internal
4//! functionality (formatter, parser, linter, etc.) so they can be called
5//! from JavaScript in a WebAssembly environment.
6
7use std::borrow::Cow;
8
9use bumpalo::Bump;
10use wasm_bindgen::prelude::*;
11
12use mago_formatter::Formatter;
13use mago_formatter::settings::FormatSettings;
14use mago_php_version::PHPVersion;
15
16mod analysis;
17mod rules;
18mod settings;
19
20/// Runs the full analysis pipeline (parse, semantics, lint, analyze, format).
21///
22/// Takes a string of PHP code and a settings object, returning a comprehensive
23/// analysis result.
24#[wasm_bindgen(js_name = run)]
25pub fn run(code: String, settings: JsValue) -> Result<JsValue, JsValue> {
26    let settings: settings::WasmSettings = if !settings.is_undefined() && !settings.is_null() {
27        serde_wasm_bindgen::from_value(settings)?
28    } else {
29        settings::WasmSettings::default()
30    };
31
32    let results = analysis::analyze_code(code, settings);
33
34    Ok(serde_wasm_bindgen::to_value(&results)?)
35}
36
37/// Returns metadata for all available linter rules.
38///
39/// This allows a UI to dynamically display available rules and their descriptions.
40#[wasm_bindgen(js_name = getRules)]
41pub fn get_rules(linter_settings: JsValue) -> Result<JsValue, JsValue> {
42    let settings = if !linter_settings.is_undefined() && !linter_settings.is_null() {
43        serde_wasm_bindgen::from_value(linter_settings)?
44    } else {
45        mago_linter::settings::Settings::default()
46    };
47
48    let rules = rules::get_available_rules(settings);
49    Ok(serde_wasm_bindgen::to_value(&rules)?)
50}
51
52/// Runs only the formatter on the given code.
53///
54/// This is a lightweight function for callers who only need to format code
55/// without performing a full analysis.
56#[wasm_bindgen(js_name = formatCode)]
57pub fn format_code(code: String, php_version: JsValue, settings: JsValue) -> Result<String, JsValue> {
58    let php_version: PHPVersion = if !php_version.is_undefined() && !php_version.is_null() {
59        serde_wasm_bindgen::from_value(php_version)?
60    } else {
61        PHPVersion::default()
62    };
63
64    let settings: FormatSettings = if !settings.is_undefined() && !settings.is_null() {
65        serde_wasm_bindgen::from_value(settings)?
66    } else {
67        FormatSettings::default()
68    };
69
70    let arena = Bump::new();
71    let formatter = Formatter::new(&arena, php_version, settings);
72
73    formatter
74        .format_code(Cow::Borrowed("code.php"), Cow::Owned(code))
75        .map(|s| s.to_string())
76        .map_err(|err| JsValue::from_str(&err.to_string()))
77}