-
Notifications
You must be signed in to change notification settings - Fork 9
/
Copy pathEndpointError.tsx
104 lines (100 loc) · 4.17 KB
/
EndpointError.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
import * as ApiDefinition from "@fern-api/fdr-sdk/api-definition";
import type { APIV1Read } from "@fern-api/fdr-sdk/client/types";
import { visitDiscriminatedUnion } from "@fern-api/ui-core-utils";
import { FernCollapse } from "@fern-ui/components";
import { AvailabilityBadge } from "@fern-ui/components/badges";
import cn from "clsx";
import { MouseEventHandler, memo } from "react";
import { MdxContent } from "../../mdx/MdxContent";
import { renderTypeShorthand } from "../../type-shorthand";
import { type JsonPropertyPath } from "../examples/JsonPropertyPath";
import { TypeReferenceDefinitions } from "../types/type-reference/TypeReferenceDefinitions";
export declare namespace EndpointError {
export interface Props {
error: ApiDefinition.ErrorResponse;
isFirst: boolean;
isLast: boolean;
isSelected: boolean;
onClick: MouseEventHandler<HTMLButtonElement>;
onHoverProperty?: (path: JsonPropertyPath, opts: { isHovering: boolean }) => void;
availability: APIV1Read.Availability | null | undefined;
types: Record<string, ApiDefinition.TypeDefinition>;
}
}
export const EndpointError = memo<EndpointError.Props>(function EndpointErrorUnmemoized({
error,
isFirst,
isLast,
isSelected,
onHoverProperty,
onClick,
availability,
types,
}) {
return (
<button
className={cn(
"space flex flex-col items-start px-3 hover:bg-tag-default-soft transition-colors py-3",
{
"bg-tag-default-soft": isSelected,
},
{
"border-default border-b": !isLast,
},
{
"rounded-t-md": isFirst,
"rounded-b-md": isLast,
},
)}
onClick={onClick}
>
<div className="flex items-baseline space-x-2">
<div className="rounded-lg bg-tag-danger px-2 py-1 text-xs text-intent-danger">{error.statusCode}</div>
<div className="t-muted text-xs text-left">{error.name}</div>
{availability != null && <AvailabilityBadge availability={availability} size="sm" rounded />}
</div>
{error.shape != null && (
<FernCollapse open={isSelected} className="w-full">
<div className="space-y-2 pt-2">
<div className="t-muted w-full text-start text-sm leading-7">
<MdxContent
mdx={error.description}
fallback={`This error returns ${renderTypeShorthand(error.shape, { withArticle: true }, types)}.`}
/>
</div>
{shouldHideShape(error.shape, types) ? null : (
<div className="w-full text-start">
<TypeReferenceDefinitions
isCollapsible
applyErrorStyles
shape={error.shape}
onHoverProperty={onHoverProperty}
types={types}
isResponse={true}
/>
</div>
)}
</div>
</FernCollapse>
)}
</button>
);
});
function shouldHideShape(
shape: ApiDefinition.TypeShapeOrReference,
types: Record<string, ApiDefinition.TypeDefinition>,
): boolean {
return visitDiscriminatedUnion(ApiDefinition.unwrapReference(shape, types).shape)._visit<boolean>({
primitive: () => true,
literal: () => true,
object: (object) => ApiDefinition.unwrapObjectType(object, types).properties.length === 0,
undiscriminatedUnion: () => false,
discriminatedUnion: () => false,
enum: () => false,
list: (value) => shouldHideShape(value.itemShape, types),
set: (value) => shouldHideShape(value.itemShape, types),
map: () => false,
unknown: () => true,
_other: () => true,
});
}