Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: hide filesv2 from static props #2044

Merged
merged 14 commits into from
Jan 23, 2025
Merged
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
3 changes: 2 additions & 1 deletion packages/fern-docs/bundle/next.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ const isTrailingSlashEnabled =
process.env.TRAILING_SLASH === "1" ||
process.env.NEXT_PUBLIC_TRAILING_SLASH === "1";

// TODO: move this to a shared location (this is copied in @fern-docs/ui FernImage.tsx)
const DOCS_FILES_ALLOWLIST = [
{
protocol: "https",
Expand Down Expand Up @@ -66,7 +67,7 @@ const nextConfig = {
"@fern-docs/components",
"@fern-docs/edge-config",
"@fern-docs/mdx",
"@fern-docs/next-seo",
"@fern-docs/seo",
"@fern-docs/search-server",
"@fern-docs/search-ui",
"@fern-docs/search-utils",
Expand Down
1 change: 1 addition & 0 deletions packages/fern-docs/bundle/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
"@fern-docs/search-server": "workspace:*",
"@fern-docs/search-ui": "workspace:*",
"@fern-docs/search-utils": "workspace:*",
"@fern-docs/seo": "workspace:*",
"@fern-docs/syntax-highlighter": "workspace:*",
"@fern-docs/ui": "workspace:*",
"@fern-docs/utils": "workspace:*",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,7 @@ import { getDocsDomainEdge, getHostEdge } from "@/server/xfernhost/edge";
import { withDefaultProtocol } from "@fern-api/ui-core-utils";
import { APIKeyInjectionConfig, OryAccessTokenSchema } from "@fern-docs/auth";
import { getAuthEdgeConfig } from "@fern-docs/edge-config";
import { COOKIE_FERN_TOKEN } from "@fern-docs/utils";
import { removeTrailingSlash } from "next/dist/shared/lib/router/utils/remove-trailing-slash";
import { COOKIE_FERN_TOKEN, removeTrailingSlash } from "@fern-docs/utils";
import { cookies } from "next/headers";
import { NextRequest, NextResponse } from "next/server";
import urlJoin from "url-join";
Expand Down
2 changes: 1 addition & 1 deletion packages/fern-docs/bundle/src/app/sitemap.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { DocsLoader } from "@/server/DocsLoader";
import { conformTrailingSlash } from "@/server/trailingSlash";
import { withPrunedNavigation } from "@/server/withPrunedNavigation";
import { getDocsDomainApp, getHostApp } from "@/server/xfernhost/app";
import { NodeCollector } from "@fern-api/fdr-sdk/navigation";
import { withDefaultProtocol } from "@fern-api/ui-core-utils";
import { conformTrailingSlash } from "@fern-docs/utils";
import type { MetadataRoute } from "next";
import urljoin from "url-join";

Expand Down
2 changes: 1 addition & 1 deletion packages/fern-docs/bundle/src/middleware.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { rewritePosthog } from "@/server/analytics/rewritePosthog";
import { extractNextDataPathname } from "@/server/extractNextDataPathname";
import { getLaunchDarklySettings } from "@fern-docs/edge-config";
import { removeTrailingSlash } from "next/dist/shared/lib/router/utils/remove-trailing-slash";
import { removeTrailingSlash } from "@fern-docs/utils";
import { NextResponse, type NextMiddleware } from "next/server";
import { MARKDOWN_PATTERN, RSS_PATTERN } from "./server/patterns";
import { withMiddlewareAuth } from "./server/withMiddlewareAuth";
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { track } from "@/server/analytics/posthog";
import { FernNavigation } from "@fern-api/fdr-sdk";
import { DocsPage } from "@fern-docs/ui";
import { TRACK_LOAD_DOCS_PERFORMANCE } from "@fern-docs/utils";
import { GetServerSidePropsResult } from "next/types";
import { ComponentProps } from "react";
import { track } from "./analytics/posthog";
import type { LoadWithUrlResponse } from "./loadWithUrl";

export class LoadDocsPerformanceTracker {
Expand Down
3 changes: 1 addition & 2 deletions packages/fern-docs/bundle/src/server/auth/getAuthState.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,7 @@ import {
getAuthEdgeConfig,
getPreviewUrlAuthConfig,
} from "@fern-docs/edge-config";
import { withoutStaging } from "@fern-docs/utils";
import { removeTrailingSlash } from "next/dist/shared/lib/router/utils/remove-trailing-slash";
import { removeTrailingSlash, withoutStaging } from "@fern-docs/utils";
import urlJoin from "url-join";
import { safeVerifyFernJWTConfig } from "./FernJWT";
import { getAllowedRedirectUrls } from "./allowed-redirects";
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { withDefaultProtocol } from "@fern-api/ui-core-utils";
import { removeTrailingSlash } from "next/dist/shared/lib/router/utils/remove-trailing-slash";
import { removeTrailingSlash } from "@fern-docs/utils";
import urlJoin from "url-join";
import { AuthState, getWorkosRbacRoles } from "./getAuthState";
import { getWorkosSSOAuthorizationUrl } from "./workos";
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import type * as FernDocs from "@fern-api/fdr-sdk/docs";
import * as FernNavigation from "@fern-api/fdr-sdk/navigation";
import { withDefaultProtocol } from "@fern-api/ui-core-utils";
import { JsonLd } from "@fern-docs/next-seo";
import { JsonLd } from "@fern-docs/seo";
import urljoin from "url-join";

function toUrl(domain: string, slug: FernNavigation.Slug): string {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,11 @@ import {
} from "@fern-api/fdr-sdk/api-definition";
import { MarkdownText } from "@fern-api/fdr-sdk/docs";
import { isNonNullish } from "@fern-api/ui-core-utils";
import { EdgeFlags } from "@fern-docs/utils";
import { EdgeFlags, removeLeadingSlash } from "@fern-docs/utils";
import { isString } from "es-toolkit/predicate";
import { DocsLoader } from "./DocsLoader";
import { pascalCaseHeaderKey } from "./headerKeyCase";
import { convertToLlmTxtMarkdown } from "./llm-txt-md";
import { removeLeadingSlash } from "./removeLeadingSlash";

export async function getMarkdownForPath(
node: FernNavigation.NavigationNodePage,
Expand Down
2 changes: 1 addition & 1 deletion packages/fern-docs/bundle/src/server/getSectionRoot.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import * as FernNavigation from "@fern-api/fdr-sdk/navigation";
import { CONTINUE, STOP } from "@fern-api/fdr-sdk/traversers";
import { removeLeadingSlash } from "./removeLeadingSlash";
import { removeLeadingSlash } from "@fern-docs/utils";

export function getSectionRoot(
root: FernNavigation.RootNode | undefined,
Expand Down
3 changes: 1 addition & 2 deletions packages/fern-docs/bundle/src/server/pageRoutes.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { addLeadingSlash } from "@fern-docs/utils";
import { addLeadingSlash, removeTrailingSlash } from "@fern-docs/utils";
import getAssetPathFromRoute from "next/dist/shared/lib/router/utils/get-asset-path-from-route";
import { removeTrailingSlash } from "next/dist/shared/lib/router/utils/remove-trailing-slash";
import urlJoin from "url-join";

export function getPageRoute(
Expand Down
4 changes: 2 additions & 2 deletions packages/fern-docs/bundle/src/server/queue-reindex.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ import {
HEADER_X_FERN_HOST,
HEADER_X_VERCEL_PROTECTION_BYPASS,
addLeadingSlash,
conformTrailingSlash,
removeTrailingSlash,
} from "@fern-docs/utils";
import { removeTrailingSlash } from "next/dist/shared/lib/router/utils/remove-trailing-slash";
import { conformTrailingSlash } from "./trailingSlash";

const q = new Client({ token: qstashToken() });

Expand Down
2 changes: 1 addition & 1 deletion packages/fern-docs/bundle/src/server/revalidator.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { conformTrailingSlash } from "@fern-docs/utils";
import type { FernDocs } from "@fern-fern/fern-docs-sdk";
import type { NextApiResponse } from "next";
import urljoin from "url-join";
import { conformTrailingSlash } from "./trailingSlash";

export class Revalidator implements Revalidator {
constructor(
Expand Down
68 changes: 49 additions & 19 deletions packages/fern-docs/bundle/src/server/withInitialProps.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,33 +7,42 @@ import {
getEdgeFlags,
getSeoDisabled,
} from "@fern-docs/edge-config";
import { withSeo } from "@fern-docs/seo";
import {
DocsPage,
NavbarLink,
type DocsPage,
type ImageData,
type NavbarLink,
getApiRouteSupplier,
getGitHubInfo,
getGitHubRepo,
getSeoProps,
renderThemeStylesheet,
withLogo,
} from "@fern-docs/ui";
import { serializeMdx } from "@fern-docs/ui/bundlers/mdx-bundler";
import { addLeadingSlash, getRedirectForPath } from "@fern-docs/utils";
import {
addLeadingSlash,
getRedirectForPath,
isTrailingSlashEnabled,
} from "@fern-docs/utils";
import { SidebarTab } from "@fern-platform/fdr-utils";
import { GetServerSidePropsResult, Redirect } from "next";
import { ComponentProps } from "react";
import { UnreachableCaseError } from "ts-essentials";
import urlJoin from "url-join";
import { DocsLoader } from "./DocsLoader";
import { getAuthState } from "./auth/getAuthState";
import { getReturnToQueryParam } from "./auth/return-to";
import { handleLoadDocsError } from "./handleLoadDocsError";
import { withLaunchDarkly } from "./ld-adapter";
import type { LoadWithUrlResponse } from "./loadWithUrl";
import { isTrailingSlashEnabled } from "./trailingSlash";
import {
pruneNavigationPredicate,
withPrunedNavigation,
} from "./withPrunedNavigation";
import { withResolvedDocsContent } from "./withResolvedDocsContent";
import {
extractFrontmatterFromDocsContent,
withResolvedDocsContent,
} from "./withResolvedDocsContent";
import { withVersionSwitcherInfo } from "./withVersionSwitcherInfo";

interface WithInitialProps {
Expand Down Expand Up @@ -192,12 +201,6 @@ export async function withInitialProps({
: undefined,
};

const logoHref =
docs.definition.config.logoHref ??
(found.landingPage?.slug != null && !found.landingPage.hidden
? encodeURI(addLeadingSlash(found.landingPage.slug))
: undefined);

const navbarLinks: NavbarLink[] = [];

docs.definition.config.navbarLinks?.forEach((link) => {
Expand Down Expand Up @@ -295,6 +298,34 @@ export async function withInitialProps({
pruneNavigationPredicate(tab, pruneOpts) || tab === found.currentTab
);

function resolveFileSrc(src: string | undefined): ImageData | undefined {
if (src == null) {
return undefined;
}

const fileId = FernNavigation.FileId(
src.startsWith("file:") ? src.slice(5) : src
);
const file = docs.definition.filesV2[fileId];
if (file == null) {
// the file is not found, so we return the src as the image data
return { src };
}

if (file.type === "image") {
return {
src: file.url,
width: file.width,
height: file.height,
blurDataURL: file.blurDataUrl,
};
} else if (file.type === "url") {
return { src: file.url };
} else {
throw new UnreachableCaseError(file);
}
}

const content = await withResolvedDocsContent({
domain: docs.baseUrl.domain,
found,
Expand All @@ -311,7 +342,9 @@ export async function withInitialProps({
tab: found?.currentTab?.title,
},
},
replaceSrc: resolveFileSrc,
});
const frontmatter = extractFrontmatterFromDocsContent(found.node.id, content);

if (content == null) {
return { notFound: true };
Expand Down Expand Up @@ -361,9 +394,7 @@ export async function withInitialProps({
colors,
js: docs.definition.config.js,
navbarLinks,
logoHeight: docs.definition.config.logoHeight,
logoHref: logoHref != null ? FernNavigation.Url(logoHref) : undefined,
files: docs.definition.filesV2,
logo: withLogo(docs.definition, found, frontmatter, resolveFileSrc),
content,
announcement:
docs.definition.config.announcement != null
Expand All @@ -382,15 +413,14 @@ export async function withInitialProps({
},
edgeFlags,
apis: Object.keys(docs.definition.apis).map(FernNavigation.ApiDefinitionId),
seo: getSeoProps(
seo: withSeo(
docs.baseUrl.domain,
docs.definition.config,
docs.definition.pages,
frontmatter,
docs.definition.filesV2,
docs.definition.apis,
found,
await getSeoDisabled(domain),
isTrailingSlashEnabled()
await getSeoDisabled(domain)
),
user: authState.authed ? authState.user : undefined,
fallback: {},
Expand Down
49 changes: 47 additions & 2 deletions packages/fern-docs/bundle/src/server/withResolvedDocsContent.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
import { DocsV1Read } from "@fern-api/fdr-sdk";
import type * as FernNavigation from "@fern-api/fdr-sdk/navigation";
import { resolveDocsContent, type DocsContent } from "@fern-docs/ui";
import type * as FernDocs from "@fern-api/fdr-sdk/docs";
import * as FernNavigation from "@fern-api/fdr-sdk/navigation";
import { getFrontmatter } from "@fern-docs/mdx";
import {
resolveDocsContent,
type DocsContent,
type ImageData,
} from "@fern-docs/ui";
import { serializeMdx } from "@fern-docs/ui/bundlers/mdx-bundler";
import { EdgeFlags } from "@fern-docs/utils";
import { AuthState } from "./auth/getAuthState";
Expand All @@ -13,6 +19,7 @@ interface WithResolvedDocsContentOpts {
definition: DocsV1Read.DocsDefinition;
edgeFlags: EdgeFlags;
scope?: Record<string, unknown>;
replaceSrc?: (src: string) => ImageData | undefined;
}

export async function withResolvedDocsContent({
Expand All @@ -22,6 +29,7 @@ export async function withResolvedDocsContent({
definition,
edgeFlags,
scope,
replaceSrc,
}: WithResolvedDocsContentOpts): Promise<DocsContent | undefined> {
const node = withPrunedNavigation(found.node, {
visibleNodeIds: [found.node.id],
Expand Down Expand Up @@ -67,9 +75,46 @@ export async function withResolvedDocsContent({
mdxOptions: {
files: definition.jsFiles,
scope,

// inject the file url and dimensions for images and other embeddable files
replaceSrc,
},
serializeMdx,
domain,
engine: "mdx-bundler",
});
}

export function extractFrontmatterFromDocsContent(
nodeId: FernNavigation.NodeId,
docsContent: DocsContent | undefined
): FernDocs.Frontmatter | undefined {
if (docsContent == null) {
return undefined;
}
switch (docsContent.type) {
case "markdown-page":
return getFrontmatterFromMarkdownText(docsContent.content);
case "changelog-entry":
return getFrontmatterFromMarkdownText(docsContent.page);
case "api-reference-page": {
const mdx = docsContent.mdxs[nodeId];
if (mdx == null) {
return undefined;
}
return getFrontmatterFromMarkdownText(mdx.content);
}
default:
// TODO: handle changelog overview page and other pages
return undefined;
}
}

function getFrontmatterFromMarkdownText(
markdownText: FernDocs.MarkdownText
): FernDocs.Frontmatter | undefined {
if (typeof markdownText === "string") {
return getFrontmatter(markdownText).data;
}
return markdownText.frontmatter;
}
Loading
Loading