Skip to content

Commit 0ad3201

Browse files
committed
fix(wasm): add missing config fields and fix parity with CLI
1 parent 4ddf73d commit 0ad3201

File tree

2 files changed

+258
-95
lines changed

2 files changed

+258
-95
lines changed

src/wasm.rs

Lines changed: 28 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -165,63 +165,22 @@ pub struct LinterConfig {
165165
/// Markdown flavor: "standard", "mkdocs", "mdx", "quarto", "obsidian", or "kramdown"
166166
pub flavor: Option<String>,
167167

168+
/// Rules allowed to apply fixes (if specified, only these rules are fixed)
169+
pub fixable: Option<Vec<String>>,
170+
171+
/// Rules that should never apply fixes (takes precedence over fixable)
172+
pub unfixable: Option<Vec<String>>,
173+
168174
/// Rule-specific configurations
169175
/// Keys are rule names (e.g., "MD060", "MD013") and values are rule options
170176
#[serde(flatten)]
171177
pub rules: Option<std::collections::HashMap<String, serde_json::Value>>,
172178
}
173179

174180
impl LinterConfig {
175-
/// Convert to internal Config
181+
/// Convert to internal Config (discards any config parse warnings)
176182
fn to_config(&self) -> Config {
177-
let mut config = Config::default();
178-
179-
// Apply disabled rules
180-
if let Some(ref disable) = self.disable {
181-
config.global.disable = disable.clone();
182-
}
183-
184-
// Apply enabled rules
185-
if let Some(ref enable) = self.enable {
186-
config.global.enable = enable.clone();
187-
}
188-
189-
// Apply extend-enable / extend-disable
190-
if let Some(ref extend_enable) = self.extend_enable {
191-
config.global.extend_enable = extend_enable.clone();
192-
}
193-
if let Some(ref extend_disable) = self.extend_disable {
194-
config.global.extend_disable = extend_disable.clone();
195-
}
196-
197-
// Apply line length
198-
if let Some(line_length) = self.line_length {
199-
config.global.line_length = LineLength::new(line_length as usize);
200-
}
201-
202-
// Apply flavor
203-
config.global.flavor = self.markdown_flavor();
204-
205-
// Apply rule-specific configurations
206-
if let Some(ref rules) = self.rules {
207-
for (rule_name, json_value) in rules {
208-
// Only process keys that look like rule names (MD###)
209-
if !is_rule_name(rule_name) {
210-
continue;
211-
}
212-
213-
// Convert JSON value to RuleConfig
214-
let result = json_to_rule_config_with_warnings(json_value);
215-
if let Some(rule_config) = result.config {
216-
config.rules.insert(rule_name.to_ascii_uppercase(), rule_config);
217-
}
218-
}
219-
}
220-
221-
// Per-rule `enabled = true` → extend_enable for opt-in rules
222-
config.promote_enabled_to_extend_enable();
223-
224-
config
183+
self.to_config_with_warnings().0
225184
}
226185

227186
/// Convert to internal Config, collecting any warnings about invalid configuration
@@ -234,9 +193,10 @@ impl LinterConfig {
234193
config.global.disable = disable.clone();
235194
}
236195

237-
// Apply enabled rules
196+
// Apply enabled rules (presence of `enable` key means explicit mode)
238197
if let Some(ref enable) = self.enable {
239198
config.global.enable = enable.clone();
199+
config.global.enable_is_explicit = true;
240200
}
241201

242202
// Apply extend-enable / extend-disable
@@ -255,6 +215,14 @@ impl LinterConfig {
255215
// Apply flavor
256216
config.global.flavor = self.markdown_flavor();
257217

218+
// Apply fixable / unfixable
219+
if let Some(ref fixable) = self.fixable {
220+
config.global.fixable = fixable.clone();
221+
}
222+
if let Some(ref unfixable) = self.unfixable {
223+
config.global.unfixable = unfixable.clone();
224+
}
225+
258226
// Apply rule-specific configurations
259227
if let Some(ref rules) = self.rules {
260228
for (rule_name, json_value) in rules {
@@ -280,16 +248,13 @@ impl LinterConfig {
280248
(config, warnings)
281249
}
282250

283-
/// Parse markdown flavor from config
251+
/// Parse markdown flavor from config, delegating to `MarkdownFlavor::from_str`
252+
/// to support all aliases (e.g., "qmd"/"rmd" → Quarto, "gfm" → Standard)
284253
fn markdown_flavor(&self) -> MarkdownFlavor {
285-
match self.flavor.as_deref() {
286-
Some("mkdocs") => MarkdownFlavor::MkDocs,
287-
Some("mdx") => MarkdownFlavor::MDX,
288-
Some("quarto") => MarkdownFlavor::Quarto,
289-
Some("obsidian") => MarkdownFlavor::Obsidian,
290-
Some("kramdown") | Some("jekyll") => MarkdownFlavor::Kramdown,
291-
_ => MarkdownFlavor::Standard,
292-
}
254+
self.flavor
255+
.as_deref()
256+
.and_then(|s| s.parse::<MarkdownFlavor>().ok())
257+
.unwrap_or_default()
293258
}
294259
}
295260

@@ -419,15 +384,10 @@ impl Linter {
419384
"enable": self.config.global.enable,
420385
"extend_enable": self.config.global.extend_enable,
421386
"extend_disable": self.config.global.extend_disable,
387+
"fixable": self.config.global.fixable,
388+
"unfixable": self.config.global.unfixable,
422389
"line_length": self.config.global.line_length.get(),
423-
"flavor": match self.flavor {
424-
MarkdownFlavor::Standard => "standard",
425-
MarkdownFlavor::MkDocs => "mkdocs",
426-
MarkdownFlavor::MDX => "mdx",
427-
MarkdownFlavor::Quarto => "quarto",
428-
MarkdownFlavor::Obsidian => "obsidian",
429-
MarkdownFlavor::Kramdown => "kramdown",
430-
},
390+
"flavor": self.flavor.to_string(),
431391
"rules": rules_json
432392
})
433393
.to_string()
@@ -499,6 +459,7 @@ mod tests {
499459
enable: None,
500460
line_length: Some(100),
501461
flavor: Some("mkdocs".to_string()),
462+
..Default::default()
502463
};
503464

504465
let internal = config.to_config();

0 commit comments

Comments
 (0)