Skip to content

Commit

Permalink
fix: support recursive property rendering (#371)
Browse files Browse the repository at this point in the history
  • Loading branch information
abvthecity authored Jan 19, 2024
1 parent 668264a commit 8b42020
Show file tree
Hide file tree
Showing 9 changed files with 69 additions and 34 deletions.
26 changes: 16 additions & 10 deletions packages/commons/app-utils/src/resolver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -222,9 +222,9 @@ function resolveWebhookPayloadShape(
return visitDiscriminatedUnion(payloadShape, "type")._visit<ResolvedTypeReference>({
object: (object) => ({
type: "object",
properties: resolveObjectProperties(object, types),
properties: () => resolveObjectProperties(object, types),
}),
reference: (reference) => resolveTypeReference(reference.value, types),
reference: (reference) => ({ type: "reference", shape: () => resolveTypeReference(reference.value, types) }),
_other: () => ({ type: "unknown" }),
});
}
Expand All @@ -236,10 +236,10 @@ function resolveRequestBodyShape(
return visitDiscriminatedUnion(requestBodyShape, "type")._visit<ResolvedHttpRequestBodyShape>({
object: (object) => ({
type: "object",
properties: resolveObjectProperties(object, types),
properties: () => resolveObjectProperties(object, types),
}),
fileUpload: (fileUpload) => fileUpload,
reference: (reference) => resolveTypeReference(reference.value, types),
reference: (reference) => ({ type: "reference", shape: () => resolveTypeReference(reference.value, types) }),
_other: () => ({ type: "unknown" }),
});
}
Expand All @@ -251,12 +251,12 @@ function resolveResponseBodyShape(
return visitDiscriminatedUnion(responseBodyShape, "type")._visit<ResolvedHttpResponseBodyShape>({
object: (object) => ({
type: "object",
properties: resolveObjectProperties(object, types),
properties: () => resolveObjectProperties(object, types),
}),
fileDownload: (fileDownload) => fileDownload,
streamingText: (streamingText) => streamingText,
streamCondition: (streamCondition) => streamCondition,
reference: (reference) => resolveTypeReference(reference.value, types),
reference: (reference) => ({ type: "reference", shape: () => resolveTypeReference(reference.value, types) }),
_other: () => ({ type: "unknown" }),
});
}
Expand All @@ -268,7 +268,7 @@ function resolveTypeShape(
return visitDiscriminatedUnion(typeShape, "type")._visit<ResolvedTypeReference>({
object: (object) => ({
type: "object",
properties: resolveObjectProperties(object, types),
properties: () => resolveObjectProperties(object, types),
}),
enum: (enum_) => enum_,
undiscriminatedUnion: (undiscriminatedUnion) => ({
Expand Down Expand Up @@ -334,7 +334,7 @@ function resolveObjectProperties(
console.error("Object extends non-object", typeId);
return [];
}
return shape.properties;
return shape.properties();
});
if (extendedProperties.length === 0) {
return directProperties;
Expand Down Expand Up @@ -486,7 +486,7 @@ export interface ResolvedWebhookPayload extends APIV1Read.WithDescription {

export interface ResolvedObjectShape {
type: "object";
properties: ResolvedObjectProperty[];
properties: () => ResolvedObjectProperty[];
}

export interface ResolvedUndiscriminatedUnionShapeVariant
Expand Down Expand Up @@ -547,7 +547,13 @@ export type ResolvedTypeReference =
| ResolvedSetShape
| ResolvedMapShape
| APIV1Read.LiteralType
| APIV1Read.TypeReference.Unknown;
| APIV1Read.TypeReference.Unknown
| ResolvedReferenceShape;

export interface ResolvedReferenceShape {
type: "reference";
shape: () => ResolvedTypeReference;
}

export type ResolvedHttpRequestBodyShape = APIV1Read.HttpRequestBodyShape.FileUpload | ResolvedTypeReference;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ export const DiscriminatedUnionVariant: React.FC<DiscriminatedUnionVariant.Props
const shape = useMemo((): ResolvedTypeShape => {
return {
type: "object",
properties: [
properties: () => [
{
key: discriminant,
valueShape: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,16 +52,18 @@ export const InternalTypeDefinition: React.FC<InternalTypeDefinition.Props> = ({
() =>
visitDiscriminatedUnion(typeShape, "type")._visit<CollapsibleContent | undefined>({
object: (object) => ({
elements: object.properties.map((property) => (
<ObjectProperty
key={property.key}
property={property}
anchorIdParts={[...anchorIdParts, property.key]}
applyErrorStyles={false}
route={route}
defaultExpandAll={defaultExpandAll}
/>
)),
elements: object
.properties()
.map((property) => (
<ObjectProperty
key={property.key}
property={property}
anchorIdParts={[...anchorIdParts, property.key]}
applyErrorStyles={false}
route={route}
defaultExpandAll={defaultExpandAll}
/>
)),
elementNameSingular: "property",
elementNamePlural: "properties",
}),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,15 +51,17 @@ export const InternalTypeDefinitionError: React.FC<InternalTypeDefinitionError.P
() =>
visitDiscriminatedUnion(typeShape, "type")._visit<CollapsibleContent | undefined>({
object: (object) => ({
elements: object.properties.map((property) => (
<ObjectProperty
key={property.key}
property={property}
anchorIdParts={[...anchorIdParts, property.key]}
route={route}
applyErrorStyles
/>
)),
elements: object
.properties()
.map((property) => (
<ObjectProperty
key={property.key}
property={property}
anchorIdParts={[...anchorIdParts, property.key]}
route={route}
applyErrorStyles
/>
)),
elementNameSingular: "property",
elementNamePlural: "properties",
}),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -138,5 +138,16 @@ export const InternalTypeReferenceDefinitions: React.FC<InternalTypeReferenceDef
stringLiteral: () => null,
unknown: () => null,
_other: () => null,
reference: (reference) => (
<InternalTypeReferenceDefinitions
shape={reference.shape()}
isCollapsible={isCollapsible}
applyErrorStyles={applyErrorStyles}
className={className}
anchorIdParts={anchorIdParts}
route={route}
defaultExpandAll={defaultExpandAll}
/>
),
});
};
Original file line number Diff line number Diff line change
Expand Up @@ -53,5 +53,6 @@ export function renderTypeShorthand(
// other
unknown: () => "any",
_other: () => "<unknown>",
reference: (reference) => renderTypeShorthand(reference.shape(), { plural, withArticle }),
});
}
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ function getIconInfoForTypeReference(typeRef: ResolvedTypeReference): IconInfo |
stringLiteral: () => ({ content: "!", size: 6 }),
unknown: () => ({ content: "{}", size: 6 }),
_other: () => null,
reference: (reference) => getIconInfoForTypeReference(reference.shape()),
});
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ export const PlaygroundTypeReferenceForm: FC<PlaygroundTypeReferenceFormProps> =
onOpenStack={onOpenStack}
onCloseStack={onCloseStack}
>
<PlaygroundObjectPropertiesForm properties={object.properties} onChange={onChange} value={value} />
<PlaygroundObjectPropertiesForm properties={object.properties()} onChange={onChange} value={value} />
</WithPanel>
),
enum: ({ values }) => <PlaygroundEnumForm enumValues={values} onChange={onChange} value={value} />,
Expand Down Expand Up @@ -276,5 +276,14 @@ export const PlaygroundTypeReferenceForm: FC<PlaygroundTypeReferenceFormProps> =
/>
),
_other: () => null,
reference: (reference) => (
<PlaygroundTypeReferenceForm
shape={reference.shape()}
onChange={onChange}
value={value}
onFocus={onFocus}
onBlur={onBlur}
/>
),
});
};
9 changes: 6 additions & 3 deletions packages/ui/app/src/api-playground/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -285,7 +285,7 @@ export function matchesTypeReference(shape: ResolvedTypeReference, value: unknow
return false;
}
const propertyMap = new Map<string, ResolvedObjectProperty>();
object.properties.forEach((property) => propertyMap.set(property.key, property));
object.properties().forEach((property) => propertyMap.set(property.key, property));
return Object.keys(value).every((key) => {
const property = propertyMap.get(key);
if (property == null) {
Expand Down Expand Up @@ -349,6 +349,7 @@ export function matchesTypeReference(shape: ResolvedTypeReference, value: unknow
booleanLiteral: (literalType) => value === literalType.value,
unknown: () => value == null,
_other: () => value == null,
reference: (reference) => matchesTypeReference(reference.shape(), value),
});
}

Expand All @@ -368,15 +369,15 @@ export function getDefaultValuesForBody(requestShape: ResolvedHttpRequestBodySha
} else if (requestShape.type === "fileUpload") {
return null;
} else if (requestShape.type === "object") {
return getDefaultValueForObjectProperties(requestShape.properties);
return getDefaultValueForObjectProperties(requestShape.properties());
} else {
return getDefaultValueForType(requestShape);
}
}

export function getDefaultValueForType(shape: ResolvedTypeReference): unknown {
return visitDiscriminatedUnion(shape, "type")._visit<unknown>({
object: (object) => getDefaultValueForObjectProperties(object.properties),
object: (object) => getDefaultValueForObjectProperties(object.properties()),
discriminatedUnion: (discriminatedUnion) => {
const variant = discriminatedUnion.variants[0];

Expand Down Expand Up @@ -415,6 +416,7 @@ export function getDefaultValueForType(shape: ResolvedTypeReference): unknown {
booleanLiteral: (literal) => literal.value,
unknown: () => undefined,
_other: () => undefined,
reference: (reference) => getDefaultValueForType(reference.shape()),
});
}

Expand All @@ -441,5 +443,6 @@ export function isExpandable(valueShape: ResolvedTypeReference, currentValue: un
date: () => false,
booleanLiteral: () => false,
stringLiteral: () => false,
reference: (reference) => isExpandable(reference.shape(), currentValue),
});
}

1 comment on commit 8b42020

@vercel
Copy link

@vercel vercel bot commented on 8b42020 Jan 19, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

fern-dev – ./packages/ui/fe-bundle

fern-dev-buildwithfern.vercel.app
app-dev.buildwithfern.com
fern-dev-git-main-buildwithfern.vercel.app

Please sign in to comment.