Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions scripts/smart-search.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -48,14 +48,16 @@ async function main() {
*/
async function collectPages() {
const pages = [];
const entries = await getAllDocMeta();
const docsEntries = await getAllDocMeta("docs");
const toolkitEntries = await getAllDocMeta("toolkit");
const entries = [...docsEntries, ...toolkitEntries];

for (const entry of entries) {
const entryContent = await getRawDocContent(entry.download_url);

const parsedContent = await getTextContentFromMd(entryContent);

const cleanedPath = getDocUriFromPath(entry.path);
const cleanedPath = getDocUriFromPath(entry.path, "docs");

const id = generateDocIdFromUri(cleanedPath);

Expand Down
2 changes: 1 addition & 1 deletion src/components/on-this-page-nav.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ export default function OnThisPageNav({ headings }) {
return (
<>
<h2 className="py-2 font-semibold">On This Page</h2>
{headings.length > 0 && (
{headings && headings.length > 0 && (
<ul className="mt-4 text-sm text-gray-400">
{headings.map((heading) => (
<li
Expand Down
17 changes: 17 additions & 0 deletions src/components/primary-nav.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,23 @@ export default function PrimaryMenu({ className }) {
Docs
</Link>
</li>
<li key="toolkit" className={navItemClass}>
<Link
className="block px-1"
href="/toolkit/"
noDefaultStyles
activeClassName="text-purple-500"
onClick={() =>
sendMainNavItemSelectEvent({
item_id: "/toolkit/",
item_name: "Toolkit",
item_category: "mdx_doc",
})
}
>
Toolkit
</Link>
</li>
<li key="blog" className={navItemClass}>
<Link
className="block px-1"
Expand Down
5 changes: 5 additions & 0 deletions src/constants/repo.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,8 @@ export const DOCS_OWNER = "wpengine";
export const DOCS_REPO = "faustjs";
export const DOCS_FOLDER = "docs";
export const DOCS_BRANCH = "canary";

export const TOOLKIT_OWNER = "wpengine";
export const TOOLKIT_REPO = "hwptoolkit";
export const TOOLKIT_FOLDER = "docs";
export const TOOLKIT_BRANCH = "chore-move-and-validate-logging-docs";
8 changes: 6 additions & 2 deletions src/lib/remark-parsing.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,11 @@ function addFrontmatterToVFile() {
* scope: { toc: { href: string; value: string; depth: number; }[]; }
* }>}
*/
export async function getSerializedContextFromMd(mdContent, pageUrl) {
export async function getSerializedContextFromMd(
mdContent,
pageUrl,
type = "docs",
) {
return serialize({
source: mdContent,
options: {
Expand All @@ -64,7 +68,7 @@ export async function getSerializedContextFromMd(mdContent, pageUrl) {
{
selectors: ["img[src]"],
inspectEach: ({ url, node }) => {
node.properties.src = getRemoteImgUrl(url, pageUrl);
node.properties.src = getRemoteImgUrl(url, pageUrl, type);
},
},
],
Expand Down
161 changes: 137 additions & 24 deletions src/lib/remote-mdx-files.mjs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { hash } from "node:crypto";
import fs from "node:fs/promises";
import path from "node:path";
import { env } from "node:process";
import { Octokit } from "@octokit/core";
Expand All @@ -7,6 +8,10 @@ import {
DOCS_REPO,
DOCS_BRANCH,
DOCS_FOLDER,
TOOLKIT_OWNER,
TOOLKIT_REPO,
TOOLKIT_BRANCH,
TOOLKIT_FOLDER,
} from "../constants/repo.mjs";
import { getSerializedContextFromMd } from "./remark-parsing.mjs";

Expand All @@ -21,52 +26,137 @@ const octokit = new Octokit({
const DOCS_EXT_REG = /(?<slug>.*)index.md(?:x?)$/i;
const IMG_PATH_REG = /^(?<path>\.\/)?(?<slug>.+)$/i;

const DOCS_PATH = `https://raw.githubusercontent.com/${DOCS_OWNER}/${DOCS_REPO}/refs/heads/${DOCS_BRANCH}/${DOCS_FOLDER}`;
function getRepoConfig(type = "docs") {
switch (type) {
case "toolkit": {
return {
owner: TOOLKIT_OWNER,
repo: TOOLKIT_REPO,
branch: TOOLKIT_BRANCH,
folder: TOOLKIT_FOLDER,
};
}

default: {
return {
owner: DOCS_OWNER,
repo: DOCS_REPO,
branch: DOCS_BRANCH,
folder: DOCS_FOLDER,
};
}
}
}

function getDocsPath(type = "docs") {
if (env.LOCAL_FILE_PATH) {
const { folder: docsFolder } = getRepoConfig(type);
return path.join(env.LOCAL_FILE_PATH, docsFolder);
}

const { owner, repo, branch, folder } = getRepoConfig(type);
return `https://raw.githubusercontent.com/${owner}/${repo}/refs/heads/${branch}/${folder}`;
}

const DOCS_NAV_CONFIG_URL = `${DOCS_PATH}/nav.json`;
function getDocsNavConfigUrl(type = "docs") {
return `${getDocsPath(type)}/nav.json`;
}

function docUrlFromSlug(slug = []) {
return path.join(DOCS_PATH, ...slug, "index.md");
function docUrlFromSlug(slug = [], type = "docs") {
return path.join(getDocsPath(type), ...slug, "index.md");
}

/**
* Returns the URL of an image from its path and the URL of the page it's on.
*
* @param {string} imgPath
* @param {string[]} pageUrl
* @param {string} type
* @returns
*/
function imgUrlFromPath(imgPath, pageUrl) {
function imgUrlFromPath(imgPath, pageUrl, type = "docs") {
if (!Array.isArray(pageUrl)) {
throw new TypeError("pageUrl should be an array");
}

return `${DOCS_PATH}/${pageUrl.join("/")}/${imgPath}`;
return `${getDocsPath(type)}/${pageUrl.join("/")}/${imgPath}`;
}

/**
* Returns the URL of an image from its local path and the URL of the page it's on.
*
* @param {string} localPath
* @param {string[]} pageUrl
* @param {string} type
* @returns {string}
*/
export function getRemoteImgUrl(localPath, pageUrl) {
return imgUrlFromPath(localPath.match(IMG_PATH_REG).groups.slug, pageUrl);
export function getRemoteImgUrl(localPath, pageUrl, type = "docs") {
return imgUrlFromPath(
localPath.match(IMG_PATH_REG).groups.slug,
pageUrl,
type,
);
}

/**
* Helper function to get local file metadata
*
* @param {string} type
* @param {string} pathToFolder
*/
async function getLocalDocMeta(type, pathToFolder) {
const { folder: docsFolder } = getRepoConfig(type);
const basePath = pathToFolder
? path.join(env.LOCAL_FILE_PATH, pathToFolder)
: path.join(env.LOCAL_FILE_PATH, docsFolder);

const localItems = [];
const localSubItems = [];

const entries = await fs.readdir(basePath, { withFileTypes: true });

for (const entry of entries) {
if (entry.isFile() && entry.name === "index.md") {
const relativePath = pathToFolder
? path.join(pathToFolder, entry.name)
: path.join(docsFolder, entry.name);
localItems.push({
type: "file",
name: entry.name,
path: relativePath,
});
} else if (entry.isDirectory() && entry.name !== "images") {
const subPath = pathToFolder
? path.join(pathToFolder, entry.name)
: path.join(docsFolder, entry.name);
localSubItems.push(getAllDocMeta(type, subPath));
}
}

const localSubFolderItems = await Promise.all(localSubItems);

return [...localItems, ...localSubFolderItems.flat()];
}

/**
* Retrieves the metadata for all documents in the docs folder.
*
* @param {string} type
* @param {string} pathToFolder
*/
export async function getAllDocMeta(pathToFolder = DOCS_FOLDER) {
export async function getAllDocMeta(type, pathToFolder) {
if (env.LOCAL_FILE_PATH) {
return getLocalDocMeta(type, pathToFolder);
}

const { owner, repo, branch, folder } = getRepoConfig(type);
const { status, data } = await octokit.request(
"GET /repos/{owner}/{repo}/contents/{path}",
{
owner: DOCS_OWNER,
repo: DOCS_REPO,
path: pathToFolder,
ref: DOCS_BRANCH, // This makes it so only released features show up in the docs.
owner,
repo,
path: pathToFolder ?? folder,
ref: branch, // This makes it so only released features show up in the docs.
},
);

Expand All @@ -82,7 +172,7 @@ export async function getAllDocMeta(pathToFolder = DOCS_FOLDER) {
if (item.type === "file" && item.name === "index.md") {
items.push(item);
} else if (item.type === "dir" && item.name !== "images") {
subItems.push(getAllDocMeta(item.path));
subItems.push(getAllDocMeta(type, item.path));
}
}

Expand All @@ -94,9 +184,16 @@ export async function getAllDocMeta(pathToFolder = DOCS_FOLDER) {
/**
* Retrieves the nav.json file from the docs folder.
*
* @param {string} type
*/
export async function getDocsNav() {
const resp = await fetch(DOCS_NAV_CONFIG_URL);
export async function getDocsNav(type = "docs") {
if (env.LOCAL_FILE_PATH) {
const navPath = getDocsNavConfigUrl(type);
const content = await fs.readFile(navPath, "utf8");
return JSON.parse(content);
}

const resp = await fetch(getDocsNavConfigUrl(type));

if (!resp.ok) {
throw new Error(resp.statusText);
Expand All @@ -105,8 +202,8 @@ export async function getDocsNav() {
return resp.json();
}

export async function getAllDocUri() {
const data = await getAllDocMeta();
export async function getAllDocUri(type = "docs") {
const data = await getAllDocMeta(type);

if (!Array.isArray(data)) {
console.error(data);
Expand All @@ -116,15 +213,17 @@ export async function getAllDocUri() {
const accumulator = [];
for (const file of data) {
if (DOCS_EXT_REG.test(file.path)) {
accumulator.push(getDocUriFromPath(file.path));
accumulator.push(getDocUriFromPath(file.path, type));
}
}

return accumulator;
}

export function getDocUriFromPath(ghPath) {
return path.join("/", ghPath.match(DOCS_EXT_REG).groups.slug);
export function getDocUriFromPath(ghPath, type = "docs") {
const { folder } = getRepoConfig(type);
const relativePath = path.relative(folder, ghPath);
return path.join("/", relativePath.match(DOCS_EXT_REG).groups.slug);
}

/**
Expand All @@ -134,6 +233,19 @@ export function getDocUriFromPath(ghPath) {
* @returns {Promise<string>}
*/
export async function getRawDocContent(url) {
if (env.LOCAL_FILE_PATH) {
try {
return await fs.readFile(url, "utf8");
} catch (error) {
if (error.code === "ENOENT") {
// eslint-disable-next-line no-throw-literal
throw { notFound: true };
}

throw error;
}
}

const resp = await fetch(url);

if (!resp.ok) {
Expand All @@ -152,12 +264,13 @@ export async function getRawDocContent(url) {
* Retrieves the parsed content of a document from its slug.
*
* @param {string} slug
* @param {string} type
* @returns {ReturnType<typeof import("./remark-parsing.mjs").getSerializedContextFromMd>}
*/
export async function getParsedDoc(slug) {
const content = await getRawDocContent(docUrlFromSlug(slug));
export async function getParsedDoc(slug, type = "docs") {
const content = await getRawDocContent(docUrlFromSlug(slug, type));

return getSerializedContextFromMd(content, slug);
return getSerializedContextFromMd(content, slug, type);
}

/**
Expand Down
3 changes: 2 additions & 1 deletion src/pages/_app.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ const GA_TRACKING_ID = process.env.NEXT_PUBLIC_GA_TRACKING_ID;
export default function MyApp({ Component, pageProps }) {
const router = useRouter();
const isDocsRoute = router.pathname.startsWith("/docs");
const isToolkitRoute = router.pathname.startsWith("/toolkit");

return (
<FaustProvider pageProps={pageProps}>
Expand All @@ -27,7 +28,7 @@ export default function MyApp({ Component, pageProps }) {
{/* eslint-disable-next-line unicorn/no-null */}
<WordPressBlocksProvider config={{ blocks, theme: null }}>
<Layout>
{isDocsRoute ? (
{isDocsRoute || isToolkitRoute ? (
<DocsLayout {...pageProps}>
<Component {...pageProps} />
</DocsLayout>
Expand Down
4 changes: 2 additions & 2 deletions src/pages/docs/[[...slug]].jsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ export default function Doc({ source }) {

export async function getStaticProps({ params }) {
try {
const source = await getParsedDoc(params.slug);
const docsNavData = await getDocsNav();
const source = await getParsedDoc(params.slug, "docs");
const docsNavData = await getDocsNav("docs");

return {
props: {
Expand Down
Loading