Skip to content

Commit

Permalink
fix(type-safe-api): fix named composite models and composite model types
Browse files Browse the repository at this point in the history
Smithy uses the `title` field in OpenAPI to name composite models (all-of, one-of, any-of), which
OpenAPI generator also used to produce more readable generated code. This change updates to use the
title to name composite models if present for parity with OpenAPI generator.

Additionally, nested composite model properties were typed as `any`. Since we know that we always
hoist and generate a type for composite models, we use the model name as the type for these.
  • Loading branch information
cogwirrel committed Oct 30, 2024
1 parent ac073d3 commit 752077c
Show file tree
Hide file tree
Showing 5 changed files with 5,647 additions and 1,497 deletions.
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
/*! Copyright [Amazon.com](http://amazon.com/), Inc. or its affiliates. All Rights Reserved.
SPDX-License-Identifier: Apache-2.0 */
import * as fs from "fs";
import * as util from "util";
import SwaggerParser from "@apidevtools/swagger-parser";
import { parse } from "ts-command-line-args";
import * as ejs from "ejs";
Expand Down Expand Up @@ -359,6 +360,10 @@ const toTypeScriptType = (property: parseOpenapi.Model): string => {
return `Array<${property.link && property.link.export !== "enum" ? toTypeScriptType(property.link) : property.type}>`;
case "dictionary":
return `{ [key: string]: ${property.link && property.link.export !== "enum" ? toTypeScriptType(property.link) : property.type}; }`;
case "one-of":
case "any-of":
case "all-of":
return property.name;
default:
return property.type;
}
Expand Down Expand Up @@ -412,6 +417,10 @@ const toJavaType = (property: parseOpenapi.Model): string => {
return `${property.uniqueItems ? 'Set' : 'List'}<${property.link && property.link.export !== "enum" ? toJavaType(property.link) : property.type}>`;
case "dictionary":
return `Map<String, ${property.link && property.link.export !== "enum" ? toJavaType(property.link) : property.type}>`;
case "one-of":
case "any-of":
case "all-of":
return property.name;
default:
// "any" has export = interface
if (PRIMITIVE_TYPES.has(property.type)) {
Expand Down Expand Up @@ -461,6 +470,10 @@ const toPythonType = (property: parseOpenapi.Model): string => {
return `List[${property.link && property.link.export !== "enum" ? toPythonType(property.link) : property.type}]`;
case "dictionary":
return `Dict[str, ${property.link && property.link.export !== "enum" ? toPythonType(property.link) : property.type}]`;
case "one-of":
case "any-of":
case "all-of":
return property.name;
default:
// "any" has export = interface
if (PRIMITIVE_TYPES.has(property.type)) {
Expand Down Expand Up @@ -649,7 +662,7 @@ const filterInlineCompositeSchemas = (schemas: (OpenAPIV3.SchemaObject | OpenAPI
let inlineSchemaIndex = 0;
return schemas.flatMap((s, i) => {
if (hasSubSchemasToVisit(s)) {
const subSchema: SubSchema = { nameParts: [...nameParts, `${namePartPrefix}${inlineSchemaIndex === 0 ? '' : inlineSchemaIndex}`], schema: s, prop: `${prop}.[${i}]` };
const subSchema: SubSchema = { nameParts: s.title ? [_upperFirst(_camelCase(s.title))] : [...nameParts, `${namePartPrefix}${inlineSchemaIndex === 0 ? '' : inlineSchemaIndex}`], schema: s, prop: `${prop}.[${i}]` };
inlineSchemaIndex++;
return [subSchema];
}
Expand Down Expand Up @@ -1034,7 +1047,7 @@ export default async (argv: string[], rootScriptDir: string) => {
const data = await buildData(spec, JSON.parse(args.metadata ?? '{}'));

if (args.printData) {
console.log(JSON.stringify(data, null, 2));
console.log(util.inspect(data, { depth: 100 }));
}

// Read all .ejs files in each template directory
Expand Down
41 changes: 40 additions & 1 deletion packages/type-safe-api/test/resources/specs/edge-cases.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -118,11 +118,50 @@ paths:
string
required:
- someProperty
/named-one-of:
post:
operationId: namedOneOf
responses:
200:
description: ok
content:
application/json:
schema:
$ref: "#/components/schemas/NamedOneOfUnion"
/array-of-one-ofs:
post:
operationId: arrayOfOneOfs
responses:
200:
description: ok
content:
application/json:
schema:
$ref: "#/components/schemas/ArrayOfOneOfs"
components:
schemas:
MyEnum:
type: string
enum:
- one
- two
- three
- three
NamedOneOfUnion:
oneOf:
- type: object
title: namedOneOf
properties:
foo:
type: string
- type: object
title: anotherNamedOneOf
properties:
bar:
type: string
ArrayOfOneOfs:
type: object
properties:
oneOfs:
type: array
items:
$ref: "#/components/schemas/NamedOneOfUnion"
Loading

0 comments on commit 752077c

Please sign in to comment.