Skip to content

Commit

Permalink
Merge branch 'main' into chdeskur/ai-chat-copy
Browse files Browse the repository at this point in the history
  • Loading branch information
chdeskur authored Feb 6, 2025
2 parents 3a5df06 + 53db319 commit 7013092
Show file tree
Hide file tree
Showing 23 changed files with 6,660 additions and 3,417 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,10 @@ export class OpenApiDocumentConverterNode extends BaseOpenApiV3_1ConverterNode<
FernRegistry.api.latest.SubpackageMetadata
> = computeSubpackages({ endpoints, webhookEndpoints });

const types = this.components?.convert();
const types = {
...this.components?.convert(),
...this.context.generatedTypes,
};

return {
id: FernRegistry.ApiDefinitionId(apiDefinitionId),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {
BaseOpenApiV3_1ConverterNode,
BaseOpenApiV3_1ConverterNodeConstructorArgs,
} from "../../BaseOpenApiV3_1Converter.node";
import { HttpMethod } from "../../constants";
import { coalesceServers } from "../../utils/3.1/coalesceServers";
import { resolveParameterReference } from "../../utils/3.1/resolveParameterReference";
import { getEndpointId } from "../../utils/getEndpointId";
Expand Down Expand Up @@ -52,7 +53,7 @@ export class OperationObjectConverterNode extends BaseOpenApiV3_1ConverterNode<
protected servers: ServerObjectConverterNode[] | undefined,
protected globalAuth: SecurityRequirementObjectConverterNode | undefined,
protected path: string,
protected method: "GET" | "POST" | "PUT" | "PATCH" | "DELETE",
protected method: HttpMethod,
protected basePath: XFernBasePathConverterNode | undefined,
protected isWebhook?: boolean
) {
Expand Down Expand Up @@ -183,6 +184,7 @@ export class OperationObjectConverterNode extends BaseOpenApiV3_1ConverterNode<
pathId: "responses",
},
this.path,
this.method,
Object.values(this.requests?.requestBodiesByContentType ?? {}),
{
pathParameters: this.pathParameters,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { isNonNullish } from "@fern-api/ui-core-utils";
import { mapValues } from "es-toolkit";
import { camelCase, mapValues } from "es-toolkit";
import { OpenAPIV3_1 } from "openapi-types";
import { UnreachableCaseError } from "ts-essentials";
import { FernRegistry } from "../../../../client/generated";
Expand All @@ -10,13 +10,15 @@ import {
import {
APPLICATION_JSON_CONTENT_TYPE,
APPLICATION_OCTET_STREAM_CONTENT_TYPE,
HttpMethod,
} from "../../../constants";
import {
ConstArrayToType,
SUPPORTED_RESPONSE_CONTENT_TYPES,
SUPPORTED_STREAMING_FORMATS,
} from "../../../types/format.types";
import { resolveSchemaReference } from "../../../utils/3.1/resolveSchemaReference";
import { createTypeDefinition } from "../../../utils/createTypeDefinition";
import { getExampleName } from "../../../utils/getExampleName";
import { matchExampleName } from "../../../utils/matchExampleNames";
import { maybeSingleValueToArray } from "../../../utils/maybeSingleValueToArray";
Expand Down Expand Up @@ -52,6 +54,7 @@ export class ResponseMediaTypeObjectConverterNode extends BaseOpenApiV3_1Convert
contentType: string | undefined,
protected streamingFormat: ResponseStreamingFormat | undefined,
protected path: string,
protected method: HttpMethod,
protected statusCode: number,
protected requests: RequestMediaTypeObjectConverterNode[],
protected shapes: ExampleObjectConverterNode.Shapes
Expand Down Expand Up @@ -416,6 +419,56 @@ export class ResponseMediaTypeObjectConverterNode extends BaseOpenApiV3_1Convert
}
}

convertJsonLike():
| FernRegistry.api.latest.HttpResponseBodyShape
| FernRegistry.api.latest.HttpResponseBodyShape[]
| undefined {
const maybeShapes = maybeSingleValueToArray(this.schema?.convert());

return maybeShapes
?.map((shape) => {
const type = shape.type;
switch (type) {
case "alias":
return shape;
case "discriminatedUnion":
case "undiscriminatedUnion":
case "enum": {
const uniqueId = camelCase(
[this.method, this.path, this.statusCode, "response"].join("_")
);
createTypeDefinition({
uniqueId,
type: shape,
contextTypes: this.context.generatedTypes,
description: this.schema?.description,
availability: this.schema?.availability?.convert(),
});
return {
type: "alias" as const,
value: {
type: "id" as const,
id: FernRegistry.TypeId(uniqueId),
default:
shape.type === "enum" && shape.default != null
? {
type: "enum" as const,
value: shape.default,
}
: undefined,
},
};
}
case "object":
return shape;
default:
new UnreachableCaseError(type);
return undefined;
}
})
.filter(isNonNullish);
}

convert():
| FernRegistry.api.latest.HttpResponseBodyShape
| FernRegistry.api.latest.HttpResponseBodyShape[]
Expand All @@ -430,19 +483,20 @@ export class ResponseMediaTypeObjectConverterNode extends BaseOpenApiV3_1Convert
switch (this.contentType) {
case "application/json":
if (this.streamingFormat == null) {
const maybeShapes = maybeSingleValueToArray(this.schema?.convert());
return this.convertJsonLike();
// const maybeShapes = maybeSingleValueToArray(this.schema?.convert());

return maybeShapes
?.map((shape) => {
if (
shape == null ||
(shape.type !== "object" && shape.type !== "alias")
) {
return undefined;
}
return shape;
})
.filter(isNonNullish);
// return maybeShapes
// ?.map((shape) => {
// if (
// shape == null ||
// (shape.type !== "object" && shape.type !== "alias")
// ) {
// return undefined;
// }
// return shape;
// })
// .filter(isNonNullish);
} else {
return this.convertStreamingFormat();
}
Expand All @@ -457,26 +511,7 @@ export class ResponseMediaTypeObjectConverterNode extends BaseOpenApiV3_1Convert
return undefined;
}
} else if (this.unsupportedContentType != null) {
const maybeShapes = maybeSingleValueToArray(this.schema?.convert());

return maybeShapes
?.map((shape) => {
const type = shape.type;
switch (type) {
case "alias":
return shape;
case "discriminatedUnion":
case "undiscriminatedUnion":
case "enum":
return undefined;
case "object":
return shape;
default:
new UnreachableCaseError(type);
return undefined;
}
})
.filter(isNonNullish);
return this.convertJsonLike();
} else {
return undefined;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {
BaseOpenApiV3_1ConverterNode,
BaseOpenApiV3_1ConverterNodeConstructorArgs,
} from "../../../BaseOpenApiV3_1Converter.node";
import { HttpMethod } from "../../../constants";
import { resolveResponseReference } from "../../../utils/3.1/resolveResponseReference";
import { isReferenceObject } from "../../guards/isReferenceObject";
import { ExampleObjectConverterNode } from "../ExampleObjectConverter.node";
Expand All @@ -28,6 +29,7 @@ export class ResponseObjectConverterNode extends BaseOpenApiV3_1ConverterNode<
OpenAPIV3_1.ResponseObject | OpenAPIV3_1.ReferenceObject
>,
protected path: string,
protected method: HttpMethod,
protected statusCode: number,
protected requests: RequestMediaTypeObjectConverterNode[],
protected shapes: ExampleObjectConverterNode.Shapes
Expand Down Expand Up @@ -73,6 +75,7 @@ export class ResponseObjectConverterNode extends BaseOpenApiV3_1ConverterNode<
"empty",
streamingFormat,
this.path,
this.method,
this.statusCode,
this.requests,
this.shapes
Expand All @@ -93,6 +96,7 @@ export class ResponseObjectConverterNode extends BaseOpenApiV3_1ConverterNode<
contentType,
streamingFormat,
this.path,
this.method,
this.statusCode,
this.requests,
// TODO: add response headers, but this needs to be added to FDR shape
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {
BaseOpenApiV3_1ConverterNode,
BaseOpenApiV3_1ConverterNodeConstructorArgs,
} from "../../../BaseOpenApiV3_1Converter.node";
import { HttpMethod } from "../../../constants";
import { maybeSingleValueToArray } from "../../../utils/maybeSingleValueToArray";
import { singleUndefinedArrayIfNullOrEmpty } from "../../../utils/singleUndefinedArrayIfNullOrEmpty";
import { STATUS_CODE_MESSAGES } from "../../../utils/statusCodes";
Expand Down Expand Up @@ -36,6 +37,7 @@ export class ResponsesObjectConverterNode extends BaseOpenApiV3_1ConverterNode<
constructor(
args: BaseOpenApiV3_1ConverterNodeConstructorArgs<OpenAPIV3_1.ResponsesObject>,
protected path: string,
protected method: HttpMethod,
protected requests: RequestMediaTypeObjectConverterNode[],
protected shapes: ExampleObjectConverterNode.Shapes
) {
Expand All @@ -59,6 +61,7 @@ export class ResponsesObjectConverterNode extends BaseOpenApiV3_1ConverterNode<
pathId: "errors",
},
this.path,
this.method,
parseInt(statusCode),
[],
this.shapes
Expand All @@ -77,6 +80,7 @@ export class ResponsesObjectConverterNode extends BaseOpenApiV3_1ConverterNode<
pathId: "responses",
},
this.path,
this.method,
parseInt(statusCode),
this.requests,
this.shapes
Expand Down
37 changes: 18 additions & 19 deletions packages/parsers/src/openapi/3.1/schemas/OneOfConverter.node.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ export class OneOfConverterNode extends BaseOpenApiV3_1ConverterNodeWithTracking
| [FernRegistry.api.latest.TypeShape.UndiscriminatedUnion]
| FernRegistry.api.latest.TypeShape[]
> {
isUnionOfObjects: boolean | undefined;
isUnionOfContainers: boolean | undefined;
isNullable: boolean | undefined;
discriminated: boolean | undefined;
discriminant: string | undefined;
Expand All @@ -34,11 +34,19 @@ export class OneOfConverterNode extends BaseOpenApiV3_1ConverterNodeWithTracking

parse(): void {
if (this.input.oneOf != null || this.input.anyOf != null) {
this.isUnionOfObjects = (this.input.oneOf ?? this.input.anyOf)?.every(
(schema) =>
resolveSchemaReference(schema, this.context.document)?.type ===
"object"
);
// COMMENTED OUT FOR NOW, CONSIDER BRINGING BACK IF MULTIPLE RESPONSES ARE SUPPORTED
// this.isUnionOfContainers = (this.input.oneOf ?? this.input.anyOf)?.every(
// (schema) => {
// const resolvedSchema = resolveSchemaReference(
// schema,
// this.context.document
// );
// return (
// resolvedSchema?.type === "object" || resolvedSchema?.enum != null
// );
// }
// );

this.isNullable = (this.input.oneOf ?? this.input.anyOf)?.some(
(schema) =>
resolveSchemaReference(schema, this.context.document)?.type === "null"
Expand Down Expand Up @@ -99,7 +107,9 @@ export class OneOfConverterNode extends BaseOpenApiV3_1ConverterNodeWithTracking
| [FernRegistry.api.latest.TypeShape.UndiscriminatedUnion]
| FernRegistry.api.latest.TypeShape[]
| undefined {
if (!this.isUnionOfObjects && !this.discriminated) {
// COMMENTED OUT FOR NOW, CONSIDER BRINGING BACK IF MULTIPLE RESPONSES ARE SUPPORTED
// if (!this.isUnionOfContainers && !this.discriminated) {
if (!this.discriminated && this.undiscriminatedMapping?.length === 1) {
const convertedNodes = this.undiscriminatedMapping
?.flatMap((node) => node.convert())
.filter(isNonNullish);
Expand All @@ -108,17 +118,6 @@ export class OneOfConverterNode extends BaseOpenApiV3_1ConverterNodeWithTracking
: convertedNodes;
}

if (
// If no decision has been made, bail
this.discriminated == null ||
// If the union is discriminated, we need to have a discriminant and mapping
(this.discriminated &&
(this.discriminant == null || this.discriminatedMapping == null)) ||
// If the union is undiscriminated, we should not have a discriminant or mapping
(!this.discriminated && this.undiscriminatedMapping == null)
) {
return undefined;
}
const union =
this.discriminated &&
this.discriminant != null &&
Expand Down Expand Up @@ -158,7 +157,7 @@ export class OneOfConverterNode extends BaseOpenApiV3_1ConverterNodeWithTracking

return convertedShapes
?.map((shape) => {
if (shape == null || shape.type !== "object") {
if (shape == null) {
return undefined;
}
return {
Expand Down
5 changes: 5 additions & 0 deletions packages/parsers/src/openapi/BaseOpenApiV3_1Converter.node.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,15 @@ import {
BaseApiConverterNode,
BaseApiConverterNodeContext,
} from "../BaseApiConverter.node";
import { FernRegistry } from "../client/generated";
import { toOpenApiPath } from "./utils/toOpenApiPath";

export abstract class BaseOpenApiV3_1ConverterNodeContext extends BaseApiConverterNodeContext {
public abstract document: OpenAPIV3_1.Document;
public abstract generatedTypes: Record<
FernRegistry.TypeId,
FernRegistry.api.latest.TypeDefinition
>;
}

export type BaseOpenApiV3_1ConverterNodeConstructorArgs<Input> = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ describe("OpenAPI snapshot tests", () => {
log: () => undefined,
},
errors: new ErrorCollector(),
generatedTypes: {},
};

// Convert components if they exist
Expand Down
Loading

0 comments on commit 7013092

Please sign in to comment.