Skip to content

Commit

Permalink
Add ResponseErrorsV2 to IR (#765)
Browse files Browse the repository at this point in the history
  • Loading branch information
zachkirsch committed Sep 30, 2022
1 parent b7d2b30 commit e121d63
Show file tree
Hide file tree
Showing 26 changed files with 210 additions and 41 deletions.
16 changes: 8 additions & 8 deletions .pnp.cjs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Binary file not shown.
20 changes: 20 additions & 0 deletions fern/ir-types/definition/services/commons.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,28 @@ types:
properties:
fernFilepath: commons.FernFilepath
name: string

ResponseErrors: list<ResponseError>
ResponseError:
extends: commons.WithDocs
properties:
error: errors.DeclaredErrorName

ResponseErrorsV2:
properties:
discriminant: commons.WireStringWithAllCasings
types: list<ResponseErrorV2>
ResponseErrorV2:
extends: commons.WithDocs
properties:
discriminantValue: commons.WireStringWithAllCasings
shape: ResponseErrorShape
ResponseErrorShape:
union:
singleProperty: SingleResponseErrorProperty
noProperties: {}

SingleResponseErrorProperty:
properties:
name: commons.WireStringWithAllCasings
error: errors.DeclaredErrorName
5 changes: 4 additions & 1 deletion fern/ir-types/definition/services/http.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,10 @@ types:
queryParameters: list<QueryParameter>
request: HttpRequest
response: HttpResponse
errors: serviceCommons.ResponseErrors
errors:
docs: this is deprecated. Use errorsV2 instead.
type: serviceCommons.ResponseErrors
errorsV2: serviceCommons.ResponseErrorsV2
auth: boolean
HttpPath:
properties:
Expand Down
2 changes: 1 addition & 1 deletion packages/cli/cli/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@
"@fern-api/task-context": "workspace:*",
"@fern-api/validator": "workspace:*",
"@fern-api/workspace-loader": "workspace:*",
"@fern-fern/ir-model": "0.0.212",
"@fern-fern/ir-model": "0.0.220",
"ansi-escapes": "^5.0.0",
"boxen": "^7.0.0",
"chalk": "^5.0.1",
Expand Down
40 changes: 38 additions & 2 deletions packages/cli/ete-tests/src/tests/ir/__snapshots__/ir.test.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -684,7 +684,18 @@ exports[`ir simple 1`] = `
"_type": "named"
}
},
"errors": []
"errors": [],
"errorsV2": {
"discriminant": {
"originalValue": "errorName",
"camelCase": "errorName",
"snakeCase": "error_name",
"pascalCase": "ErrorName",
"screamingSnakeCase": "ERROR_NAME",
"wireValue": "errorName"
},
"types": []
}
},
{
"id": "getMovie",
Expand Down Expand Up @@ -780,7 +791,32 @@ exports[`ir simple 1`] = `
]
}
}
]
],
"errorsV2": {
"discriminant": {
"originalValue": "errorName",
"camelCase": "errorName",
"snakeCase": "error_name",
"pascalCase": "ErrorName",
"screamingSnakeCase": "ERROR_NAME",
"wireValue": "errorName"
},
"types": [
{
"discriminantValue": {
"originalValue": "NotFoundError",
"camelCase": "notFoundError",
"snakeCase": "not_found_error",
"pascalCase": "NotFoundError",
"screamingSnakeCase": "NOT_FOUND_ERROR",
"wireValue": "NotFoundError"
},
"shape": {
"type": "noProperties"
}
}
]
}
}
]
}
Expand Down
2 changes: 1 addition & 1 deletion packages/cli/generation/ir-generator/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
"@fern-api/core-utils": "workspace:*",
"@fern-api/workspace-loader": "workspace:*",
"@fern-api/yaml-schema": "workspace:*",
"@fern-fern/ir-model": "0.0.212",
"@fern-fern/ir-model": "0.0.220",
"lodash-es": "^4.17.21"
},
"devDependencies": {
Expand Down
7 changes: 7 additions & 0 deletions packages/cli/generation/ir-generator/src/FernConstants.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { FernConstants } from "@fern-fern/ir-model/ir";

export const FERN_CONSTANTS: FernConstants = {
errorDiscriminant: "_error",
errorInstanceIdKey: "_errorInstanceId",
unknownErrorDiscriminantValue: "_unknown",
};
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { TypeResolver } from "../../type-resolver/TypeResolver";
import { TypeResolver } from "../../resolvers/TypeResolver";

export const MockTypeResolver: TypeResolver = {
getDeclarationOfNamedType: () => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { RawPrimitiveType, RawSchemas } from "@fern-api/yaml-schema";
import { ErrorDeclaration } from "@fern-fern/ir-model/errors";
import { FernFileContext } from "../FernFileContext";
import { TypeResolver } from "../type-resolver/TypeResolver";
import { TypeResolver } from "../resolvers/TypeResolver";
import { generateWireStringWithAllCasings } from "../utils/generateCasings";
import { convertType } from "./type-declarations/convertTypeDeclaration";

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { RawSchemas, RAW_DEFAULT_ID_TYPE } from "@fern-api/yaml-schema";
import { TypeDeclaration } from "@fern-fern/ir-model/types";
import { FernFileContext } from "../FernFileContext";
import { TypeResolver } from "../type-resolver/TypeResolver";
import { TypeResolver } from "../resolvers/TypeResolver";
import { getDocs } from "../utils/getDocs";
import { convertTypeDeclaration } from "./type-declarations/convertTypeDeclaration";

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,25 @@ import { assertNever } from "@fern-api/core-utils";
import { RawSchemas } from "@fern-api/yaml-schema";
import { HttpEndpoint, HttpHeader, HttpMethod, HttpService, PathParameter } from "@fern-fern/ir-model/services/http";
import { FernFileContext } from "../../FernFileContext";
import { ErrorResolver } from "../../resolvers/ErrorResolver";
import { generateStringWithAllCasings, generateWireStringWithAllCasings } from "../../utils/generateCasings";
import { getDocs } from "../../utils/getDocs";
import { constructHttpPath } from "./constructHttpPath";
import { convertHttpRequest } from "./convertHttpRequest";
import { convertHttpResponse } from "./convertHttpResponse";
import { convertResponseErrors } from "./convertResponseErrors";
import { convertResponseErrorsV2 } from "./convertResponseErrorsV2";

export function convertHttpService({
serviceDefinition,
serviceId,
file,
errorResolver,
}: {
serviceDefinition: RawSchemas.HttpServiceSchema;
serviceId: string;
file: FernFileContext;
errorResolver: ErrorResolver;
}): HttpService {
return {
docs: serviceDefinition.docs,
Expand Down Expand Up @@ -86,6 +90,7 @@ export function convertHttpService({
request: convertHttpRequest({ request: endpoint.request, file }),
response: convertHttpResponse({ response: endpoint.response, file }),
errors: convertResponseErrors({ errors: endpoint.errors, file }),
errorsV2: convertResponseErrorsV2({ errors: endpoint.errors, file, errorResolver }),
})
),
};
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import { RawPrimitiveType, RawSchemas } from "@fern-api/yaml-schema";
import { ResponseErrorShape, ResponseErrorsV2, ResponseErrorV2 } from "@fern-fern/ir-model/services/commons";
import { FernFileContext } from "../../FernFileContext";
import { ErrorResolver } from "../../resolvers/ErrorResolver";
import { generateWireStringWithAllCasings } from "../../utils/generateCasings";
import { parseTypeName } from "../../utils/parseTypeName";

const ERROR_DISCRIMINANT = "errorName";
const ERROR_CONTENT_PROPERTY_NAME = "content";

export function convertResponseErrorsV2({
errors,
file,
errorResolver,
}: {
errors: RawSchemas.ResponseErrorsSchema | undefined;
file: FernFileContext;
errorResolver: ErrorResolver;
}): ResponseErrorsV2 {
const discriminant = generateWireStringWithAllCasings({
wireValue: ERROR_DISCRIMINANT,
name: ERROR_DISCRIMINANT,
});

if (errors == null || errors.length === 0) {
return {
discriminant,
types: [],
};
}

return {
discriminant,
types: Object.values(errors).map((errorReference): ResponseErrorV2 => {
const referenceToError = typeof errorReference === "string" ? errorReference : errorReference.error;

const declaration = errorResolver.getDeclaration(referenceToError, file);
if (declaration == null) {
throw new Error("Cannot locate declaration for error: " + referenceToError);
}
const rawErrorType = typeof declaration === "string" ? declaration : declaration.type;

const parsedErrorName = parseTypeName({ typeName: referenceToError, file });
const discriminantValue = parsedErrorName.name;

return {
docs: typeof errorReference !== "string" ? errorReference.docs : undefined,
discriminantValue: generateWireStringWithAllCasings({
wireValue: discriminantValue,
name: discriminantValue,
}),
shape:
rawErrorType != null && rawErrorType !== RawPrimitiveType.void
? ResponseErrorShape.singleProperty({
name: generateWireStringWithAllCasings({
wireValue: ERROR_CONTENT_PROPERTY_NAME,
name: ERROR_CONTENT_PROPERTY_NAME,
}),
error: parsedErrorName,
})
: ResponseErrorShape.noProperties(),
};
}),
};
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { assertNever } from "@fern-api/core-utils";
import { isRawEnumDefinition, isRawObjectDefinition, isRawUnionDefinition, RawSchemas } from "@fern-api/yaml-schema";
import { ResolvedTypeReference, ShapeType, Type } from "@fern-fern/ir-model/types";
import { FernFileContext } from "../../FernFileContext";
import { TypeResolver } from "../../type-resolver/TypeResolver";
import { TypeResolver } from "../../resolvers/TypeResolver";

export function convertAliasTypeDeclaration({
alias,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { RawSchemas, visitRawTypeDeclaration } from "@fern-api/yaml-schema";
import { Type, TypeDeclaration } from "@fern-fern/ir-model/types";
import { FernFileContext } from "../../FernFileContext";
import { TypeResolver } from "../../type-resolver/TypeResolver";
import { TypeResolver } from "../../resolvers/TypeResolver";
import { getDocs } from "../../utils/getDocs";
import { convertAliasTypeDeclaration } from "./convertAliasTypeDeclaration";
import { convertEnumTypeDeclaration } from "./convertEnumTypeDeclaration";
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { isRawObjectDefinition, RawSchemas } from "@fern-api/yaml-schema";
import { SingleUnionTypeProperties, Type, TypeReference } from "@fern-fern/ir-model/types";
import { FernFileContext } from "../../FernFileContext";
import { TypeResolver } from "../../type-resolver/TypeResolver";
import { TypeResolver } from "../../resolvers/TypeResolver";
import { generateWireStringWithAllCasings } from "../../utils/generateCasings";
import { getDocs } from "../../utils/getDocs";

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { RawSchemas, visitRawTypeDeclaration, visitRawTypeReference } from "@fern-api/yaml-schema";
import { DeclaredTypeName } from "@fern-fern/ir-model/types";
import { FernFileContext } from "../../FernFileContext";
import { TypeResolver } from "../../type-resolver/TypeResolver";
import { TypeResolver } from "../../resolvers/TypeResolver";
import { parseTypeName } from "../../utils/parseTypeName";

interface SeenTypeNames {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,10 @@ import { convertId } from "./converters/convertId";
import { convertHttpService } from "./converters/services/convertHttpService";
import { convertWebsocketChannel } from "./converters/services/convertWebsocketChannel";
import { convertTypeDeclaration } from "./converters/type-declarations/convertTypeDeclaration";
import { FERN_CONSTANTS } from "./FernConstants";
import { constructFernFileContext, FernFileContext } from "./FernFileContext";
import { TypeResolverImpl } from "./type-resolver/TypeResolver";
import { ErrorResolverImpl } from "./resolvers/ErrorResolver";
import { TypeResolverImpl } from "./resolvers/TypeResolver";

export async function generateIntermediateRepresentation(workspace: Workspace): Promise<IntermediateRepresentation> {
const rootApiFile = constructFernFileContext({
Expand All @@ -29,14 +31,11 @@ export async function generateIntermediateRepresentation(workspace: Workspace):
http: [],
websocket: [],
},
constants: {
errorDiscriminant: "_error",
errorInstanceIdKey: "_errorInstanceId",
unknownErrorDiscriminantValue: "_unknown",
},
constants: FERN_CONSTANTS,
};

const typeResolver = new TypeResolverImpl(workspace);
const errorResolver = new ErrorResolverImpl(workspace);

const visitServiceFile = async ({ file, schema }: { file: FernFileContext; schema: ServiceFileSchema }) => {
await visitObject(schema, {
Expand Down Expand Up @@ -94,7 +93,7 @@ export async function generateIntermediateRepresentation(workspace: Workspace):
if (services.http != null) {
for (const [serviceId, serviceDefinition] of Object.entries(services.http)) {
intermediateRepresentation.services.http.push(
convertHttpService({ serviceDefinition, serviceId, file })
convertHttpService({ serviceDefinition, serviceId, file, errorResolver })
);
}
}
Expand Down
4 changes: 2 additions & 2 deletions packages/cli/generation/ir-generator/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ export {
} from "./converters/type-declarations/convertUnionTypeDeclaration";
export { constructFernFileContext, type FernFileContext } from "./FernFileContext";
export { generateIntermediateRepresentation } from "./generateIntermediateRepresentation";
export { type ResolvedType } from "./type-resolver/ResolvedType";
export { TypeResolverImpl, type TypeResolver } from "./type-resolver/TypeResolver";
export { type ResolvedType } from "./resolvers/ResolvedType";
export { TypeResolverImpl, type TypeResolver } from "./resolvers/TypeResolver";
export { getResolvedPathOfImportedFile } from "./utils/getResolvedPathOfImportedFile";
export { parseReferenceToTypeName, type ReferenceToTypeName } from "./utils/parseReferenceToTypeName";
Loading

0 comments on commit e121d63

Please sign in to comment.