diff --git a/multiapi-engine/pom.xml b/multiapi-engine/pom.xml
index 6c668e8a..86cffc01 100644
--- a/multiapi-engine/pom.xml
+++ b/multiapi-engine/pom.xml
@@ -4,7 +4,7 @@
com.sngular
multiapi-engine
- 6.5.0
+ 6.5.1
jar
diff --git a/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/common/tools/ModelBuilder.java b/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/common/tools/ModelBuilder.java
index 736f476e..5172950e 100644
--- a/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/common/tools/ModelBuilder.java
+++ b/multiapi-engine/src/main/java/com/sngular/api/generator/plugin/common/tools/ModelBuilder.java
@@ -448,15 +448,15 @@ private static List processArray(
final List fieldObjectArrayList = new LinkedList<>();
if (!ApiTool.hasItems(schema) || ApiTool.getItems(schema).isBoolean()) {
- // No `items` schema, or `items: false` (JSON Schema 2020-12). If the array
- // declares positional `prefixItems` (tuple), or nothing typable at all, the
- // element type degrades to Object -> List.
+ // No `items` schema, or `items: false` (JSON Schema 2020-12). A `prefixItems`
+ // tuple becomes a List of its common element type when every position shares one
+ // type, otherwise (mixed types, or nothing typable) the element type is Object.
final boolean isTuple = ApiTool.hasPrefixItems(schema);
fieldObjectArrayList.add(SchemaFieldObject
.builder()
.baseName(fieldName)
.dataType(isTuple
- ? SchemaFieldObjectType.fromTypeList(TypeConstants.ARRAY, TypeConstants.OBJECT)
+ ? SchemaFieldObjectType.fromTypeList(TypeConstants.ARRAY, uniformPrefixItemType(schema, specFile))
: new SchemaFieldObjectType(TypeConstants.OBJECT))
.build());
} else {
@@ -922,8 +922,35 @@ private static String resolveArrayItemType(final JsonNode schema, final CommonSp
if (Objects.nonNull(items) && !items.isBoolean()) {
return ApiTool.hasRef(items) ? MapperUtil.getPojoNameFromRef(items, specFile, null) : ApiTool.getType(items);
}
- // `prefixItems` (tuple) or `items: false` -> degrade the element type to Object.
- return TypeConstants.OBJECT;
+ // `prefixItems` (tuple): common element type if uniform, else Object. `items: false` -> Object.
+ return uniformPrefixItemType(schema, specFile);
+ }
+
+ private static String uniformPrefixItemType(final JsonNode schema, final CommonSpecFile specFile) {
+ if (!ApiTool.hasPrefixItems(schema)) {
+ return TypeConstants.OBJECT;
+ }
+ final JsonNode prefixItems = ApiTool.getPrefixItems(schema);
+ if (Objects.isNull(prefixItems) || !prefixItems.isArray() || !prefixItems.elements().hasNext()) {
+ return TypeConstants.OBJECT;
+ }
+ String common = null;
+ for (final JsonNode item : prefixItems) {
+ final String type;
+ if (ApiTool.hasRef(item)) {
+ type = MapperUtil.getPojoNameFromRef(item, specFile, null);
+ } else if (ApiTool.hasType(item)) {
+ type = MapperUtil.getSimpleType(item, specFile);
+ } else {
+ return TypeConstants.OBJECT;
+ }
+ if (Objects.isNull(common)) {
+ common = type;
+ } else if (!common.equals(type)) {
+ return TypeConstants.OBJECT;
+ }
+ }
+ return Objects.isNull(common) ? TypeConstants.OBJECT : common;
}
private static SchemaFieldObject buildPatternPropertiesField(
diff --git a/multiapi-engine/src/test/resources/openapigenerator/testOpenApi31Completeness/assets/GadgetDTO.java b/multiapi-engine/src/test/resources/openapigenerator/testOpenApi31Completeness/assets/GadgetDTO.java
index 414b1cfc..2356a400 100644
--- a/multiapi-engine/src/test/resources/openapigenerator/testOpenApi31Completeness/assets/GadgetDTO.java
+++ b/multiapi-engine/src/test/resources/openapigenerator/testOpenApi31Completeness/assets/GadgetDTO.java
@@ -9,6 +9,7 @@
import org.springframework.web.multipart.MultipartFile;
import java.util.List;
import java.util.ArrayList;
+import java.math.BigDecimal;
import java.util.Map;
import java.util.HashMap;
@@ -24,7 +25,7 @@ public class GadgetDTO {
@JsonProperty(value ="metadata")
private Map metadata;
@JsonProperty(value ="coords")
- private List coords;
+ private List coords;
@JsonProperty(value ="owner")
private PersonDTO owner;
@JsonProperty(value ="serial")
@@ -52,7 +53,7 @@ public static class GadgetDTOBuilder {
private Object nothing;
private String id;
private Map metadata = new HashMap();
- private List coords = new ArrayList();
+ private List coords = new ArrayList();
private PersonDTO owner;
private String serial;
@@ -81,14 +82,14 @@ public GadgetDTO.GadgetDTOBuilder metadataValue(String key, String value) {
return this;
}
- public GadgetDTO.GadgetDTOBuilder coords(List coords) {
+ public GadgetDTO.GadgetDTOBuilder coords(List coords) {
if (!coords.isEmpty()) {
this.coords.addAll(coords);
}
return this;
}
- public GadgetDTO.GadgetDTOBuilder coord(Object coord) {
+ public GadgetDTO.GadgetDTOBuilder coord(BigDecimal coord) {
if (Objects.nonNull(coord)) {
this.coords.add(coord);
}
@@ -144,10 +145,10 @@ public void setMetadata(Map metadata) {
}
@Schema(name = "coords", required = false)
- public List getCoords() {
+ public List getCoords() {
return coords;
}
- public void setCoords(List coords) {
+ public void setCoords(List coords) {
this.coords = coords;
}
diff --git a/scs-multiapi-gradle-plugin/build.gradle b/scs-multiapi-gradle-plugin/build.gradle
index bc031991..d750506a 100644
--- a/scs-multiapi-gradle-plugin/build.gradle
+++ b/scs-multiapi-gradle-plugin/build.gradle
@@ -21,7 +21,7 @@ repositories {
}
group = 'com.sngular'
-version = '6.5.0'
+version = '6.5.1'
def SCSMultiApiPluginGroupId = group
def SCSMultiApiPluginVersion = version
@@ -31,7 +31,7 @@ dependencies {
shadow localGroovy()
shadow gradleApi()
- implementation 'com.sngular:multiapi-engine:6.5.0'
+ implementation 'com.sngular:multiapi-engine:6.5.1'
testImplementation 'org.assertj:assertj-core:3.24.2'
testImplementation 'com.puppycrawl.tools:checkstyle:10.12.3'
testImplementation 'org.junit.platform:junit-platform-launcher:1.9.2'
@@ -100,7 +100,7 @@ testing {
integrationTest(JvmTestSuite) {
dependencies {
- implementation 'com.sngular:scs-multiapi-gradle-plugin:6.5.0'
+ implementation 'com.sngular:scs-multiapi-gradle-plugin:6.5.1'
implementation 'org.assertj:assertj-core:3.24.2'
}
diff --git a/scs-multiapi-maven-plugin/pom.xml b/scs-multiapi-maven-plugin/pom.xml
index d70d56f0..eaa78b50 100644
--- a/scs-multiapi-maven-plugin/pom.xml
+++ b/scs-multiapi-maven-plugin/pom.xml
@@ -4,7 +4,7 @@
com.sngular
scs-multiapi-maven-plugin
- 6.5.0
+ 6.5.1
maven-plugin
AsyncApi - OpenApi Code Generator Maven Plugin
@@ -271,7 +271,7 @@
com.sngular
multiapi-engine
- 6.5.0
+ 6.5.1
org.apache.maven
@@ -560,7 +560,7 @@
org.sonatype.central
central-publishing-maven-plugin
- 0.6.0
+ 0.11.0
true
true