import path from "path-browserify"; // https://github.com/gatsbyjs/gatsby/blob/5250a02/packages/gatsby/src/utils/page-data.ts#L20 export function fixedPagePath(pagePath: string): string { return pagePath === `/` ? `index` : pagePath; } export function joinWithSlash(start: string, end: string): string { if (start.length == 0) { return end; } if (end.length == 0) { return start; } let slashes = 0; if (start.endsWith("/")) { slashes++; } if (end.startsWith("/")) { slashes++; } if (slashes == 2) { return start + end.substring(1); } if (slashes == 1) { return start + end; } return start + "/" + end; } // https://github.com/gatsbyjs/gatsby/blob/5250a02/packages/gatsby/src/utils/page-data.ts#L24 export function getFilePath(publicDir: string, pagePath: string): string { return path.join( publicDir, `page-data`, fixedPagePath(pagePath), `page-data.json`, ); } export const fixRelativeUrls = (href: string): string => { let linkUrl = href; if (linkUrl && linkUrl?.startsWith("./")) { linkUrl = new URL(linkUrl, document.baseURI).pathname; } return linkUrl; }; export const linkUrlPageData = (linkUrl: string): string => { return getFilePath("/", fixRelativeUrls(linkUrl)); }; export const linkUrlCustom = (linkUrl: string): string => { return `/asyncData${fixRelativeUrls(linkUrl)}.json`; }; export type FormattedFetchResponse< Response = { [name: string]: unknown }, FormattedResponse = { [name: string]: unknown }, > = (data: Response) => FormattedResponse; export const formatResponseFromPageData: FormattedFetchResponse<{ result: { pageContext: unknown }; }> = (data) => data.result.pageContext as { [name: string]: unknown }; export const fetchPageData = ( href: string, ): Promise<{ [name: string]: unknown }> => fetch(linkUrlPageData(href)) .then((res) => res.json()) .then((data) => formatResponseFromPageData(data));