Skip to content

Commit 080e25c

Browse files
committed
chore: do some stuff on mdx-to-md converter
1 parent 0c888e1 commit 080e25c

4 files changed

Lines changed: 160 additions & 4 deletions

File tree

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@
1212

1313
all-links-llms.txt
1414

15+
# mdx-to-md manifest (tracks processed files)
16+
public/llms/.mdx-to-md-manifest.json
17+
1518
# testing
1619
/coverage
1720

mdx-to-md-converter/src/index.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import {
2525
getAbsolutePaths,
2626
findMdxFilesWithoutMd
2727
} from './modules/gitChanges';
28+
import { ManifestManager } from './modules/manifestManager';
2829

2930
import fs from 'fs';
3031
import path from 'path';
@@ -155,6 +156,8 @@ async function main() {
155156
const outputDir = path.join(projectRoot, 'public', 'llms');
156157
const allLinksPath = path.join(projectRoot, 'public', 'all-links-llms.txt');
157158

159+
const manifest = new ManifestManager(outputDir);
160+
158161
console.log(`Searching for MDX files in: ${srcPagesPath}`);
159162

160163
const processAll = shouldProcessAllFiles();
@@ -251,6 +254,8 @@ async function main() {
251254
fs.writeFileSync(outputFilePath, '\ufeff' + finalMdContent, { encoding: 'utf8' });
252255
console.log(`✓ Saved: ${outputFilePath}`);
253256

257+
manifest.markAsProcessed(filePath, outputFilePath);
258+
254259
const urlPath = `llms/${mdFileName.replace(/\\/g, '/')}`;
255260
const url = `https://docs.liara.ir/${urlPath}`;
256261

mdx-to-md-converter/src/modules/gitChanges.ts

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { execSync } from 'child_process';
22
import fs from 'fs';
33
import path from 'path';
4+
import { ManifestManager } from './manifestManager';
45

56
export interface GitChanges {
67
modified: string[];
@@ -126,7 +127,8 @@ export function getAbsolutePaths(relativePaths: string[], basePath: string): str
126127

127128

128129
export function findMdxFilesWithoutMd(srcPagesPath: string, outputDir: string): string[] {
129-
const missingMdFiles: string[] = [];
130+
const filesToProcess: string[] = [];
131+
const manifest = new ManifestManager(outputDir);
130132

131133
function traverseMdxFiles(currentDir: string) {
132134
const items = fs.readdirSync(currentDir);
@@ -143,8 +145,8 @@ export function findMdxFilesWithoutMd(srcPagesPath: string, outputDir: string):
143145
const mdFileName = relativePath.replace(/\.mdx$/, '.md');
144146
const mdFilePath = path.join(outputDir, mdFileName);
145147

146-
if (!fs.existsSync(mdFilePath)) {
147-
missingMdFiles.push(relativePath);
148+
if (manifest.needsProcessing(fullPath, mdFilePath)) {
149+
filesToProcess.push(relativePath);
148150
}
149151
}
150152
}
@@ -154,5 +156,5 @@ export function findMdxFilesWithoutMd(srcPagesPath: string, outputDir: string):
154156
traverseMdxFiles(srcPagesPath);
155157
}
156158

157-
return missingMdFiles;
159+
return filesToProcess;
158160
}
Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
import fs from 'fs';
2+
import path from 'path';
3+
import crypto from 'crypto';
4+
5+
interface ManifestEntry {
6+
mdxPath: string;
7+
mdPath: string;
8+
mdxHash: string;
9+
lastProcessed: string;
10+
}
11+
12+
interface Manifest {
13+
version: string;
14+
entries: Record<string, ManifestEntry>;
15+
}
16+
17+
const MANIFEST_VERSION = '1.0.0';
18+
19+
export class ManifestManager {
20+
private manifestPath: string;
21+
private manifest: Manifest;
22+
23+
constructor(outputDir: string) {
24+
this.manifestPath = path.join(outputDir, '.mdx-to-md-manifest.json');
25+
this.manifest = this.loadManifest();
26+
}
27+
28+
private loadManifest(): Manifest {
29+
if (fs.existsSync(this.manifestPath)) {
30+
try {
31+
const content = fs.readFileSync(this.manifestPath, 'utf-8');
32+
return JSON.parse(content);
33+
} catch (error) {
34+
console.warn('Failed to load manifest, creating new one:', error);
35+
}
36+
}
37+
38+
return {
39+
version: MANIFEST_VERSION,
40+
entries: {}
41+
};
42+
}
43+
44+
private saveManifest(): void {
45+
try {
46+
fs.writeFileSync(
47+
this.manifestPath,
48+
JSON.stringify(this.manifest, null, 2),
49+
'utf-8'
50+
);
51+
} catch (error) {
52+
console.error('Failed to save manifest:', error);
53+
}
54+
}
55+
56+
/**
57+
* Calculate MD5 hash of a file
58+
*/
59+
private calculateFileHash(filePath: string): string {
60+
try {
61+
const content = fs.readFileSync(filePath, 'utf-8');
62+
return crypto.createHash('md5').update(content).digest('hex');
63+
} catch (error) {
64+
return '';
65+
}
66+
}
67+
68+
/**
69+
* Check if an MDX file needs to be processed
70+
* Returns true if:
71+
* - File is not in manifest
72+
* - File hash has changed
73+
* - Corresponding MD file doesn't exist
74+
*/
75+
needsProcessing(mdxPath: string, mdPath: string): boolean {
76+
const entry = this.manifest.entries[mdxPath];
77+
78+
// If not in manifest, needs processing
79+
if (!entry) {
80+
return true;
81+
}
82+
83+
// If MD file doesn't exist, needs processing
84+
if (!fs.existsSync(mdPath)) {
85+
return true;
86+
}
87+
88+
// If MDX file hash has changed, needs processing
89+
const currentHash = this.calculateFileHash(mdxPath);
90+
if (currentHash !== entry.mdxHash) {
91+
return true;
92+
}
93+
94+
return false;
95+
}
96+
97+
/**
98+
* Mark a file as processed
99+
*/
100+
markAsProcessed(mdxPath: string, mdPath: string): void {
101+
const mdxHash = this.calculateFileHash(mdxPath);
102+
103+
this.manifest.entries[mdxPath] = {
104+
mdxPath,
105+
mdPath,
106+
mdxHash,
107+
lastProcessed: new Date().toISOString()
108+
};
109+
110+
this.saveManifest();
111+
}
112+
113+
/**
114+
* Remove entry from manifest (when MDX file is deleted)
115+
*/
116+
removeEntry(mdxPath: string): void {
117+
delete this.manifest.entries[mdxPath];
118+
this.saveManifest();
119+
}
120+
121+
/**
122+
* Get all entries
123+
*/
124+
getAllEntries(): Record<string, ManifestEntry> {
125+
return this.manifest.entries;
126+
}
127+
128+
/**
129+
* Clean up entries for files that no longer exist
130+
*/
131+
cleanup(existingMdxFiles: string[]): void {
132+
const existingSet = new Set(existingMdxFiles);
133+
let changed = false;
134+
135+
for (const mdxPath in this.manifest.entries) {
136+
if (!existingSet.has(mdxPath)) {
137+
delete this.manifest.entries[mdxPath];
138+
changed = true;
139+
}
140+
}
141+
142+
if (changed) {
143+
this.saveManifest();
144+
}
145+
}
146+
}

0 commit comments

Comments
 (0)