1- import { marked } from 'marked ' ;
1+ import { ContentModel } from 'mobx-github ' ;
22import { treeFrom } from 'web-utility' ;
3- import * as fs from 'fs' ;
4- import * as path from 'path' ;
3+ import { githubClient } from './Base' ;
54
65export interface WikiNode {
76 name ?: string ;
@@ -18,58 +17,52 @@ export interface WikiNode {
1817 download_url ?: string ;
1918 content ?: string ;
2019 metadata ?: Record < string , string > ;
20+ labels ?: string [ ] ;
2121}
2222
23+ export const contentStore = new ContentModel ( 'fpsig' , 'open-source-policy' ) ;
24+
2325class WikiModel {
24- // TODO: Use ContentModel from mobx-github once authentication is configured
25- // private contentModel = new ContentModel('fpsig', 'open-source-policy');
26+ private contentModel = contentStore ;
2627
2728 async getAllContent ( ) : Promise < WikiNode [ ] > {
28- const items : WikiNode [ ] = [ ] ;
29- const policyDir = path . join ( process . cwd ( ) , 'public/wiki/policy/China/政策' ) ;
30-
31- if ( ! fs . existsSync ( policyDir ) ) {
32- return items ;
33- }
34-
35- const processDirectory = ( dir : string , baseDir : string = '' ) => {
36- const files = fs . readdirSync ( dir ) ;
29+ try {
30+ const items : WikiNode [ ] = [ ] ;
3731
38- for ( const file of files ) {
39- const fullPath = path . join ( dir , file ) ;
40- const stat = fs . statSync ( fullPath ) ;
41-
42- if ( stat . isDirectory ( ) ) {
43- const subDir = baseDir ? `${ baseDir } /${ file } ` : file ;
44- processDirectory ( fullPath , subDir ) ;
45- } else if ( file . endsWith ( '.md' ) ) {
46- const relativePath = baseDir ? `${ baseDir } /${ file } ` : file ;
32+ // Use traverseTree to get all markdown files recursively from China/政策
33+ for await ( const item of this . contentModel . traverseTree ( ) ) {
34+ if ( item . type === 'file' && item . name . endsWith ( '.md' ) && item . path . startsWith ( 'China/政策/' ) ) {
35+ // Remove the 'China/政策/' prefix to get relative path within wiki
36+ const relativePath = item . path . replace ( 'China/政策/' , '' ) ;
4737 const pathParts = relativePath . split ( '/' ) ;
4838 const fileName = pathParts . pop ( ) ;
4939 const parent_path = pathParts . length > 0 ? pathParts . join ( '/' ) : undefined ;
50-
40+
5141 const wikiNode : WikiNode = {
5242 name : fileName || '' ,
5343 path : relativePath . replace ( '.md' , '' ) ,
5444 parent_path,
5545 title : fileName ?. replace ( '.md' , '' ) || '' ,
56- type : 'file' ,
57- size : stat . size ,
58- sha : '' ,
59- url : '' ,
60- html_url : `https://github.com/fpsig/open-source-policy/blob/main/China/政策/ ${ relativePath } ` ,
61- git_url : '' ,
62- download_url : `https://raw.githubusercontent.com/fpsig/open-source-policy/main/China/政策/ ${ relativePath } ` ,
46+ type : item . type ,
47+ size : item . size ,
48+ sha : item . sha ,
49+ url : item . url ,
50+ html_url : item . html_url || undefined ,
51+ git_url : item . git_url || undefined ,
52+ download_url : item . download_url || undefined ,
6353 content : '' ,
54+ labels : [ ] ,
6455 } ;
65-
56+
6657 items . push ( wikiNode ) ;
6758 }
6859 }
69- } ;
7060
71- processDirectory ( policyDir ) ;
72- return items ;
61+ return items ;
62+ } catch ( error ) {
63+ console . error ( 'Error fetching content from GitHub:' , error ) ;
64+ return [ ] ;
65+ }
7366 }
7467
7568 async getContentTree ( ) : Promise < WikiNode [ ] > {
@@ -79,21 +72,23 @@ class WikiModel {
7972
8073 async getWikiContent ( pathParam : string ) : Promise < WikiNode > {
8174 const fullPath = pathParam . endsWith ( '.md' ) ? pathParam : `${ pathParam } .md` ;
82- const filePath = path . join ( process . cwd ( ) , 'public/wiki/policy/China/政策' , fullPath ) ;
75+ const filePath = `China/政策/${ fullPath } ` ;
76+
77+ const item = await this . contentModel . getOne ( filePath ) ;
8378
84- if ( ! fs . existsSync ( filePath ) ) {
79+ if ( ! item || item . type !== 'file' ) {
8580 throw new Error ( `Content not found at path: ${ pathParam } ` ) ;
8681 }
8782
88- const fileContent = fs . readFileSync ( filePath , 'utf-8' ) ;
89- const stat = fs . statSync ( filePath ) ;
83+ // Decode Base64 content
84+ const content = item . content ? atob ( item . content ) : '' ;
9085
9186 // Parse frontmatter
9287 let metadata : Record < string , string > = { } ;
9388 let markdownContent = '' ;
9489
95- if ( fileContent . startsWith ( '---\n' ) ) {
96- const parts = fileContent . split ( '\n---\n' ) ;
90+ if ( content . startsWith ( '---\n' ) ) {
91+ const parts = content . split ( '\n---\n' ) ;
9792 if ( parts . length >= 2 ) {
9893 const frontmatter = parts [ 0 ] . substring ( 4 ) ; // Remove first '---\n'
9994 markdownContent = parts . slice ( 1 ) . join ( '\n---\n' ) ;
@@ -108,7 +103,7 @@ class WikiModel {
108103 }
109104 }
110105 } else {
111- markdownContent = fileContent ;
106+ markdownContent = content ;
112107 }
113108
114109 const pathParts = pathParam . split ( '/' ) ;
@@ -120,15 +115,16 @@ class WikiModel {
120115 path : pathParam . replace ( '.md' , '' ) ,
121116 parent_path,
122117 title : metadata [ 'name' ] || fileName ?. replace ( '.md' , '' ) || '' ,
123- type : 'file' ,
124- size : stat . size ,
125- sha : '' ,
126- url : '' ,
127- html_url : `https://github.com/fpsig/open-source-policy/blob/main/China/政策/ ${ fullPath } ` ,
128- git_url : '' ,
129- download_url : `https://raw.githubusercontent.com/fpsig/open-source-policy/main/China/政策/ ${ fullPath } ` ,
118+ type : item . type ,
119+ size : item . size ,
120+ sha : item . sha ,
121+ url : item . url ,
122+ html_url : item . html_url || undefined ,
123+ git_url : item . git_url || undefined ,
124+ download_url : item . download_url || undefined ,
130125 content : markdownContent ,
131126 metadata,
127+ labels : [ ] ,
132128 } ;
133129 }
134130}
0 commit comments