From 289f24102c4a84c1510684a0fe34bcb9dce409ee Mon Sep 17 00:00:00 2001 From: Matt Hicks Date: Thu, 1 Aug 2024 10:13:09 -0500 Subject: [PATCH] Updates to OpenAPIGenerator --- build.sbt | 2 +- .../resources/generator/dart/model.template | 4 ++ .../generator/dart/model_with_params.template | 4 ++ .../resources/generator/dart/parent.template | 2 + .../generator/dart/OpenAPIDartGenerator.scala | 47 +++++++++++++++---- 5 files changed, 50 insertions(+), 9 deletions(-) diff --git a/build.sbt b/build.sbt index f5d74ac..270ce36 100644 --- a/build.sbt +++ b/build.sbt @@ -1,6 +1,6 @@ name := "spice" ThisBuild / organization := "com.outr" -ThisBuild / version := "0.5.12-SNAPSHOT" +ThisBuild / version := "0.5.12-SNAPSHOT1" val scala213: String = "2.13.14" diff --git a/openapi/src/main/resources/generator/dart/model.template b/openapi/src/main/resources/generator/dart/model.template index 63f1fbb..ed4088b 100644 --- a/openapi/src/main/resources/generator/dart/model.template +++ b/openapi/src/main/resources/generator/dart/model.template @@ -1,3 +1,4 @@ +import 'package:equatable/equatable.dart'; import 'package:json_annotation/json_annotation.dart'; %%IMPORTS%% @@ -14,4 +15,7 @@ class %%CLASSNAME%% %%EXTENDS%%{ static %%CLASSNAME%% fromJson(Map json) => _$%%CLASSNAME%%FromJson(json); %%TOJSON%% + + @override + List get props => [%%PROPS%%]; } \ No newline at end of file diff --git a/openapi/src/main/resources/generator/dart/model_with_params.template b/openapi/src/main/resources/generator/dart/model_with_params.template index 9335d49..9e92200 100644 --- a/openapi/src/main/resources/generator/dart/model_with_params.template +++ b/openapi/src/main/resources/generator/dart/model_with_params.template @@ -1,3 +1,4 @@ +import 'package:equatable/equatable.dart'; import 'package:json_annotation/json_annotation.dart'; import 'package:copy_with_extension/copy_with_extension.dart'; @@ -16,4 +17,7 @@ class %%CLASSNAME%% %%EXTENDS%%{ static %%CLASSNAME%% fromJson(Map json) => _$%%CLASSNAME%%FromJson(json); %%TOJSON%% + + @override + List get props => [%%PROPS%%]; } \ No newline at end of file diff --git a/openapi/src/main/resources/generator/dart/parent.template b/openapi/src/main/resources/generator/dart/parent.template index 1ff9dde..0c5c105 100644 --- a/openapi/src/main/resources/generator/dart/parent.template +++ b/openapi/src/main/resources/generator/dart/parent.template @@ -2,6 +2,8 @@ /// GENERATED CODE: Do not edit! abstract class %%CLASSNAME%% { + %%FIELDS%% + %%CLASSNAME%%(); factory %%CLASSNAME%%.fromJson(Map json) { diff --git a/openapi/src/main/scala/spice/openapi/generator/dart/OpenAPIDartGenerator.scala b/openapi/src/main/scala/spice/openapi/generator/dart/OpenAPIDartGenerator.scala index 5e541d6..9f913fc 100644 --- a/openapi/src/main/scala/spice/openapi/generator/dart/OpenAPIDartGenerator.scala +++ b/openapi/src/main/scala/spice/openapi/generator/dart/OpenAPIDartGenerator.scala @@ -36,10 +36,8 @@ object OpenAPIDartGenerator extends OpenAPIGenerator { case "json" => "Map" case _ => throw new RuntimeException(s"Unsupported dart type: [$s]") } - def param: String = { - val n = renameMap.getOrElse(s, s) - s"this.$n" - } + def param: String = s"this.$prop" + def prop: String = renameMap.getOrElse(s, s) } private implicit class OpenAPIContentExtras(content: OpenAPIContent) { @@ -85,8 +83,38 @@ object OpenAPIDartGenerator extends OpenAPIGenerator { val typeName = tn.replace(" ", "") if (!parentFiles.contains(typeName)) { val children = config.baseNames.find(_._1 == typeName).get._2.toList.sorted + var imports = children.toSet + val maps = children.map { child => + val component = api.components.get.schemas(child).asInstanceOf[OpenAPISchema.Component] + component.properties.map { + case (key, schema) => + val `type` = schema match { + case c: OpenAPISchema.Component if c.`type` == "array" => c.`type` // TODO: Support + case c: OpenAPISchema.Component if c.nullable.contains(true) => s"${c.`type`.dartType}?" + case c: OpenAPISchema.Component => c.`type`.dartType + case r: OpenAPISchema.Ref => + val c = r.ref.substring(r.ref.lastIndexOf('/') + 1) + imports += c + if (r.nullable.contains(true)) { + s"$c?" + } else { + c + } + } + val k = key match { + case "_id" => "id" + case _ => key + } + k -> `type` + } + } + val commonKeys = maps.map(_.keySet).reduce(_ intersect _) + val baseParams = commonKeys.map(key => key -> maps.head(key)).toMap + val fields = baseParams.toList.map { + case (key, value) => s"$value get $key;"; + }.mkString("\n ") val fileName = s"${typeName.type2File}.dart" - val imports = children.map { c => + val importString = imports.map { c => s"import '${c.type2File}.dart';" }.mkString("\n") val fromJson = children.map { c => @@ -99,7 +127,8 @@ object OpenAPIDartGenerator extends OpenAPIGenerator { | }""".stripMargin) val source = ParentTemplate .replace("%%CLASSNAME%%", typeName) - .replace("%%IMPORTS%%", imports) + .replace("%%FIELDS%%", fields) + .replace("%%IMPORTS%%", importString) .replace("%%FROMJSON%%", fromJson) parentFiles += typeName -> SourceFile( language = "Dart", @@ -224,12 +253,13 @@ object OpenAPIDartGenerator extends OpenAPIGenerator { } else { "" } + val props = schema.properties.toList.map(_._1.prop).mkString(", ") val parent = config.baseForTypeMap.get(tn) val extending = parent match { case Some(parentName) => imports = imports + parentName.type2File - s"extends $parentName " - case None => "" + s"extends $parentName with EquatableMixin " + case None => "extends Equatable " } val importsTemplate = imports.toList.sorted.map(s => s"import '$s.dart';").mkString("\n") match { case "" => "// No imports necessary" @@ -251,6 +281,7 @@ object OpenAPIDartGenerator extends OpenAPIGenerator { .replace("%%EXTENDS%%", extending) .replace("%%FIELDS%%", fields) .replace("%%PARAMS%%", params) + .replace("%%PROPS%%", props) .replace("%%TOJSON%%", toJson) SourceFile( language = "Dart",