const fs = require('fs'); const path = require('path'); const fetch = (...args) => import('node-fetch').then(({default: fetch}) => fetch(...args)); const WORDPRESS_API = 'https://wp.mistergeek.net/wp-json/wp/v2'; const OUTPUT_DIR = path.join(__dirname, '..', 'data', 'wordpress'); const HUGO_DATA_DIR = path.join(__dirname, '..', 'data'); async function fetchAll(endpoint, perPage = 100) { let page = 1; let items = []; while (true) { const url = `${WORDPRESS_API}/${endpoint}?page=${page}&per_page=${perPage}&_embed`; const response = await fetch(url); // If endpoint does not support paging or returns empty, break if (!response.ok) { // 400 often means "page out of range" for WP; stop paging if (response.status === 400) break; throw new Error(`Failed to fetch ${endpoint} (page ${page}): ${response.status} ${response.statusText}`); } const batch = await response.json(); items = items.concat(batch); const totalPages = parseInt(response.headers.get('x-wp-totalpages') || '1', 10); if (page >= totalPages) break; page++; } return items; } async function generateData() { // Ensure output directory exists if (!fs.existsSync(OUTPUT_DIR)) { fs.mkdirSync(OUTPUT_DIR, { recursive: true }); } console.log('Fetching WordPress data...'); // Fetch all relevant endpoints concurrently (pages + posts + taxonomies + users) const [ posts, pages, categories, tags, authors ] = await Promise.all([ fetchAll('posts'), fetchAll('pages'), fetchAll('categories'), fetchAll('tags'), fetchAll('users') ]); // Filter pages to only include published pages const publishedPages = pages.filter(page => page.status === 'publish'); // Create navigation data from published pages const navigationData = publishedPages.map(page => ({ id: page.id, title: page.title?.rendered || page.slug, slug: page.slug, link: page.link, date: page.date, modified: page.modified })); // Create author-post mapping const authorPosts = {}; posts.forEach(post => { if (post.status === 'publish') { const author = post._embedded?.author?.[0]; if (author) { const authorSlug = author.slug; if (!authorPosts[authorSlug]) { authorPosts[authorSlug] = { id: author.id, name: author.name, slug: author.slug, description: author.description || '', avatar: author.avatar_urls || {}, link: author.link, posts: [] }; } authorPosts[authorSlug].posts.push({ id: post.id, title: post.title.rendered, slug: post.slug, date: post.date, excerpt: post.excerpt.rendered, featured_image: post._embedded?.['wp:featuredmedia']?.[0]?.source_url || '', categories: (post._embedded?.['wp:term']?.[0] || []).map(cat => ({ id: cat.id, name: cat.name, slug: cat.slug })), tags: (post._embedded?.['wp:term']?.[1] || []).map(tag => ({ id: tag.id, name: tag.name, slug: tag.slug })) }); } } }); // Save data as JSON files fs.writeFileSync(path.join(OUTPUT_DIR, 'posts.json'), JSON.stringify(posts, null, 2)); fs.writeFileSync(path.join(OUTPUT_DIR, 'pages.json'), JSON.stringify(publishedPages, null, 2)); // Extract category descriptions const categoriesWithDescriptions = categories.map(cat => ({ id: cat.id, name: cat.name, slug: cat.slug, description: cat.description || '', count: cat.count || 0 })); // Also save to wordpress directory fs.writeFileSync(path.join(OUTPUT_DIR, 'categories.json'), JSON.stringify(categories, null, 2)); fs.writeFileSync(path.join(OUTPUT_DIR, 'tags.json'), JSON.stringify(tags, null, 2)); fs.writeFileSync(path.join(OUTPUT_DIR, 'authors.json'), JSON.stringify(authors, null, 2)); fs.writeFileSync(path.join(OUTPUT_DIR, 'author-posts.json'), JSON.stringify(authorPosts, null, 2)); fs.writeFileSync(path.join(OUTPUT_DIR, 'navigation.json'), JSON.stringify(navigationData, null, 2)); console.log(`✅ Fetched ${posts.length} posts, ${publishedPages.length} pages, ${categories.length} categories, ${tags.length} tags, ${authors.length} authors`); console.log(`✅ Generated navigation data with ${navigationData.length} items`); } generateData().catch(console.error);