mdsvr 2.2.17 → 2.2.19

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 (46) hide show
  1. package/dist/cli.js +16 -8
  2. package/dist/cli.js.map +1 -1
  3. package/dist/export-state.d.ts +44 -0
  4. package/dist/export-state.d.ts.map +1 -0
  5. package/dist/export-state.js +164 -0
  6. package/dist/export-state.js.map +1 -0
  7. package/dist/generators/static-export.d.ts +1 -0
  8. package/dist/generators/static-export.d.ts.map +1 -1
  9. package/dist/generators/static-export.js +133 -25
  10. package/dist/generators/static-export.js.map +1 -1
  11. package/dist/og/generator.d.ts.map +1 -1
  12. package/dist/og/generator.js +43 -0
  13. package/dist/og/generator.js.map +1 -1
  14. package/dist/og/incremental.d.ts +48 -0
  15. package/dist/og/incremental.d.ts.map +1 -0
  16. package/dist/og/incremental.js +194 -0
  17. package/dist/og/incremental.js.map +1 -0
  18. package/dist/og/index.d.ts +3 -2
  19. package/dist/og/index.d.ts.map +1 -1
  20. package/dist/og/index.js +3 -2
  21. package/dist/og/index.js.map +1 -1
  22. package/dist/renderer/components.js +1 -1
  23. package/dist/renderer/components.js.map +1 -1
  24. package/dist/renderer/markdown.d.ts.map +1 -1
  25. package/dist/renderer/markdown.js +42 -6
  26. package/dist/renderer/markdown.js.map +1 -1
  27. package/dist/router.js +9 -2
  28. package/dist/router.js.map +1 -1
  29. package/dist/server.d.ts.map +1 -1
  30. package/dist/server.js +2 -2
  31. package/dist/server.js.map +1 -1
  32. package/dist/settings/defaults.d.ts.map +1 -1
  33. package/dist/settings/defaults.js +1 -0
  34. package/dist/settings/defaults.js.map +1 -1
  35. package/dist/settings/index.d.ts.map +1 -1
  36. package/dist/settings/index.js +13 -6
  37. package/dist/settings/index.js.map +1 -1
  38. package/dist/settings/schema.js +1 -1
  39. package/dist/settings/schema.js.map +1 -1
  40. package/dist/template/index.d.ts.map +1 -1
  41. package/dist/template/index.js +345 -61
  42. package/dist/template/index.js.map +1 -1
  43. package/dist/template/sidebar.d.ts.map +1 -1
  44. package/dist/template/sidebar.js +21 -7
  45. package/dist/template/sidebar.js.map +1 -1
  46. package/package.json +3 -3
package/dist/cli.js CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import { createServer, getNetworkAddress } from "./server.js";
3
3
  import path from "node:path";
4
- import { readFile, writeFile } from "node:fs/promises";
4
+ import { readFile, writeFile, mkdir } from "node:fs/promises";
5
5
  import { fileURLToPath } from "node:url";
6
6
  import { validateSettingsFile, generateDefaultSettings, } from "./settings/index.js";
7
7
  function parseArgs(argv) {
@@ -18,6 +18,7 @@ function parseArgs(argv) {
18
18
  validate: false,
19
19
  watchSettings: true,
20
20
  export: null,
21
+ forceOg: false,
21
22
  };
22
23
  for (let i = 0; i < argv.length; i++) {
23
24
  const arg = argv[i];
@@ -64,6 +65,9 @@ function parseArgs(argv) {
64
65
  args.export = null; // Will use default _html folder
65
66
  }
66
67
  }
68
+ else if (arg === "--force-og") {
69
+ args.forceOg = true;
70
+ }
67
71
  else if (!arg.startsWith("--") && !arg.startsWith("-")) {
68
72
  args.dir = arg;
69
73
  args.dirSpecified = true;
@@ -82,9 +86,10 @@ Options:
82
86
  -o, --open Auto-open browser
83
87
  -s, --silent Suppress console output
84
88
  -e, --export [PATH] Export static HTML (default: _html/public in input dir)
85
- --init Create a starter settings.json in [dir]
86
- --validate Validate settings.json and exit
87
- --no-watch Disable settings.json hot-reload
89
+ --force-og Force full OG image regeneration (skip incremental)
90
+ --init Create a starter _mdsvr/settings.json in [dir]
91
+ --validate Validate _mdsvr/settings.json and exit
92
+ --no-watch Disable _mdsvr/settings.json hot-reload
88
93
  -v, --version Print version
89
94
  -h, --help Print this help
90
95
 
@@ -94,6 +99,7 @@ Examples:
94
99
  mdsvr . --host 0.0.0.0 --port 8080
95
100
  mdsvr ./docs --export # Export to ./_html/public
96
101
  mdsvr ./docs -e ./output # Export to custom directory
102
+ mdsvr ./docs --export --force-og # Export with full OG regeneration
97
103
  mdsvr ./docs --init
98
104
  mdsvr ./docs --validate
99
105
  `);
@@ -120,8 +126,9 @@ async function openBrowser(url) {
120
126
  exec(`${cmd} "${url}"`);
121
127
  }
122
128
  async function initSettings(dir) {
123
- const settingsPath = path.join(dir, "settings.json");
129
+ const settingsPath = path.join(dir, "_mdsvr/settings.json");
124
130
  const defaultSettings = generateDefaultSettings();
131
+ await mkdir(path.join(dir, "_mdsvr"), { recursive: true });
125
132
  await writeFile(settingsPath, JSON.stringify(defaultSettings, null, 2), "utf-8");
126
133
  }
127
134
  async function main() {
@@ -146,7 +153,7 @@ async function main() {
146
153
  if (args.init) {
147
154
  try {
148
155
  await initSettings(absoluteDir);
149
- console.log(`\n ✔ Created ${args.dir}/settings.json with defaults`);
156
+ console.log(`\n ✔ Created ${args.dir}/_mdsvr/settings.json with defaults`);
150
157
  console.log(` ✔ Run \`npx mdsvr ${args.dir}\` to start\n`);
151
158
  process.exit(0);
152
159
  }
@@ -160,11 +167,11 @@ async function main() {
160
167
  try {
161
168
  const result = await validateSettingsFile(absoluteDir);
162
169
  if (result.valid) {
163
- console.log(`\n ✔ settings.json is valid\n`);
170
+ console.log(`\n ✔ _mdsvr/settings.json is valid\n`);
164
171
  process.exit(0);
165
172
  }
166
173
  else {
167
- console.log(`\n ✖ settings.json has errors:`);
174
+ console.log(`\n ✖ _mdsvr/settings.json has errors:`);
168
175
  result.errors?.forEach((e) => console.log(` - ${e}`));
169
176
  console.log();
170
177
  process.exit(1);
@@ -190,6 +197,7 @@ async function main() {
190
197
  outputDir,
191
198
  settings,
192
199
  silent: args.silent,
200
+ forceOg: args.forceOg,
193
201
  });
194
202
  if (!args.silent) {
195
203
  console.log(`\n ✔ Static site exported to: ${outputDir}\n`);
package/dist/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,44 @@
1
+ export interface ExportState {
2
+ settingsHash: string;
3
+ html: Record<string, PageState>;
4
+ og: Record<string, OgState>;
5
+ }
6
+ export interface PageState {
7
+ outputPath: string;
8
+ sourcePath: string;
9
+ hash: string;
10
+ }
11
+ export interface OgState {
12
+ outputPath: string;
13
+ hash: string;
14
+ }
15
+ export interface CleanupResult {
16
+ deleted: string[];
17
+ deletedDirs: string[];
18
+ }
19
+ /**
20
+ * Load the export state file from the root directory
21
+ */
22
+ export declare function loadExportState(rootDir: string): Promise<ExportState>;
23
+ /**
24
+ * Save the export state file to the root directory
25
+ */
26
+ export declare function saveExportState(rootDir: string, state: ExportState): Promise<void>;
27
+ /**
28
+ * Migrate old OG state format to new export state format
29
+ */
30
+ export declare function migrateOldState(rootDir: string, exportDir: string): Promise<ExportState | null>;
31
+ /**
32
+ * Calculate hash for a file
33
+ */
34
+ export declare function calculateFileHash(filePath: string): Promise<string>;
35
+ /**
36
+ * Calculate hash of settings file
37
+ * If settings file doesn't exist, use default settings hash
38
+ */
39
+ export declare function calculateSettingsHash(rootDir: string): Promise<string>;
40
+ /**
41
+ * Clean up orphaned files (files that exist in old state but not in new state)
42
+ */
43
+ export declare function cleanupOrphanedFiles(exportDir: string, oldState: ExportState, newState: ExportState): Promise<CleanupResult>;
44
+ //# sourceMappingURL=export-state.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"export-state.d.ts","sourceRoot":"","sources":["../src/export-state.ts"],"names":[],"mappings":"AAUA,MAAM,WAAW,WAAW;IAC1B,YAAY,EAAE,MAAM,CAAC;IACrB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;IAChC,EAAE,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAC7B;AAED,MAAM,WAAW,SAAS;IACxB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,OAAO;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,WAAW,EAAE,MAAM,EAAE,CAAC;CACvB;AAED;;GAEG;AACH,wBAAsB,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC,CAS3E;AAED;;GAEG;AACH,wBAAsB,eAAe,CACnC,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,WAAW,GACjB,OAAO,CAAC,IAAI,CAAC,CAIf;AAED;;GAEG;AACH,wBAAsB,eAAe,CACnC,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC,CAgC7B;AAiBD;;GAEG;AACH,wBAAsB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAOzE;AAED;;;GAGG;AACH,wBAAsB,qBAAqB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAe5E;AAED;;GAEG;AACH,wBAAsB,oBAAoB,CACxC,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,WAAW,EACrB,QAAQ,EAAE,WAAW,GACpB,OAAO,CAAC,aAAa,CAAC,CAiCxB"}
@@ -0,0 +1,164 @@
1
+ // Centralized export state management for HTML and OG files
2
+ import { promises as fs } from "node:fs";
3
+ import path from "node:path";
4
+ import { createHash } from "node:crypto";
5
+ import { generateDefaultSettings } from "./settings/index.js";
6
+ const STATE_FILE_NAME = "_mdsvr/export-state.json";
7
+ const OLD_STATE_FILE_NAME = ".mdsvr-og-state.json";
8
+ /**
9
+ * Load the export state file from the root directory
10
+ */
11
+ export async function loadExportState(rootDir) {
12
+ const statePath = path.join(rootDir, STATE_FILE_NAME);
13
+ try {
14
+ const content = await fs.readFile(statePath, "utf-8");
15
+ return JSON.parse(content);
16
+ }
17
+ catch {
18
+ // File doesn't exist or is invalid, return empty state
19
+ return { settingsHash: "", html: {}, og: {} };
20
+ }
21
+ }
22
+ /**
23
+ * Save the export state file to the root directory
24
+ */
25
+ export async function saveExportState(rootDir, state) {
26
+ const statePath = path.join(rootDir, STATE_FILE_NAME);
27
+ await fs.mkdir(path.join(rootDir, "_mdsvr"), { recursive: true });
28
+ await fs.writeFile(statePath, JSON.stringify(state, null, 2), "utf-8");
29
+ }
30
+ /**
31
+ * Migrate old OG state format to new export state format
32
+ */
33
+ export async function migrateOldState(rootDir, exportDir) {
34
+ const oldOgDir = path.join(exportDir, "public", "og");
35
+ const oldStatePath = path.join(oldOgDir, OLD_STATE_FILE_NAME);
36
+ try {
37
+ const content = await fs.readFile(oldStatePath, "utf-8");
38
+ const oldOgState = JSON.parse(content);
39
+ // Convert old format to new format
40
+ const newState = {
41
+ settingsHash: "",
42
+ html: {},
43
+ og: {},
44
+ };
45
+ for (const [filePath, hash] of Object.entries(oldOgState)) {
46
+ // Generate OG filename from file path
47
+ const ogFilename = generateOgFilename(filePath, "jpg");
48
+ newState.og[filePath] = {
49
+ outputPath: path.join("public", "og", ogFilename),
50
+ hash,
51
+ };
52
+ }
53
+ // Delete old state file after migration
54
+ await fs.unlink(oldStatePath);
55
+ return newState;
56
+ }
57
+ catch {
58
+ // Old state file doesn't exist or is invalid, return null
59
+ return null;
60
+ }
61
+ }
62
+ /**
63
+ * Generate OG filename from file path
64
+ * e.g., /docs/README.md -> docs-readme-og.jpg
65
+ */
66
+ function generateOgFilename(filePath, format = "jpg") {
67
+ const normalized = filePath.replace(/^\//, "").replace(/\\/g, "/");
68
+ const segments = normalized.split("/").map((segment) => {
69
+ return segment.toLowerCase().replace(/\.(md|mdx)$/, "");
70
+ });
71
+ return segments.join("-") + `-og.${format}`;
72
+ }
73
+ /**
74
+ * Calculate hash for a file
75
+ */
76
+ export async function calculateFileHash(filePath) {
77
+ try {
78
+ const content = await fs.readFile(filePath, "utf-8");
79
+ return createHash("sha256").update(content).digest("hex");
80
+ }
81
+ catch {
82
+ return "";
83
+ }
84
+ }
85
+ /**
86
+ * Calculate hash of settings file
87
+ * If settings file doesn't exist, use default settings hash
88
+ */
89
+ export async function calculateSettingsHash(rootDir) {
90
+ const settingsPath = path.join(rootDir, "_mdsvr/settings.json");
91
+ try {
92
+ const content = await fs.readFile(settingsPath, "utf-8");
93
+ const parsed = JSON.parse(content);
94
+ delete parsed.$schema; // Exclude schema from hash
95
+ return createHash("sha256").update(JSON.stringify(parsed)).digest("hex");
96
+ }
97
+ catch {
98
+ // No settings file, use hash of default settings
99
+ const defaultSettings = generateDefaultSettings();
100
+ const { $schema, ...settingsWithoutSchema } = defaultSettings;
101
+ return createHash("sha256")
102
+ .update(JSON.stringify(settingsWithoutSchema))
103
+ .digest("hex");
104
+ }
105
+ }
106
+ /**
107
+ * Clean up orphaned files (files that exist in old state but not in new state)
108
+ */
109
+ export async function cleanupOrphanedFiles(exportDir, oldState, newState) {
110
+ const deleted = [];
111
+ const deletedDirs = [];
112
+ // Cleanup HTML
113
+ for (const [urlPath, pageState] of Object.entries(oldState.html)) {
114
+ if (!newState.html[urlPath]) {
115
+ const fullPath = path.join(exportDir, pageState.outputPath);
116
+ try {
117
+ await fs.unlink(fullPath);
118
+ deleted.push(fullPath);
119
+ await cleanupEmptyDir(path.dirname(fullPath), exportDir, deletedDirs);
120
+ }
121
+ catch {
122
+ // File might not exist, ignore
123
+ }
124
+ }
125
+ }
126
+ // Cleanup OG
127
+ for (const [urlPath, ogState] of Object.entries(oldState.og)) {
128
+ if (!newState.og[urlPath]) {
129
+ const fullPath = path.join(exportDir, ogState.outputPath);
130
+ try {
131
+ await fs.unlink(fullPath);
132
+ deleted.push(fullPath);
133
+ await cleanupEmptyDir(path.dirname(fullPath), exportDir, deletedDirs);
134
+ }
135
+ catch {
136
+ // File might not exist, ignore
137
+ }
138
+ }
139
+ }
140
+ return { deleted, deletedDirs };
141
+ }
142
+ /**
143
+ * Recursively delete empty directories up to rootDir
144
+ */
145
+ async function cleanupEmptyDir(dir, rootDir, deletedDirs) {
146
+ while (dir !== rootDir) {
147
+ try {
148
+ const entries = await fs.readdir(dir);
149
+ if (entries.length === 0) {
150
+ await fs.rmdir(dir);
151
+ deletedDirs.push(dir);
152
+ dir = path.dirname(dir);
153
+ }
154
+ else {
155
+ break;
156
+ }
157
+ }
158
+ catch {
159
+ // Directory might not exist, stop
160
+ break;
161
+ }
162
+ }
163
+ }
164
+ //# sourceMappingURL=export-state.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"export-state.js","sourceRoot":"","sources":["../src/export-state.ts"],"names":[],"mappings":"AAAA,4DAA4D;AAE5D,OAAO,EAAE,QAAQ,IAAI,EAAE,EAAE,MAAM,SAAS,CAAC;AACzC,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,uBAAuB,EAAE,MAAM,qBAAqB,CAAC;AAE9D,MAAM,eAAe,GAAG,0BAA0B,CAAC;AACnD,MAAM,mBAAmB,GAAG,sBAAsB,CAAC;AAwBnD;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,OAAe;IACnD,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,eAAe,CAAC,CAAC;IACtD,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;QACtD,OAAO,IAAI,CAAC,KAAK,CAAC,OAAO,CAAgB,CAAC;IAC5C,CAAC;IAAC,MAAM,CAAC;QACP,uDAAuD;QACvD,OAAO,EAAE,YAAY,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC;IAChD,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,OAAe,EACf,KAAkB;IAElB,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,eAAe,CAAC,CAAC;IACtD,MAAM,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,QAAQ,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAClE,MAAM,EAAE,CAAC,SAAS,CAAC,SAAS,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;AACzE,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,OAAe,EACf,SAAiB;IAEjB,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,QAAQ,EAAE,IAAI,CAAC,CAAC;IACtD,MAAM,YAAY,GAAG,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,mBAAmB,CAAC,CAAC;IAE9D,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC;QACzD,MAAM,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAA2B,CAAC;QAEjE,mCAAmC;QACnC,MAAM,QAAQ,GAAgB;YAC5B,YAAY,EAAE,EAAE;YAChB,IAAI,EAAE,EAAE;YACR,EAAE,EAAE,EAAE;SACP,CAAC;QAEF,KAAK,MAAM,CAAC,QAAQ,EAAE,IAAI,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,CAAC;YAC1D,sCAAsC;YACtC,MAAM,UAAU,GAAG,kBAAkB,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;YACvD,QAAQ,CAAC,EAAE,CAAC,QAAQ,CAAC,GAAG;gBACtB,UAAU,EAAE,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,EAAE,UAAU,CAAC;gBACjD,IAAI;aACL,CAAC;QACJ,CAAC;QAED,wCAAwC;QACxC,MAAM,EAAE,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC;QAE9B,OAAO,QAAQ,CAAC;IAClB,CAAC;IAAC,MAAM,CAAC;QACP,0DAA0D;QAC1D,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,SAAS,kBAAkB,CACzB,QAAgB,EAChB,SAAwB,KAAK;IAE7B,MAAM,UAAU,GAAG,QAAQ,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;IACnE,MAAM,QAAQ,GAAG,UAAU,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE;QACrD,OAAO,OAAO,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,aAAa,EAAE,EAAE,CAAC,CAAC;IAC1D,CAAC,CAAC,CAAC;IACH,OAAO,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,OAAO,MAAM,EAAE,CAAC;AAC9C,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB,CAAC,QAAgB;IACtD,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;QACrD,OAAO,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IAC5D,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,qBAAqB,CAAC,OAAe;IACzD,MAAM,YAAY,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,sBAAsB,CAAC,CAAC;IAChE,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC;QACzD,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QACnC,OAAO,MAAM,CAAC,OAAO,CAAC,CAAC,2BAA2B;QAClD,OAAO,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IAC3E,CAAC;IAAC,MAAM,CAAC;QACP,iDAAiD;QACjD,MAAM,eAAe,GAAG,uBAAuB,EAAE,CAAC;QAClD,MAAM,EAAE,OAAO,EAAE,GAAG,qBAAqB,EAAE,GAAG,eAAsB,CAAC;QACrE,OAAO,UAAU,CAAC,QAAQ,CAAC;aACxB,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,qBAAqB,CAAC,CAAC;aAC7C,MAAM,CAAC,KAAK,CAAC,CAAC;IACnB,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,oBAAoB,CACxC,SAAiB,EACjB,QAAqB,EACrB,QAAqB;IAErB,MAAM,OAAO,GAAa,EAAE,CAAC;IAC7B,MAAM,WAAW,GAAa,EAAE,CAAC;IAEjC,eAAe;IACf,KAAK,MAAM,CAAC,OAAO,EAAE,SAAS,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;QACjE,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;YAC5B,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,SAAS,CAAC,UAAU,CAAC,CAAC;YAC5D,IAAI,CAAC;gBACH,MAAM,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;gBAC1B,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;gBACvB,MAAM,eAAe,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,SAAS,EAAE,WAAW,CAAC,CAAC;YACxE,CAAC;YAAC,MAAM,CAAC;gBACP,+BAA+B;YACjC,CAAC;QACH,CAAC;IACH,CAAC;IAED,aAAa;IACb,KAAK,MAAM,CAAC,OAAO,EAAE,OAAO,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC,EAAE,CAAC;QAC7D,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC;YAC1B,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,OAAO,CAAC,UAAU,CAAC,CAAC;YAC1D,IAAI,CAAC;gBACH,MAAM,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;gBAC1B,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;gBACvB,MAAM,eAAe,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,SAAS,EAAE,WAAW,CAAC,CAAC;YACxE,CAAC;YAAC,MAAM,CAAC;gBACP,+BAA+B;YACjC,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,EAAE,OAAO,EAAE,WAAW,EAAE,CAAC;AAClC,CAAC;AAED;;GAEG;AACH,KAAK,UAAU,eAAe,CAC5B,GAAW,EACX,OAAe,EACf,WAAqB;IAErB,OAAO,GAAG,KAAK,OAAO,EAAE,CAAC;QACvB,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;YACtC,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBACzB,MAAM,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;gBACpB,WAAW,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;gBACtB,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;YAC1B,CAAC;iBAAM,CAAC;gBACN,MAAM;YACR,CAAC;QACH,CAAC;QAAC,MAAM,CAAC;YACP,kCAAkC;YAClC,MAAM;QACR,CAAC;IACH,CAAC;AACH,CAAC"}
@@ -4,6 +4,7 @@ export interface ExportOptions {
4
4
  outputDir: string;
5
5
  settings: Settings;
6
6
  silent?: boolean;
7
+ forceOg?: boolean;
7
8
  }
8
9
  export declare function exportStaticSite(options: ExportOptions): Promise<void>;
9
10
  //# sourceMappingURL=static-export.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"static-export.d.ts","sourceRoot":"","sources":["../../src/generators/static-export.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAOrD,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,QAAQ,CAAC;IACnB,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAwBD,wBAAsB,gBAAgB,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CA+E5E"}
1
+ {"version":3,"file":"static-export.d.ts","sourceRoot":"","sources":["../../src/generators/static-export.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAkBrD,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,QAAQ,CAAC;IACnB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAyBD,wBAAsB,gBAAgB,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAqK5E"}
@@ -7,6 +7,7 @@ import { buildSidebar } from "../template/sidebar.js";
7
7
  import { renderDirectory } from "../directory.js";
8
8
  import { buildSearchIndex } from "./search-index.js";
9
9
  import { generateOgImage, getOgImagePath, } from "../og/index.js";
10
+ import { loadExportState, saveExportState, migrateOldState, cleanupOrphanedFiles, calculateFileHash, calculateSettingsHash, } from "../export-state.js";
10
11
  function withBasePath(href, settings) {
11
12
  const basePath = settings.generate.basePath || "";
12
13
  if (!basePath)
@@ -17,7 +18,7 @@ function withBasePath(href, settings) {
17
18
  return normalizedBase + href;
18
19
  }
19
20
  export async function exportStaticSite(options) {
20
- const { rootDir, outputDir, settings, silent = false } = options;
21
+ let { rootDir, outputDir, settings, silent = false, forceOg = false, } = options;
21
22
  try {
22
23
  // 1. Validate input/output directories
23
24
  const absRootDir = path.resolve(rootDir);
@@ -34,11 +35,36 @@ export async function exportStaticSite(options) {
34
35
  console.log(` From: ${absRootDir}`);
35
36
  console.log(` To: ${absOutputDir}\n`);
36
37
  }
38
+ // 1.5. Load and migrate old state if needed
39
+ let oldState = await loadExportState(absRootDir);
40
+ const migratedState = await migrateOldState(absRootDir, absOutputDir);
41
+ if (migratedState) {
42
+ oldState = migratedState;
43
+ if (!silent) {
44
+ console.log(` 📦 Migrated old OG state to new format`);
45
+ }
46
+ }
47
+ // 1.6. Check if settings changed - if so, force full export
48
+ const currentSettingsHash = await calculateSettingsHash(absRootDir);
49
+ if (oldState.settingsHash &&
50
+ oldState.settingsHash !== currentSettingsHash) {
51
+ if (!silent) {
52
+ console.log(` ⚙️ Settings changed, forcing full export`);
53
+ }
54
+ // Clear old state to force regeneration of all files
55
+ oldState = { settingsHash: "", html: {}, og: {} };
56
+ forceOg = true;
57
+ }
37
58
  // 2. Process all markdown files
38
59
  let processedCount = 0;
39
60
  const dirMap = new Map();
40
61
  const pageInfos = [];
41
- await processDirectory(absRootDir, absOutputDir, absRootDir, settings, silent, dirMap, pageInfos, (count) => {
62
+ const currentState = {
63
+ settingsHash: currentSettingsHash,
64
+ html: {},
65
+ og: {},
66
+ };
67
+ await processDirectory(absRootDir, absOutputDir, absRootDir, settings, silent, dirMap, pageInfos, currentState, (count) => {
42
68
  processedCount = count;
43
69
  });
44
70
  // 3. Generate auto-index pages for directories without README/index
@@ -47,17 +73,41 @@ export async function exportStaticSite(options) {
47
73
  if (!dirInfo.hasIndex) {
48
74
  await generateAutoIndex(dirInfo, rootDir, settings);
49
75
  autoIndexCount++;
76
+ const autoIndexOutputPath = path.join(dirInfo.outputPath, "index.html");
77
+ const relativeOutputPath = path.relative(absOutputDir, autoIndexOutputPath);
78
+ // Add to pageInfos so OG images are generated for auto-index pages
79
+ pageInfos.push({
80
+ urlPath: dirInfo.urlPath,
81
+ outputPath: autoIndexOutputPath,
82
+ sourcePath: "", // Auto-index pages have no source file
83
+ title: dirInfo.urlPath ? `Index of ${dirInfo.urlPath}` : "Index",
84
+ description: settings.site.description,
85
+ });
86
+ // Track auto-index page in current state
87
+ currentState.html[dirInfo.urlPath] = {
88
+ outputPath: relativeOutputPath,
89
+ sourcePath: "",
90
+ hash: "auto-index",
91
+ };
50
92
  if (!silent) {
51
- console.log(` ✓ ${path.relative(absOutputDir, dirInfo.outputPath)}/index.html (auto-generated)`);
93
+ console.log(` ✓ ${relativeOutputPath} (auto-generated)`);
52
94
  }
53
95
  }
54
96
  }
97
+ // 3.5. Cleanup orphaned files before generating new content
98
+ const cleanupResult = await cleanupOrphanedFiles(absOutputDir, oldState, currentState);
99
+ if (cleanupResult.deleted.length > 0 && !silent) {
100
+ console.log(` 🧹 Cleaned up ${cleanupResult.deleted.length} orphaned files`);
101
+ }
102
+ if (cleanupResult.deletedDirs.length > 0 && !silent) {
103
+ console.log(` 🧹 Cleaned up ${cleanupResult.deletedDirs.length} empty directories`);
104
+ }
55
105
  // 4. Generate OG images if enabled
56
106
  if (settings.seo.og?.enabled) {
57
107
  if (!silent) {
58
108
  console.log(`\n 🖼️ Generating OG images...`);
59
109
  }
60
- await generateOgImages(pageInfos, absOutputDir, settings, silent);
110
+ await generateOgImages(pageInfos, absOutputDir, absRootDir, settings, silent, forceOg, currentState, oldState);
61
111
  }
62
112
  // 5. Generate search-index.json if search is enabled
63
113
  if (settings.search.enabled) {
@@ -68,6 +118,8 @@ export async function exportStaticSite(options) {
68
118
  console.log(` ✓ search-index.json (${searchIndex.length} entries)`);
69
119
  }
70
120
  }
121
+ // 6. Save new export state
122
+ await saveExportState(absRootDir, currentState);
71
123
  if (!silent) {
72
124
  console.log(`\n ✓ Export complete: ${processedCount} pages generated\n`);
73
125
  }
@@ -77,7 +129,7 @@ export async function exportStaticSite(options) {
77
129
  throw new Error(`Export failed: ${message}`);
78
130
  }
79
131
  }
80
- async function processDirectory(dirPath, outputPath, rootDir, settings, silent, dirMap, pageInfos, updateCount, count = 0) {
132
+ async function processDirectory(dirPath, outputPath, rootDir, settings, silent, dirMap, pageInfos, currentState, updateCount, count = 0) {
81
133
  const entries = await fs.readdir(dirPath, { withFileTypes: true });
82
134
  // Track this directory for auto-index generation
83
135
  const relativePath = path.relative(rootDir, dirPath);
@@ -111,7 +163,7 @@ async function processDirectory(dirPath, outputPath, rootDir, settings, silent,
111
163
  else {
112
164
  // Create directory in output and process normally
113
165
  await fs.mkdir(outputFilePath, { recursive: true });
114
- count = await processDirectory(fullPath, outputFilePath, rootDir, settings, silent, dirMap, pageInfos, updateCount, count);
166
+ count = await processDirectory(fullPath, outputFilePath, rootDir, settings, silent, dirMap, pageInfos, currentState, updateCount, count);
115
167
  }
116
168
  }
117
169
  else if (entry.isFile()) {
@@ -152,7 +204,7 @@ async function processDirectory(dirPath, outputPath, rootDir, settings, silent,
152
204
  .replace(/\.(md|mdx)$/, "");
153
205
  urlPath = withBasePath(rawUrlPath, settings);
154
206
  }
155
- const pageInfo = await renderMarkdownFile(fullPath, htmlOutputPath, urlPath, rootDir, settings);
207
+ const pageInfo = await renderMarkdownFile(fullPath, htmlOutputPath, urlPath, rootDir, settings, currentState);
156
208
  pageInfos.push(pageInfo);
157
209
  if (!silent) {
158
210
  const displayPath = baseNameLower === "readme"
@@ -172,7 +224,7 @@ async function processDirectory(dirPath, outputPath, rootDir, settings, silent,
172
224
  }
173
225
  return count;
174
226
  }
175
- async function renderMarkdownFile(filePath, outputPath, urlPath, rootDir, settings) {
227
+ async function renderMarkdownFile(filePath, outputPath, urlPath, rootDir, settings, currentState) {
176
228
  const content = await fs.readFile(filePath, "utf-8");
177
229
  const ext = path.extname(filePath).toLowerCase();
178
230
  let result;
@@ -204,10 +256,20 @@ async function renderMarkdownFile(filePath, outputPath, urlPath, rootDir, settin
204
256
  isStaticExport: true,
205
257
  });
206
258
  await fs.writeFile(outputPath, html, "utf-8");
259
+ // Calculate hash and track in current state
260
+ const hash = await calculateFileHash(filePath);
261
+ const relativeOutputPath = path.relative(rootDir, outputPath);
262
+ const relativeSourcePath = path.relative(rootDir, filePath);
263
+ currentState.html[urlPath] = {
264
+ outputPath: relativeOutputPath,
265
+ sourcePath: relativeSourcePath,
266
+ hash,
267
+ };
207
268
  // Return page info for OG generation
208
269
  return {
209
270
  urlPath,
210
271
  outputPath,
272
+ sourcePath: filePath,
211
273
  title,
212
274
  description: result.frontmatter.description,
213
275
  };
@@ -297,16 +359,15 @@ function humanizeFilename(filename) {
297
359
  /**
298
360
  * Generate OG images for all pages
299
361
  */
300
- async function generateOgImages(pageInfos, outputDir, settings, silent) {
362
+ async function generateOgImages(pageInfos, outputDir, rootDir, settings, silent, forceOg = false, currentState, oldState) {
301
363
  const publicDir = path.join(outputDir, "public");
302
364
  const ogDir = path.join(publicDir, "og");
303
365
  const format = settings.seo.og?.imageFormat || "jpg";
304
366
  const ogSettings = settings.seo.og;
305
367
  let generatedCount = 0;
306
368
  let failedCount = 0;
369
+ let skippedCount = 0;
307
370
  for (const pageInfo of pageInfos) {
308
- // Skip if the page already has a custom image
309
- // if (pageInfo.image) continue;
310
371
  const ogImagePath = getOgImagePath(pageInfo.urlPath, ogDir, format, settings.generate.basePath);
311
372
  // Build OG image data
312
373
  const ogData = {
@@ -319,23 +380,65 @@ async function generateOgImages(pageInfos, outputDir, settings, silent) {
319
380
  backgroundColor: ogSettings?.colors?.background || "#0a0a0f",
320
381
  textColor: ogSettings?.colors?.text || "#ffffff",
321
382
  };
322
- // Generate the OG image
323
- const result = await generateOgImage(ogData, {
324
- outputPath: ogImagePath,
325
- format,
326
- quality: 85,
327
- });
328
- if (result.success) {
329
- generatedCount++;
330
- if (!silent) {
331
- const displayPath = path.relative(outputDir, ogImagePath);
332
- console.log(` ✓ OG image: ${displayPath}`);
383
+ // For incremental export, check if file has changed
384
+ let shouldGenerate = forceOg;
385
+ let fileHash = "";
386
+ if (!forceOg) {
387
+ // Calculate hash for the source file
388
+ if (pageInfo.sourcePath) {
389
+ try {
390
+ fileHash = await calculateFileHash(pageInfo.sourcePath);
391
+ const relativeOgPath = path.relative(outputDir, ogImagePath);
392
+ currentState.og[pageInfo.urlPath] = {
393
+ outputPath: relativeOgPath,
394
+ hash: fileHash,
395
+ };
396
+ // Check if hash changed by comparing with old state
397
+ const oldHash = oldState.html[pageInfo.urlPath]?.hash;
398
+ if (oldHash !== fileHash) {
399
+ shouldGenerate = true;
400
+ }
401
+ }
402
+ catch {
403
+ // If we can't calculate hash, generate the image
404
+ shouldGenerate = true;
405
+ }
406
+ }
407
+ else {
408
+ // Auto-index pages have no source, always generate
409
+ shouldGenerate = true;
410
+ const relativeOgPath = path.relative(outputDir, ogImagePath);
411
+ currentState.og[pageInfo.urlPath] = {
412
+ outputPath: relativeOgPath,
413
+ hash: "auto-index",
414
+ };
415
+ }
416
+ }
417
+ if (shouldGenerate) {
418
+ // Generate the OG image
419
+ const result = await generateOgImage(ogData, {
420
+ outputPath: ogImagePath,
421
+ format,
422
+ quality: 85,
423
+ });
424
+ if (result.success) {
425
+ generatedCount++;
426
+ if (!silent) {
427
+ const displayPath = path.relative(outputDir, ogImagePath);
428
+ console.log(` ✓ OG image: ${displayPath}`);
429
+ }
430
+ }
431
+ else {
432
+ failedCount++;
433
+ if (!silent) {
434
+ console.log(` ✗ OG image failed: ${pageInfo.urlPath} (${result.error})`);
435
+ }
333
436
  }
334
437
  }
335
438
  else {
336
- failedCount++;
439
+ skippedCount++;
337
440
  if (!silent) {
338
- console.log(` OG image failed: ${pageInfo.urlPath} (${result.error})`);
441
+ console.log(` OG image skipped: ${pageInfo.urlPath} (unchanged)`);
339
442
  }
340
443
  }
341
444
  }
@@ -343,7 +446,12 @@ async function generateOgImages(pageInfos, outputDir, settings, silent) {
343
446
  await createEmptyIndexFile(publicDir);
344
447
  await createEmptyIndexFile(ogDir);
345
448
  if (!silent) {
346
- console.log(` ✓ OG images: ${generatedCount} generated, ${failedCount} failed`);
449
+ if (forceOg) {
450
+ console.log(` ✓ OG images: ${generatedCount} generated, ${failedCount} failed (forced)`);
451
+ }
452
+ else {
453
+ console.log(` ✓ OG images: ${generatedCount} changed, ${skippedCount} skipped, ${failedCount} failed`);
454
+ }
347
455
  }
348
456
  }
349
457
  /**