summary refs log tree commit diff
path: root/lib/generateApi.ts
blob: 0024d9ff7661d3cb6866b132b22d10376bd8c2e8 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
import fs from 'fs';
import path from 'path';
import Post from './Post';
import { dateToPath } from './utils';
import { Object as PlainObject } from './interfaces';

function mkDirByPathSync(targetDir: string) {
  const sep = path.sep;
  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') {
        // curDir already exists!
        return curDir;
      }

      // To avoid `EISDIR` error on Mac and `EACCES`-->`ENOENT` and `EPERM` on Windows.
      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;
      if (!caughtErr || (caughtErr && targetDir === curDir)) {
        throw err; // Throw if it's just the last created dir.
      }
    }

    return curDir;
  }, initDir);
}

export function saveApiEntry(post: Post, path: string) {
  const dir = `${path}/api/posts/${dateToPath(post.date)}`;

  mkDirByPathSync(dir);

  const apiEntry = post.toApi();

  fs.writeFile(
    `${dir}/${post.fileTitle}.json`,
    JSON.stringify(apiEntry),
    (err) => (err ? console.log(err) : null)
  );
}

/*
 * This function generates paged api index on path `/api/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
  );
}

function generateCategories(posts: Array<Post>, path: string) {
  const categories: PlainObject = {};
  posts.forEach((post) => {
    const apiEntry = post.toApi();
    delete apiEntry.content;
    if (apiEntry.meta['category']) {
      apiEntry.meta['category'].forEach((category: string) =>
        categories[category]
          ? categories[category].push(apiEntry)
          : (categories[category] = [apiEntry])
      );
    }
  });

  const dir = `${path}/api/category`;
  mkDirByPathSync(dir);
  Object.keys(categories).forEach((category) => {
    const filePath = `${dir}/${category}.json`;
    fs.writeFile(filePath, JSON.stringify(categories[category]), (err) =>
      err ? console.log(err) : null
    );
  });
}

export function generateApi(posts: Array<Post>, path: string) {
  try {
    generateApiIndex(posts, path);
    generateCategories(posts, path);
    posts.forEach((post) => saveApiEntry(post, path));
  } catch (err) {
    console.log(err);
  }
}