summary refs log tree commit diff
diff options
context:
space:
mode:
authorPatryk Niedźwiedziński <pniedzwiedzinski19@gmail.com>2020-01-28 11:55:03 +0100
committerPatryk Niedźwiedziński <pniedzwiedzinski19@gmail.com>2020-01-28 11:55:03 +0100
commit9f75ff1d2d5ebf34c040474e836e125f80253365 (patch)
tree523c52b9dd158e21d9247b58d81c655102323a26
parentc11d7a84aa59e9b1179a9834129b2d776bab8bca (diff)
downloadkronikarz-9f75ff1d2d5ebf34c040474e836e125f80253365.tar.gz
kronikarz-9f75ff1d2d5ebf34c040474e836e125f80253365.zip
Add Post class
-rw-r--r--lib/Post.ts70
-rw-r--r--lib/generateApi.ts49
-rw-r--r--lib/getPost.ts7
-rw-r--r--lib/getPosts.ts5
-rw-r--r--lib/index.ts2
-rw-r--r--lib/interfaces.ts35
-rw-r--r--lib/parsePost.ts46
-rw-r--r--lib/utils.ts14
-rw-r--r--test/getPost.spec.ts2
9 files changed, 144 insertions, 86 deletions
diff --git a/lib/Post.ts b/lib/Post.ts
new file mode 100644
index 0000000..27a6cb9
--- /dev/null
+++ b/lib/Post.ts
@@ -0,0 +1,70 @@
+import * as fs from 'fs';
+import { JSDOM } from 'jsdom';
+
+const frontmatter = require('front-matter');
+const md = require('markdown-it')();
+
+import { dateToPath, dateToString } from './utils';
+import { Date, FrontMatterObject, PostApiEntry, Meta } from './interfaces';
+
+export default class Post {
+  date: Date;
+  fileTitle: string;
+  fileContent: string;
+  post: FrontMatterObject;
+
+  constructor(filePath: string) {
+    let [year, month, day, title] = filePath.split('/').splice(-4, 4);
+    this.fileTitle = title.substr(0, title.lastIndexOf('.'));
+    this.date = { year, month, day };
+    this.fileContent = fs.readFileSync(filePath, 'utf-8');
+    this.post = frontmatter(this.fileContent);
+  }
+
+  toApi(): PostApiEntry {
+    const { author, title, additionalMeta } = this.getMeta();
+    const { description, html } = this.getPostContent();
+    return {
+      date: dateToString(this.date),
+      author,
+      title,
+      path: `/kronika/${dateToPath(this.date)}/${this.fileTitle}`,
+      description,
+      meta: additionalMeta,
+      content: html,
+    };
+  }
+
+  getMeta(): Meta {
+    const { attributes } = this.post;
+    const author: string = attributes.author;
+    delete attributes.author;
+    const title: string = attributes.title;
+    delete attributes.title;
+    return {
+      author,
+      title,
+      additionalMeta: attributes,
+    };
+  }
+
+  getPostContent() {
+    const { body } = this.post;
+    const html = `<div>${md.render(body)}</div>`;
+    const description = this.getDescription(html);
+
+    return {
+      html,
+      description,
+    };
+  }
+
+  getDescription(html: string): string {
+    const { document } = new JSDOM(`<div>${html}</div>`).window;
+    const elements = document.getElementsByTagName('p');
+
+    const description = elements[1].textContent;
+
+    return description || '';
+  }
+}
diff --git a/lib/generateApi.ts b/lib/generateApi.ts
index 836fa2a..cade7e4 100644
--- a/lib/generateApi.ts
+++ b/lib/generateApi.ts
@@ -1,29 +1,30 @@
-import fs from "fs";
-import path from "path";
-import { Post } from "./interfaces";
+import fs from 'fs';
+import path from 'path';
+import Post from './Post';
+import { dateToPath } from './utils';
 
 function mkDirByPathSync(targetDir: string) {
   const sep = path.sep;
-  const initDir = path.isAbsolute(targetDir) ? sep : "";
-  const baseDir = ".";
+  const initDir = path.isAbsolute(targetDir) ? sep : '';
+  const baseDir = '.';
 
   return targetDir.split(sep).reduce((parentDir, childDir) => {
     const curDir = path.resolve(baseDir, parentDir, childDir);
     try {
       fs.mkdirSync(curDir);
     } catch (err) {
-      if (err.code === "EEXIST") {
+      if (err.code === 'EEXIST') {
         // curDir already exists!
         return curDir;
       }
 
       // To avoid `EISDIR` error on Mac and `EACCES`-->`ENOENT` and `EPERM` on Windows.
-      if (err.code === "ENOENT") {
+      if (err.code === 'ENOENT') {
         // Throw the original parentDir error on curDir `ENOENT` failure.
         throw new Error(`EACCES: permission denied, mkdir '${parentDir}'`);
       }
 
-      const caughtErr = ["EACCES", "EPERM", "EISDIR"].indexOf(err.code) > -1;
+      const caughtErr = ['EACCES', 'EPERM', 'EISDIR'].indexOf(err.code) > -1;
       if (!caughtErr || (caughtErr && targetDir === curDir)) {
         throw err; // Throw if it's just the last created dir.
       }
@@ -34,26 +35,38 @@ function mkDirByPathSync(targetDir: string) {
 }
 
 export function saveApiEntry(post: Post, path: string) {
-  const { year, month, day } = post.date;
-  const dir = `${path}/api/posts/${year}/${month}/${day}`;
+  const dir = `${path}/api/posts/${dateToPath(post.date)}`;
 
   mkDirByPathSync(dir);
 
-  const apiEntry = {
-    title: post.title,
-    date: `${year}-${month}-${day}`,
-    content: post.content.html,
-    meta: post.content.meta
-  };
+  const apiEntry = post.toApi();
 
-  fs.writeFile(`${dir}/${post.title}.json`, JSON.stringify(apiEntry), err =>
+  fs.writeFile(
+    `${dir}/${post.fileTitle}.json`,
+    JSON.stringify(apiEntry),
+    (err) => (err ? console.log(err) : null)
+  );
+}
+
+/*
+ * This function generates paged api index on path `/api/paged-posts`
+ */
+function generateApiIndex(posts: Array<Post>, path: string) {
+  const parsedPosts = posts.map((post) => {
+    const apiEntry = post.toApi();
+    delete apiEntry.content;
+    return apiEntry;
+  });
+  const filePath = `${path}/api/posts.json`;
+  fs.writeFile(filePath, JSON.stringify(parsedPosts), (err) =>
     err ? console.log(err) : null
   );
 }
 
 export function generateApi(posts: Array<Post>, path: string) {
   try {
-    posts.forEach(post => saveApiEntry(post, path));
+    generateApiIndex(posts, path);
+    posts.forEach((post) => saveApiEntry(post, path));
   } catch (err) {
     console.log(err);
   }
diff --git a/lib/getPost.ts b/lib/getPost.ts
index 2555215..6e90b1f 100644
--- a/lib/getPost.ts
+++ b/lib/getPost.ts
@@ -1,5 +1,4 @@
-import { parsePost } from "./parsePost";
-import { Post } from "./interfaces";
+import Post from "./Post";
 
 interface getPostArgument {
   year: string;
@@ -14,6 +13,6 @@ export function getPost(
 ): Post {
   const filePath = `${path}/${year}/${month}/${day}/${title}.md`;
 
-  const post = parsePost(filePath);
-  return post;
+  const post = new Post(filePath);
+    return post;
 }
diff --git a/lib/getPosts.ts b/lib/getPosts.ts
index c363c67..814f6d8 100644
--- a/lib/getPosts.ts
+++ b/lib/getPosts.ts
@@ -1,5 +1,4 @@
-import { Post } from "./interfaces";
-import { parsePost } from "./parsePost";
+import Post from "./Post";
 import { readDir } from "./utils";
 
 function getPosts(path: string): Array<Post> {
@@ -14,7 +13,7 @@ function getPosts(path: string): Array<Post> {
         files.forEach((file: string) => {
           const fsRoute = `${path}/${year}/${month}/${day}/${file}`;
           try {
-            const post = parsePost(fsRoute);
+            const post = new Post(fsRoute);
             routesArray.push(post);
           } catch (err) {
             console.log(err);
diff --git a/lib/index.ts b/lib/index.ts
index f9647bc..4bf4dd3 100644
--- a/lib/index.ts
+++ b/lib/index.ts
@@ -1,7 +1,7 @@
 import { getPost as apiGetPost } from "./getPost";
 import { getPosts as apiGetPosts } from "./getPosts";
 import { generateApi as apiGenerateApi } from "./generateApi"
-import { Post } from "./interfaces";
+import Post from "./Post";
 
 export default class Kronikarz {
   postPath: string;
diff --git a/lib/interfaces.ts b/lib/interfaces.ts
index 1d598c6..974765f 100644
--- a/lib/interfaces.ts
+++ b/lib/interfaces.ts
@@ -1,24 +1,33 @@
-interface Date {
+export interface Date {
   year: string;
   month: string;
   day: string;
 }
 
-interface Meta {
-  [key: string]: string;
+/*export interface Meta {
+  [key: string]: object;
+}*/
+
+export interface Meta {
+  title: string;
+  author: string;
+    additionalMeta: object;
 }
 
-export interface PostContent {
-  html: string;
-  markdown: string;
-  description: string;
-  meta: Meta;
+export interface FrontMatterObject {
+  body: string;
+  attributes: Meta;
 }
 
-export interface Post {
-  date: Date;
+export interface PostApiListEntry {
+  date: string;
+  author: string;
   title: string;
-  content: PostContent;
-  filePath: string;
-  route: string;
+  path: string;
+  description: string;
+  meta: object;
+}
+
+export interface PostApiEntry extends PostApiListEntry {
+  content: string;
 }
diff --git a/lib/parsePost.ts b/lib/parsePost.ts
deleted file mode 100644
index 2f5f2b9..0000000
--- a/lib/parsePost.ts
+++ /dev/null
@@ -1,46 +0,0 @@
-import * as fs from "fs";
-import { JSDOM } from "jsdom";
-import { Post, PostContent } from "./interfaces";
-
-const frontmatter = require("front-matter");
-const md = require("markdown-it")();
-
-function getDescription(html: string): string {
-  const { document } = new JSDOM(`<div>${html}</div>`).window;
-  const elements = document.getElementsByTagName("p");
-
-  const description = elements[1].textContent;
-
-  return description || "";
-}
-
-function getPostContent(fileContent: string): PostContent {
-  const post = frontmatter(fileContent);
-
-  const markdown = post.body;
-  const html = `<div>${md.render(markdown)}</div>`;
-  const description = getDescription(html);
-
-  return {
-    html,
-    markdown,
-    description,
-    meta: post.attributes
-  };
-}
-
-export function parsePost(filePath: string): Post {
-  let [year, month, day, title] = filePath.split("/").splice(-4, 4);
-  title = title.substr(0, title.lastIndexOf("."));
-  const date = { year, month, day };
-  const fileContent = fs.readFileSync(filePath, "utf-8");
-  const content = getPostContent(fileContent);
-
-  return {
-    date,
-    title,
-    content,
-    filePath,
-    route: `/kronika/${year}/${month}/${day}/${title}`
-  };
-}
diff --git a/lib/utils.ts b/lib/utils.ts
index 23a3947..f75c0e4 100644
--- a/lib/utils.ts
+++ b/lib/utils.ts
@@ -1,4 +1,6 @@
 import * as fs from "fs";
+import { Date } from './interfaces';
+import Post from './Post'
 
 export function readDir(path: string): Array<string> {
   if (fs.existsSync(path)) {
@@ -7,3 +9,15 @@ export function readDir(path: string): Array<string> {
     throw `Path "${path}" doesn't exist`;
   }
 }
+
+export function sortPosts(posts: Array<Post>): Array<Post> {
+    return posts;
+}
+
+export function dateToString({ year, month, day }: Date): string {
+    return `${year}-${month}-${day}`
+}
+
+export function dateToPath({ year, month, day }: Date): string {
+    return `${year}/${month}/${day}`
+}
diff --git a/test/getPost.spec.ts b/test/getPost.spec.ts
index 6a5e4e0..72d7b5e 100644
--- a/test/getPost.spec.ts
+++ b/test/getPost.spec.ts
@@ -4,5 +4,5 @@ const k = new Kronikarz(__dirname + "/samples");
 
 test("simple get", () => {
   const post = k.getPost("2019", "12", "12", "test");
-  expect(post.content.meta["title"]).toBe("Test");
+  expect(post.title).toBe("Test");
 });