From 530833ac3105f1ded641e60426ef84357e8c00db Mon Sep 17 00:00:00 2001 From: Rohin Bhargava Date: Tue, 21 Jan 2025 10:28:41 -0500 Subject: [PATCH] fix: ensure nullable shows in api reference (#2010) Co-authored-by: fern-bot --- .../fern-docs/ui/src/type-shorthand/index.tsx | 165 ++++++++++-------- 1 file changed, 89 insertions(+), 76 deletions(-) diff --git a/packages/fern-docs/ui/src/type-shorthand/index.tsx b/packages/fern-docs/ui/src/type-shorthand/index.tsx index e176379181..91bcd0c8f0 100644 --- a/packages/fern-docs/ui/src/type-shorthand/index.tsx +++ b/packages/fern-docs/ui/src/type-shorthand/index.tsx @@ -24,7 +24,11 @@ export function renderTypeShorthandRoot( hideOptional = false ): ReactNode { const unwrapped = unwrapReference(shape, types); - const typeShorthand = renderTypeShorthand(unwrapped.shape, {}, types); + const typeShorthand = renderTypeShorthand( + unwrapped.shape, + { nullable: unwrapped.isNullable }, + types + ); return ( {typeShorthand} @@ -155,14 +159,18 @@ function toPrimitiveTypeLabelsString({ export function renderTypeShorthand( shape: TypeShapeOrReference, - { plural = false, withArticle = false }: TypeShorthandOptions = { + { + plural = false, + withArticle = false, + nullable = false, + }: TypeShorthandOptions = { plural: false, withArticle: false, + nullable: false, }, types: Record ): string { const unwrapped = unwrapReference(shape, types); - const maybeWithArticle = (article: string, stringWithoutArticle: string) => withArticle ? `${article} ${stringWithoutArticle}` : stringWithoutArticle; @@ -174,77 +182,82 @@ export function renderTypeShorthand( return `${maybeWithArticle("an", "optional")} ${renderTypeShorthand(unwrapped.shape, { plural }, types)}`; } - return visitDiscriminatedUnion(unwrapped.shape)._visit({ - // primitives - primitive: (primitive) => - visitDiscriminatedUnion(primitive.value, "type")._visit({ - string: () => (plural ? "strings" : maybeWithArticle("a", "string")), - integer: () => - plural ? "integers" : maybeWithArticle("an", "integer"), - uint: () => (plural ? "uints" : maybeWithArticle("a", "uint")), - uint64: () => (plural ? "uint64s" : maybeWithArticle("a", "uint64")), - double: () => (plural ? "doubles" : maybeWithArticle("a", "double")), - long: () => (plural ? "longs" : maybeWithArticle("a", "long")), - boolean: () => (plural ? "booleans" : maybeWithArticle("a", "boolean")), - datetime: () => - plural ? "datetimes" : maybeWithArticle("a", "datetime"), - uuid: () => (plural ? "UUIDs" : maybeWithArticle("a", "UUID")), - base64: () => - plural ? "Base64 strings" : maybeWithArticle("a", "Base64 string"), - date: () => (plural ? "dates" : maybeWithArticle("a", "date")), - bigInteger: () => - plural ? "big integers" : maybeWithArticle("a", "big integer"), - _other: () => "", - }), - - // referenced shapes - object: () => (plural ? "objects" : maybeWithArticle("an", "object")), - undiscriminatedUnion: (union) => { - return uniq( - union.variants.map((variant) => - renderTypeShorthand(variant.shape, { plural, withArticle }, types) - ) - ).join(" or "); - }, - discriminatedUnion: () => - plural ? "objects" : maybeWithArticle("an", "object"), - enum: (enumValue) => { - // if there are only 1 or 2 values, we can list them like literals (e.g. "apple" or "banana") - if (enumValue.values.length > 0 && enumValue.values.length < 3) { - return enumValue.values.map((value) => `"${value.value}"`).join(" or "); - } - return plural ? "enums" : maybeWithArticle("an", "enum"); - }, - - // containing shapes - list: (list) => - `${plural ? "lists of" : maybeWithArticle("a", "list of")} ${renderTypeShorthand( - list.itemShape, - { plural: true }, - types - )}`, - set: (set) => - `${plural ? "sets of" : maybeWithArticle("a", "set of")} ${renderTypeShorthand( - set.itemShape, - { plural: true }, - types - )}`, - map: (map) => - `${plural ? "maps from" : maybeWithArticle("a", "map from")} ${renderTypeShorthand( - map.keyShape, - { plural: true }, - types - )} to ${renderTypeShorthand(map.valueShape, { plural: true }, types)}`, - - // literals - literal: (literal) => - visitDiscriminatedUnion(literal.value, "type")._visit({ - stringLiteral: ({ value }) => `"${value}"`, - booleanLiteral: ({ value }) => value.toString(), - _other: () => "", - }), - // other - unknown: (value) => value.displayName ?? "any", - _other: () => "", - }); + return ( + visitDiscriminatedUnion(unwrapped.shape)._visit({ + // primitives + primitive: (primitive) => + visitDiscriminatedUnion(primitive.value, "type")._visit({ + string: () => (plural ? "strings" : maybeWithArticle("a", "string")), + integer: () => + plural ? "integers" : maybeWithArticle("an", "integer"), + uint: () => (plural ? "uints" : maybeWithArticle("a", "uint")), + uint64: () => (plural ? "uint64s" : maybeWithArticle("a", "uint64")), + double: () => (plural ? "doubles" : maybeWithArticle("a", "double")), + long: () => (plural ? "longs" : maybeWithArticle("a", "long")), + boolean: () => + plural ? "booleans" : maybeWithArticle("a", "boolean"), + datetime: () => + plural ? "datetimes" : maybeWithArticle("a", "datetime"), + uuid: () => (plural ? "UUIDs" : maybeWithArticle("a", "UUID")), + base64: () => + plural ? "Base64 strings" : maybeWithArticle("a", "Base64 string"), + date: () => (plural ? "dates" : maybeWithArticle("a", "date")), + bigInteger: () => + plural ? "big integers" : maybeWithArticle("a", "big integer"), + _other: () => "", + }), + + // referenced shapes + object: () => (plural ? "objects" : maybeWithArticle("an", "object")), + undiscriminatedUnion: (union) => { + return uniq( + union.variants.map((variant) => + renderTypeShorthand(variant.shape, { plural, withArticle }, types) + ) + ).join(" or "); + }, + discriminatedUnion: () => + plural ? "objects" : maybeWithArticle("an", "object"), + enum: (enumValue) => { + // if there are only 1 or 2 values, we can list them like literals (e.g. "apple" or "banana") + if (enumValue.values.length > 0 && enumValue.values.length < 3) { + return enumValue.values + .map((value) => `"${value.value}"`) + .join(" or "); + } + return plural ? "enums" : maybeWithArticle("an", "enum"); + }, + + // containing shapes + list: (list) => + `${plural ? "lists of" : maybeWithArticle("a", "list of")} ${renderTypeShorthand( + list.itemShape, + { plural: true }, + types + )}`, + set: (set) => + `${plural ? "sets of" : maybeWithArticle("a", "set of")} ${renderTypeShorthand( + set.itemShape, + { plural: true }, + types + )}`, + map: (map) => + `${plural ? "maps from" : maybeWithArticle("a", "map from")} ${renderTypeShorthand( + map.keyShape, + { plural: true }, + types + )} to ${renderTypeShorthand(map.valueShape, { plural: true }, types)}`, + + // literals + literal: (literal) => + visitDiscriminatedUnion(literal.value, "type")._visit({ + stringLiteral: ({ value }) => `"${value}"`, + booleanLiteral: ({ value }) => value.toString(), + _other: () => "", + }), + // other + unknown: (value) => value.displayName ?? "any", + _other: () => "", + }) + (nullable ? " or null" : "") + ); }