Skip to content

Commit

Permalink
Render the auth scheme in generated docs (#1215)
Browse files Browse the repository at this point in the history
Co-authored-by: Andrew Jiang <[email protected]>
  • Loading branch information
sulaiman-fern and abvthecity authored Aug 1, 2024
1 parent 6eb0f1a commit 5088acf
Show file tree
Hide file tree
Showing 6 changed files with 98 additions and 17 deletions.
98 changes: 83 additions & 15 deletions packages/ui/app/src/api-page/endpoints/EndpointContentLeft.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,13 @@ import { visitDiscriminatedUnion } from "@fern-ui/core-utils";
import { useBooleanState } from "@fern-ui/react-commons";
import { camelCase, sortBy, upperFirst } from "lodash-es";
import { memo } from "react";
import { useFeatureFlags } from "../../atoms";
import {
ResolvedEndpointDefinition,
ResolvedError,
ResolvedHttpRequestBodyShape,
ResolvedHttpResponseBodyShape,
ResolvedObjectProperty,
ResolvedTypeDefinition,
dereferenceObjectProperties,
getParameterDescription,
Expand Down Expand Up @@ -60,8 +62,56 @@ const UnmemoizedEndpointContentLeft: React.FC<EndpointContentLeft.Props> = ({
const requestExpandAll = useBooleanState(false);
const responseExpandAll = useBooleanState(false);
const errorExpandAll = useBooleanState(false);
const { isAuthEnabledInDocs } = useFeatureFlags();

const headers = endpoint.headers.filter((header) => !header.hidden);
let authHeaders: ResolvedObjectProperty | undefined;
if (endpoint.auth && isAuthEnabledInDocs) {
authHeaders = visitDiscriminatedUnion(endpoint.auth, "type")._visit<ResolvedObjectProperty>({
basicAuth: () => {
return {
key: "Authorization",
description: "Basic authentication of the form Basic <username:password>.",
hidden: false,
valueShape: {
type: "unknown",
displayName: "string",
},
availability: undefined,
};
},
bearerAuth: () => {
return {
key: "Authorization",
description: "Bearer authentication of the form Bearer <token>, where token is your auth token.",
hidden: false,
valueShape: {
type: "unknown",
displayName: "string",
},
availability: undefined,
};
},
header: (value) => {
return {
key: value.headerWireValue,
description:
value.prefix != null ? `Header authentication of the form ${value.prefix} <token>` : undefined,
hidden: false,
valueShape: {
type: "unknown",
displayName: "string",
},
availability: undefined,
};
},
});
}

let headers = endpoint.headers.filter((header) => !header.hidden);

if (authHeaders) {
headers = [authHeaders, ...headers];
}

return (
<div className="flex max-w-full flex-1 flex-col gap-12">
Expand All @@ -88,20 +138,38 @@ const UnmemoizedEndpointContentLeft: React.FC<EndpointContentLeft.Props> = ({
{headers.length > 0 && (
<EndpointSection title="Headers" anchorIdParts={REQUEST_HEADER} route={"/" + endpoint.slug}>
<div>
{headers.map((parameter) => (
<div key={parameter.key}>
<TypeComponentSeparator />
<EndpointParameter
name={parameter.key}
shape={parameter.valueShape}
anchorIdParts={[...REQUEST_HEADER, parameter.key]}
route={"/" + endpoint.slug}
description={getParameterDescription(parameter, types)}
availability={parameter.availability}
types={types}
/>
</div>
))}
{headers.map((parameter) => {
let isAuth = false;
const auth = endpoint.auth;
if (
(auth?.type === "header" && parameter.key === auth?.headerWireValue) ||
parameter.key === "Authorization"
) {
isAuth = true;
}

return (
<div key={parameter.key} className="relative">
{isAuth && (
<div className="absolute right-0 top-3">
<div className="px-2 bg-tag-danger rounded-xl flex items-center h-5">
<span className="text-xs t-danger">Auth</span>
</div>
</div>
)}
<TypeComponentSeparator />
<EndpointParameter
name={parameter.key}
shape={parameter.valueShape}
anchorIdParts={[...REQUEST_HEADER, parameter.key]}
route={"/" + endpoint.slug}
description={getParameterDescription(parameter, types)}
availability={parameter.availability}
types={types}
/>
</div>
);
})}
</div>
</EndpointSection>
)}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
DereferencedTypeShape,
ResolvedTypeDefinition,
ResolvedTypeShape,
ResolvedUnknownTypeShape,
unwrapAlias,
unwrapOptional,
unwrapReference,
Expand Down Expand Up @@ -144,7 +145,9 @@ export function renderTypeShorthand(
_other: () => "<unknown>",
}),
// other
unknown: () => "any",
unknown: (unknown: ResolvedUnknownTypeShape) => {
return unknown.displayName ?? "any";
},
_other: () => "<unknown>",
alias: (reference) => renderTypeShorthand(reference.shape, { plural, withArticle }, types),
});
Expand Down
1 change: 1 addition & 0 deletions packages/ui/app/src/atoms/docs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ export const DEFAULT_FEATURE_FLAGS: FeatureFlags = {
scrollInContainerEnabled: false,
useMdxBundler: false,
isBatchStreamToggleDisabled: false,
isAuthEnabledInDocs: false,
};

const EMPTY_DOCS_STATE: DocsProps = {
Expand Down
1 change: 1 addition & 0 deletions packages/ui/app/src/atoms/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ export interface FeatureFlags {
scrollInContainerEnabled: boolean;
useMdxBundler: boolean;
isBatchStreamToggleDisabled: boolean;
isAuthEnabledInDocs: boolean;
}

export interface NavigationProps {
Expand Down
5 changes: 5 additions & 0 deletions packages/ui/app/src/resolver/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -550,8 +550,13 @@ export type ResolvedTypeShape =
| ResolvedMapShape
| (APIV1Read.TypeReference.Literal & WithMetadata)
| APIV1Read.TypeReference.Unknown
| ResolvedUnknownTypeShape
| ResolvedReferenceShape;

export interface ResolvedUnknownTypeShape extends APIV1Read.TypeReference.Unknown {
displayName?: string;
}

export type WithoutMetadata = APIV1Read.TypeReference.Unknown | ResolvedReferenceShape;

export function hasMetadata(shape: ResolvedTypeShape): shape is Exclude<ResolvedTypeShape, WithoutMetadata> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ const FEATURE_FLAGS = [
"scroll-in-container-enabled" as const,
"use-mdx-bundler" as const,
"batch-stream-toggle-disabled" as const,
"enabled-auth-in-generated-docs" as const,
];

type FeatureFlag = (typeof FEATURE_FLAGS)[number];
Expand Down Expand Up @@ -59,7 +60,7 @@ export async function getFeatureFlags(domain: string): Promise<FeatureFlags> {
const scrollInContainerEnabled = checkDomainMatchesCustomers(domain, config["scroll-in-container-enabled"]);
const useMdxBundler = checkDomainMatchesCustomers(domain, config["use-mdx-bundler"]);
const isBatchStreamToggleDisabled = checkDomainMatchesCustomers(domain, config["batch-stream-toggle-disabled"]);

const isAuthEnabledInDocs = checkDomainMatchesCustomers(domain, config["enabled-auth-in-generated-docs"]);
return {
isApiPlaygroundEnabled: isApiPlaygroundEnabledOverrides(domain) || isApiPlaygroundEnabled,
isApiScrollingDisabled,
Expand All @@ -77,6 +78,7 @@ export async function getFeatureFlags(domain: string): Promise<FeatureFlags> {
scrollInContainerEnabled,
useMdxBundler,
isBatchStreamToggleDisabled,
isAuthEnabledInDocs,
};
} catch (e) {
// eslint-disable-next-line no-console
Expand All @@ -98,6 +100,7 @@ export async function getFeatureFlags(domain: string): Promise<FeatureFlags> {
scrollInContainerEnabled: false,
useMdxBundler: false,
isBatchStreamToggleDisabled: false,
isAuthEnabledInDocs: false,
};
}
}
Expand Down

0 comments on commit 5088acf

Please sign in to comment.