Skip to content

Commit

Permalink
feat: enable falling back to orgid when resolving ld config to enable…
Browse files Browse the repository at this point in the history
… previews (#2090)
  • Loading branch information
abvthecity authored Jan 28, 2025
1 parent 22c2318 commit f38c445
Show file tree
Hide file tree
Showing 5 changed files with 41 additions and 16 deletions.
6 changes: 5 additions & 1 deletion packages/fern-docs/bundle/src/middleware.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { extractNextDataPathname } from "@/server/extractNextDataPathname";
import { getLaunchDarklySettings } from "@fern-docs/edge-config";
import { removeTrailingSlash } from "@fern-docs/utils";
import { NextResponse, type NextMiddleware } from "next/server";
import { getOrgMetadataForDomain } from "./server/auth/metadata-for-url";
import { MARKDOWN_PATTERN, RSS_PATTERN } from "./server/patterns";
import { withMiddlewareAuth } from "./server/withMiddlewareAuth";
import { withMiddlewareRewrite } from "./server/withMiddlewareRewrite";
Expand Down Expand Up @@ -132,7 +133,10 @@ export const middleware: NextMiddleware = async (request) => {

// TODO: this adds additional latency to the page load. can we batch this somehow?
const launchDarkly = await getLaunchDarklySettings(
getDocsDomainEdge(request)
getDocsDomainEdge(request),
getOrgMetadataForDomain(getDocsDomainEdge(request)).then(
(metadata) => metadata?.orgId
)
);

return withMiddlewareAuth(
Expand Down
13 changes: 10 additions & 3 deletions packages/fern-docs/bundle/src/server/ld-adapter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,17 @@ import * as ld from "@launchdarkly/node-server-sdk";
import { isEqual } from "es-toolkit/predicate";
import { camelCase } from "es-toolkit/string";
import { AuthState } from "./auth/getAuthState";
import { getOrgMetadataForDomain } from "./auth/metadata-for-url";

async function withLaunchDarklyContext(
endpoint: string,
endpoint: string | undefined,
authState: AuthState,
node: FernNavigation.utils.Node,
rawCookie: string | undefined
): Promise<ld.LDContext> {
if (endpoint == null) {
return { kind: "user", key: "anonymous", anonymous: true };
}
try {
const url = new URL(endpoint);
url.searchParams.set("anonymous", String(!authState.authed));
Expand Down Expand Up @@ -45,7 +49,7 @@ async function withLaunchDarklyContext(

interface LaunchDarklyInfo {
clientSideId: string;
contextEndpoint: string;
contextEndpoint: string | undefined;
context: ld.LDContext | undefined;
defaultFlags: object | undefined;
options:
Expand All @@ -69,7 +73,10 @@ export async function withLaunchDarkly(
(node: FernNavigation.WithFeatureFlags) => boolean,
]
> {
const launchDarklyConfig = await getLaunchDarklySettings(domain);
const launchDarklyConfig = await getLaunchDarklySettings(
domain,
getOrgMetadataForDomain(domain).then((metadata) => metadata?.orgId)
);
if (launchDarklyConfig) {
const context = await withLaunchDarklyContext(
launchDarklyConfig["context-endpoint"],
Expand Down
10 changes: 7 additions & 3 deletions packages/fern-docs/edge-config/src/getLaunchDarklySettings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ const LaunchDarklyEdgeConfigSchema = z.object({
// IMPORTANT: we will pass cookies to this endpoint, so if we move this to docs.yml,
// we should add a check to make sure the target domain is trusted. Trust should always be granted manually by a fern engineer,
// so it should be managed in edge config, or FGA.
"context-endpoint": z.string(),
"context-endpoint": z.string().optional(),

options: z
.object({
Expand All @@ -26,11 +26,15 @@ export type LaunchDarklyEdgeConfig = z.infer<
>;

export async function getLaunchDarklySettings(
domain: string
domain: string,
orgId?: Promise<string | undefined>
): Promise<LaunchDarklyEdgeConfig | undefined> {
const allConfigs =
await get<Record<string, LaunchDarklyEdgeConfig>>("launchdarkly");
const config = allConfigs?.[domain] ?? allConfigs?.[withoutStaging(domain)];
const config =
allConfigs?.[domain] ??
allConfigs?.[withoutStaging(domain)] ??
allConfigs?.[(await orgId) ?? ""];
if (config) {
const result = LaunchDarklyEdgeConfigSchema.safeParse(config);
if (result.success) {
Expand Down
2 changes: 1 addition & 1 deletion packages/fern-docs/ui/src/atoms/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ export type NavbarLink = DefaultNavbarLink | GithubNavbarLink;

export interface LaunchDarklyInfo {
clientSideId: string;
contextEndpoint: string;
contextEndpoint: string | undefined;
context: LDContext | undefined;
defaultFlags: object | undefined;
options:
Expand Down
26 changes: 18 additions & 8 deletions packages/fern-docs/ui/src/feature-flags/LDFeatureFlagProvider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ interface Props extends PropsWithChildren {
/**
* The endpoint to fetch the user context from.
*/
contextEndpoint: string;
contextEndpoint: string | undefined;

/**
* Default anonymous user context.
Expand All @@ -32,6 +32,12 @@ interface Props extends PropsWithChildren {
};
}

const ANONYMOUS_CONTEXT: LDContext = {
kind: "user",
key: "anonymous",
anonymous: true,
};

export const LDFeatureFlagProvider: FC<Props> = ({
clientSideId,
contextEndpoint,
Expand All @@ -43,16 +49,20 @@ export const LDFeatureFlagProvider: FC<Props> = ({
return (
<LDProvider
clientSideID={clientSideId}
context={defaultContext}
context={defaultContext ?? ANONYMOUS_CONTEXT}
flags={defaultFlags}
options={options}
>
<IdentifyWrapper
contextEndpoint={contextEndpoint}
defaultContext={defaultContext}
>
{children}
</IdentifyWrapper>
{contextEndpoint ? (
<IdentifyWrapper
contextEndpoint={contextEndpoint}
defaultContext={defaultContext}
>
{children}
</IdentifyWrapper>
) : (
children
)}
</LDProvider>
);
};
Expand Down

0 comments on commit f38c445

Please sign in to comment.