From b6c380a58064d1312212597e06e1a2da8cb6c6e5 Mon Sep 17 00:00:00 2001 From: Zach Kirsch Date: Thu, 15 Sep 2022 22:39:03 -0700 Subject: [PATCH] Fix resolved type generation (#710) --- fern/ir-types/definition/types.yml | 2 - .../tests/ir/__snapshots__/ir.test.ts.snap | 178 ++++++++++++++++++ .../simple/fern/api/definition/director.yml | 4 + .../simple/fern/api/definition/imdb.yml | 8 + .../src/type-resolver/TypeResolver.ts | 37 ++-- 5 files changed, 215 insertions(+), 14 deletions(-) create mode 100644 packages/cli/ete-tests/src/tests/ir/fixtures/simple/fern/api/definition/director.yml diff --git a/fern/ir-types/definition/types.yml b/fern/ir-types/definition/types.yml index 23a109cfa2e..45473580389 100644 --- a/fern/ir-types/definition/types.yml +++ b/fern/ir-types/definition/types.yml @@ -24,7 +24,6 @@ types: properties: aliasOf: TypeReference resolvedType: ResolvedTypeReference - ResolvedTypeReference: union: container: ContainerType @@ -32,7 +31,6 @@ types: primitive: PrimitiveType unknown: {} void: {} - ResolvedNamedType: properties: name: DeclaredTypeName diff --git a/packages/cli/ete-tests/src/tests/ir/__snapshots__/ir.test.ts.snap b/packages/cli/ete-tests/src/tests/ir/__snapshots__/ir.test.ts.snap index 2bf1b231851..1ec80ef5b42 100644 --- a/packages/cli/ete-tests/src/tests/ir/__snapshots__/ir.test.ts.snap +++ b/packages/cli/ete-tests/src/tests/ir/__snapshots__/ir.test.ts.snap @@ -8,6 +8,40 @@ exports[`ir simple 1`] = ` "schemes": [] }, "types": [ + { + "name": { + "fernFilepath": [ + { + "originalValue": "director", + "camelCase": "director", + "snakeCase": "director", + "pascalCase": "Director", + "screamingSnakeCase": "DIRECTOR" + } + ], + "name": "Director" + }, + "shape": { + "extends": [], + "properties": [ + { + "name": { + "originalValue": "name", + "camelCase": "name", + "snakeCase": "name", + "pascalCase": "Name", + "screamingSnakeCase": "NAME", + "wireValue": "name" + }, + "valueType": { + "primitive": "STRING", + "_type": "primitive" + } + } + ], + "_type": "object" + } + }, { "name": { "fernFilepath": [ @@ -33,6 +67,31 @@ exports[`ir simple 1`] = ` "_type": "alias" } }, + { + "name": { + "fernFilepath": [ + { + "originalValue": "imdb", + "camelCase": "imdb", + "snakeCase": "imdb", + "pascalCase": "Imdb", + "screamingSnakeCase": "IMDB" + } + ], + "name": "ActorId" + }, + "shape": { + "aliasOf": { + "primitive": "STRING", + "_type": "primitive" + }, + "resolvedType": { + "primitive": "STRING", + "_type": "primitive" + }, + "_type": "alias" + } + }, { "name": { "fernFilepath": [ @@ -151,6 +210,125 @@ exports[`ir simple 1`] = ` ], "_type": "object" } + }, + { + "name": { + "fernFilepath": [ + { + "originalValue": "imdb", + "camelCase": "imdb", + "snakeCase": "imdb", + "pascalCase": "Imdb", + "screamingSnakeCase": "IMDB" + } + ], + "name": "Person" + }, + "shape": { + "discriminant": "type", + "types": [ + { + "discriminantValue": { + "originalValue": "actor", + "camelCase": "actor", + "snakeCase": "actor", + "pascalCase": "Actor", + "screamingSnakeCase": "ACTOR", + "wireValue": "actor" + }, + "valueType": { + "name": "ActorId", + "fernFilepath": [ + { + "originalValue": "imdb", + "camelCase": "imdb", + "snakeCase": "imdb", + "pascalCase": "Imdb", + "screamingSnakeCase": "IMDB" + } + ], + "_type": "named" + }, + "shape": { + "name": { + "originalValue": "value", + "camelCase": "value", + "snakeCase": "value", + "pascalCase": "Value", + "screamingSnakeCase": "VALUE", + "wireValue": "value" + }, + "type": { + "name": "ActorId", + "fernFilepath": [ + { + "originalValue": "imdb", + "camelCase": "imdb", + "snakeCase": "imdb", + "pascalCase": "Imdb", + "screamingSnakeCase": "IMDB" + } + ], + "_type": "named" + }, + "_type": "singleProperty" + } + }, + { + "discriminantValue": { + "originalValue": "director", + "camelCase": "director", + "snakeCase": "director", + "pascalCase": "Director", + "screamingSnakeCase": "DIRECTOR", + "wireValue": "director" + }, + "valueType": { + "name": "Director", + "fernFilepath": [ + { + "originalValue": "director", + "camelCase": "director", + "snakeCase": "director", + "pascalCase": "Director", + "screamingSnakeCase": "DIRECTOR" + } + ], + "_type": "named" + }, + "shape": { + "name": "Director", + "fernFilepath": [ + { + "originalValue": "director", + "camelCase": "director", + "snakeCase": "director", + "pascalCase": "Director", + "screamingSnakeCase": "DIRECTOR" + } + ], + "_type": "samePropertiesAsObject" + } + }, + { + "discriminantValue": { + "originalValue": "producer", + "camelCase": "producer", + "snakeCase": "producer", + "pascalCase": "Producer", + "screamingSnakeCase": "PRODUCER", + "wireValue": "producer" + }, + "valueType": { + "_type": "void" + }, + "shape": { + "_type": "noProperties" + } + } + ], + "_type": "union" + } } ], "errors": [ diff --git a/packages/cli/ete-tests/src/tests/ir/fixtures/simple/fern/api/definition/director.yml b/packages/cli/ete-tests/src/tests/ir/fixtures/simple/fern/api/definition/director.yml new file mode 100644 index 00000000000..45cfd8010f1 --- /dev/null +++ b/packages/cli/ete-tests/src/tests/ir/fixtures/simple/fern/api/definition/director.yml @@ -0,0 +1,4 @@ +types: + Director: + properties: + name: string diff --git a/packages/cli/ete-tests/src/tests/ir/fixtures/simple/fern/api/definition/imdb.yml b/packages/cli/ete-tests/src/tests/ir/fixtures/simple/fern/api/definition/imdb.yml index fb73e59edf3..7bf9e5fce85 100644 --- a/packages/cli/ete-tests/src/tests/ir/fixtures/simple/fern/api/definition/imdb.yml +++ b/packages/cli/ete-tests/src/tests/ir/fixtures/simple/fern/api/definition/imdb.yml @@ -1,5 +1,8 @@ +imports: + director: director.yml ids: - MovieId + - ActorId types: Movie: properties: @@ -10,6 +13,11 @@ types: properties: title: string rating: double + Person: + union: + actor: ActorId + director: director.Director + producer: {} errors: NotFoundError: http: diff --git a/packages/cli/generation/ir-generator/src/type-resolver/TypeResolver.ts b/packages/cli/generation/ir-generator/src/type-resolver/TypeResolver.ts index 4d1ce6fdd64..fe2c2d65f10 100644 --- a/packages/cli/generation/ir-generator/src/type-resolver/TypeResolver.ts +++ b/packages/cli/generation/ir-generator/src/type-resolver/TypeResolver.ts @@ -1,8 +1,6 @@ -import { RelativeFilePath } from "@fern-api/core-utils"; import { Workspace } from "@fern-api/workspace-loader"; -import { visitRawTypeDeclaration } from "@fern-api/yaml-schema"; +import { RawSchemas, RAW_DEFAULT_ID_TYPE, ServiceFileSchema, visitRawTypeDeclaration } from "@fern-api/yaml-schema"; import { ResolvedTypeReference, ShapeType, TypeReference } from "@fern-fern/ir-model/types"; -import path from "path"; import { constructFernFileContext, FernFileContext } from "../FernFileContext"; import { parseInlineType } from "../utils/parseInlineType"; import { parseReferenceToTypeName } from "../utils/parseReferenceToTypeName"; @@ -23,23 +21,19 @@ export class TypeResolverImpl implements TypeResolver { void: ResolvedTypeReference.void, named: (typeName) => { const reference = parseReferenceToTypeName({ - reference: typeName.name, - referencedIn: RelativeFilePath.of( - typeName.fernFilepath.map((part) => part.originalValue).join(path.sep) - ), + reference: type, + referencedIn: file.relativeFilepath, imports: file.imports, }); if (reference == null) { - throw new Error("Cannot find type: " + typeName.name); + throw new Error("Cannot find type: " + type); } const serviceFile = this.workspace.serviceFiles[reference.relativeFilePath]; if (serviceFile == null) { throw new Error("Cannot find file: " + reference.relativeFilePath); } - const declaration = serviceFile.types?.[reference.typeName]; - if (declaration == null) { - throw new Error("Cannot find type declaration: " + reference.typeName); - } + + const declaration = getDeclaration(serviceFile, reference.typeName); return visitRawTypeDeclaration(declaration, { alias: (aliasDeclaration) => { return this.resolveType({ @@ -73,3 +67,22 @@ export class TypeResolverImpl implements TypeResolver { }); } } + +function getDeclaration(serviceFile: ServiceFileSchema, typeName: string): RawSchemas.TypeDeclarationSchema { + const declaration = serviceFile.types?.[typeName]; + if (declaration != null) { + return declaration; + } + + const idDeclaration = serviceFile.ids?.find((id) => + typeof id === "string" ? id === typeName : id.name === typeName + ); + if (idDeclaration != null) { + if (typeof idDeclaration !== "string" && idDeclaration.type != null) { + return idDeclaration.type; + } + return RAW_DEFAULT_ID_TYPE; + } + + throw new Error("Cannot find type declaration: " + typeName); +}