1use std::path::PathBuf;
2
3use dmc_diagnostic::{Code, DiagResult};
4use duck_diagnostic::{Diagnostic, diag};
5#[derive(clap::Args)]
6pub struct InitCmd {
7 #[arg(long, default_value = "dmc.toml")]
8 pub path: PathBuf,
9}
10
11impl InitCmd {
12 pub fn run(self) -> DiagResult<Diagnostic<Code>> {
14 if self.path.exists() {
15 return Err(diag!(Code::ConfigExists, format!("refusing to overwrite existing {}", self.path.display())));
16 }
17
18 std::fs::write(&self.path, DEFAULT_CONFIG).map_err(|e| {
19 diag!(
20 Code::Custom { code: String::from("N001"), severity: duck_diagnostic::Severity::Note },
21 format!("write error: {}", e.to_string())
22 )
23 })?;
24
25 Ok(diag!(
26 Code::Custom { code: String::from("N001"), severity: duck_diagnostic::Severity::Note },
27 format!("wrote {}", self.path.display())
28 ))
29 }
30}
31
32const DEFAULT_CONFIG: &str = r#"# dmc.toml - Rust MDX compiler config.
33# Every option below is commented at its default; uncomment + change to override.
34
35# --- Engine ---------------------------------------------------------------
36# Project root used to resolve relative paths in collection patterns.
37# root = "."
38
39# Where compiled JSON indexes are written. One file per collection: <output_dir>/<name>.json
40output_dir = ".dmc"
41
42# Optional: name + format of the aggregated index file (when multiple collections).
43# output_name = "index"
44# output_format = "esm" # "esm" | "json"
45
46# Wipe output_dir before each build (also enabled by `--clean` flag).
47# clean = false
48
49# Abort on the first frontmatter validation failure (also enabled by `--strict` flag).
50# strict = false
51
52# Include rendered HTML in the per-record output (alongside `body`/`content`).
53# Sidecar always emits HTML when JS plugins are configured; this is for the
54# native render path.
55# include_html = false
56
57# --- Compile (markdown / mdx) ---------------------------------------------
58# GitHub-Flavored Markdown extensions: tables, strikethrough, autolinks, task lists.
59# markdown_gfm = true
60
61# Native HTML emit on (auto-disabled for files that go through the sidecar).
62# emit_html = true
63
64# Native MDX body emit on.
65# emit_body = true
66
67# Run a JS minifier on the emitted MDX body (requires sidecar).
68# mdx_minify = false
69
70# MDX output format: "module" wraps body as an ES module with the imports
71# rolled in; "function-body" returns just the function body string.
72# mdx_output_format = "function-body"
73
74# --- JS plugin pipelines (run via the Node sidecar) -----------------------
75# Each entry is either "package-name" or ["package-name", { ...options }].
76# Plugins resolve from the project's node_modules first, then sidecar's.
77#
78# Example:
79# markdown_remark_plugins = [
80# "remark-gfm",
81# ["remark-toc", { tight = true }],
82# ]
83# markdown_rehype_plugins = [
84# ["rehype-pretty-code", { theme = "github-dark" }],
85# ]
86#
87# markdown_remark_plugins = []
88# markdown_rehype_plugins = []
89# mdx_remark_plugins = []
90# mdx_rehype_plugins = []
91
92# --- Asset handling -------------------------------------------------------
93# Copy files referenced by relative `` / `<a href="...">` into the
94# output bundle. Requires both `output_assets` and `output_base` set.
95# copy_linked_files = false
96# output_assets = "static"
97# output_base = "/"
98
99# --- Sidecar tuning (env-only, listed for reference) ----------------------
100# DMC_SIDECAR_POOL_SIZE -> number of long-lived `node` processes (default min(cores, 4))
101# dmc_SIDECAR -> override path to dmc-sidecar/index.mjs
102
103# --- Collections ----------------------------------------------------------
104# Each collection globs files under `base_dir` matching `pattern`, compiles
105# them, validates frontmatter against `schema` (optional), and writes
106# `<output_dir>/<name>.json`. The schema doubles as a TypeScript source --
107# `index.d.ts` ships a typed interface derived from it.
108[[collections]]
109name = "docs"
110pattern = "docs/**/*.{md,mdx}"
111base_dir = "."
112# single = false # if true, expect exactly one match; emit a single object instead of an array
113
114# Frontmatter schema. dmc-schema descriptor (each node has `kind`):
115# string | number | boolean | array (with `item`) | object (with `fields`,
116# optional `passthrough`) | enum (with `variants`) | literal | union |
117# nullable | optional | default | record | tuple | intersection |
118# discriminatedUnion | isodate | path | slug | unique | file | image |
119# markdown | mdx | raw | toc | metadata | excerpt | coerce.{string,number,boolean,date}
120# Wrap a field in `{ kind = "optional", inner = { ... } }` to make it optional.
121schema = { kind = "object", fields = { title = { kind = "string" }, description = { kind = "optional", inner = { kind = "string" } }, date = { kind = "optional", inner = { kind = "isodate" } }, draft = { kind = "optional", inner = { kind = "boolean" } }, tags = { kind = "optional", inner = { kind = "array", item = { kind = "string" } } }, author = { kind = "optional", inner = { kind = "object", fields = { name = { kind = "string" }, url = { kind = "optional", inner = { kind = "string" } } } } } } }
122"#;