contentz-tech/build

View on GitHub
src/builders/feed.ts

Summary

Maintainability
A
0 mins
Test Coverage
import { writeFile } from "../utils/fs";
import { check } from "../utils/cache";
import { IState } from "../state";
import { IArticle } from "../getters/articles";

const path: string = "./public/atom.xml";

/**
 * Check if all articles are already cached
 * @param state Current state of the project
 */
async function checkCache(state: IState): Promise<boolean> {
  if (!state.config.incremental) return false;
  const caches = await Promise.all(
    state.articles.order
      .map((path: string) => state.articles.byPath[path])
      .map((article: IArticle) => ({
        path: article.path,
        content: article.content
      }))
      .map(({ path, content }) => check(path, content))
  );
  return caches.reduce((prev, next) => next === prev, true);
}

async function builder(state: IState) {
  if ((await checkCache(state)) && (await check("config.yml", state.config))) {
    return;
  }
  if (!state.config.domain) return;

  const rss = state.articles.order
    .map((path: string): IArticle => state.articles.byPath[path])
    .map((article: IArticle): string => {
      const link = state.config.domain + article.path;
      return `
      <entry>
        <id>${article.title}</id>
        <title>${article.title}</title>
        <link href="${link}"/>
        ${article.date ? `<updated>${article.date.toJSON()}</updated>` : ""}
        <content type="xhtml">
          <div xmlns="http://www.w3.org/1999/xhtml">
            ${article.description ? `<p>${article.description}</p>` : ""}
            <a href="${link}">Read Article</a>
          </div>
        </content>
        <author>
          ${state.config.title ? `<name>${state.config.title}</name>` : ""}
          ${state.config.email ? `<email>${state.config.email}</email>` : ""}
        </author>
      </entry>`;
    })
    .join("");

  const feed = `<?xml version="1.0" encoding="utf-8"?>
  <feed xmlns="http://www.w3.org/2005/Atom">
    ${
      state.config.title
        ? `<title>${state.config.title} - Articles</title>`
        : "<title>My Articles</title>"
    }
    <link href="${state.config.domain}" rel="self"/>
    <link href="${state.config.domain}"/>
    <updated>${Date.now()}</updated>
    <id>${state.config.domain}</id>
    <author>
      ${state.config.title ? `<name>${state.config.title}</name>` : ""}
      ${state.config.email ? `<email>${state.config.email}</email>` : ""}
    </author>${rss}
  </feed>`;

  return await writeFile(path, feed, "utf8");
}

export { builder };