Skip to content

Commit

Permalink
fix: OpenAPI parser v2 enum default for type reference (#2110)
Browse files Browse the repository at this point in the history
  • Loading branch information
RohinBhargava authored Feb 4, 2025
1 parent dc61444 commit 182016c
Show file tree
Hide file tree
Showing 16 changed files with 1,110 additions and 399 deletions.
2 changes: 1 addition & 1 deletion packages/parsers/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@fern-api/docs-parsers",
"version": "0.0.48",
"version": "0.0.49",
"repository": {
"type": "git",
"url": "https://github.com/fern-api/fern-platform.git",
Expand Down
1 change: 1 addition & 0 deletions packages/parsers/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export * from "./client/generated";
export * from "./ErrorCollector";
export * from "./openapi";
export * from "./openrpc";
Original file line number Diff line number Diff line change
Expand Up @@ -83,13 +83,16 @@ export class RequestMediaTypeObjectConverterNode extends BaseOpenApiV3_1Converte
this.context.document,
undefined
);
this.schema = new ReferenceConverterNode({
input: this.input.schema,
context: this.context,
accessPath: this.accessPath,
pathId: "schema",
seenSchemas: new Set(),
});
this.schema = new ReferenceConverterNode(
{
input: this.input.schema,
context: this.context,
accessPath: this.accessPath,
pathId: "schema",
seenSchemas: new Set(),
},
false
);
} else if (isObjectSchema(this.input.schema)) {
this.resolvedSchema = this.input.schema;
const mediaType = MediaType.parse(contentType);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,20 @@ import {
} from "../../BaseOpenApiV3_1Converter.node";
import { getSchemaIdFromReference } from "../../utils/3.1/getSchemaIdFromReference";
import { resolveSchemaReference } from "../../utils/3.1/resolveSchemaReference";
import { isNonArraySchema } from "../guards/isNonArraySchema";
import { SchemaConverterNode } from "./SchemaConverter.node";
import { EnumConverterNode } from "./primitives/EnumConverter.node";

export class ReferenceConverterNode extends BaseOpenApiV3_1ConverterNodeWithTracking<
OpenAPIV3_1.ReferenceObject,
FernRegistry.api.latest.TypeShape.Alias
> {
schemaId: string | undefined;
maybeEnumConverterNode: EnumConverterNode | undefined;

constructor(
args: BaseOpenApiV3_1ConverterNodeWithTrackingConstructorArgs<OpenAPIV3_1.ReferenceObject>
args: BaseOpenApiV3_1ConverterNodeWithTrackingConstructorArgs<OpenAPIV3_1.ReferenceObject>,
protected nullable: boolean | undefined
) {
super(args);
this.safeParse();
Expand All @@ -24,6 +28,19 @@ export class ReferenceConverterNode extends BaseOpenApiV3_1ConverterNodeWithTrac
parse(): void {
this.schemaId = getSchemaIdFromReference(this.input);

const maybeEnum = resolveSchemaReference(this.input, this.context.document);
if (maybeEnum?.enum != null && isNonArraySchema(maybeEnum)) {
this.maybeEnumConverterNode = new EnumConverterNode(
{
input: maybeEnum,
context: this.context,
accessPath: this.accessPath,
pathId: this.schemaId ?? "",
},
this.nullable
);
}

if (this.schemaId == null) {
this.context.errors.error({
message: `Unprocessable reference: ${this.input.$ref}`,
Expand All @@ -42,8 +59,13 @@ export class ReferenceConverterNode extends BaseOpenApiV3_1ConverterNodeWithTrac
value: {
type: "id",
id: FernRegistry.TypeId(this.schemaId),
default: resolveSchemaReference(this.input, this.context.document)
?.default,
default:
this.maybeEnumConverterNode?.default != null
? {
type: "enum",
value: this.maybeEnumConverterNode.default,
}
: undefined,
},
};
}
Expand Down
121 changes: 72 additions & 49 deletions packages/parsers/src/openapi/3.1/schemas/SchemaConverter.node.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,6 @@ export class SchemaConverterNode extends BaseOpenApiV3_1ConverterNodeWithTrackin
| undefined
>
| undefined;
nullable: boolean | undefined;
description: string | undefined;
name: string | undefined;
examples: unknown | undefined;
Expand All @@ -65,7 +64,8 @@ export class SchemaConverterNode extends BaseOpenApiV3_1ConverterNodeWithTrackin
constructor(
args: BaseOpenApiV3_1ConverterNodeWithTrackingConstructorArgs<
OpenAPIV3_1.SchemaObject | OpenAPIV3_1.ReferenceObject
>
>,
protected nullable?: boolean | undefined
) {
super(args);
this.safeParse();
Expand Down Expand Up @@ -103,13 +103,16 @@ export class SchemaConverterNode extends BaseOpenApiV3_1ConverterNodeWithTrackin
}
this.seenSchemas.add(refPath);

this.typeShapeNode = new ReferenceConverterNode({
input: this.input,
context: this.context,
accessPath: this.accessPath,
pathId: refPath,
seenSchemas: this.seenSchemas,
});
this.typeShapeNode = new ReferenceConverterNode(
{
input: this.input,
context: this.context,
accessPath: this.accessPath,
pathId: refPath,
seenSchemas: this.seenSchemas,
},
this.nullable
);
} else {
// If the object is not a reference object, then it is a schema object, gather all appropriate variables
this.name = this.input.title;
Expand Down Expand Up @@ -151,12 +154,15 @@ export class SchemaConverterNode extends BaseOpenApiV3_1ConverterNodeWithTrackin
seenSchemas: this.seenSchemas,
});
} else if (isNonArraySchema(this.input) && this.input.enum != null) {
this.typeShapeNode = new EnumConverterNode({
input: this.input,
context: this.context,
accessPath: this.accessPath,
pathId: this.pathId,
});
this.typeShapeNode = new EnumConverterNode(
{
input: this.input,
context: this.context,
accessPath: this.accessPath,
pathId: this.pathId,
},
this.nullable
);
}
// We assume that if one of is defined, it is an object node
else if (typeof this.input.type === "string") {
Expand Down Expand Up @@ -185,42 +191,54 @@ export class SchemaConverterNode extends BaseOpenApiV3_1ConverterNodeWithTrackin
break;
case "boolean":
if (isBooleanSchema(this.input)) {
this.typeShapeNode = new BooleanConverterNode({
input: this.input,
context: this.context,
accessPath: this.accessPath,
pathId: this.pathId,
});
this.typeShapeNode = new BooleanConverterNode(
{
input: this.input,
context: this.context,
accessPath: this.accessPath,
pathId: this.pathId,
},
this.nullable
);
}
break;
case "integer":
if (isIntegerSchema(this.input)) {
this.typeShapeNode = new IntegerConverterNode({
input: this.input,
context: this.context,
accessPath: this.accessPath,
pathId: this.pathId,
});
this.typeShapeNode = new IntegerConverterNode(
{
input: this.input,
context: this.context,
accessPath: this.accessPath,
pathId: this.pathId,
},
this.nullable
);
}
break;
case "number":
if (isNumberSchema(this.input)) {
this.typeShapeNode = new NumberConverterNode({
input: this.input,
context: this.context,
accessPath: this.accessPath,
pathId: this.pathId,
});
this.typeShapeNode = new NumberConverterNode(
{
input: this.input,
context: this.context,
accessPath: this.accessPath,
pathId: this.pathId,
},
this.nullable
);
}
break;
case "string":
if (isStringSchema(this.input)) {
this.typeShapeNode = new StringConverterNode({
input: this.input,
context: this.context,
accessPath: this.accessPath,
pathId: this.pathId,
});
this.typeShapeNode = new StringConverterNode(
{
input: this.input,
context: this.context,
accessPath: this.accessPath,
pathId: this.pathId,
},
this.nullable
);
}
break;
case "null":
Expand All @@ -246,16 +264,19 @@ export class SchemaConverterNode extends BaseOpenApiV3_1ConverterNodeWithTrackin
const newType = this.input.type.filter((t) => t !== "null")[0];

if (newType !== "array") {
this.typeShapeNode = new SchemaConverterNode({
input: {
...this.input,
type: newType,
this.typeShapeNode = new SchemaConverterNode(
{
input: {
...this.input,
type: newType,
},
context: this.context,
accessPath: this.accessPath,
pathId: this.pathId,
seenSchemas: this.seenSchemas,
},
context: this.context,
accessPath: this.accessPath,
pathId: this.pathId,
seenSchemas: this.seenSchemas,
});
this.nullable
);
}
} else if (this.input.properties != null) {
this.typeShapeNode = new ObjectConverterNode({
Expand Down Expand Up @@ -300,6 +321,8 @@ export class SchemaConverterNode extends BaseOpenApiV3_1ConverterNodeWithTrackin
}

example(includeOptionals: boolean): unknown | undefined {
return this.typeShapeNode?.example(includeOptionals);
return this.availability?.availability !== "deprecated"
? this.typeShapeNode?.example(includeOptionals)
: undefined;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@ export class BooleanConverterNode extends BaseOpenApiV3_1ConverterNodeWithExampl
default: boolean | undefined;

constructor(
args: BaseOpenApiV3_1ConverterNodeConstructorArgs<BooleanConverterNode.Input>
args: BaseOpenApiV3_1ConverterNodeConstructorArgs<BooleanConverterNode.Input>,
protected nullable: boolean | undefined
) {
super(args);
this.safeParse();
Expand Down Expand Up @@ -54,9 +55,12 @@ export class BooleanConverterNode extends BaseOpenApiV3_1ConverterNodeWithExampl
};
}

example(): boolean | undefined {
example(): string | boolean | undefined {
return (
this.input.example ?? this.input.examples?.[0] ?? this.default ?? false
this.input.example ??
this.input.examples?.[0] ??
this.default ??
(this.nullable ? "null" : false)
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ export class EnumConverterNode extends BaseOpenApiV3_1ConverterNodeWithExample<
values: string[] = [];

constructor(
args: BaseOpenApiV3_1ConverterNodeConstructorArgs<OpenAPIV3_1.NonArraySchemaObject>
args: BaseOpenApiV3_1ConverterNodeConstructorArgs<OpenAPIV3_1.NonArraySchemaObject>,
protected nullable: boolean | undefined
) {
super(args);
this.safeParse();
Expand Down Expand Up @@ -82,7 +83,8 @@ export class EnumConverterNode extends BaseOpenApiV3_1ConverterNodeWithExample<
this.input.example ??
this.input.examples?.[0] ??
this.default ??
this.values[0]
this.values[0] ??
(this.nullable ? "null" : undefined)
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,8 @@ export class IntegerConverterNode extends BaseOpenApiV3_1ConverterNodeWithExampl
default: number | undefined;

constructor(
args: BaseOpenApiV3_1ConverterNodeConstructorArgs<IntegerConverterNode.Input>
args: BaseOpenApiV3_1ConverterNodeConstructorArgs<IntegerConverterNode.Input>,
protected nullable: boolean | undefined
) {
super(args);
this.safeParse();
Expand Down Expand Up @@ -105,7 +106,12 @@ export class IntegerConverterNode extends BaseOpenApiV3_1ConverterNodeWithExampl
};
}

example(): number | undefined {
return this.input.example ?? this.input.examples?.[0] ?? this.default ?? 0;
example(): string | number | undefined {
return (
this.input.example ??
this.input.examples?.[0] ??
this.default ??
(this.nullable ? "null" : 0)
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,8 @@ export class NumberConverterNode extends BaseOpenApiV3_1ConverterNodeWithExample
default: number | undefined;

constructor(
args: BaseOpenApiV3_1ConverterNodeConstructorArgs<NumberConverterNode.Input>
args: BaseOpenApiV3_1ConverterNodeConstructorArgs<NumberConverterNode.Input>,
protected nullable: boolean | undefined
) {
super(args);
this.safeParse();
Expand Down Expand Up @@ -103,7 +104,12 @@ export class NumberConverterNode extends BaseOpenApiV3_1ConverterNodeWithExample
};
}

example(): number | undefined {
return this.input.example ?? this.input.examples?.[0] ?? this.default ?? 0;
example(): string | number | undefined {
return (
this.input.example ??
this.input.examples?.[0] ??
this.default ??
(this.nullable ? "null" : 0)
);
}
}
Loading

0 comments on commit 182016c

Please sign in to comment.