UNPKG

gatsby-openrpc-theme

Version:

A gatsby theme for generated OpenRPC documentation

194 lines (168 loc) 4.6 kB
/** * Implement Gatsby's Node APIs in this file. * * See: https://www.gatsbyjs.org/docs/node-apis/ */ const path = require("path"); const _ = require("lodash"); // Add schema customization to ensure fields and frontmatter exist exports.createSchemaCustomization = ({ actions }) => { const { createTypes } = actions; const typeDefs = ` type SiteSiteMetadata { title: String description: String author: String logoUrl: String primaryColor: String primaryColorDark: String secondaryColor: String secondaryColorDark: String menuLinks: [MenuLink] footerLinks: [FooterLink] } type MenuLink { name: String link: String ignoreNextPrev: Boolean } type FooterLink { name: String link: String } type Mdx implements Node { frontmatter: MdxFrontmatter fields: MdxFields } type MdxFrontmatter { title: String } type MdxFields { slug: String } `; createTypes(typeDefs); }; function findDoc(doc) { if (!doc.link) return null return ( doc.link === this.link || doc.link === this.link.substring(0, this.link.length - 1) ) } function getSibling(index, list, direction) { if (direction === `next`) { const next = index === list.length - 1 ? null : list[index + 1] return next } else if (direction === `prev`) { const prev = index === 0 ? null : list[index - 1] return prev } else { return null } } exports.createPages = async ({ graphql, actions, reporter }) => { const { createPage } = actions // Dynamically import slash const { default: slash } = await import('slash'); const defaultTemplate = path.resolve(__dirname, "src/templates/default.tsx"); // Update GraphQL query syntax for Gatsby v5 const result = await graphql(` { allMdx { edges { node { id fields { slug } frontmatter { title } internal { contentFilePath } } next { fields { slug } frontmatter { title } } previous { fields { slug } frontmatter { title } } } } } `); if (result.errors) { reporter.panicOnBuild('Error loading MDX result', result.errors); return; } // Create pages from MDX files const allPages = result.data?.allMdx?.edges || []; const links = result.data?.site?.siteMetadata?.menuLinks || []; allPages.forEach(({ node, next, previous }) => { const slug = _.get(node, `fields.slug`); if (!slug) return; const docIndex = links.findIndex(findDoc, { link: slug }); let nextAndPrev = {} if (docIndex > -1) { nextAndPrev.prev = links[docIndex - 1] || null; nextAndPrev.next = links[docIndex + 1] || null; } if (nextAndPrev.prev && nextAndPrev.prev.ignoreNextPrev) { delete nextAndPrev.prev; } if (nextAndPrev.next && nextAndPrev.next.ignoreNextPrev) { delete nextAndPrev.next; } createPage({ path: `${node.fields.slug}`, component: `${slash(defaultTemplate)}?__contentFilePath=${slash(node.internal.contentFilePath)}`, context: { id: node.id, slug: node.fields.slug, next: next, prev: previous, }, }); }); }; // Create slugs for files exports.onCreateNode = async ({ node, getNode, actions }) => { const { createNodeField } = actions; if (node.internal.type === `Mdx`) { // Dynamically import slash const { default: slash } = await import('slash'); const fileNode = getNode(node.parent); if (!fileNode) return; const parsedFilePath = path.parse(fileNode.relativePath || ''); // Use slash to normalize paths, handle empty dir case const dirPath = parsedFilePath.dir ? `/${parsedFilePath.dir}` : ''; const slug = slash(`${dirPath}/${parsedFilePath.name}/`); createNodeField({ node, name: `slug`, value: slug, }); } }; // Support for webpack ESM modules exports.onCreateWebpackConfig = ({ actions }) => { actions.setWebpackConfig({ resolve: { fallback: { // Add any polyfills needed for Node.js modules }, }, }) }