diff --git a/packages/cli/generation/ir-generator/src/converters/services/getObjectPropertyFromResolvedType.ts b/packages/cli/generation/ir-generator/src/converters/services/getObjectPropertyFromResolvedType.ts index 5e9e72f1908..d898410785c 100644 --- a/packages/cli/generation/ir-generator/src/converters/services/getObjectPropertyFromResolvedType.ts +++ b/packages/cli/generation/ir-generator/src/converters/services/getObjectPropertyFromResolvedType.ts @@ -86,7 +86,7 @@ async function getAllPropertiesForRawObjectSchema( }); } - const objectProperties = await getObjectPropertiesFromRawObjectSchema(objectSchema, file); + const objectProperties = await getObjectPropertiesFromRawObjectSchema(objectSchema, file, typeResolver); objectProperties.forEach((objectProperty) => { properties[objectProperty.name.name.originalName] = objectProperty; }); diff --git a/packages/cli/generation/ir-generator/src/converters/type-declarations/convertGenericTypeDeclaration.ts b/packages/cli/generation/ir-generator/src/converters/type-declarations/convertGenericTypeDeclaration.ts index de6ba900599..4f0f1daf759 100644 --- a/packages/cli/generation/ir-generator/src/converters/type-declarations/convertGenericTypeDeclaration.ts +++ b/packages/cli/generation/ir-generator/src/converters/type-declarations/convertGenericTypeDeclaration.ts @@ -42,7 +42,8 @@ export async function convertGenericTypeDeclaration({ ), properties: await getObjectPropertiesFromRawObjectSchema( { properties: Object.fromEntries(newProperties) }, - file + file, + typeResolver ), extraProperties: resolvedBaseGeneric.declaration["extra-properties"] ?? false, extendedProperties: undefined, diff --git a/packages/cli/generation/ir-generator/src/converters/type-declarations/convertObjectTypeDeclaration.ts b/packages/cli/generation/ir-generator/src/converters/type-declarations/convertObjectTypeDeclaration.ts index 5b29cebd88a..2812f3935c0 100644 --- a/packages/cli/generation/ir-generator/src/converters/type-declarations/convertObjectTypeDeclaration.ts +++ b/packages/cli/generation/ir-generator/src/converters/type-declarations/convertObjectTypeDeclaration.ts @@ -3,17 +3,22 @@ import { RawSchemas } from "@fern-api/fern-definition-schema"; import { FernFileContext } from "../../FernFileContext"; import { parseTypeName } from "../../utils/parseTypeName"; import { convertDeclaration } from "../convertDeclaration"; +import { TypeResolver } from "../../resolvers/TypeResolver"; +import { ResolvedContainerType, ResolvedType } from "../../resolvers/ResolvedType"; +import { assertNever } from "@fern-api/core-utils"; export async function convertObjectTypeDeclaration({ object, - file + file, + typeResolver }: { object: RawSchemas.ObjectSchema; file: FernFileContext; + typeResolver: TypeResolver; }): Promise { return Type.object({ extends: getExtensionsAsList(object.extends).map((extended) => parseTypeName({ typeName: extended, file })), - properties: await getObjectPropertiesFromRawObjectSchema(object, file), + properties: await getObjectPropertiesFromRawObjectSchema(object, file, typeResolver), extraProperties: object["extra-properties"] ?? false, extendedProperties: undefined, inline: object.inline @@ -22,23 +27,65 @@ export async function convertObjectTypeDeclaration({ export async function getObjectPropertiesFromRawObjectSchema( object: RawSchemas.ObjectSchema, - file: FernFileContext + file: FernFileContext, + typeResolver: TypeResolver ): Promise { if (object.properties == null) { return []; } return await Promise.all( - Object.entries(object.properties).map(async ([propertyKey, propertyDefinition]) => ({ - ...(await convertDeclaration(propertyDefinition)), - name: file.casingsGenerator.generateNameAndWireValue({ - wireValue: propertyKey, - name: getPropertyName({ propertyKey, property: propertyDefinition }).name - }), - valueType: file.parseTypeReference(propertyDefinition) - })) + Object.entries(object.properties).map(async ([propertyKey, propertyDefinition]) => { + const isString = typeof propertyDefinition === "string"; + const typeName = isString ? propertyDefinition : propertyDefinition.type; + const default_ = isString ? undefined : propertyDefinition.default; + const validation = isString ? undefined : propertyDefinition.validation; + + const type = typeResolver.resolveNamedType({ + referenceToNamedType: typeName, + file + }); + const inline = getInline(type); + const prop = { + ...(await convertDeclaration(propertyDefinition)), + name: file.casingsGenerator.generateNameAndWireValue({ + wireValue: propertyKey, + name: getPropertyName({ propertyKey, property: propertyDefinition }).name + }), + valueType: file.parseTypeReference({ type: typeName, default: default_, validation, inline }) + }; + return prop; + }) ); } +function getInline(type: ResolvedType | ResolvedContainerType | undefined): boolean | undefined { + if (type == null) { + return undefined; + } + switch (type._type) { + case "container": + return getInline(type.container); + case "named": + return type.declaration.inline ?? undefined; + case "primitive": + return undefined; + case "list": + return undefined; + case "map": + return undefined; + case "optional": + return getInline(type.itemType); + case "unknown": + return undefined; + case "set": + return undefined; + case "literal": + return undefined; + default: + assertNever(type); + } +} + export function getExtensionsAsList(extensions: string | string[] | undefined): string[] { if (extensions == null) { return []; diff --git a/packages/cli/generation/ir-generator/src/converters/type-declarations/convertTypeDeclaration.ts b/packages/cli/generation/ir-generator/src/converters/type-declarations/convertTypeDeclaration.ts index 1b8191dc11f..b76a72db090 100644 --- a/packages/cli/generation/ir-generator/src/converters/type-declarations/convertTypeDeclaration.ts +++ b/packages/cli/generation/ir-generator/src/converters/type-declarations/convertTypeDeclaration.ts @@ -112,7 +112,7 @@ export async function convertType({ }): Promise { return await visitRawTypeDeclaration | Type>(typeDeclaration, { alias: (alias) => convertAliasTypeDeclaration({ alias, file, typeResolver }), - object: (object) => convertObjectTypeDeclaration({ object, file }), + object: (object) => convertObjectTypeDeclaration({ object, file, typeResolver }), discriminatedUnion: (union) => convertDiscriminatedUnionTypeDeclaration({ union, file, typeResolver }), undiscriminatedUnion: (union) => convertUndiscriminatedUnionTypeDeclaration({ union, file }), enum: async (enum_) => Type.enum(await convertEnumTypeDeclaration({ _enum: enum_, file })) @@ -200,7 +200,7 @@ function getInline(typeDeclaration: RawSchemas.TypeDeclarationSchema): boolean | return undefined; } if ("inline" in typeDeclaration) { - return typeDeclaration.inline; + return typeDeclaration.inline || undefined; } return undefined; } diff --git a/packages/cli/generation/ir-generator/src/resolvers/TypeResolver.ts b/packages/cli/generation/ir-generator/src/resolvers/TypeResolver.ts index e9b065cde4d..d5ff88b6c46 100644 --- a/packages/cli/generation/ir-generator/src/resolvers/TypeResolver.ts +++ b/packages/cli/generation/ir-generator/src/resolvers/TypeResolver.ts @@ -296,7 +296,7 @@ export class TypeResolverImpl implements TypeResolver { const parsedTypeReference = parseInlineType({ type: referenceToNamedType, - inline: undefined, + inline: declaration.inline, _default: undefined, validation: undefined, file: referencedIn