const EleventyFetch = require('@11ty/eleventy-fetch'); const fs = require('fs'); const merge = require('lodash/merge') const wordpressPassword = process.env.WORDPRESS_PASSWORD; const auth = Buffer.from(`lewis:${wordpressPassword}`).toString('base64'); const dateSort = (a, b) => new Date(b.date) - new Date(a.date); class PostCache { constructor() { this.readCache(); } readCache() { if (!fs.existsSync(".cache/wordpress_post_fetch.json")) { this.last_read_date = null; this.posts = {}; } else { const data = JSON.parse(fs.readFileSync(".cache/wordpress_post_fetch.json")); this.last_read_date = new Date(data.last_read_date); this.posts = data.posts; } } writeCache() { fs.writeFileSync(".cache/wordpress_post_fetch.json", JSON.stringify(this, null, 2)); } async fetchCommentsByType(type = "comment") { const params = new URLSearchParams(); params.set("per_page", 100); params.set("type", type); if (this.last_read_date) { params.set("modified_after", this.last_read_date.toISOString()); } const response = await fetch(`https://lewisdale.dev/wp-json/wp/v2/comments?${params.toString()}`, { headers: { "Authorization": `Basic ${auth}` } }); return await response.json() } async fetchComments() { const comments = [...await this.fetchCommentsByType(), ...await this.fetchCommentsByType("webmention")]; comments.forEach(comment => { if (this.posts[comment.post]) { this.posts[comment.post].comments[comment.id] = comment; } }); } async fetchPosts() { const params = new URLSearchParams(); params.set("per_page", 100); if (this.last_read_date) { params.set("modified_after", this.last_read_date.toISOString()); } const response = await fetch(`https://lewisdale.dev/wp-json/wp/v2/posts?${params.toString()}`, { headers: { "Authorization": `Basic ${auth}` } }); const posts = await response.json(); posts.forEach(post => { this.posts[post.id] = merge({ comments: {} }, this.posts[post.id], post); }); } async fetchLatest() { await this.fetchPosts(); await this.fetchComments(); this.last_read_date = new Date(); this.writeCache(); } } const mapComment = comment => ({ author: { name: comment.author_name, avatars: comment.author_avatar_urls, url: comment.meta.semantic_linkbacks_author_url, }, content: comment.content.rendered, canonical: comment.meta.semantic_linkbacks_canonical, date: comment.date, }); module.exports = async () => { const cache = new PostCache(); await cache.fetchLatest(); return Object.values(cache.posts) .sort(dateSort) .map(post => ({ ...post, comments: Object.values(post.comments) .sort(dateSort) .reduce((comments, comment) => { if (!comments[comment.meta.semantic_linkbacks_type]) { comments[comment.meta.semantic_linkbacks_type] = []; } comments[comment.meta.semantic_linkbacks_type].push(mapComment(comment)); return comments; }, { like: [], reply: [], repost: [] }) })); };