docmedown 0.1.0 → 0.1.1

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.
Files changed (32) hide show
  1. package/README.md +31 -0
  2. package/dist/cli.js +665 -507
  3. package/dist/docmedown.cjs +105 -41
  4. package/dist/docmedown.iife.js +106 -42
  5. package/dist/docmedown.mjs +7753 -4477
  6. package/dist/types/runtime/app.d.ts +3 -3
  7. package/dist/types/runtime/components/Builtins.d.ts +3 -3
  8. package/dist/types/runtime/components/Content.d.ts +1 -1
  9. package/dist/types/runtime/components/DmdRegistry.d.ts +1 -1
  10. package/dist/types/runtime/components/Layout.d.ts +1 -1
  11. package/dist/types/runtime/components/Navbar.d.ts +1 -1
  12. package/dist/types/runtime/components/Sidebar.d.ts +1 -1
  13. package/dist/types/runtime/components/TableOfContents.d.ts +2 -2
  14. package/dist/types/runtime/config-schema.d.ts +344 -0
  15. package/dist/types/runtime/config.d.ts +10 -3
  16. package/dist/types/runtime/index.d.ts +6 -5
  17. package/dist/types/runtime/loader/auto-indexer.d.ts +1 -1
  18. package/dist/types/runtime/loader/local-loader.d.ts +1 -1
  19. package/dist/types/runtime/loader/remote-github.d.ts +2 -2
  20. package/dist/types/runtime/loader/remote-gitlab.d.ts +2 -2
  21. package/dist/types/runtime/markdown/callouts.d.ts +1 -1
  22. package/dist/types/runtime/markdown/highlighter.d.ts +16 -16
  23. package/dist/types/runtime/markdown/parser.d.ts +1 -1
  24. package/dist/types/runtime/markdown/renderer.d.ts +1 -1
  25. package/dist/types/runtime/provider/DocProvider.d.ts +5 -5
  26. package/dist/types/runtime/provider/ThemeProvider.d.ts +3 -3
  27. package/dist/types/runtime/search/SearchModal.d.ts +2 -2
  28. package/dist/types/runtime/search/search-index.d.ts +1 -1
  29. package/dist/types/runtime/types.d.ts +25 -99
  30. package/package.json +11 -3
  31. package/schemas/docs.schema.json +157 -0
  32. package/templates/docs.json +1 -0
package/dist/cli.js CHANGED
@@ -24,34 +24,319 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
24
24
  ));
25
25
 
26
26
  // src/cli/index.ts
27
+ var import_node_fs7 = __toESM(require("fs"));
28
+ var import_node_path7 = __toESM(require("path"));
27
29
  var import_commander = require("commander");
28
- var import_fs7 = __toESM(require("fs"));
29
- var import_path7 = __toESM(require("path"));
30
30
 
31
- // src/cli/commands/init.ts
32
- var import_fs4 = __toESM(require("fs"));
33
- var import_path4 = __toESM(require("path"));
34
- var import_chalk3 = __toESM(require("chalk"));
35
- var import_prompts = __toESM(require("prompts"));
36
-
37
- // src/cli/utils/server.ts
38
- var import_http = __toESM(require("http"));
39
- var import_fs3 = __toESM(require("fs"));
40
- var import_path3 = __toESM(require("path"));
41
- var import_mime_types = __toESM(require("mime-types"));
42
- var import_ws = require("ws");
43
- var import_chokidar2 = __toESM(require("chokidar"));
44
- var import_chalk2 = __toESM(require("chalk"));
31
+ // package.json
32
+ var package_default = {
33
+ name: "docmedown",
34
+ version: "0.1.1",
35
+ description: "The simplest MarkDown documenter yet. CLI & Web Script React SPA documentation engine.",
36
+ main: "./dist/docmedown.cjs",
37
+ module: "./dist/docmedown.mjs",
38
+ types: "./dist/types/runtime/index.d.ts",
39
+ exports: {
40
+ ".": {
41
+ types: "./dist/types/runtime/index.d.ts",
42
+ import: "./dist/docmedown.mjs",
43
+ require: "./dist/docmedown.cjs"
44
+ },
45
+ "./iife": "./dist/docmedown.iife.js"
46
+ },
47
+ unpkg: "./dist/docmedown.iife.js",
48
+ jsdelivr: "./dist/docmedown.iife.js",
49
+ bin: {
50
+ docmedown: "bin/docmedown.js",
51
+ dmd: "bin/docmedown.js"
52
+ },
53
+ files: [
54
+ "dist",
55
+ "bin",
56
+ "templates",
57
+ "schemas",
58
+ "README.md",
59
+ "LICENSE"
60
+ ],
61
+ scripts: {
62
+ "dev:runtime": "vite build --watch",
63
+ "build:runtime": "vite build",
64
+ "build:cli": "tsup",
65
+ typecheck: "tsc --noEmit",
66
+ lint: "biome check .",
67
+ "lint:fix": "biome check --write .",
68
+ format: "biome format --write .",
69
+ "build:types": "tsc -p tsconfig.runtime.json",
70
+ build: "npm run build:runtime && npm run build:cli && npm run build:types",
71
+ docmedown: "node ./bin/docmedown.js",
72
+ dmd: "node ./bin/docmedown.js",
73
+ "init:docs": "node ./bin/docmedown.js init",
74
+ serve: "node ./bin/docmedown.js serve ./docs",
75
+ dev: "node ./bin/docmedown.js serve ./docs",
76
+ "build:docs": "node ./bin/docmedown.js build ./docs",
77
+ "build:docs:watch": "node ./bin/docmedown.js build ./docs --watch",
78
+ "build:offline": "node ./bin/docmedown.js build ./docs",
79
+ "config:docs": "node ./bin/docmedown.js config ./docs/docs.json",
80
+ test: "npx tsx --test tests/parser.test.ts tests/scanner.test.ts tests/runtime-integration.test.ts tests/package-smoke.test.ts",
81
+ "test:release": "npm run typecheck && npm run lint && npm run test && npm run build && npm run build:docs && npm pack --dry-run",
82
+ deploy: "node ./scripts/deploy.mjs",
83
+ "deploy:dry-run": "npm run deploy -- --dry-run",
84
+ prepublishOnly: "npm run test:release"
85
+ },
86
+ keywords: [
87
+ "markdown",
88
+ "documentation",
89
+ "docs",
90
+ "docusaurus",
91
+ "docsify",
92
+ "react",
93
+ "spa",
94
+ "cli",
95
+ "offline-docs",
96
+ "github-docs"
97
+ ],
98
+ author: "Gabriel M. Silva",
99
+ license: "MIT",
100
+ engines: {
101
+ node: ">=20.19.0"
102
+ },
103
+ repository: {
104
+ type: "git",
105
+ url: "git+https://github.com/gabrielmsilva00/docmedown.git"
106
+ },
107
+ bugs: {
108
+ url: "https://github.com/gabrielmsilva00/docmedown/issues"
109
+ },
110
+ homepage: "https://github.com/gabrielmsilva00/docmedown#readme",
111
+ packageManager: "npm@11.16.0",
112
+ overrides: {
113
+ tsup: {
114
+ esbuild: "0.28.2"
115
+ }
116
+ },
117
+ dependencies: {
118
+ chalk: "^4.1.2",
119
+ chokidar: "^3.6.0",
120
+ commander: "^12.1.0",
121
+ "gray-matter": "^4.0.3",
122
+ "mime-types": "^2.1.35",
123
+ open: "^10.1.0",
124
+ prompts: "^2.4.2",
125
+ ws: "^8.18.0",
126
+ zod: "^4.4.3"
127
+ },
128
+ devDependencies: {
129
+ "@biomejs/biome": "^2.5.10",
130
+ "@types/node": "^22.5.0",
131
+ "@types/prismjs": "^1.26.6",
132
+ "@types/prompts": "^2.4.9",
133
+ "@types/react": "^18.3.5",
134
+ "@types/react-dom": "^18.3.0",
135
+ "@types/ws": "^8.5.12",
136
+ "@vitejs/plugin-react": "^6.1.0",
137
+ katex: "^0.16.11",
138
+ marked: "^14.1.1",
139
+ minisearch: "^7.1.0",
140
+ prismjs: "^1.29.0",
141
+ react: "^18.3.1",
142
+ "react-dom": "^18.3.1",
143
+ tsup: "^8.2.4",
144
+ tsx: "^4.19.0",
145
+ typescript: "^5.5.4",
146
+ vite: "^8.2.2",
147
+ "vite-plugin-css-injected-by-js": "^5.0.2"
148
+ }
149
+ };
45
150
 
46
151
  // src/cli/commands/build.ts
47
- var import_fs2 = __toESM(require("fs"));
48
- var import_path2 = __toESM(require("path"));
152
+ var import_node_fs2 = __toESM(require("fs"));
153
+ var import_node_path2 = __toESM(require("path"));
49
154
  var import_chalk = __toESM(require("chalk"));
50
155
  var import_chokidar = __toESM(require("chokidar"));
51
156
 
157
+ // src/runtime/config-schema.ts
158
+ var import_zod = require("zod");
159
+ var nonEmptyString = import_zod.z.string().trim().min(1, "Must not be empty.");
160
+ var themePresetSchema = import_zod.z.enum(["indigo", "emerald", "sunset", "violet", "rose", "slate", "cyberpunk"]);
161
+ var colorModeSchema = import_zod.z.enum(["light", "dark", "auto"]);
162
+ var socialTypeSchema = import_zod.z.enum(["github", "gitlab", "twitter", "x", "discord", "custom"]);
163
+ var badgeTypeSchema = import_zod.z.enum(["info", "success", "warning", "new"]);
164
+ var navLinkSchema = import_zod.z.object({
165
+ label: nonEmptyString,
166
+ href: nonEmptyString,
167
+ external: import_zod.z.boolean().optional(),
168
+ icon: import_zod.z.string().optional()
169
+ }).strict();
170
+ var socialLinkSchema = import_zod.z.object({
171
+ type: socialTypeSchema,
172
+ url: import_zod.z.string().url("Must be an absolute URL."),
173
+ label: import_zod.z.string().optional(),
174
+ icon: import_zod.z.string().optional()
175
+ }).strict();
176
+ var remoteSourceSchema = import_zod.z.discriminatedUnion("type", [
177
+ import_zod.z.object({
178
+ type: import_zod.z.literal("github"),
179
+ repo: nonEmptyString.regex(/^[^/\s]+\/[^/\s]+$/, "Use the owner/repository format."),
180
+ branch: nonEmptyString.optional(),
181
+ docsDir: import_zod.z.string().optional(),
182
+ token: import_zod.z.string().optional(),
183
+ baseUrl: import_zod.z.string().url("Must be an absolute URL.").optional()
184
+ }).strict(),
185
+ import_zod.z.object({
186
+ type: import_zod.z.literal("gitlab"),
187
+ repo: nonEmptyString.regex(/^[^/\s]+\/[^/\s]+$/, "Use the namespace/repository format."),
188
+ branch: nonEmptyString.optional(),
189
+ docsDir: import_zod.z.string().optional(),
190
+ token: import_zod.z.string().optional(),
191
+ baseUrl: import_zod.z.string().url("Must be an absolute URL.").optional()
192
+ }).strict(),
193
+ import_zod.z.object({
194
+ type: import_zod.z.literal("raw"),
195
+ baseUrl: import_zod.z.string().url("Must be an absolute URL."),
196
+ branch: nonEmptyString.optional(),
197
+ docsDir: import_zod.z.string().optional(),
198
+ token: import_zod.z.string().optional()
199
+ }).strict()
200
+ ]);
201
+ var sidebarItemSchema = import_zod.z.lazy(
202
+ () => import_zod.z.object({
203
+ title: import_zod.z.string().optional(),
204
+ path: import_zod.z.string().optional(),
205
+ slug: import_zod.z.string().optional(),
206
+ icon: import_zod.z.string().optional(),
207
+ badge: import_zod.z.string().optional(),
208
+ badgeType: badgeTypeSchema.optional(),
209
+ collapsed: import_zod.z.boolean().optional(),
210
+ children: import_zod.z.array(sidebarItemSchema).optional()
211
+ }).strict()
212
+ );
213
+ var docThemeConfigSchema = import_zod.z.object({
214
+ preset: themePresetSchema.optional(),
215
+ defaultMode: colorModeSchema.optional(),
216
+ accentColor: import_zod.z.string().optional(),
217
+ accentColorDark: import_zod.z.string().optional(),
218
+ fontFamily: import_zod.z.string().optional(),
219
+ codeTheme: import_zod.z.enum(["github", "dracula", "one-dark", "synthwave"]).optional(),
220
+ logo: import_zod.z.object({
221
+ light: import_zod.z.string().optional(),
222
+ dark: import_zod.z.string().optional(),
223
+ alt: import_zod.z.string().optional(),
224
+ text: import_zod.z.string().optional()
225
+ }).strict().optional(),
226
+ favicon: import_zod.z.string().optional()
227
+ }).strict();
228
+ var docSearchConfigSchema = import_zod.z.object({
229
+ enabled: import_zod.z.boolean().optional(),
230
+ placeholder: import_zod.z.string().optional(),
231
+ maxResults: import_zod.z.number().int().positive().max(100).optional()
232
+ }).strict();
233
+ var docConfigSchema = import_zod.z.object({
234
+ $schema: import_zod.z.string().url("Must be an absolute URL.").optional(),
235
+ name: nonEmptyString.optional(),
236
+ tagline: import_zod.z.string().optional(),
237
+ description: import_zod.z.string().optional(),
238
+ version: import_zod.z.string().optional(),
239
+ rootDoc: nonEmptyString.optional(),
240
+ source: remoteSourceSchema.optional(),
241
+ theme: docThemeConfigSchema.optional(),
242
+ nav: import_zod.z.array(navLinkSchema).optional(),
243
+ socials: import_zod.z.array(socialLinkSchema).optional(),
244
+ sidebar: import_zod.z.array(sidebarItemSchema).optional(),
245
+ autoIndex: import_zod.z.object({
246
+ enabled: import_zod.z.boolean().optional(),
247
+ exclude: import_zod.z.array(nonEmptyString).optional(),
248
+ sort: import_zod.z.enum(["alphabetical", "frontmatter", "natural"]).optional(),
249
+ defaultCollapsed: import_zod.z.boolean().optional()
250
+ }).strict().optional(),
251
+ search: docSearchConfigSchema.optional(),
252
+ footer: import_zod.z.object({
253
+ copyright: import_zod.z.string().optional(),
254
+ links: import_zod.z.array(navLinkSchema).optional(),
255
+ showBuiltWith: import_zod.z.boolean().optional()
256
+ }).strict().optional(),
257
+ componentsUrl: import_zod.z.string().optional(),
258
+ editUrl: import_zod.z.string().optional()
259
+ }).strict();
260
+ var normalizedDocConfigSchema = docConfigSchema.extend({
261
+ name: nonEmptyString
262
+ });
263
+ function formatConfigIssues(error) {
264
+ return error.issues.map((issue) => `${issue.path.length > 0 ? issue.path.join(".") : "config"}: ${issue.message}`).join("\n");
265
+ }
266
+ function parseDocConfig(input) {
267
+ const result = docConfigSchema.safeParse(input);
268
+ if (result.success) return result.data;
269
+ throw new Error(`Invalid DocMeDown configuration:
270
+ ${formatConfigIssues(result.error)}`);
271
+ }
272
+
273
+ // src/runtime/config.ts
274
+ var DEFAULT_CONFIG = {
275
+ name: "DocMeDown",
276
+ tagline: "The simplest Markdown documenter yet",
277
+ description: "Instant documentation site powered by DocMeDown",
278
+ version: "1.0.0",
279
+ rootDoc: "README.md",
280
+ theme: {
281
+ preset: "indigo",
282
+ defaultMode: "auto",
283
+ codeTheme: "github"
284
+ },
285
+ autoIndex: {
286
+ enabled: true,
287
+ sort: "natural",
288
+ defaultCollapsed: false,
289
+ exclude: ["node_modules", ".git", ".dmd", "dist", "bin", "package.json", "tsconfig.json"]
290
+ },
291
+ search: {
292
+ enabled: true,
293
+ placeholder: "Search documentation...",
294
+ maxResults: 10
295
+ },
296
+ footer: {
297
+ copyright: `\xA9 ${(/* @__PURE__ */ new Date()).getFullYear()} DocMeDown. All rights reserved.`,
298
+ showBuiltWith: true
299
+ }
300
+ };
301
+ function normalizeConfig(userConfig = {}) {
302
+ const parsedConfig = parseDocConfig(userConfig);
303
+ const mergedConfig = {
304
+ ...DEFAULT_CONFIG,
305
+ ...parsedConfig,
306
+ theme: {
307
+ ...DEFAULT_CONFIG.theme,
308
+ ...parsedConfig.theme,
309
+ logo: {
310
+ ...DEFAULT_CONFIG.theme?.logo,
311
+ ...parsedConfig.theme?.logo
312
+ }
313
+ },
314
+ autoIndex: {
315
+ ...DEFAULT_CONFIG.autoIndex,
316
+ ...parsedConfig.autoIndex
317
+ },
318
+ search: {
319
+ ...DEFAULT_CONFIG.search,
320
+ ...parsedConfig.search
321
+ },
322
+ footer: {
323
+ ...DEFAULT_CONFIG.footer,
324
+ ...parsedConfig.footer
325
+ }
326
+ };
327
+ return normalizedDocConfigSchema.parse(mergedConfig);
328
+ }
329
+ function parseDocConfigJson(json, source) {
330
+ try {
331
+ return parseDocConfig(JSON.parse(json));
332
+ } catch (error) {
333
+ throw new Error(`${source}: ${error instanceof Error ? error.message : String(error)}`);
334
+ }
335
+ }
336
+
52
337
  // src/cli/utils/scanner.ts
53
- var import_fs = __toESM(require("fs"));
54
- var import_path = __toESM(require("path"));
338
+ var import_node_fs = __toESM(require("fs"));
339
+ var import_node_path = __toESM(require("path"));
55
340
  var import_gray_matter = __toESM(require("gray-matter"));
56
341
 
57
342
  // src/runtime/loader/auto-indexer.ts
@@ -181,16 +466,16 @@ function extractHeadings(content) {
181
466
  }
182
467
  function scanDirectory(dir, baseDir = dir, excludeList = ["node_modules", ".git", ".dmd", "dist", "bin"], stopAtNestedDocsRoots = true) {
183
468
  const results = [];
184
- if (!import_fs.default.existsSync(dir)) return results;
185
- const entries = import_fs.default.readdirSync(dir, { withFileTypes: true });
469
+ if (!import_node_fs.default.existsSync(dir)) return results;
470
+ const entries = import_node_fs.default.readdirSync(dir, { withFileTypes: true });
186
471
  for (const entry of entries) {
187
472
  if (excludeList.includes(entry.name) || entry.name.startsWith(".")) {
188
473
  continue;
189
474
  }
190
- const fullPath = import_path.default.join(dir, entry.name);
191
- const relPath = import_path.default.relative(baseDir, fullPath).replace(/\\/g, "/");
475
+ const fullPath = import_node_path.default.join(dir, entry.name);
476
+ const relPath = import_node_path.default.relative(baseDir, fullPath).replace(/\\/g, "/");
192
477
  if (entry.isDirectory()) {
193
- const isNestedDocsRoot = stopAtNestedDocsRoots && fullPath !== baseDir && import_fs.default.existsSync(import_path.default.join(fullPath, "docs.json"));
478
+ const isNestedDocsRoot = stopAtNestedDocsRoots && fullPath !== baseDir && import_node_fs.default.existsSync(import_node_path.default.join(fullPath, "docs.json"));
194
479
  if (!isNestedDocsRoot) {
195
480
  results.push(...scanDirectory(fullPath, baseDir, excludeList, stopAtNestedDocsRoots));
196
481
  }
@@ -205,13 +490,13 @@ function generateManifest(docDir, config) {
205
490
  const docItems = [];
206
491
  const frontmatters = {};
207
492
  for (const relFile of files) {
208
- const fullPath = import_path.default.join(docDir, relFile);
209
- const raw = import_fs.default.readFileSync(fullPath, "utf-8");
493
+ const fullPath = import_node_path.default.join(docDir, relFile);
494
+ const raw = import_node_fs.default.readFileSync(fullPath, "utf-8");
210
495
  const { data: fm, content } = (0, import_gray_matter.default)(raw);
211
496
  const cleanSlug = relFile.replace(/\.(md|mdx)$/i, "");
212
497
  const isOverview = cleanSlug.toLowerCase() === "readme" || cleanSlug.toLowerCase() === "index";
213
498
  const slug = isOverview ? "README" : cleanSlug;
214
- const title = fm.title || fm.sidebar_label || formatTitleFromFilename(import_path.default.basename(relFile));
499
+ const title = fm.title || fm.sidebar_label || formatTitleFromFilename(import_node_path.default.basename(relFile));
215
500
  frontmatters[relFile] = fm;
216
501
  const headings = extractHeadings(content);
217
502
  const words = content.trim().split(/\s+/).length;
@@ -225,7 +510,7 @@ function generateManifest(docDir, config) {
225
510
  headings,
226
511
  content,
227
512
  readingTimeMinutes,
228
- lastModified: import_fs.default.statSync(fullPath).mtime.toISOString()
513
+ lastModified: import_node_fs.default.statSync(fullPath).mtime.toISOString()
229
514
  });
230
515
  }
231
516
  const tree = buildSidebarTree(files, frontmatters, config.sidebar);
@@ -238,41 +523,12 @@ function generateManifest(docDir, config) {
238
523
  };
239
524
  }
240
525
 
241
- // src/runtime/config.ts
242
- var DEFAULT_CONFIG = {
243
- name: "DocMeDown",
244
- tagline: "The simplest Markdown documenter yet",
245
- description: "Instant documentation site powered by DocMeDown",
246
- version: "1.0.0",
247
- rootDoc: "README.md",
248
- theme: {
249
- preset: "indigo",
250
- defaultMode: "auto",
251
- codeTheme: "github"
252
- },
253
- autoIndex: {
254
- enabled: true,
255
- sort: "natural",
256
- defaultCollapsed: false,
257
- exclude: ["node_modules", ".git", ".dmd", "dist", "bin", "package.json", "tsconfig.json"]
258
- },
259
- search: {
260
- enabled: true,
261
- placeholder: "Search documentation...",
262
- maxResults: 10
263
- },
264
- footer: {
265
- copyright: `\xA9 ${(/* @__PURE__ */ new Date()).getFullYear()} DocMeDown. All rights reserved.`,
266
- showBuiltWith: true
267
- }
268
- };
269
-
270
526
  // src/cli/commands/build.ts
271
527
  var DEFAULT_OFFLINE_OUTPUT_DIRECTORY = ".dist";
272
528
  function getBuildOutputPaths(targetDir, offlineOutDir) {
273
529
  return {
274
530
  onlineDir: targetDir,
275
- offlineDir: offlineOutDir ? import_path2.default.resolve(process.cwd(), offlineOutDir) : import_path2.default.join(targetDir, DEFAULT_OFFLINE_OUTPUT_DIRECTORY)
531
+ offlineDir: offlineOutDir ? import_node_path2.default.resolve(process.cwd(), offlineOutDir) : import_node_path2.default.join(targetDir, DEFAULT_OFFLINE_OUTPUT_DIRECTORY)
276
532
  };
277
533
  }
278
534
  function encodeOfflinePayload(value) {
@@ -288,13 +544,13 @@ var GENERATED_DOC_OUTPUTS = ["_manifest.json", "_docs.js", "docmedown.iife.js"];
288
544
  function findNestedDocumentationRoots(targetDir) {
289
545
  const roots = [];
290
546
  function visit(directory) {
291
- if (!import_fs2.default.existsSync(directory)) return;
292
- for (const entry of import_fs2.default.readdirSync(directory, { withFileTypes: true })) {
547
+ if (!import_node_fs2.default.existsSync(directory)) return;
548
+ for (const entry of import_node_fs2.default.readdirSync(directory, { withFileTypes: true })) {
293
549
  if (!entry.isDirectory() || entry.name.startsWith(".") || ["node_modules", ".git", "dist", "bin"].includes(entry.name)) {
294
550
  continue;
295
551
  }
296
- const fullPath = import_path2.default.join(directory, entry.name);
297
- if (import_fs2.default.existsSync(import_path2.default.join(fullPath, "docs.json"))) {
552
+ const fullPath = import_node_path2.default.join(directory, entry.name);
553
+ if (import_node_fs2.default.existsSync(import_node_path2.default.join(fullPath, "docs.json"))) {
298
554
  roots.push(fullPath);
299
555
  visit(fullPath);
300
556
  } else {
@@ -306,68 +562,68 @@ function findNestedDocumentationRoots(targetDir) {
306
562
  return roots;
307
563
  }
308
564
  function shouldWatchDocumentationSource(rootDir, changedPath) {
309
- const relativePath = import_path2.default.relative(rootDir, changedPath).replace(/\\/g, "/");
565
+ const relativePath = import_node_path2.default.relative(rootDir, changedPath).replace(/\\/g, "/");
310
566
  const firstSegment = relativePath.split("/")[0];
311
567
  const isCustomComponentModule = /(^|\/)\.dmd\/(components|index)\.js$/i.test(relativePath);
312
568
  return Boolean(relativePath) && !relativePath.startsWith("..") && (!relativePath.startsWith(".") || isCustomComponentModule) && !GENERATED_DOC_OUTPUTS.includes(relativePath) && firstSegment !== "node_modules" && firstSegment !== "dist";
313
569
  }
314
570
  async function buildCommand(targetDirArg = "./docs", options = {}) {
315
- const targetDir = import_path2.default.resolve(process.cwd(), targetDirArg);
571
+ const targetDir = import_node_path2.default.resolve(process.cwd(), targetDirArg);
316
572
  const { onlineDir, offlineDir } = getBuildOutputPaths(targetDir, options.outDir);
317
573
  const buildOfflineBundle = options.singleFile !== false;
318
574
  console.log(import_chalk.default.bold.magenta("\n\u26A1 DocMeDown Build\n"));
319
- if (!import_fs2.default.existsSync(targetDir)) {
575
+ if (!import_node_fs2.default.existsSync(targetDir)) {
320
576
  console.error(import_chalk.default.red(`\u2716 Directory not found: ${targetDir}`));
321
577
  process.exit(1);
322
578
  }
323
- if (!import_fs2.default.existsSync(onlineDir)) {
324
- import_fs2.default.mkdirSync(onlineDir, { recursive: true });
579
+ if (!import_node_fs2.default.existsSync(onlineDir)) {
580
+ import_node_fs2.default.mkdirSync(onlineDir, { recursive: true });
325
581
  }
326
- if (buildOfflineBundle && !import_fs2.default.existsSync(offlineDir)) {
327
- import_fs2.default.mkdirSync(offlineDir, { recursive: true });
582
+ if (buildOfflineBundle && !import_node_fs2.default.existsSync(offlineDir)) {
583
+ import_node_fs2.default.mkdirSync(offlineDir, { recursive: true });
328
584
  }
329
- let config = DEFAULT_CONFIG;
330
- const configPath = import_path2.default.join(targetDir, "docs.json");
331
- if (import_fs2.default.existsSync(configPath)) {
585
+ let config = normalizeConfig();
586
+ const configPath = import_node_path2.default.join(targetDir, "docs.json");
587
+ if (import_node_fs2.default.existsSync(configPath)) {
332
588
  try {
333
- config = { ...DEFAULT_CONFIG, ...JSON.parse(import_fs2.default.readFileSync(configPath, "utf-8")) };
334
- } catch (err) {
335
- console.warn(import_chalk.default.yellow(`\u26A0 Could not parse docs.json, using defaults.`));
589
+ config = normalizeConfig(parseDocConfigJson(import_node_fs2.default.readFileSync(configPath, "utf-8"), configPath));
590
+ } catch (error) {
591
+ throw new Error(`Could not validate ${configPath}: ${error instanceof Error ? error.message : String(error)}`);
336
592
  }
337
593
  }
338
594
  console.log(import_chalk.default.cyan(" Indexing documentation pages..."));
339
595
  const manifest = generateManifest(targetDir, config);
340
- const manifestPath = import_path2.default.join(onlineDir, "_manifest.json");
341
- import_fs2.default.writeFileSync(manifestPath, JSON.stringify(manifest, null, 2), "utf-8");
596
+ const manifestPath = import_node_path2.default.join(onlineDir, "_manifest.json");
597
+ import_node_fs2.default.writeFileSync(manifestPath, JSON.stringify(manifest, null, 2), "utf-8");
342
598
  console.log(import_chalk.default.green(` \u2714 Generated _manifest.json (${manifest.docs.length} pages indexed)`));
343
599
  const docsMap = {};
344
600
  const files = scanDirectory(targetDir);
345
601
  for (const file of files) {
346
- const full = import_path2.default.join(targetDir, file);
347
- const raw = import_fs2.default.readFileSync(full, "utf-8");
602
+ const full = import_node_path2.default.join(targetDir, file);
603
+ const raw = import_node_fs2.default.readFileSync(full, "utf-8");
348
604
  const slug = file.replace(/\.(md|mdx)$/i, "");
349
605
  const cleanSlug = slug.toLowerCase() === "readme" || slug.toLowerCase() === "index" ? "README" : slug;
350
606
  docsMap[cleanSlug] = raw;
351
607
  docsMap[file] = raw;
352
608
  }
353
- const componentsPath = import_path2.default.join(targetDir, ".dmd", "components.js");
354
- const componentsSource = import_fs2.default.existsSync(componentsPath) ? import_fs2.default.readFileSync(componentsPath, "utf-8") : void 0;
609
+ const componentsPath = import_node_path2.default.join(targetDir, ".dmd", "components.js");
610
+ const componentsSource = import_node_fs2.default.existsSync(componentsPath) ? import_node_fs2.default.readFileSync(componentsPath, "utf-8") : void 0;
355
611
  const docsJsContent = `window.__DOCMEDOWN_DATA__ = ${JSON.stringify({ manifest, docs: docsMap, componentsSource }, null, 2)};
356
612
  `;
357
- const docsJsPath = import_path2.default.join(onlineDir, "_docs.js");
358
- import_fs2.default.writeFileSync(docsJsPath, docsJsContent, "utf-8");
613
+ const docsJsPath = import_node_path2.default.join(onlineDir, "_docs.js");
614
+ import_node_fs2.default.writeFileSync(docsJsPath, docsJsContent, "utf-8");
359
615
  console.log(import_chalk.default.green(` \u2714 Generated _docs.js for offline file:/// double-click usage`));
360
616
  if (buildOfflineBundle) {
361
617
  console.log(import_chalk.default.cyan("\n Compiling standalone single-file offline index.html..."));
362
618
  const candidates2 = [
363
- import_path2.default.resolve(__dirname, "docmedown.iife.js"),
364
- import_path2.default.resolve(__dirname, "../dist/docmedown.iife.js"),
365
- import_path2.default.resolve(__dirname, "../docmedown.iife.js")
619
+ import_node_path2.default.resolve(__dirname, "docmedown.iife.js"),
620
+ import_node_path2.default.resolve(__dirname, "../dist/docmedown.iife.js"),
621
+ import_node_path2.default.resolve(__dirname, "../docmedown.iife.js")
366
622
  ];
367
- const distIifePath2 = candidates2.find((p) => import_fs2.default.existsSync(p));
623
+ const distIifePath2 = candidates2.find((p) => import_node_fs2.default.existsSync(p));
368
624
  let bundleJs = "";
369
625
  if (distIifePath2) {
370
- bundleJs = import_fs2.default.readFileSync(distIifePath2, "utf-8");
626
+ bundleJs = import_node_fs2.default.readFileSync(distIifePath2, "utf-8");
371
627
  } else {
372
628
  console.warn(import_chalk.default.yellow(" \u26A0 Local runtime bundle not found, linking CDN script."));
373
629
  }
@@ -403,35 +659,35 @@ ${safeBundleJs}
403
659
  </script>
404
660
  </body>
405
661
  </html>`;
406
- const singleFilePath = import_path2.default.join(offlineDir, "index.html");
407
- import_fs2.default.writeFileSync(singleFilePath, singleFileHtml, "utf-8");
662
+ const singleFilePath = import_node_path2.default.join(offlineDir, "index.html");
663
+ import_node_fs2.default.writeFileSync(singleFilePath, singleFileHtml, "utf-8");
408
664
  console.log(import_chalk.default.bold.green(` \u2714 Built self-contained offline bundle: ${singleFilePath}`));
409
665
  console.log(import_chalk.default.dim(` You can now double-click index.html to view offline without any server!
410
666
  `));
411
667
  }
412
668
  const candidates = [
413
- import_path2.default.resolve(__dirname, "docmedown.iife.js"),
414
- import_path2.default.resolve(__dirname, "../dist/docmedown.iife.js"),
415
- import_path2.default.resolve(__dirname, "../docmedown.iife.js")
669
+ import_node_path2.default.resolve(__dirname, "docmedown.iife.js"),
670
+ import_node_path2.default.resolve(__dirname, "../dist/docmedown.iife.js"),
671
+ import_node_path2.default.resolve(__dirname, "../docmedown.iife.js")
416
672
  ];
417
- const distIifePath = candidates.find((p) => import_fs2.default.existsSync(p));
418
- const targetBundlePath = import_path2.default.join(onlineDir, "docmedown.iife.js");
673
+ const distIifePath = candidates.find((p) => import_node_fs2.default.existsSync(p));
674
+ const targetBundlePath = import_node_path2.default.join(onlineDir, "docmedown.iife.js");
419
675
  if (distIifePath) {
420
- import_fs2.default.copyFileSync(distIifePath, targetBundlePath);
676
+ import_node_fs2.default.copyFileSync(distIifePath, targetBundlePath);
421
677
  console.log(import_chalk.default.green(` \u2714 Updated serveable runtime: ${targetBundlePath}`));
422
678
  }
423
679
  if (options.buildNested !== false) {
424
680
  const nestedRoots = findNestedDocumentationRoots(targetDir);
425
681
  for (const nestedRoot of nestedRoots) {
426
682
  console.log(import_chalk.default.cyan(`
427
- Building nested documentation site: ${import_path2.default.relative(targetDir, nestedRoot)}...`));
683
+ Building nested documentation site: ${import_node_path2.default.relative(targetDir, nestedRoot)}...`));
428
684
  await buildCommand(nestedRoot, { buildNested: false });
429
685
  }
430
686
  }
431
687
  console.log(import_chalk.default.bold.green("\u2728 Build completed successfully!\n"));
432
688
  }
433
689
  async function watchBuildCommand(targetDirArg = "./docs", options = {}) {
434
- const targetDir = import_path2.default.resolve(process.cwd(), targetDirArg);
690
+ const targetDir = import_node_path2.default.resolve(process.cwd(), targetDirArg);
435
691
  await buildCommand(targetDir, { ...options, watch: false });
436
692
  console.log(import_chalk.default.dim(` Watching source files in: ${targetDir}`));
437
693
  console.log(import_chalk.default.dim(" Source changes rebuild serveable files and .dist/index.html. Press Ctrl+C to stop.\n"));
@@ -452,7 +708,7 @@ async function watchBuildCommand(targetDirArg = "./docs", options = {}) {
452
708
  if (!shouldWatchDocumentationSource(targetDir, changedPath)) return;
453
709
  if (rebuildTimeout) clearTimeout(rebuildTimeout);
454
710
  rebuildTimeout = setTimeout(async () => {
455
- const relativePath = import_path2.default.relative(targetDir, changedPath);
711
+ const relativePath = import_node_path2.default.relative(targetDir, changedPath);
456
712
  console.log(import_chalk.default.cyan(`[DocMeDown] Changed: ${relativePath} -> Rebuilding documentation...`));
457
713
  try {
458
714
  await buildCommand(targetDir, { ...options, watch: false });
@@ -464,99 +720,261 @@ async function watchBuildCommand(targetDirArg = "./docs", options = {}) {
464
720
  return new Promise(() => void 0);
465
721
  }
466
722
 
467
- // src/cli/utils/server.ts
468
- function shouldRebuildDocumentation(rootDir, changedPath) {
469
- return shouldWatchDocumentationSource(rootDir, changedPath);
470
- }
471
- function startDevServer(options) {
472
- const { rootDir, host = "localhost", port: initialPort = 3e3, onSourceChange } = options;
473
- return new Promise((resolve, reject) => {
474
- let port = initialPort;
475
- const liveReloadScript = `
476
- <script>
477
- (function() {
478
- const protocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:';
479
- let ws = null;
480
- function connect() {
481
- ws = new WebSocket(protocol + '//' + window.location.host + '/__dmd_reload');
482
- ws.onmessage = function(e) {
483
- if (e.data === 'reload') {
484
- console.log('[DocMeDown] File changed, reloading...');
485
- window.location.reload();
486
- }
487
- };
488
- ws.onclose = function() {
489
- setTimeout(connect, 1500);
490
- };
723
+ // src/cli/commands/config-tui.ts
724
+ var import_node_fs3 = __toESM(require("fs"));
725
+ var import_node_path3 = __toESM(require("path"));
726
+ var import_chalk2 = __toESM(require("chalk"));
727
+ var import_prompts = __toESM(require("prompts"));
728
+ async function configTuiCommand(configPathArg) {
729
+ console.log(import_chalk2.default.bold.magenta("\n\u26A1 DocMeDown - Interactive Configuration Wizard\n"));
730
+ let configPath = "";
731
+ if (configPathArg) {
732
+ configPath = import_node_path3.default.resolve(process.cwd(), configPathArg);
733
+ if (import_node_fs3.default.existsSync(configPath) && import_node_fs3.default.statSync(configPath).isDirectory()) {
734
+ configPath = import_node_path3.default.join(configPath, "docs.json");
735
+ }
736
+ } else {
737
+ const candidates = [
738
+ import_node_path3.default.resolve(process.cwd(), "docs.json"),
739
+ import_node_path3.default.resolve(process.cwd(), "docs/docs.json"),
740
+ import_node_path3.default.resolve(process.cwd(), "dmd.json")
741
+ ];
742
+ configPath = candidates.find((p) => import_node_fs3.default.existsSync(p)) || import_node_path3.default.resolve(process.cwd(), "docs/docs.json");
491
743
  }
492
- connect();
493
- })();
494
- </script>
495
- `;
496
- const server = import_http.default.createServer((req, res) => {
497
- res.setHeader("Access-Control-Allow-Origin", "*");
498
- res.setHeader("Access-Control-Allow-Methods", "GET, OPTIONS");
499
- if (req.method === "OPTIONS") {
500
- res.writeHead(204);
501
- res.end();
502
- return;
503
- }
504
- let reqPath = decodeURIComponent(req.url?.split("?")[0] || "/");
505
- if (reqPath === "/" || reqPath === "") {
506
- reqPath = "/index.html";
507
- }
508
- let filePath = import_path3.default.join(rootDir, reqPath);
509
- if (!import_fs3.default.existsSync(filePath) || import_fs3.default.statSync(filePath).isDirectory()) {
510
- const potentialIndex = import_path3.default.join(rootDir, "index.html");
511
- if (import_fs3.default.existsSync(potentialIndex)) {
512
- filePath = potentialIndex;
513
- } else {
514
- res.writeHead(200, { "Content-Type": "text/html" });
515
- res.end(`
516
- <!DOCTYPE html>
517
- <html>
518
- <head><title>DocMeDown</title></head>
519
- <body>
520
- <div id="dmd-app"></div>
521
- <script src="/docmedown.iife.js"></script>
522
- ${liveReloadScript}
523
- </body>
524
- </html>
525
- `);
526
- return;
527
- }
528
- }
529
- if (reqPath === "/docmedown.iife.js" && !import_fs3.default.existsSync(filePath)) {
744
+ let existingConfig = normalizeConfig();
745
+ if (import_node_fs3.default.existsSync(configPath)) {
746
+ try {
747
+ existingConfig = normalizeConfig(parseDocConfigJson(import_node_fs3.default.readFileSync(configPath, "utf-8"), configPath));
748
+ console.log(import_chalk2.default.dim(` Loaded existing configuration from: ${configPath}
749
+ `));
750
+ } catch (error) {
751
+ console.warn(import_chalk2.default.yellow(` \u26A0 ${error instanceof Error ? error.message : String(error)}
752
+ `));
753
+ }
754
+ } else {
755
+ console.log(import_chalk2.default.dim(` Creating new configuration at: ${configPath}
756
+ `));
757
+ }
758
+ const response = await (0, import_prompts.default)([
759
+ {
760
+ type: "text",
761
+ name: "name",
762
+ message: "Project Name:",
763
+ initial: existingConfig.name || "My Project Docs"
764
+ },
765
+ {
766
+ type: "text",
767
+ name: "tagline",
768
+ message: "Tagline / Short description:",
769
+ initial: existingConfig.tagline || "The simplest Markdown documenter yet"
770
+ },
771
+ {
772
+ type: "select",
773
+ name: "preset",
774
+ message: "Select Theme Color Palette:",
775
+ choices: [
776
+ { title: "Indigo (Modern & Clean)", value: "indigo" },
777
+ { title: "Emerald (Fresh & Tech)", value: "emerald" },
778
+ { title: "Sunset (Warm Amber)", value: "sunset" },
779
+ { title: "Violet (Vibrant Purple)", value: "violet" },
780
+ { title: "Rose (Bold Quartz)", value: "rose" },
781
+ { title: "Slate (Minimalist Monochrome)", value: "slate" },
782
+ { title: "Cyberpunk (Neon Glow)", value: "cyberpunk" }
783
+ ],
784
+ initial: ["indigo", "emerald", "sunset", "violet", "rose", "slate", "cyberpunk"].indexOf(
785
+ existingConfig.theme?.preset || "indigo"
786
+ )
787
+ },
788
+ {
789
+ type: "select",
790
+ name: "defaultMode",
791
+ message: "Default Color Mode:",
792
+ choices: [
793
+ { title: "Auto (Follows OS system preference)", value: "auto" },
794
+ { title: "Dark (Default dark theme)", value: "dark" },
795
+ { title: "Light (Default light theme)", value: "light" }
796
+ ],
797
+ initial: ["auto", "dark", "light"].indexOf(existingConfig.theme?.defaultMode || "auto")
798
+ },
799
+ {
800
+ type: "select",
801
+ name: "sourceType",
802
+ message: "Documentation Source Mode:",
803
+ choices: [
804
+ { title: "Local Markdown Files (hosted together in folder)", value: "local" },
805
+ { title: "Remote GitHub Repository (live dynamic fetch)", value: "github" },
806
+ { title: "Remote GitLab Repository (live dynamic fetch)", value: "gitlab" }
807
+ ],
808
+ initial: existingConfig.source?.type ? existingConfig.source.type === "github" ? 1 : 2 : 0
809
+ },
810
+ {
811
+ type: (prev) => prev === "github" ? "text" : null,
812
+ name: "githubRepo",
813
+ message: "GitHub Repository (owner/repo):",
814
+ initial: existingConfig.source?.type === "raw" ? "facebook/react" : existingConfig.source?.repo || "facebook/react"
815
+ },
816
+ {
817
+ type: (_prev, values) => values.sourceType === "github" ? "text" : null,
818
+ name: "githubBranch",
819
+ message: "GitHub Branch:",
820
+ initial: existingConfig.source?.branch || "main"
821
+ },
822
+ {
823
+ type: (_prev, values) => values.sourceType === "github" ? "text" : null,
824
+ name: "githubDocsDir",
825
+ message: "GitHub Docs Subfolder (leave empty for root):",
826
+ initial: existingConfig.source?.docsDir || "docs"
827
+ },
828
+ {
829
+ type: "text",
830
+ name: "githubSocial",
831
+ message: "GitHub Repository URL for Navbar link (optional):",
832
+ initial: existingConfig.socials?.find((s) => s.type === "github")?.url || ""
833
+ }
834
+ ]);
835
+ if (!response.name) {
836
+ console.log(import_chalk2.default.yellow("\nConfiguration cancelled."));
837
+ return;
838
+ }
839
+ const updatedConfig = normalizeConfig({
840
+ ...existingConfig,
841
+ name: response.name,
842
+ tagline: response.tagline,
843
+ theme: {
844
+ ...existingConfig.theme,
845
+ preset: response.preset,
846
+ defaultMode: response.defaultMode
847
+ },
848
+ socials: response.githubSocial ? [{ type: "github", url: response.githubSocial }] : existingConfig.socials
849
+ });
850
+ if (response.sourceType === "github") {
851
+ updatedConfig.source = {
852
+ type: "github",
853
+ repo: response.githubRepo,
854
+ branch: response.githubBranch,
855
+ docsDir: response.githubDocsDir
856
+ };
857
+ } else if (response.sourceType === "local") {
858
+ delete updatedConfig.source;
859
+ }
860
+ const dir = import_node_path3.default.dirname(configPath);
861
+ if (!import_node_fs3.default.existsSync(dir)) {
862
+ import_node_fs3.default.mkdirSync(dir, { recursive: true });
863
+ }
864
+ const validatedConfig = normalizeConfig(updatedConfig);
865
+ import_node_fs3.default.writeFileSync(configPath, JSON.stringify(validatedConfig, null, 2), "utf-8");
866
+ console.log(import_chalk2.default.bold.green(`
867
+ \u2714 Configuration successfully saved to: ${configPath}
868
+ `));
869
+ }
870
+
871
+ // src/cli/commands/init.ts
872
+ var import_node_fs5 = __toESM(require("fs"));
873
+ var import_node_path5 = __toESM(require("path"));
874
+ var import_chalk4 = __toESM(require("chalk"));
875
+ var import_open = __toESM(require("open"));
876
+ var import_prompts2 = __toESM(require("prompts"));
877
+
878
+ // src/cli/utils/server.ts
879
+ var import_node_fs4 = __toESM(require("fs"));
880
+ var import_node_http = __toESM(require("http"));
881
+ var import_node_path4 = __toESM(require("path"));
882
+ var import_chalk3 = __toESM(require("chalk"));
883
+ var import_chokidar2 = __toESM(require("chokidar"));
884
+ var import_mime_types = __toESM(require("mime-types"));
885
+ var import_ws = require("ws");
886
+ function shouldRebuildDocumentation(rootDir, changedPath) {
887
+ return shouldWatchDocumentationSource(rootDir, changedPath);
888
+ }
889
+ function startDevServer(options) {
890
+ const { rootDir, host = "localhost", port: initialPort = 3e3, onSourceChange } = options;
891
+ return new Promise((resolve, reject) => {
892
+ let port = initialPort;
893
+ const liveReloadScript = `
894
+ <script>
895
+ (function() {
896
+ const protocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:';
897
+ let ws = null;
898
+ function connect() {
899
+ ws = new WebSocket(protocol + '//' + window.location.host + '/__dmd_reload');
900
+ ws.onmessage = function(e) {
901
+ if (e.data === 'reload') {
902
+ console.log('[DocMeDown] File changed, reloading...');
903
+ window.location.reload();
904
+ }
905
+ };
906
+ ws.onclose = function() {
907
+ setTimeout(connect, 1500);
908
+ };
909
+ }
910
+ connect();
911
+ })();
912
+ </script>
913
+ `;
914
+ const server = import_node_http.default.createServer((req, res) => {
915
+ res.setHeader("Access-Control-Allow-Origin", "*");
916
+ res.setHeader("Access-Control-Allow-Methods", "GET, OPTIONS");
917
+ if (req.method === "OPTIONS") {
918
+ res.writeHead(204);
919
+ res.end();
920
+ return;
921
+ }
922
+ let reqPath = decodeURIComponent(req.url?.split("?")[0] || "/");
923
+ if (reqPath === "/" || reqPath === "") {
924
+ reqPath = "/index.html";
925
+ }
926
+ let filePath = import_node_path4.default.join(rootDir, reqPath);
927
+ if (!import_node_fs4.default.existsSync(filePath) || import_node_fs4.default.statSync(filePath).isDirectory()) {
928
+ const potentialIndex = import_node_path4.default.join(rootDir, "index.html");
929
+ if (import_node_fs4.default.existsSync(potentialIndex)) {
930
+ filePath = potentialIndex;
931
+ } else {
932
+ res.writeHead(200, { "Content-Type": "text/html" });
933
+ res.end(`
934
+ <!DOCTYPE html>
935
+ <html>
936
+ <head><title>DocMeDown</title></head>
937
+ <body>
938
+ <div id="dmd-app"></div>
939
+ <script src="/docmedown.iife.js"></script>
940
+ ${liveReloadScript}
941
+ </body>
942
+ </html>
943
+ `);
944
+ return;
945
+ }
946
+ }
947
+ if (reqPath === "/docmedown.iife.js" && !import_node_fs4.default.existsSync(filePath)) {
530
948
  const bundleCandidates = [
531
- import_path3.default.resolve(__dirname, "docmedown.iife.js"),
532
- import_path3.default.resolve(__dirname, "../dist/docmedown.iife.js"),
533
- import_path3.default.resolve(__dirname, "../docmedown.iife.js")
949
+ import_node_path4.default.resolve(__dirname, "docmedown.iife.js"),
950
+ import_node_path4.default.resolve(__dirname, "../dist/docmedown.iife.js"),
951
+ import_node_path4.default.resolve(__dirname, "../docmedown.iife.js")
534
952
  ];
535
- const distFile = bundleCandidates.find((p) => import_fs3.default.existsSync(p));
953
+ const distFile = bundleCandidates.find((p) => import_node_fs4.default.existsSync(p));
536
954
  if (distFile) {
537
955
  filePath = distFile;
538
956
  }
539
957
  }
540
958
  try {
541
- const stat = import_fs3.default.statSync(filePath);
959
+ const stat = import_node_fs4.default.statSync(filePath);
542
960
  if (stat.isDirectory()) {
543
- filePath = import_path3.default.join(filePath, "index.html");
961
+ filePath = import_node_path4.default.join(filePath, "index.html");
544
962
  }
545
963
  const mimeType = import_mime_types.default.lookup(filePath) || "application/octet-stream";
546
964
  res.setHeader("Content-Type", mimeType);
547
965
  if (mimeType.includes("html")) {
548
- let content = import_fs3.default.readFileSync(filePath, "utf-8");
966
+ let content = import_node_fs4.default.readFileSync(filePath, "utf-8");
549
967
  if (!content.includes("/__dmd_reload")) {
550
968
  content = content.replace("</body>", `${liveReloadScript}</body>`);
551
969
  }
552
970
  res.writeHead(200);
553
971
  res.end(content);
554
972
  } else {
555
- const stream = import_fs3.default.createReadStream(filePath);
973
+ const stream = import_node_fs4.default.createReadStream(filePath);
556
974
  res.writeHead(200);
557
975
  stream.pipe(res);
558
976
  }
559
- } catch (err) {
977
+ } catch (_err) {
560
978
  res.writeHead(404, { "Content-Type": "text/plain" });
561
979
  res.end("404 Not Found");
562
980
  }
@@ -590,16 +1008,16 @@ function startDevServer(options) {
590
1008
  if (!shouldRebuildDocumentation(rootDir, changedPath)) return;
591
1009
  if (reloadTimeout) clearTimeout(reloadTimeout);
592
1010
  reloadTimeout = setTimeout(async () => {
593
- const rel = import_path3.default.relative(rootDir, changedPath);
1011
+ const rel = import_node_path4.default.relative(rootDir, changedPath);
594
1012
  try {
595
1013
  if (onSourceChange) {
596
- console.log(import_chalk2.default.cyan(`[DocMeDown] Changed: ${rel} -> Rebuilding documentation...`));
1014
+ console.log(import_chalk3.default.cyan(`[DocMeDown] Changed: ${rel} -> Rebuilding documentation...`));
597
1015
  await onSourceChange(event, changedPath);
598
1016
  } else {
599
- console.log(import_chalk2.default.cyan(`[DocMeDown] Changed: ${rel} -> Reloading preview...`));
1017
+ console.log(import_chalk3.default.cyan(`[DocMeDown] Changed: ${rel} -> Reloading preview...`));
600
1018
  }
601
1019
  } catch (err) {
602
- console.error(import_chalk2.default.red(`[DocMeDown] Rebuild failed: ${err.message}`));
1020
+ console.error(import_chalk3.default.red(`[DocMeDown] Rebuild failed: ${err.message}`));
603
1021
  }
604
1022
  clients.forEach((ws) => {
605
1023
  if (ws.readyState === import_ws.WebSocket.OPEN) {
@@ -634,108 +1052,107 @@ function startDevServer(options) {
634
1052
  }
635
1053
 
636
1054
  // src/cli/commands/init.ts
637
- var import_open = __toESM(require("open"));
638
1055
  async function initCommand(targetDirArg = "./docs", options = {}) {
639
- const targetDir = import_path4.default.resolve(process.cwd(), targetDirArg);
640
- console.log(import_chalk3.default.bold.magenta("\n\u26A1 DocMeDown - Instant Documentation Initializer\n"));
641
- if (!import_fs4.default.existsSync(targetDir)) {
642
- import_fs4.default.mkdirSync(targetDir, { recursive: true });
1056
+ const targetDir = import_node_path5.default.resolve(process.cwd(), targetDirArg);
1057
+ console.log(import_chalk4.default.bold.magenta("\n\u26A1 DocMeDown - Instant Documentation Initializer\n"));
1058
+ if (!import_node_fs5.default.existsSync(targetDir)) {
1059
+ import_node_fs5.default.mkdirSync(targetDir, { recursive: true });
643
1060
  }
644
- const templatesDir = import_path4.default.resolve(__dirname, "../../templates");
645
- const fallbackTemplatesDir = import_path4.default.resolve(__dirname, "../templates");
646
- const activeTemplateDir = import_fs4.default.existsSync(templatesDir) ? templatesDir : fallbackTemplatesDir;
647
- const indexPath = import_path4.default.join(targetDir, "index.html");
648
- if (!import_fs4.default.existsSync(indexPath)) {
649
- const templateHtml = import_fs4.default.readFileSync(import_path4.default.join(activeTemplateDir, "index.html"), "utf-8");
650
- import_fs4.default.writeFileSync(indexPath, templateHtml, "utf-8");
651
- console.log(import_chalk3.default.green(" \u2714 Created index.html"));
1061
+ const templatesDir = import_node_path5.default.resolve(__dirname, "../../templates");
1062
+ const fallbackTemplatesDir = import_node_path5.default.resolve(__dirname, "../templates");
1063
+ const activeTemplateDir = import_node_fs5.default.existsSync(templatesDir) ? templatesDir : fallbackTemplatesDir;
1064
+ const indexPath = import_node_path5.default.join(targetDir, "index.html");
1065
+ if (!import_node_fs5.default.existsSync(indexPath)) {
1066
+ const templateHtml = import_node_fs5.default.readFileSync(import_node_path5.default.join(activeTemplateDir, "index.html"), "utf-8");
1067
+ import_node_fs5.default.writeFileSync(indexPath, templateHtml, "utf-8");
1068
+ console.log(import_chalk4.default.green(" \u2714 Created index.html"));
652
1069
  }
653
- const configPath = import_path4.default.join(targetDir, "docs.json");
654
- if (!import_fs4.default.existsSync(configPath)) {
655
- const templateConfig = import_fs4.default.readFileSync(import_path4.default.join(activeTemplateDir, "docs.json"), "utf-8");
656
- import_fs4.default.writeFileSync(configPath, templateConfig, "utf-8");
657
- console.log(import_chalk3.default.green(" \u2714 Created docs.json"));
1070
+ const configPath = import_node_path5.default.join(targetDir, "docs.json");
1071
+ if (!import_node_fs5.default.existsSync(configPath)) {
1072
+ const templateConfig = import_node_fs5.default.readFileSync(import_node_path5.default.join(activeTemplateDir, "docs.json"), "utf-8");
1073
+ import_node_fs5.default.writeFileSync(configPath, templateConfig, "utf-8");
1074
+ console.log(import_chalk4.default.green(" \u2714 Created docs.json"));
658
1075
  }
659
- const readmePath = import_path4.default.join(targetDir, "README.md");
660
- if (!import_fs4.default.existsSync(readmePath)) {
661
- const templateReadme = import_fs4.default.readFileSync(import_path4.default.join(activeTemplateDir, "README.md"), "utf-8");
662
- import_fs4.default.writeFileSync(readmePath, templateReadme, "utf-8");
663
- console.log(import_chalk3.default.green(" \u2714 Created README.md"));
1076
+ const readmePath = import_node_path5.default.join(targetDir, "README.md");
1077
+ if (!import_node_fs5.default.existsSync(readmePath)) {
1078
+ const templateReadme = import_node_fs5.default.readFileSync(import_node_path5.default.join(activeTemplateDir, "README.md"), "utf-8");
1079
+ import_node_fs5.default.writeFileSync(readmePath, templateReadme, "utf-8");
1080
+ console.log(import_chalk4.default.green(" \u2714 Created README.md"));
664
1081
  }
665
- const gsPath = import_path4.default.join(targetDir, "getting-started.md");
666
- if (!import_fs4.default.existsSync(gsPath)) {
667
- const templateGs = import_fs4.default.readFileSync(import_path4.default.join(activeTemplateDir, "getting-started.md"), "utf-8");
668
- import_fs4.default.writeFileSync(gsPath, templateGs, "utf-8");
669
- console.log(import_chalk3.default.green(" \u2714 Created getting-started.md"));
1082
+ const gsPath = import_node_path5.default.join(targetDir, "getting-started.md");
1083
+ if (!import_node_fs5.default.existsSync(gsPath)) {
1084
+ const templateGs = import_node_fs5.default.readFileSync(import_node_path5.default.join(activeTemplateDir, "getting-started.md"), "utf-8");
1085
+ import_node_fs5.default.writeFileSync(gsPath, templateGs, "utf-8");
1086
+ console.log(import_chalk4.default.green(" \u2714 Created getting-started.md"));
670
1087
  }
671
- const guidesDir = import_path4.default.join(targetDir, "guides");
672
- if (!import_fs4.default.existsSync(guidesDir)) {
673
- import_fs4.default.mkdirSync(guidesDir, { recursive: true });
1088
+ const guidesDir = import_node_path5.default.join(targetDir, "guides");
1089
+ if (!import_node_fs5.default.existsSync(guidesDir)) {
1090
+ import_node_fs5.default.mkdirSync(guidesDir, { recursive: true });
674
1091
  }
675
- const guidePath = import_path4.default.join(guidesDir, "custom-components.md");
676
- if (!import_fs4.default.existsSync(guidePath)) {
677
- const templateGuide = import_fs4.default.readFileSync(import_path4.default.join(activeTemplateDir, "guides/custom-components.md"), "utf-8");
678
- import_fs4.default.writeFileSync(guidePath, templateGuide, "utf-8");
679
- console.log(import_chalk3.default.green(" \u2714 Created guides/custom-components.md"));
1092
+ const guidePath = import_node_path5.default.join(guidesDir, "custom-components.md");
1093
+ if (!import_node_fs5.default.existsSync(guidePath)) {
1094
+ const templateGuide = import_node_fs5.default.readFileSync(import_node_path5.default.join(activeTemplateDir, "guides/custom-components.md"), "utf-8");
1095
+ import_node_fs5.default.writeFileSync(guidePath, templateGuide, "utf-8");
1096
+ console.log(import_chalk4.default.green(" \u2714 Created guides/custom-components.md"));
680
1097
  }
681
- const dmdDir = import_path4.default.join(targetDir, ".dmd");
682
- if (!import_fs4.default.existsSync(dmdDir)) {
683
- import_fs4.default.mkdirSync(dmdDir, { recursive: true });
1098
+ const dmdDir = import_node_path5.default.join(targetDir, ".dmd");
1099
+ if (!import_node_fs5.default.existsSync(dmdDir)) {
1100
+ import_node_fs5.default.mkdirSync(dmdDir, { recursive: true });
684
1101
  }
685
- const dmdComponentPath = import_path4.default.join(dmdDir, "components.js");
686
- if (!import_fs4.default.existsSync(dmdComponentPath)) {
687
- const templateDmd = import_fs4.default.readFileSync(import_path4.default.join(activeTemplateDir, ".dmd/components.js"), "utf-8");
688
- import_fs4.default.writeFileSync(dmdComponentPath, templateDmd, "utf-8");
689
- console.log(import_chalk3.default.green(" \u2714 Created .dmd/components.js"));
1102
+ const dmdComponentPath = import_node_path5.default.join(dmdDir, "components.js");
1103
+ if (!import_node_fs5.default.existsSync(dmdComponentPath)) {
1104
+ const templateDmd = import_node_fs5.default.readFileSync(import_node_path5.default.join(activeTemplateDir, ".dmd/components.js"), "utf-8");
1105
+ import_node_fs5.default.writeFileSync(dmdComponentPath, templateDmd, "utf-8");
1106
+ console.log(import_chalk4.default.green(" \u2714 Created .dmd/components.js"));
690
1107
  }
691
1108
  await buildCommand(targetDir);
692
- console.log(import_chalk3.default.bold.green("\n\u2728 DocMeDown site successfully initialized!\n"));
693
- console.log(import_chalk3.default.dim(` Location: ${targetDir}
1109
+ console.log(import_chalk4.default.bold.green("\n\u2728 DocMeDown site successfully initialized!\n"));
1110
+ console.log(import_chalk4.default.dim(` Location: ${targetDir}
694
1111
  `));
695
- console.log(import_chalk3.default.cyan(" To preview your docs:"));
696
- console.log(import_chalk3.default.white(` npx docmedown serve ${targetDirArg}
1112
+ console.log(import_chalk4.default.cyan(" To preview your docs:"));
1113
+ console.log(import_chalk4.default.white(` npx docmedown serve ${targetDirArg}
697
1114
  `));
698
- console.log(import_chalk3.default.cyan(" To customize settings:"));
699
- console.log(import_chalk3.default.white(` npx docmedown config ${targetDirArg}/docs.json
1115
+ console.log(import_chalk4.default.cyan(" To customize settings:"));
1116
+ console.log(import_chalk4.default.white(` npx docmedown config ${targetDirArg}/docs.json
700
1117
  `));
701
1118
  if (options.start !== false && process.stdout.isTTY) {
702
- const response = await (0, import_prompts.default)({
1119
+ const response = await (0, import_prompts2.default)({
703
1120
  type: "confirm",
704
1121
  name: "startServer",
705
1122
  message: "Would you like to start the local preview server now?",
706
1123
  initial: true
707
1124
  });
708
1125
  if (response.startServer) {
709
- console.log(import_chalk3.default.cyan("\n\u{1F680} Starting local live preview server..."));
1126
+ console.log(import_chalk4.default.cyan("\n\u{1F680} Starting local live preview server..."));
710
1127
  const devServer = await startDevServer({ rootDir: targetDir, port: 3e3 });
711
1128
  const url = `http://localhost:${devServer.port}`;
712
- console.log(import_chalk3.default.bold.green(`
713
- \u2714 Documentation live at: ${import_chalk3.default.underline(url)}
1129
+ console.log(import_chalk4.default.bold.green(`
1130
+ \u2714 Documentation live at: ${import_chalk4.default.underline(url)}
714
1131
  `));
715
- console.log(import_chalk3.default.dim(" Press Ctrl+C to stop the server\n"));
1132
+ console.log(import_chalk4.default.dim(" Press Ctrl+C to stop the server\n"));
716
1133
  await (0, import_open.default)(url);
717
1134
  }
718
1135
  }
719
1136
  }
720
1137
 
721
1138
  // src/cli/commands/serve.ts
722
- var import_path5 = __toESM(require("path"));
723
- var import_fs5 = __toESM(require("fs"));
724
- var import_chalk4 = __toESM(require("chalk"));
1139
+ var import_node_fs6 = __toESM(require("fs"));
1140
+ var import_node_path6 = __toESM(require("path"));
1141
+ var import_chalk5 = __toESM(require("chalk"));
725
1142
  var import_open2 = __toESM(require("open"));
726
1143
  async function serveCommand(targetDirArg = "./docs", options = {}) {
727
- let targetDir = import_path5.default.resolve(process.cwd(), targetDirArg);
728
- if (!import_fs5.default.existsSync(targetDir)) {
729
- if (import_fs5.default.existsSync(import_path5.default.resolve(process.cwd(), "docs"))) {
730
- targetDir = import_path5.default.resolve(process.cwd(), "docs");
1144
+ let targetDir = import_node_path6.default.resolve(process.cwd(), targetDirArg);
1145
+ if (!import_node_fs6.default.existsSync(targetDir)) {
1146
+ if (import_node_fs6.default.existsSync(import_node_path6.default.resolve(process.cwd(), "docs"))) {
1147
+ targetDir = import_node_path6.default.resolve(process.cwd(), "docs");
731
1148
  } else {
732
1149
  targetDir = process.cwd();
733
1150
  }
734
1151
  }
735
- console.log(import_chalk4.default.bold.magenta("\n\u26A1 DocMeDown Dev Server\n"));
736
- console.log(import_chalk4.default.dim(` Serving directory: ${targetDir}`));
1152
+ console.log(import_chalk5.default.bold.magenta("\n\u26A1 DocMeDown Dev Server\n"));
1153
+ console.log(import_chalk5.default.dim(` Serving directory: ${targetDir}`));
737
1154
  try {
738
- console.log(import_chalk4.default.dim(" Building serveable and offline documentation artifacts..."));
1155
+ console.log(import_chalk5.default.dim(" Building serveable and offline documentation artifacts..."));
739
1156
  await buildCommand(targetDir);
740
1157
  const devServer = await startDevServer({
741
1158
  rootDir: targetDir,
@@ -744,290 +1161,31 @@ async function serveCommand(targetDirArg = "./docs", options = {}) {
744
1161
  onSourceChange: () => buildCommand(targetDir)
745
1162
  });
746
1163
  const url = `http://${options.host || "localhost"}:${devServer.port}`;
747
- console.log(import_chalk4.default.bold.green(`
1164
+ console.log(import_chalk5.default.bold.green(`
748
1165
  \u2714 Live Documentation Server running at:`));
749
- console.log(import_chalk4.default.bold.cyan(` \u279C Local: ${import_chalk4.default.underline(url)}`));
750
- console.log(import_chalk4.default.dim(` \u279C Watch: Source changes rebuild preview and .dist/index.html`));
751
- console.log(import_chalk4.default.dim(`
1166
+ console.log(import_chalk5.default.bold.cyan(` \u279C Local: ${import_chalk5.default.underline(url)}`));
1167
+ console.log(import_chalk5.default.dim(` \u279C Watch: Source changes rebuild preview and .dist/index.html`));
1168
+ console.log(import_chalk5.default.dim(`
752
1169
  Press Ctrl+C to stop.
753
1170
  `));
754
1171
  if (options.open !== false) {
755
1172
  await (0, import_open2.default)(url);
756
1173
  }
757
1174
  } catch (err) {
758
- console.error(import_chalk4.default.red(`
1175
+ console.error(import_chalk5.default.red(`
759
1176
  \u2716 Error starting server: ${err.message}
760
1177
  `));
761
1178
  process.exit(1);
762
1179
  }
763
1180
  }
764
1181
 
765
- // src/cli/commands/config-tui.ts
766
- var import_fs6 = __toESM(require("fs"));
767
- var import_path6 = __toESM(require("path"));
768
- var import_chalk5 = __toESM(require("chalk"));
769
- var import_prompts2 = __toESM(require("prompts"));
770
- async function configTuiCommand(configPathArg) {
771
- console.log(import_chalk5.default.bold.magenta("\n\u26A1 DocMeDown - Interactive Configuration Wizard\n"));
772
- let configPath = "";
773
- if (configPathArg) {
774
- configPath = import_path6.default.resolve(process.cwd(), configPathArg);
775
- if (import_fs6.default.existsSync(configPath) && import_fs6.default.statSync(configPath).isDirectory()) {
776
- configPath = import_path6.default.join(configPath, "docs.json");
777
- }
778
- } else {
779
- const candidates = [
780
- import_path6.default.resolve(process.cwd(), "docs.json"),
781
- import_path6.default.resolve(process.cwd(), "docs/docs.json"),
782
- import_path6.default.resolve(process.cwd(), "dmd.json")
783
- ];
784
- configPath = candidates.find((p) => import_fs6.default.existsSync(p)) || import_path6.default.resolve(process.cwd(), "docs/docs.json");
785
- }
786
- let existingConfig = DEFAULT_CONFIG;
787
- if (import_fs6.default.existsSync(configPath)) {
788
- try {
789
- existingConfig = { ...DEFAULT_CONFIG, ...JSON.parse(import_fs6.default.readFileSync(configPath, "utf-8")) };
790
- console.log(import_chalk5.default.dim(` Loaded existing configuration from: ${configPath}
791
- `));
792
- } catch {
793
- console.warn(import_chalk5.default.yellow(` \u26A0 Error reading ${configPath}, starting fresh.
794
- `));
795
- }
796
- } else {
797
- console.log(import_chalk5.default.dim(` Creating new configuration at: ${configPath}
798
- `));
799
- }
800
- const response = await (0, import_prompts2.default)([
801
- {
802
- type: "text",
803
- name: "name",
804
- message: "Project Name:",
805
- initial: existingConfig.name || "My Project Docs"
806
- },
807
- {
808
- type: "text",
809
- name: "tagline",
810
- message: "Tagline / Short description:",
811
- initial: existingConfig.tagline || "The simplest Markdown documenter yet"
812
- },
813
- {
814
- type: "select",
815
- name: "preset",
816
- message: "Select Theme Color Palette:",
817
- choices: [
818
- { title: "Indigo (Modern & Clean)", value: "indigo" },
819
- { title: "Emerald (Fresh & Tech)", value: "emerald" },
820
- { title: "Sunset (Warm Amber)", value: "sunset" },
821
- { title: "Violet (Vibrant Purple)", value: "violet" },
822
- { title: "Rose (Bold Quartz)", value: "rose" },
823
- { title: "Slate (Minimalist Monochrome)", value: "slate" },
824
- { title: "Cyberpunk (Neon Glow)", value: "cyberpunk" }
825
- ],
826
- initial: ["indigo", "emerald", "sunset", "violet", "rose", "slate", "cyberpunk"].indexOf(
827
- existingConfig.theme?.preset || "indigo"
828
- )
829
- },
830
- {
831
- type: "select",
832
- name: "defaultMode",
833
- message: "Default Color Mode:",
834
- choices: [
835
- { title: "Auto (Follows OS system preference)", value: "auto" },
836
- { title: "Dark (Default dark theme)", value: "dark" },
837
- { title: "Light (Default light theme)", value: "light" }
838
- ],
839
- initial: ["auto", "dark", "light"].indexOf(existingConfig.theme?.defaultMode || "auto")
840
- },
841
- {
842
- type: "select",
843
- name: "sourceType",
844
- message: "Documentation Source Mode:",
845
- choices: [
846
- { title: "Local Markdown Files (hosted together in folder)", value: "local" },
847
- { title: "Remote GitHub Repository (live dynamic fetch)", value: "github" },
848
- { title: "Remote GitLab Repository (live dynamic fetch)", value: "gitlab" }
849
- ],
850
- initial: existingConfig.source?.type ? existingConfig.source.type === "github" ? 1 : 2 : 0
851
- },
852
- {
853
- type: (prev) => prev === "github" ? "text" : null,
854
- name: "githubRepo",
855
- message: "GitHub Repository (owner/repo):",
856
- initial: existingConfig.source?.repo || "facebook/react"
857
- },
858
- {
859
- type: (prev, values) => values.sourceType === "github" ? "text" : null,
860
- name: "githubBranch",
861
- message: "GitHub Branch:",
862
- initial: existingConfig.source?.branch || "main"
863
- },
864
- {
865
- type: (prev, values) => values.sourceType === "github" ? "text" : null,
866
- name: "githubDocsDir",
867
- message: "GitHub Docs Subfolder (leave empty for root):",
868
- initial: existingConfig.source?.docsDir || "docs"
869
- },
870
- {
871
- type: "text",
872
- name: "githubSocial",
873
- message: "GitHub Repository URL for Navbar link (optional):",
874
- initial: existingConfig.socials?.find((s) => s.type === "github")?.url || ""
875
- }
876
- ]);
877
- if (!response.name) {
878
- console.log(import_chalk5.default.yellow("\nConfiguration cancelled."));
879
- return;
880
- }
881
- const updatedConfig = {
882
- ...existingConfig,
883
- name: response.name,
884
- tagline: response.tagline,
885
- theme: {
886
- ...existingConfig.theme,
887
- preset: response.preset,
888
- defaultMode: response.defaultMode
889
- },
890
- socials: response.githubSocial ? [{ type: "github", url: response.githubSocial }] : existingConfig.socials
891
- };
892
- if (response.sourceType === "github") {
893
- updatedConfig.source = {
894
- type: "github",
895
- repo: response.githubRepo,
896
- branch: response.githubBranch,
897
- docsDir: response.githubDocsDir
898
- };
899
- } else if (response.sourceType === "local") {
900
- delete updatedConfig.source;
901
- }
902
- const dir = import_path6.default.dirname(configPath);
903
- if (!import_fs6.default.existsSync(dir)) {
904
- import_fs6.default.mkdirSync(dir, { recursive: true });
905
- }
906
- import_fs6.default.writeFileSync(configPath, JSON.stringify(updatedConfig, null, 2), "utf-8");
907
- console.log(import_chalk5.default.bold.green(`
908
- \u2714 Configuration successfully saved to: ${configPath}
909
- `));
910
- }
911
-
912
- // package.json
913
- var package_default = {
914
- name: "docmedown",
915
- version: "0.1.0",
916
- description: "The simplest MarkDown documenter yet. CLI & Web Script React SPA documentation engine.",
917
- main: "./dist/docmedown.cjs",
918
- module: "./dist/docmedown.mjs",
919
- types: "./dist/types/runtime/index.d.ts",
920
- exports: {
921
- ".": {
922
- types: "./dist/types/runtime/index.d.ts",
923
- import: "./dist/docmedown.mjs",
924
- require: "./dist/docmedown.cjs"
925
- },
926
- "./iife": "./dist/docmedown.iife.js"
927
- },
928
- unpkg: "./dist/docmedown.iife.js",
929
- jsdelivr: "./dist/docmedown.iife.js",
930
- bin: {
931
- docmedown: "bin/docmedown.js",
932
- dmd: "bin/docmedown.js"
933
- },
934
- files: [
935
- "dist",
936
- "bin",
937
- "templates",
938
- "README.md",
939
- "LICENSE"
940
- ],
941
- scripts: {
942
- "dev:runtime": "vite build --watch",
943
- "build:runtime": "vite build",
944
- "build:cli": "tsup",
945
- typecheck: "tsc --noEmit",
946
- "build:types": "tsc -p tsconfig.runtime.json",
947
- build: "npm run build:runtime && npm run build:cli && npm run build:types",
948
- docmedown: "node ./bin/docmedown.js",
949
- dmd: "node ./bin/docmedown.js",
950
- "init:docs": "node ./bin/docmedown.js init",
951
- serve: "node ./bin/docmedown.js serve ./docs",
952
- dev: "node ./bin/docmedown.js serve ./docs",
953
- "build:docs": "node ./bin/docmedown.js build ./docs",
954
- "build:docs:watch": "node ./bin/docmedown.js build ./docs --watch",
955
- "build:offline": "node ./bin/docmedown.js build ./docs",
956
- "config:docs": "node ./bin/docmedown.js config ./docs/docs.json",
957
- test: "npx tsx --test tests/parser.test.ts tests/scanner.test.ts tests/runtime-integration.test.ts tests/package-smoke.test.ts",
958
- "test:release": "npm run typecheck && npm run test && npm run build && npm run build:docs && npm pack --dry-run",
959
- prepublishOnly: "npm run test:release"
960
- },
961
- keywords: [
962
- "markdown",
963
- "documentation",
964
- "docs",
965
- "docusaurus",
966
- "docsify",
967
- "react",
968
- "spa",
969
- "cli",
970
- "offline-docs",
971
- "github-docs"
972
- ],
973
- author: "Gabriel M. Silva",
974
- license: "MIT",
975
- engines: {
976
- node: ">=20.19.0"
977
- },
978
- repository: {
979
- type: "git",
980
- url: "git+https://github.com/gabrielmsilva00/docmedown.git"
981
- },
982
- bugs: {
983
- url: "https://github.com/gabrielmsilva00/docmedown/issues"
984
- },
985
- homepage: "https://github.com/gabrielmsilva00/docmedown#readme",
986
- packageManager: "npm@11.16.0",
987
- overrides: {
988
- tsup: {
989
- esbuild: "0.28.2"
990
- }
991
- },
992
- dependencies: {
993
- chalk: "^4.1.2",
994
- chokidar: "^3.6.0",
995
- commander: "^12.1.0",
996
- "gray-matter": "^4.0.3",
997
- "mime-types": "^2.1.35",
998
- open: "^10.1.0",
999
- prompts: "^2.4.2",
1000
- ws: "^8.18.0"
1001
- },
1002
- devDependencies: {
1003
- "@types/node": "^22.5.0",
1004
- "@types/prismjs": "^1.26.6",
1005
- "@types/prompts": "^2.4.9",
1006
- "@types/react": "^18.3.5",
1007
- "@types/react-dom": "^18.3.0",
1008
- "@types/ws": "^8.5.12",
1009
- "@vitejs/plugin-react": "^6.1.0",
1010
- katex: "^0.16.11",
1011
- marked: "^14.1.1",
1012
- minisearch: "^7.1.0",
1013
- prismjs: "^1.29.0",
1014
- react: "^18.3.1",
1015
- "react-dom": "^18.3.1",
1016
- tsup: "^8.2.4",
1017
- tsx: "^4.19.0",
1018
- typescript: "^5.5.4",
1019
- vite: "^8.2.2",
1020
- "vite-plugin-css-injected-by-js": "^5.0.2"
1021
- }
1022
- };
1023
-
1024
1182
  // src/cli/index.ts
1025
1183
  var program = new import_commander.Command();
1026
1184
  program.name("docmedown").description("DocMeDown - The simplest MarkDown documenter yet. CLI & Web Script React SPA.").version(package_default.version);
1027
1185
  program.argument("[dir]", "Documentation directory to initialize or serve", "./docs").option("-p, --port <number>", "Port for local dev server", "3000").option("--no-open", "Do not automatically open the browser").action(async (dir, options) => {
1028
- const targetDir = import_path7.default.resolve(process.cwd(), dir);
1029
- const hasIndex = import_fs7.default.existsSync(import_path7.default.join(targetDir, "index.html"));
1030
- const hasDocs = import_fs7.default.existsSync(import_path7.default.join(targetDir, "README.md")) || import_fs7.default.existsSync(import_path7.default.join(targetDir, "docs.json"));
1186
+ const targetDir = import_node_path7.default.resolve(process.cwd(), dir);
1187
+ const hasIndex = import_node_fs7.default.existsSync(import_node_path7.default.join(targetDir, "index.html"));
1188
+ const hasDocs = import_node_fs7.default.existsSync(import_node_path7.default.join(targetDir, "README.md")) || import_node_fs7.default.existsSync(import_node_path7.default.join(targetDir, "docs.json"));
1031
1189
  if (!hasIndex && !hasDocs) {
1032
1190
  await initCommand(dir, { start: options.open });
1033
1191
  } else {