Skip to content

Commit

Permalink
fix(type-safe-api): ensure inline enums are typed correctly in genera…
Browse files Browse the repository at this point in the history
…ted code (#864)

Hoist inline enums to ensure a model is created for them and they can therefore be typed correctly.

Fixes #863
  • Loading branch information
cogwirrel authored Oct 19, 2024
1 parent 47fe68f commit bbccca3
Show file tree
Hide file tree
Showing 5 changed files with 1,885 additions and 65 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -572,7 +572,7 @@ const isCompositeSchema = (schema: OpenAPIV3.SchemaObject) =>
!!schema.allOf || !!schema.anyOf || !!schema.oneOf;

const hasSubSchemasToVisit = (schema?: OpenAPIV3.SchemaObject | OpenAPIV3.ReferenceObject): schema is OpenAPIV3.SchemaObject =>
!!schema && !isRef(schema) && (["object", "array"].includes(schema.type as any) || isCompositeSchema(schema) || !!schema.not);
!!schema && !isRef(schema) && (["object", "array"].includes(schema.type as any) || isCompositeSchema(schema) || !!schema.not || (schema.type === "string" && !!schema.enum));

const filterInlineCompositeSchemas = (schemas: (OpenAPIV3.SchemaObject | OpenAPIV3.ReferenceObject)[], nameParts: string[], namePartPrefix: string, prop: string): SubSchema[] => {
let inlineSchemaIndex = 0;
Expand Down Expand Up @@ -602,8 +602,8 @@ const hoistInlineObjectSubSchemas = (nameParts: string[], schema: OpenAPIV3.Sche
const recursiveRefs = inlineSubSchemas.flatMap((s) => hoistInlineObjectSubSchemas(s.nameParts, s.schema));

// Clone the object subschemas to build the refs. Note that only objects with "properties" are hoisted as these are non-dictionary types
const refs = inlineSubSchemas.filter(s => (s.schema.type === "object" && s.schema.properties) || isCompositeSchema(s.schema)).map(s => {
const name = s.nameParts.map(_upperFirst).join('');
const refs = inlineSubSchemas.filter(s => (s.schema.type === "object" && s.schema.properties) || isCompositeSchema(s.schema) || (s.schema.type === "string" && s.schema.enum)).map(s => {
const name = [...s.nameParts, ...(s.schema.type === "string" && s.schema.enum ? ["Enum"] : [])].map(_upperFirst).join('');
const $ref = `#/components/schemas/${name}`;
const ref = {
$ref,
Expand Down
16 changes: 16 additions & 0 deletions packages/type-safe-api/test/resources/specs/edge-cases.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,22 @@ paths:
responses:
200:
description: ok
/inline-enum:
get:
operationId: inlineEnum
responses:
200:
description: ok
content:
application/json:
schema:
type: object
properties:
category:
type: string
enum:
- fruit
- vegetable
components:
schemas:
MyEnum:
Expand Down
Loading

0 comments on commit bbccca3

Please sign in to comment.