diff --git a/.gitignore b/.gitignore index 4e42f48..b4e75f3 100644 --- a/.gitignore +++ b/.gitignore @@ -131,3 +131,4 @@ dist .pnp.* ignore data +.test diff --git a/src/index.ts b/src/index.ts index a345eb7..907e09a 100644 --- a/src/index.ts +++ b/src/index.ts @@ -5,43 +5,41 @@ import fs from "fs"; import path from "path"; import jsdom from "jsdom"; import IConfig from "@src/types/Config"; +import IPost from "@src/types/Post"; +// parse config (cant use require or import because the compiler gets mad) let config: IConfig = JSON.parse(fs.readFileSync(path.join(__dirname, '../', 'data', 'config.json'), 'utf-8')) + +// init app let app = express(); // set view engine to ejs app.set("view engine", "ejs") app.set('views', path.join(__dirname, 'views', 'themes', config.theme)) -// type for post object -type Post = { - file: string; - title: string; - parsedPost: string; - rawPost: string; - metadata: fs.Stats; -} - // html stripper, used for title -async function htmlstripper(html: string){ +async function htmlStripper(html: string){ return new jsdom.JSDOM(html).window.document.body.textContent || " "; } // returns Post array -async function contentScan(){ - let posts: Post[] = [] +async function contentScan(): Promise{ + let posts: IPost[] = [] let postsDir = path.join(__dirname, '../', 'data',"posts") let files = await fs.readdirSync(postsDir).filter((name: string) => name.toLowerCase().endsWith(".md")) for (const file of files) { + let postPath = path.join(postsDir, file) let metadata = fs.statSync(postPath) let postContent = fs.readFileSync(postPath, "utf-8") + + // Retrieve first line in file, then turn it into html and then strip the html. posts.push( { file: file, - title: await htmlstripper( + title: await htmlStripper( await marked.parse( - postContent.split("\n")[0] + postContent.split("\n")[0] ) ), metadata: metadata, @@ -54,15 +52,23 @@ async function contentScan(){ } app.get("/", async (req:express.Request,res:express.Response) => { + // render index.ejs & pass config, and posts. res.render(`index`, {posts: (await contentScan()), config: config}) }); +// post reader app.use("/post/:post", async (req:express.Request,res:express.Response) => { + + // check if the post exists let pathToPost = path.join(__dirname, '../', 'data', "posts", req.params.post); - if(!fs.existsSync(pathToPost)) return res.end("404."); + if(!fs.existsSync(pathToPost)) return res.status(404).end(); + + // retrieve posts and check for parameter let posts = await contentScan(); let post = posts.filter(post => post.file === req.params.post) - if(!post[0]) return res.end("404.") + if(!post[0]) return res.status(404).end() + + // render post using post.ejs. pass all the posts, the post itself and the config res.render(`post`, {posts: posts, post: post[0], config: config}) }) diff --git a/src/types/Post.ts b/src/types/Post.ts new file mode 100644 index 0000000..91a1dbc --- /dev/null +++ b/src/types/Post.ts @@ -0,0 +1,10 @@ +import fs from "fs" +export default interface IPost { + file: string; // File name + title: string; // Title of post, usually the first line. + parsedPost: string; // Parsed Post (MD => HTML) + rawPost: string; // Raw Markdown Post + metadata: fs.Stats; // Metadata provided by FS +} + +