@dogsbay/format-vitepress 0.2.0-beta.101

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,46 @@
1
+ # @dogsbay/format-vitepress
2
+
3
+ VitePress importer for [Dogsbay](https://github.com/dogsbay). Converts a
4
+ VitePress docs project into `TreeNode[]` + `NavItem[]`, ready for export to
5
+ Astro, Obsidian, or canonical Dogsbay Markdown.
6
+
7
+ ```bash
8
+ npx dogsbay convert ./my-vitepress-docs --to astro -o ./out
9
+ ```
10
+
11
+ ## What it does
12
+
13
+ - Translates VitePress markdown to Dogsbay-MD: `:::` containers,
14
+ `::: code-group`, fence metadata (`[label]`, `{1,3-5}`, `:line-numbers`),
15
+ `<<<` snippets, `<!--@include:-->`, GitHub alerts, custom anchors.
16
+ - Reads the sidebar out of `.vitepress/config.*` **without executing it** —
17
+ no `node_modules` needed, no code from the source repo runs.
18
+ - Honours `srcDir`, `srcExclude`, `rewrites`, `base`, `cleanUrls`, and
19
+ `locales.root.themeConfig`.
20
+ - Removes Vue (`<script setup>`, components, `{{ }}`) and **names every
21
+ component it removed**, because a silent drop is indistinguishable from a
22
+ clean import.
23
+
24
+ Validated on vite, vitest and hono: 391 pages, 100% sidebar recovery, 98.7–99.5%
25
+ content retention, all three building through a real `astro build`.
26
+
27
+ ## Usage
28
+
29
+ ```ts
30
+ import { importVitepress } from "@dogsbay/format-vitepress/cli";
31
+
32
+ const { pages, nav } = await importVitepress("./docs", { hrefPrefix: "/docs" });
33
+ ```
34
+
35
+ Or the pieces:
36
+
37
+ ```ts
38
+ import { parseVitepress, readConfig, buildNav } from "@dogsbay/format-vitepress";
39
+ ```
40
+
41
+ ## Docs
42
+
43
+ - [Migration guide](../../docs/migrating-vitepress.md)
44
+ - [Internals](../../docs-dev/format-vitepress.md)
45
+
46
+ MIT
package/dist/cli.d.ts ADDED
@@ -0,0 +1,18 @@
1
+ import type { FormatPlugin, ExportPage, NavItem } from "@dogsbay/types";
2
+ export interface VitepressImportResult {
3
+ pages: ExportPage[];
4
+ nav: NavItem[];
5
+ /** Directory page slugs are relative to (`srcDir`). */
6
+ srcDir: string;
7
+ navSource: "sidebar" | "directory";
8
+ assetMounts: {
9
+ dir: string;
10
+ into?: string;
11
+ mediaOnly?: boolean;
12
+ }[];
13
+ /** Site title from the config, when it had one. */
14
+ siteName?: string;
15
+ }
16
+ export declare function importVitepress(source: string, opts?: Record<string, unknown>): Promise<VitepressImportResult>;
17
+ export declare const plugin: FormatPlugin;
18
+ //# sourceMappingURL=cli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,YAAY,EAAE,UAAU,EAAE,OAAO,EAAW,MAAM,gBAAgB,CAAC;AAWjF,MAAM,WAAW,qBAAqB;IACpC,KAAK,EAAE,UAAU,EAAE,CAAC;IACpB,GAAG,EAAE,OAAO,EAAE,CAAC;IACf,uDAAuD;IACvD,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,SAAS,GAAG,WAAW,CAAC;IACnC,WAAW,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,OAAO,CAAA;KAAE,EAAE,CAAC;IACnE,mDAAmD;IACnD,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,wBAAsB,eAAe,CACnC,MAAM,EAAE,MAAM,EACd,IAAI,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,GACjC,OAAO,CAAC,qBAAqB,CAAC,CAgEhC;AAqCD,eAAO,MAAM,MAAM,EAAE,YAiBpB,CAAC"}
package/dist/cli.js ADDED
@@ -0,0 +1,114 @@
1
+ /**
2
+ * FormatPlugin for VitePress as a source format.
3
+ *
4
+ * Orchestrates: detect corpus → loadVitepress (config + page walk + nav) →
5
+ * translate each page (parseVitepress) → assemble ExportPage[] + NavItem[].
6
+ *
7
+ * VitePress content is `.md`, so this plugin MUST be registered before the
8
+ * generic dogsbay-md detector. `detectVitepress` requires an actual
9
+ * `.vitepress/config.*`, so it cannot claim a plain-Markdown corpus.
10
+ */
11
+ import { readFileSync } from "node:fs";
12
+ import { extractHeadings } from "@dogsbay/format-dogsbay-md";
13
+ import { parseVitepress } from "./parse.js";
14
+ import { loadVitepress, detectVitepress, translateOptionsFor, titleFromSlug, } from "./loaders/load.js";
15
+ export async function importVitepress(source, opts = {}) {
16
+ const hrefPrefix = typeof opts.hrefPrefix === "string" ? opts.hrefPrefix : "";
17
+ const loaded = await loadVitepress(source, {
18
+ hrefPrefix,
19
+ evalConfig: opts.evalConfig === true || opts.evalConfig === "true",
20
+ });
21
+ const pages = [];
22
+ const components = {};
23
+ let ledgerTotal = 0;
24
+ let failed = 0;
25
+ for (const ps of loaded.pages) {
26
+ try {
27
+ const content = readFileSync(ps.filePath, "utf-8");
28
+ const tOpts = translateOptionsFor(ps, loaded.srcDir, loaded.root, loaded.warnings);
29
+ const { tree, frontmatter, body, ledger, components: comps } = parseVitepress(content, tOpts);
30
+ ledgerTotal += ledger.length;
31
+ for (const [name, n] of Object.entries(comps)) {
32
+ components[name] = (components[name] ?? 0) + n;
33
+ }
34
+ const headings = extractHeadings(tree);
35
+ const h1 = headings.find((h) => h.depth === 1);
36
+ const fmTitle = typeof frontmatter.title === "string" && frontmatter.title.trim()
37
+ ? frontmatter.title.trim()
38
+ : undefined;
39
+ // A `layout: home` page carries its name in `hero.name`, not a heading.
40
+ const heroName = typeof frontmatter.hero?.name === "string"
41
+ ? (frontmatter.hero.name)
42
+ : undefined;
43
+ pages.push({
44
+ slug: ps.slug,
45
+ title: fmTitle || h1?.text || heroName || titleFromSlug(ps.slug),
46
+ tree,
47
+ headings,
48
+ frontmatter,
49
+ meta: (ledger.length
50
+ ? { vitepressLedger: ledger }
51
+ : {}),
52
+ bodyMarkdown: body,
53
+ });
54
+ }
55
+ catch (err) {
56
+ failed += 1;
57
+ const msg = err instanceof Error ? err.message : String(err);
58
+ console.warn(`vitepress import: failed to convert ${ps.filePath} (slug "${ps.slug}"), skipping: ${msg}`);
59
+ }
60
+ }
61
+ reportSummary(loaded.warnings, failed, loaded.pages.length, ledgerTotal, components, loaded.navSource);
62
+ return {
63
+ pages,
64
+ nav: loaded.nav,
65
+ srcDir: loaded.srcDir,
66
+ navSource: loaded.navSource,
67
+ assetMounts: loaded.assetDirs,
68
+ siteName: loaded.config.title,
69
+ };
70
+ }
71
+ /**
72
+ * Say what was lost. Unmapped components are COUNTED AND NAMED rather than
73
+ * summarized — the format-starlight lesson: a component nested inside a mapped
74
+ * container is not dropped, its tag leaks into the page as text, and only a
75
+ * per-tag count makes that visible.
76
+ */
77
+ function reportSummary(warnings, failed, total, ledgerTotal, components, navSource) {
78
+ for (const w of warnings.slice(0, 20))
79
+ console.warn(`vitepress import: ${w}`);
80
+ if (warnings.length > 20) {
81
+ console.warn(`vitepress import: …and ${warnings.length - 20} more warnings`);
82
+ }
83
+ if (failed > 0) {
84
+ console.warn(`vitepress import: ${failed} of ${total} page(s) failed and were skipped`);
85
+ }
86
+ if (ledgerTotal > 0) {
87
+ console.warn(`vitepress import: ${ledgerTotal} construct(s) mapped with caveats (see per-page ledger)`);
88
+ }
89
+ const comps = Object.entries(components).sort((a, b) => b[1] - a[1]);
90
+ if (comps.length > 0) {
91
+ const listed = comps.slice(0, 10).map(([n, c]) => `${n}×${c}`).join(", ");
92
+ const more = comps.length > 10 ? `, …${comps.length - 10} more` : "";
93
+ console.warn(`vitepress import: Vue components removed — ${listed}${more}`);
94
+ }
95
+ console.warn(`vitepress import: nav built from the ${navSource}`);
96
+ }
97
+ export const plugin = {
98
+ name: "vitepress",
99
+ canImport: true,
100
+ canExport: false,
101
+ detectSource: (path) => detectVitepress(path),
102
+ importOptions: [
103
+ {
104
+ flags: "--eval-config",
105
+ description: "execute .vitepress/config.* instead of reading it statically (runs code from the source repo; needs its dependencies installed)",
106
+ },
107
+ ],
108
+ exportOptions: [],
109
+ async import(source, opts) {
110
+ const { pages, nav, srcDir, assetMounts } = await importVitepress(source, opts);
111
+ return { pages, nav, contentRoot: srcDir, assetMounts };
112
+ },
113
+ };
114
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,49 @@
1
+ /** A sidebar/nav entry as VitePress declares it. */
2
+ export interface RawNavItem {
3
+ text?: string;
4
+ link?: string;
5
+ items?: RawNavItem[];
6
+ collapsed?: boolean;
7
+ /** `nav` entries use `activeMatch`; useful for pairing nav ↔ sidebar keys. */
8
+ activeMatch?: string;
9
+ /** `link` may be `{ text, link }` under a nav dropdown; kept for fidelity. */
10
+ [key: string]: unknown;
11
+ }
12
+ export type RawSidebar = RawNavItem[] | Record<string, RawNavItem[]>;
13
+ export interface VitePressConfig {
14
+ title?: string;
15
+ description?: string;
16
+ base?: string;
17
+ srcDir?: string;
18
+ srcExclude?: string[];
19
+ rewrites?: Record<string, string>;
20
+ cleanUrls?: boolean;
21
+ sidebar?: RawSidebar;
22
+ nav?: RawNavItem[];
23
+ /** Locale keys other than `root`, so the loader can report what it skipped. */
24
+ locales?: string[];
25
+ /** Absolute path of the config file that was read. */
26
+ configPath: string;
27
+ /** Expressions the static reader could not evaluate. */
28
+ unresolved: string[];
29
+ }
30
+ /**
31
+ * Locate `.vitepress/config.*`.
32
+ *
33
+ * VitePress also permits `.vitepress/config/index.*` — the split-config layout
34
+ * used by larger sites (Element Plus, Vue's own docs).
35
+ */
36
+ export declare function findConfigFile(vitepressDir: string): string | undefined;
37
+ /** Read the config file statically (no execution). */
38
+ export declare function readConfig(configPath: string): VitePressConfig;
39
+ /**
40
+ * Read the config by IMPORTING it. Opt-in (`--eval-config`).
41
+ *
42
+ * SECURITY: this EXECUTES JavaScript/TypeScript from the source repository,
43
+ * and needs a loader that understands TS (`tsx`, or a `.mjs`/`.js` config).
44
+ * Acceptable for a local migration CLI pointed at a repo you already trust
45
+ * enough to `npm install`; not acceptable for untrusted input. All execution
46
+ * funnels through this one function so it can later be sandboxed.
47
+ */
48
+ export declare function evalConfig(configPath: string): Promise<VitePressConfig>;
49
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAaA,oDAAoD;AACpD,MAAM,WAAW,UAAU;IACzB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,UAAU,EAAE,CAAC;IACrB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,8EAA8E;IAC9E,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,8EAA8E;IAC9E,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,MAAM,MAAM,UAAU,GAAG,UAAU,EAAE,GAAG,MAAM,CAAC,MAAM,EAAE,UAAU,EAAE,CAAC,CAAC;AAErE,MAAM,WAAW,eAAe;IAC9B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAClC,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,OAAO,CAAC,EAAE,UAAU,CAAC;IACrB,GAAG,CAAC,EAAE,UAAU,EAAE,CAAC;IACnB,+EAA+E;IAC/E,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,sDAAsD;IACtD,UAAU,EAAE,MAAM,CAAC;IACnB,wDAAwD;IACxD,UAAU,EAAE,MAAM,EAAE,CAAC;CACtB;AAKD;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAYvE;AAqHD,sDAAsD;AACtD,wBAAgB,UAAU,CAAC,UAAU,EAAE,MAAM,GAAG,eAAe,CAc9D;AAED;;;;;;;;GAQG;AACH,wBAAsB,UAAU,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,CAAC,CAQ7E"}
package/dist/config.js ADDED
@@ -0,0 +1,183 @@
1
+ /**
2
+ * Read `.vitepress/config.*` into the typed slice this importer needs.
3
+ *
4
+ * STATICALLY, by default — see `literal.ts` for why. `--eval-config` swaps in
5
+ * a real `import()` for repos whose config outruns the literal subset AND
6
+ * whose dependencies are installed; that path executes code from the source
7
+ * repository and is therefore opt-in, never the default.
8
+ */
9
+ import { existsSync, readFileSync } from "node:fs";
10
+ import { join } from "node:path";
11
+ import { pathToFileURL } from "node:url";
12
+ import { evaluateModule, asArray, asObject, asString, UNRESOLVED } from "./literal.js";
13
+ const CONFIG_BASENAMES = ["config"];
14
+ const CONFIG_EXTS = [".ts", ".mts", ".mjs", ".js", ".cts", ".cjs"];
15
+ /**
16
+ * Locate `.vitepress/config.*`.
17
+ *
18
+ * VitePress also permits `.vitepress/config/index.*` — the split-config layout
19
+ * used by larger sites (Element Plus, Vue's own docs).
20
+ */
21
+ export function findConfigFile(vitepressDir) {
22
+ for (const base of CONFIG_BASENAMES) {
23
+ for (const ext of CONFIG_EXTS) {
24
+ const p = join(vitepressDir, base + ext);
25
+ if (existsSync(p))
26
+ return p;
27
+ }
28
+ }
29
+ for (const ext of CONFIG_EXTS) {
30
+ const p = join(vitepressDir, "config", "index" + ext);
31
+ if (existsSync(p))
32
+ return p;
33
+ }
34
+ return undefined;
35
+ }
36
+ /**
37
+ * VitePress merges `locales.root` over the top-level config, and each locale's
38
+ * `themeConfig` over the top-level `themeConfig`. Vitest puts its entire
39
+ * sidebar under `locales.root.themeConfig`, so reading only the top level
40
+ * would find no nav at all and silently fall back to a directory scan.
41
+ */
42
+ function mergedThemeConfig(root) {
43
+ const theme = { ...(asObject(root.themeConfig) ?? {}) };
44
+ const locales = asObject(root.locales);
45
+ const localeKeys = locales ? Object.keys(locales) : [];
46
+ if (locales) {
47
+ const rootLocale = asObject(locales.root);
48
+ if (rootLocale) {
49
+ Object.assign(theme, asObject(rootLocale.themeConfig) ?? {});
50
+ }
51
+ }
52
+ return { theme, localeKeys };
53
+ }
54
+ /** Drop UNRESOLVED leaves so callers never see the sentinel. */
55
+ function clean(v) {
56
+ if (v === UNRESOLVED)
57
+ return undefined;
58
+ if (Array.isArray(v)) {
59
+ const out = v.map(clean).filter((x) => x !== undefined);
60
+ return out;
61
+ }
62
+ const obj = asObject(v);
63
+ if (obj) {
64
+ const out = {};
65
+ for (const [k, val] of Object.entries(obj)) {
66
+ const c = clean(val);
67
+ if (c !== undefined)
68
+ out[k] = c;
69
+ }
70
+ return out;
71
+ }
72
+ return v;
73
+ }
74
+ function toRawItems(v) {
75
+ const arr = asArray(v);
76
+ if (!arr)
77
+ return undefined;
78
+ const cleaned = clean(arr);
79
+ return cleaned.filter((x) => x && typeof x === "object");
80
+ }
81
+ function toRawSidebar(v) {
82
+ const arr = asArray(v);
83
+ if (arr)
84
+ return toRawItems(v);
85
+ const obj = asObject(v);
86
+ if (!obj)
87
+ return undefined;
88
+ const out = {};
89
+ for (const [key, val] of Object.entries(obj)) {
90
+ // A path key may hold either the item array directly, or the
91
+ // `{ base, items }` form VitePress supports for prefixed sidebars.
92
+ const items = toRawItems(val);
93
+ if (items) {
94
+ out[key] = items;
95
+ continue;
96
+ }
97
+ const nested = asObject(val);
98
+ if (nested) {
99
+ const inner = toRawItems(nested.items);
100
+ if (inner) {
101
+ const base = asString(nested.base);
102
+ out[base ? base : key] = inner;
103
+ }
104
+ }
105
+ }
106
+ return Object.keys(out).length > 0 ? out : undefined;
107
+ }
108
+ function shapeConfig(root, configPath, unresolved) {
109
+ const { theme, localeKeys } = mergedThemeConfig(root);
110
+ const cfg = { configPath, unresolved };
111
+ const title = asString(root.title);
112
+ if (title)
113
+ cfg.title = title;
114
+ const description = asString(root.description);
115
+ if (description)
116
+ cfg.description = description;
117
+ const base = asString(root.base);
118
+ if (base)
119
+ cfg.base = base;
120
+ const srcDir = asString(root.srcDir);
121
+ if (srcDir)
122
+ cfg.srcDir = srcDir;
123
+ if (typeof root.cleanUrls === "boolean")
124
+ cfg.cleanUrls = root.cleanUrls;
125
+ const srcExclude = asArray(root.srcExclude);
126
+ if (srcExclude) {
127
+ cfg.srcExclude = srcExclude.filter((x) => typeof x === "string");
128
+ }
129
+ const rewrites = asObject(root.rewrites);
130
+ if (rewrites) {
131
+ const out = {};
132
+ for (const [k, v] of Object.entries(rewrites)) {
133
+ if (typeof v === "string")
134
+ out[k] = v;
135
+ }
136
+ if (Object.keys(out).length > 0)
137
+ cfg.rewrites = out;
138
+ }
139
+ const sidebar = toRawSidebar(theme.sidebar);
140
+ if (sidebar)
141
+ cfg.sidebar = sidebar;
142
+ const nav = toRawItems(theme.nav);
143
+ if (nav)
144
+ cfg.nav = nav;
145
+ if (localeKeys.length > 0)
146
+ cfg.locales = localeKeys;
147
+ return cfg;
148
+ }
149
+ /** Read the config file statically (no execution). */
150
+ export function readConfig(configPath) {
151
+ const src = readFileSync(configPath, "utf-8");
152
+ const { value, unresolved } = evaluateModule(src);
153
+ const root = asObject(value);
154
+ if (!root) {
155
+ return {
156
+ configPath,
157
+ unresolved: [
158
+ ...unresolved,
159
+ "the config's default export could not be read as an object literal",
160
+ ],
161
+ };
162
+ }
163
+ return shapeConfig(root, configPath, unresolved);
164
+ }
165
+ /**
166
+ * Read the config by IMPORTING it. Opt-in (`--eval-config`).
167
+ *
168
+ * SECURITY: this EXECUTES JavaScript/TypeScript from the source repository,
169
+ * and needs a loader that understands TS (`tsx`, or a `.mjs`/`.js` config).
170
+ * Acceptable for a local migration CLI pointed at a repo you already trust
171
+ * enough to `npm install`; not acceptable for untrusted input. All execution
172
+ * funnels through this one function so it can later be sandboxed.
173
+ */
174
+ export async function evalConfig(configPath) {
175
+ const mod = (await import(pathToFileURL(configPath).href));
176
+ const raw = (mod.default ?? mod);
177
+ const root = asObject(raw);
178
+ if (!root) {
179
+ throw new Error(`${configPath}: default export is not an object`);
180
+ }
181
+ return shapeConfig(root, configPath, []);
182
+ }
183
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ /**
2
+ * @dogsbay/format-vitepress — VitePress format plugin.
3
+ *
4
+ * Imports a VitePress docs project into TreeNode[] by translating VitePress
5
+ * containers, code-fence conventions, snippets and includes to Dogsbay-MD,
6
+ * then parsing with the canonical dogsbay-md parser (zero new node types).
7
+ *
8
+ * Nav comes from `.vitepress/config.*`, read STATICALLY — see `literal.ts`.
9
+ *
10
+ * See plans/format-vitepress.md.
11
+ */
12
+ export { parseVitepress, type ParseVitepressResult } from "./parse.js";
13
+ export { vitepressToDogsbayMd, translateFenceInfo, splitRegion, type TranslateResult, type TranslateLedgerEntry, type TranslateOptions, type SnippetRequest, } from "./translate.js";
14
+ export { findConfigFile, readConfig, evalConfig, type VitePressConfig, type RawNavItem, type RawSidebar, } from "./config.js";
15
+ export { evaluateModule, UNRESOLVED, type EvalResult, type LiteralValue, } from "./literal.js";
16
+ export { buildNav, itemsToNav, navFromSlugs, linkToSlug, slugToHref, type NavContext, } from "./nav.js";
17
+ export { loadVitepress, detectVitepress, findVitepressDir, pathToSlug, globToRegExp, extractRegion, dedent, translateOptionsFor, titleFromSlug, type VitepressLoadResult, type VitepressPageSource, type VitepressLoadOptions, } from "./loaders/load.js";
18
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,OAAO,EAAE,cAAc,EAAE,KAAK,oBAAoB,EAAE,MAAM,YAAY,CAAC;AACvE,OAAO,EACL,oBAAoB,EACpB,kBAAkB,EAClB,WAAW,EACX,KAAK,eAAe,EACpB,KAAK,oBAAoB,EACzB,KAAK,gBAAgB,EACrB,KAAK,cAAc,GACpB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EACL,cAAc,EACd,UAAU,EACV,UAAU,EACV,KAAK,eAAe,EACpB,KAAK,UAAU,EACf,KAAK,UAAU,GAChB,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,cAAc,EACd,UAAU,EACV,KAAK,UAAU,EACf,KAAK,YAAY,GAClB,MAAM,cAAc,CAAC;AACtB,OAAO,EACL,QAAQ,EACR,UAAU,EACV,YAAY,EACZ,UAAU,EACV,UAAU,EACV,KAAK,UAAU,GAChB,MAAM,UAAU,CAAC;AAClB,OAAO,EACL,aAAa,EACb,eAAe,EACf,gBAAgB,EAChB,UAAU,EACV,YAAY,EACZ,aAAa,EACb,MAAM,EACN,mBAAmB,EACnB,aAAa,EACb,KAAK,mBAAmB,EACxB,KAAK,mBAAmB,EACxB,KAAK,oBAAoB,GAC1B,MAAM,mBAAmB,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,18 @@
1
+ /**
2
+ * @dogsbay/format-vitepress — VitePress format plugin.
3
+ *
4
+ * Imports a VitePress docs project into TreeNode[] by translating VitePress
5
+ * containers, code-fence conventions, snippets and includes to Dogsbay-MD,
6
+ * then parsing with the canonical dogsbay-md parser (zero new node types).
7
+ *
8
+ * Nav comes from `.vitepress/config.*`, read STATICALLY — see `literal.ts`.
9
+ *
10
+ * See plans/format-vitepress.md.
11
+ */
12
+ export { parseVitepress } from "./parse.js";
13
+ export { vitepressToDogsbayMd, translateFenceInfo, splitRegion, } from "./translate.js";
14
+ export { findConfigFile, readConfig, evalConfig, } from "./config.js";
15
+ export { evaluateModule, UNRESOLVED, } from "./literal.js";
16
+ export { buildNav, itemsToNav, navFromSlugs, linkToSlug, slugToHref, } from "./nav.js";
17
+ export { loadVitepress, detectVitepress, findVitepressDir, pathToSlug, globToRegExp, extractRegion, dedent, translateOptionsFor, titleFromSlug, } from "./loaders/load.js";
18
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,OAAO,EAAE,cAAc,EAA6B,MAAM,YAAY,CAAC;AACvE,OAAO,EACL,oBAAoB,EACpB,kBAAkB,EAClB,WAAW,GAKZ,MAAM,gBAAgB,CAAC;AACxB,OAAO,EACL,cAAc,EACd,UAAU,EACV,UAAU,GAIX,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,cAAc,EACd,UAAU,GAGX,MAAM,cAAc,CAAC;AACtB,OAAO,EACL,QAAQ,EACR,UAAU,EACV,YAAY,EACZ,UAAU,EACV,UAAU,GAEX,MAAM,UAAU,CAAC;AAClB,OAAO,EACL,aAAa,EACb,eAAe,EACf,gBAAgB,EAChB,UAAU,EACV,YAAY,EACZ,aAAa,EACb,MAAM,EACN,mBAAmB,EACnB,aAAa,GAId,MAAM,mBAAmB,CAAC"}
@@ -0,0 +1,55 @@
1
+ /**
2
+ * A tolerant, execution-free evaluator for the literal subset of a
3
+ * TypeScript/JavaScript module.
4
+ *
5
+ * Why this exists: VitePress keeps the sidebar INSIDE `.vitepress/config.ts`,
6
+ * so — unlike Docusaurus, whose sidebars live in their own data module — we
7
+ * cannot punt nav extraction to a separate file. And a real VitePress config
8
+ * imports theme packages, Shiki transformers and Vite plugins, so *executing*
9
+ * it needs the source repo's `node_modules` installed and runs arbitrary code
10
+ * from that repo. (See `format-docusaurus/src/config.ts` for the same call.)
11
+ *
12
+ * So we read it instead. This module understands:
13
+ *
14
+ * - object / array / string / number / boolean / null literals
15
+ * - template literals with no `${}` interpolation
16
+ * - `...spread` of anything else this module can evaluate
17
+ * - module-level `const X = <literal>` identifier references
18
+ * - zero-arg calls to module-level `function f() { return <literal> }` and
19
+ * `const f = () => <literal>` (hono's `sidebar: { '/': sidebars() }`)
20
+ * - wrapper calls with a single literal argument (`defineConfig({…})`)
21
+ * - member access into an already-evaluated object (`shared.themeConfig`)
22
+ * - TS noise: type annotations, `as const`, `as T`, `satisfies T`, generics
23
+ *
24
+ * Anything else evaluates to the `UNRESOLVED` sentinel — never to a plausible
25
+ * wrong value and never to a silent omission. Callers report what they could
26
+ * not read (`EvalResult.unresolved`), because a sidebar that quietly lost a
27
+ * section looks exactly like a sidebar that never had one.
28
+ *
29
+ * The parser never desyncs: an expression it does not understand is skipped
30
+ * by balancing delimiters, so the surrounding object continues to parse.
31
+ */
32
+ /** Sentinel for an expression this evaluator cannot read. */
33
+ export declare const UNRESOLVED: unique symbol;
34
+ export type LiteralValue = string | number | boolean | null | typeof UNRESOLVED | LiteralValue[] | {
35
+ [key: string]: LiteralValue;
36
+ };
37
+ export interface EvalResult {
38
+ /** The module's default export, evaluated as far as possible. */
39
+ value: LiteralValue;
40
+ /** Human-readable descriptions of expressions that could not be read. */
41
+ unresolved: string[];
42
+ }
43
+ /**
44
+ * Evaluate a module's default export as far as the literal subset allows.
45
+ *
46
+ * Falls back to the binding named by `fallbackExport` (default `config`) when
47
+ * there is no `export default`, which covers
48
+ * `const config = { … }; export { config }`.
49
+ */
50
+ export declare function evaluateModule(source: string, fallbackExport?: string): EvalResult;
51
+ /** Narrowing helper: a plain object with no UNRESOLVED identity. */
52
+ export declare function asObject(v: LiteralValue): Record<string, LiteralValue> | undefined;
53
+ export declare function asArray(v: LiteralValue): LiteralValue[] | undefined;
54
+ export declare function asString(v: LiteralValue): string | undefined;
55
+ //# sourceMappingURL=literal.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"literal.d.ts","sourceRoot":"","sources":["../src/literal.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AAEH,6DAA6D;AAC7D,eAAO,MAAM,UAAU,eAAiC,CAAC;AAEzD,MAAM,MAAM,YAAY,GACpB,MAAM,GACN,MAAM,GACN,OAAO,GACP,IAAI,GACJ,OAAO,UAAU,GACjB,YAAY,EAAE,GACd;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,YAAY,CAAA;CAAE,CAAC;AAEpC,MAAM,WAAW,UAAU;IACzB,iEAAiE;IACjE,KAAK,EAAE,YAAY,CAAC;IACpB,yEAAyE;IACzE,UAAU,EAAE,MAAM,EAAE,CAAC;CACtB;AAuxBD;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,EAAE,cAAc,SAAW,GAAG,UAAU,CAQpF;AAED,oEAAoE;AACpE,wBAAgB,QAAQ,CAAC,CAAC,EAAE,YAAY,GAAG,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,GAAG,SAAS,CAKlF;AAED,wBAAgB,OAAO,CAAC,CAAC,EAAE,YAAY,GAAG,YAAY,EAAE,GAAG,SAAS,CAEnE;AAED,wBAAgB,QAAQ,CAAC,CAAC,EAAE,YAAY,GAAG,MAAM,GAAG,SAAS,CAE5D"}