Skip to content

Commit

Permalink
fix: transition away from domain checks and instead use feature flags (
Browse files Browse the repository at this point in the history
  • Loading branch information
RohinBhargava authored Aug 22, 2024
1 parent 807cb2a commit 2f55725
Show file tree
Hide file tree
Showing 17 changed files with 94 additions and 49 deletions.
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { useDomain } from "../../atoms";
import { useFeatureFlags } from "../../atoms";
import { FernErrorTag } from "../../components/FernErrorBoundary";
import { ResolvedResponseBody, ResolvedTypeDefinition, visitResolvedHttpResponseBodyShape } from "../../resolver/types";
import { ApiPageDescription } from "../ApiPageDescription";
Expand All @@ -25,12 +25,13 @@ export const EndpointResponseSection: React.FC<EndpointResponseSection.Props> =
defaultExpandAll = false,
types,
}) => {
const domain = useDomain();
const { isAudioFileDownloadSpanSummary } = useFeatureFlags();

return (
<div>
<ApiPageDescription className="mt-3 text-sm" description={responseBody.description} isMarkdown={true} />
<div className="t-muted border-default border-b pb-5 text-sm leading-6">
{getResponseSummary({ responseBody, types, domain })}
{getResponseSummary({ responseBody, types, isAudioFileDownloadSpanSummary })}
</div>
{visitResolvedHttpResponseBodyShape(responseBody.shape, {
fileDownload: () => null,
Expand Down Expand Up @@ -86,14 +87,14 @@ export const EndpointResponseSection: React.FC<EndpointResponseSection.Props> =
function getResponseSummary({
responseBody,
types,
domain,
isAudioFileDownloadSpanSummary,
}: {
responseBody: ResolvedResponseBody;
types: Record<string, ResolvedTypeDefinition>;
domain: string;
isAudioFileDownloadSpanSummary: boolean;
}) {
if (responseBody.shape.type === "fileDownload") {
if (domain.includes("elevenlabs")) {
if (isAudioFileDownloadSpanSummary) {
return (
<span>
This endpoint returns an <code>audio/mpeg</code> file.
Expand Down
7 changes: 4 additions & 3 deletions packages/ui/app/src/api-page/examples/AudioExample.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { FernAudioPlayer } from "@fern-ui/components";
import { FC } from "react";
import { useDomain } from "../../atoms";
import { useFeatureFlags } from "../../atoms";
import { FernErrorBoundary } from "../../components/FernErrorBoundary";
import { TitledExample } from "./TitledExample";

Expand All @@ -9,8 +9,9 @@ export declare namespace AudioExample {
}

const AudioExampleInternal: FC<AudioExample.Props> = ({ ...props }) => {
const domain = useDomain();
if (!domain.includes("elevenlabs")) {
const { isAudioExampleInternal } = useFeatureFlags();

if (!isAudioExampleInternal) {
return null;
}
return (
Expand Down
11 changes: 5 additions & 6 deletions packages/ui/app/src/api-playground/PlaygroundEndpoint.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ import {
PLAYGROUND_AUTH_STATE_ATOM,
store,
useBasePath,
useDomain,
useFeatureFlags,
usePlaygroundEndpointFormState,
} from "../atoms";
Expand Down Expand Up @@ -73,8 +72,8 @@ export const PlaygroundEndpoint: FC<PlaygroundEndpointProps> = ({ endpoint, type
setFormState(getInitialEndpointRequestFormState(endpoint, types));
}, []);

const domain = useDomain();
const basePath = useBasePath();
const { usesApplicationJsonInFormDataValue } = useFeatureFlags();
const { proxyShouldUseAppBuildwithfernCom } = useFeatureFlags();
const [response, setResponse] = useState<Loadable<PlaygroundResponse>>(notStartedLoading());

Expand Down Expand Up @@ -119,7 +118,7 @@ export const PlaygroundEndpoint: FC<PlaygroundEndpointProps> = ({ endpoint, type
uploadEnvironment,
endpoint.requestBody?.shape,
formState.body,
domain,
usesApplicationJsonInFormDataValue,
),
};
if (endpoint.responseBody?.shape.type === "stream") {
Expand Down Expand Up @@ -178,7 +177,7 @@ export const PlaygroundEndpoint: FC<PlaygroundEndpointProps> = ({ endpoint, type
},
});
}
}, [domain, endpoint, formState, proxyEnvironment, uploadEnvironment]);
}, [endpoint, formState, proxyEnvironment, uploadEnvironment, usesApplicationJsonInFormDataValue]);

const selectedEnvironmentId = useSelectedEnvironmentId();

Expand Down Expand Up @@ -220,7 +219,7 @@ async function serializeFormStateBody(
environment: string,
shape: ResolvedHttpRequestBodyShape | undefined,
body: PlaygroundFormStateBody | undefined,
domain: string,
usesApplicationJsonInFormDataValue: boolean,
): Promise<ProxyRequest.SerializableBody | undefined> {
if (shape == null || body == null) {
return undefined;
Expand Down Expand Up @@ -266,7 +265,7 @@ async function serializeFormStateBody(
// revert this once we have a better solution
contentType:
compact(property?.contentType)[0] ??
(domain.includes("fileforge") ? "application/json" : undefined),
(usesApplicationJsonInFormDataValue ? "application/json" : undefined),
};
break;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import { useAtom, useAtomValue } from "jotai";
import { atomWithStorage } from "jotai/utils";
import { isEmpty, round } from "lodash-es";
import { Dispatch, FC, SetStateAction, useEffect, useRef, useState } from "react";
import { IS_MOBILE_SCREEN_ATOM, PLAYGROUND_AUTH_STATE_ATOM, store, useDomain, useFeatureFlags } from "../atoms";
import { IS_MOBILE_SCREEN_ATOM, PLAYGROUND_AUTH_STATE_ATOM, store, useFeatureFlags } from "../atoms";
import { FernErrorTag } from "../components/FernErrorBoundary";
import { ResolvedEndpointDefinition, ResolvedTypeDefinition } from "../resolver/types";
import { PlaygroundAuthorizationFormCard } from "./PlaygroundAuthorizationForm";
Expand Down Expand Up @@ -52,8 +52,7 @@ export const PlaygroundEndpointContent: FC<PlaygroundEndpointContentProps> = ({
sendRequest,
types,
}) => {
const domain = useDomain();
const { isSnippetTemplatesEnabled } = useFeatureFlags();
const { isBinaryOctetStreamAudioPlayer, isSnippetTemplatesEnabled, isFileForgeHackEnabled } = useFeatureFlags();
const [requestType, setRequestType] = useAtom(requestTypeAtom);

const scrollAreaRef = useRef<HTMLDivElement>(null);
Expand Down Expand Up @@ -136,7 +135,7 @@ export const PlaygroundEndpointContent: FC<PlaygroundEndpointContentProps> = ({
const resolver = new PlaygroundCodeSnippetResolverBuilder(
endpoint,
isSnippetTemplatesEnabled,
domain,
isFileForgeHackEnabled,
).create(authState, formState);
return resolver.resolve(requestType);
}}
Expand Down Expand Up @@ -226,7 +225,7 @@ export const PlaygroundEndpointContent: FC<PlaygroundEndpointContentProps> = ({
response.type !== "file" ? (
<PlaygroundResponsePreview response={response} />
) : response.contentType.startsWith("audio/") ||
(domain.includes("ircamamplify") && response.contentType === "binary/octet-stream") ? (
(isBinaryOctetStreamAudioPlayer && response.contentType === "binary/octet-stream") ? (
<FernAudioPlayer
src={response.response.body}
className="flex h-full items-center justify-center p-4"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { useAtomValue } from "jotai";
import { FC, useMemo } from "react";
import { PLAYGROUND_AUTH_STATE_ATOM, useDomain, useFeatureFlags } from "../atoms";
import { PLAYGROUND_AUTH_STATE_ATOM, useFeatureFlags } from "../atoms";
import { ResolvedEndpointDefinition } from "../resolver/types";
import { FernSyntaxHighlighter } from "../syntax-highlighting/FernSyntaxHighlighter";
import { PlaygroundCodeSnippetResolverBuilder } from "./code-snippets/resolver";
Expand All @@ -16,10 +16,10 @@ interface PlaygroundRequestPreviewProps {
export const PlaygroundRequestPreview: FC<PlaygroundRequestPreviewProps> = ({ endpoint, formState, requestType }) => {
const { isSnippetTemplatesEnabled } = useFeatureFlags();
const authState = useAtomValue(PLAYGROUND_AUTH_STATE_ATOM);
const domain = useDomain();
const { isFileForgeHackEnabled } = useFeatureFlags();
const builder = useMemo(
() => new PlaygroundCodeSnippetResolverBuilder(endpoint, isSnippetTemplatesEnabled, domain),
[domain, endpoint, isSnippetTemplatesEnabled],
() => new PlaygroundCodeSnippetResolverBuilder(endpoint, isSnippetTemplatesEnabled, isFileForgeHackEnabled),
[endpoint, isSnippetTemplatesEnabled, isFileForgeHackEnabled],
);
const resolver = useMemo(() => builder.createRedacted(authState, formState), [authState, builder, formState]);
const code = useSnippet(resolver, requestType);
Expand Down
6 changes: 3 additions & 3 deletions packages/ui/app/src/api-playground/code-snippets/resolver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ export class PlaygroundCodeSnippetResolverBuilder {
constructor(
private endpoint: ResolvedEndpointDefinition,
private isSnippetTemplatesEnabled: boolean,
private docsHost: string,
private isFileForgeHackEnabled: boolean,
) {}

public create(
Expand All @@ -26,7 +26,7 @@ export class PlaygroundCodeSnippetResolverBuilder {
formState,
false,
this.isSnippetTemplatesEnabled,
this.docsHost.includes("fileforge"),
this.isFileForgeHackEnabled,
);
}

Expand All @@ -40,7 +40,7 @@ export class PlaygroundCodeSnippetResolverBuilder {
formState,
true,
this.isSnippetTemplatesEnabled,
this.docsHost.includes("fileforge"),
this.isFileForgeHackEnabled,
);
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { FernInput, FernNumericInput, FernSwitch, FernTextarea } from "@fern-ui/components";
import { visitDiscriminatedUnion } from "@fern-ui/core-utils";
import { ReactElement, memo, useCallback } from "react";
import { useDomain } from "../../atoms";
import { useFeatureFlags } from "../../atoms";
import {
ResolvedObjectProperty,
ResolvedTypeDefinition,
Expand Down Expand Up @@ -36,7 +36,7 @@ interface PlaygroundTypeReferenceFormProps {
}

export const PlaygroundTypeReferenceForm = memo<PlaygroundTypeReferenceFormProps>((props) => {
const domain = useDomain();
const { hasVoiceIdPlaygroundForm } = useFeatureFlags();
const { id, property, shape, onChange, value, types, disabled } = props;
const onRemove = useCallback(() => {
onChange(undefined);
Expand Down Expand Up @@ -88,7 +88,7 @@ export const PlaygroundTypeReferenceForm = memo<PlaygroundTypeReferenceFormProps
visitDiscriminatedUnion(primitive.value, "type")._visit<ReactElement | null>({
string: (string) => (
<WithLabel property={property} value={value} onRemove={onRemove} types={types} htmlFor={id}>
{domain.includes("elevenlabs") && property?.key === "voice_id" ? (
{hasVoiceIdPlaygroundForm && property?.key === "voice_id" ? (
<PlaygroundElevenLabsVoiceIdForm
id={id}
className="w-full"
Expand Down
8 changes: 8 additions & 0 deletions packages/ui/app/src/atoms/docs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,14 @@ export const DEFAULT_FEATURE_FLAGS: FeatureFlags = {
isBatchStreamToggleDisabled: false,
isAuthEnabledInDocs: false,
isAiChatbotEnabledInPreview: false,
isAudioFileDownloadSpanSummary: false,
isDocsLogoTextEnabled: false,
isAudioExampleInternal: false,
usesApplicationJsonInFormDataValue: false,
isBinaryOctetStreamAudioPlayer: false,
hasVoiceIdPlaygroundForm: false,
isCohereTheme: false,
isFileForgeHackEnabled: false,
};

const EMPTY_DOCS_STATE: DocsProps = {
Expand Down
3 changes: 2 additions & 1 deletion packages/ui/app/src/atoms/logo.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import { atom, useAtomValue } from "jotai";
import { DOCS_ATOM } from "./docs";
import { FEATURE_FLAGS_ATOM } from "./flags";

export const LOGO_TEXT_ATOM = atom<string | undefined>((get) =>
get(DOCS_ATOM).baseUrl.domain.includes("cohere") ? "docs" : undefined,
get(FEATURE_FLAGS_ATOM).isDocsLogoTextEnabled ? "docs" : undefined,
);
LOGO_TEXT_ATOM.debugLabel = "LOGO_TEXT_ATOM";

Expand Down
8 changes: 8 additions & 0 deletions packages/ui/app/src/atoms/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,14 @@ export interface FeatureFlags {
isBatchStreamToggleDisabled: boolean;
isAuthEnabledInDocs: boolean;
isAiChatbotEnabledInPreview: boolean;
isAudioFileDownloadSpanSummary: boolean;
isDocsLogoTextEnabled: boolean;
isAudioExampleInternal: boolean;
usesApplicationJsonInFormDataValue: boolean;
isBinaryOctetStreamAudioPlayer: boolean;
hasVoiceIdPlaygroundForm: boolean;
isCohereTheme: boolean;
isFileForgeHackEnabled: boolean;
}

export interface NavigationProps {
Expand Down
6 changes: 2 additions & 4 deletions packages/ui/app/src/resolver/ApiDefinitionResolver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,8 @@ export class ApiDefinitionResolver {
pages: Record<string, DocsV1Read.PageContent>,
mdxOptions: FernSerializeMdxOptions | undefined,
featureFlags: FeatureFlags,
domain: string,
): Promise<ResolvedRootPackage> {
const resolver = new ApiDefinitionResolver(root, holder, typeResolver, pages, featureFlags, domain, mdxOptions);
const resolver = new ApiDefinitionResolver(root, holder, typeResolver, pages, featureFlags, mdxOptions);
return resolver.resolveApiDefinition();
}

Expand All @@ -60,7 +59,6 @@ export class ApiDefinitionResolver {
private typeResolver: ApiTypeResolver,
private pages: Record<string, DocsV1Read.PageContent>,
private featureFlags: FeatureFlags,
private domain: string,
private mdxOptions: FernSerializeMdxOptions | undefined,
) {}

Expand Down Expand Up @@ -846,7 +844,7 @@ export class ApiDefinitionResolver {
// revert this once we have a better solution
const contentType =
compact(property?.contentType)[0] ??
(this.domain.includes("fileforge") ? "application/json" : undefined);
(this.featureFlags.usesApplicationJsonInFormDataValue ? "application/json" : undefined);
return { type: "json" as const, value: value.value, contentType };
},
filename: (value) => ({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@ describe("resolveApiDefinition", () => {
{},
undefined,
DEFAULT_FEATURE_FLAGS,
"fern.docs.buildwithfern.com",
);
expect(resolved).toMatchSnapshot();
});
Expand Down Expand Up @@ -73,7 +72,6 @@ describe("resolveApiDefinition", () => {
{},
undefined,
DEFAULT_FEATURE_FLAGS,
"documentation.sayari.com",
);
expect(resolved).toMatchSnapshot();
expect((resolved.items[0] as ResolvedEndpointDefinition).auth).toBeUndefined();
Expand Down
11 changes: 1 addition & 10 deletions packages/ui/app/src/util/convertNavigatableToResolvedPath.ts
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,6 @@ export async function convertNavigatableToResolvedPath({
pages,
mdxOptions,
featureFlags,
domain,
);
return {
type: "api-page",
Expand Down Expand Up @@ -249,15 +248,7 @@ async function resolveMarkdownPage(
const typeResolver = new ApiTypeResolver(definition.types, mdxOptions);
return [
apiNode.title,
await ApiDefinitionResolver.resolve(
apiNode,
holder,
typeResolver,
pages,
mdxOptions,
featureFlags,
domain,
),
await ApiDefinitionResolver.resolve(apiNode, holder, typeResolver, pages, mdxOptions, featureFlags),
];
}),
),
Expand Down
Loading

0 comments on commit 2f55725

Please sign in to comment.