diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/DefaultGenerator.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/DefaultGenerator.java index 0fa4b0dceea5..60b17e8e47d5 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/DefaultGenerator.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/DefaultGenerator.java @@ -570,6 +570,20 @@ void generateModels(List files, List allModels, List unu allModels.add(modelTemplate); } + // Don't generate model files for types that were explicitly type-mapped + // AND whose mapped name has a corresponding import mapping. + // This indicates the user wants to replace the schema type with an + // external type (e.g. --type-mappings Address=CustomAddress + // --import-mappings CustomAddress=package:custom/address.dart). + // The model metadata is still kept in allModels for use by supporting file templates. + if (config.typeMapping().containsKey(modelName)) { + String mappedTypeName = config.typeMapping().get(modelName); + if (config.importMapping().containsKey(mappedTypeName)) { + LOGGER.info("Model {} (type-mapped to {}) not generated due to import mapping", modelName, mappedTypeName); + continue; + } + } + // to generate model files generateModel(files, models, modelName); diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/DartDioClientCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/DartDioClientCodegen.java index 73132481e383..88e47bbf957a 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/DartDioClientCodegen.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/DartDioClientCodegen.java @@ -617,6 +617,18 @@ public Map postProcessAllModels(Map objs) CodegenModel cm = mo.getModel(); cm.imports = rewriteImports(cm.imports, true); cm.vendorExtensions.put("x-has-vars", !cm.vars.isEmpty()); + + // Check if this model's classname has an import mapping. + // If so, mark it so that supporting file templates (serializers, barrel) + // can use the mapped import path instead of the default model/ path. + if (importMapping().containsKey(cm.classname)) { + cm.vendorExtensions.put("x-is-import-mapped", true); + cm.vendorExtensions.put("x-import-path", importMapping().get(cm.classname)); + } else { + cm.vendorExtensions.put("x-is-import-mapped", false); + cm.vendorExtensions.put("x-import-path", + "package:" + pubName + "/" + sourceFolder + "/" + modelPackage() + "/" + cm.classFilename + ".dart"); + } } } diff --git a/modules/openapi-generator/src/main/resources/dart/libraries/dio/lib.mustache b/modules/openapi-generator/src/main/resources/dart/libraries/dio/lib.mustache index 63b1ce28e031..880bb6258354 100644 --- a/modules/openapi-generator/src/main/resources/dart/libraries/dio/lib.mustache +++ b/modules/openapi-generator/src/main/resources/dart/libraries/dio/lib.mustache @@ -9,5 +9,5 @@ export 'package:{{pubName}}/{{sourceFolder}}/auth/oauth.dart'; {{#apiInfo}}{{#apis}}export 'package:{{pubName}}/{{sourceFolder}}/{{apiPackage}}/{{classFilename}}.dart'; {{/apis}}{{/apiInfo}} -{{#models}}{{#model}}export 'package:{{pubName}}/{{sourceFolder}}/{{modelPackage}}/{{classFilename}}.dart'; +{{#models}}{{#model}}export '{{{vendorExtensions.x-import-path}}}'; {{/model}}{{/models}} diff --git a/modules/openapi-generator/src/main/resources/dart/libraries/dio/serialization/built_value/serializers.mustache b/modules/openapi-generator/src/main/resources/dart/libraries/dio/serialization/built_value/serializers.mustache index 58ec9562052e..0ae5dc8af49e 100644 --- a/modules/openapi-generator/src/main/resources/dart/libraries/dio/serialization/built_value/serializers.mustache +++ b/modules/openapi-generator/src/main/resources/dart/libraries/dio/serialization/built_value/serializers.mustache @@ -12,7 +12,7 @@ import 'package:{{pubName}}/{{sourceFolder}}/date_serializer.dart'; import 'package:{{pubName}}/{{sourceFolder}}/{{modelPackage}}/date.dart';{{/useDateLibCore}} {{#useDateLibTimeMachine}}import 'package:time_machine/time_machine.dart'; import 'package:{{pubName}}/{{sourceFolder}}/offset_date_serializer.dart';{{/useDateLibTimeMachine}} -{{#models}}{{#model}}import 'package:{{pubName}}/{{sourceFolder}}/{{modelPackage}}/{{classFilename}}.dart'; +{{#models}}{{#model}}import '{{{vendorExtensions.x-import-path}}}'; {{/model}}{{/models}}{{#builtValueSerializerImports}}import '{{{.}}}'; {{/builtValueSerializerImports}} diff --git a/modules/openapi-generator/src/main/resources/dart/libraries/dio/serialization/json_serializable/deserialize.mustache b/modules/openapi-generator/src/main/resources/dart/libraries/dio/serialization/json_serializable/deserialize.mustache index da750aa02b14..8996416c038a 100644 --- a/modules/openapi-generator/src/main/resources/dart/libraries/dio/serialization/json_serializable/deserialize.mustache +++ b/modules/openapi-generator/src/main/resources/dart/libraries/dio/serialization/json_serializable/deserialize.mustache @@ -1,7 +1,7 @@ {{#models}} {{#model}} {{^isEnum}} -import 'package:{{pubName}}/{{sourceFolder}}/{{modelPackage}}/{{classFilename}}.dart'; +import '{{{vendorExtensions.x-import-path}}}'; {{/isEnum}} {{/model}} {{/models}} diff --git a/modules/openapi-generator/src/test/java/org/openapitools/codegen/dart/dio/DartDioClientCodegenTest.java b/modules/openapi-generator/src/test/java/org/openapitools/codegen/dart/dio/DartDioClientCodegenTest.java index 90017530fb85..e19857605731 100644 --- a/modules/openapi-generator/src/test/java/org/openapitools/codegen/dart/dio/DartDioClientCodegenTest.java +++ b/modules/openapi-generator/src/test/java/org/openapitools/codegen/dart/dio/DartDioClientCodegenTest.java @@ -25,6 +25,7 @@ import java.io.*; import java.nio.charset.StandardCharsets; import java.nio.file.Files; +import java.nio.file.Path; import java.util.ArrayList; import java.util.List; import java.util.Locale; @@ -93,6 +94,54 @@ public void testKeywords() { } } + @Test + public void testImportMappingsInSerializersAndBarrelFile() throws IOException { + File output = Files.createTempDirectory("test").toFile(); + output.deleteOnExit(); + + final String pubName = "my_api"; + final CodegenConfigurator configurator = new CodegenConfigurator() + .setGeneratorName("dart-dio") + .setGitUserId("my-user") + .setGitRepoId("my-repo") + .setInputSpec("src/test/resources/3_0/dart-dio/import_mapping.yaml") + .setOutputDir(output.getAbsolutePath().replace("\\", "/")); + + configurator.addAdditionalProperty("pubName", pubName); + configurator.addTypeMapping("Address", "CustomAddress"); + configurator.addImportMapping("CustomAddress", "package:my_api/src/custom_models/custom_address.dart"); + + ClientOptInput opts = configurator.toClientOptInput(); + + Generator generator = new DefaultGenerator().opts(opts); + List files = generator.generate(); + files.forEach(File::deleteOnExit); + + // The model file for the mapped type should NOT be generated + TestUtils.assertFileNotExists(output.toPath().resolve("lib/src/model/custom_address.dart")); + + // order_out.dart should use the custom import path (this already works per the issue report) + Path orderOutPath = output.toPath().resolve("lib/src/model/order_out.dart"); + TestUtils.assertFileContains(orderOutPath, + "package:my_api/src/custom_models/custom_address.dart"); + TestUtils.assertFileNotContains(orderOutPath, + "package:my_api/src/model/custom_address.dart"); + + // serializers.dart should use the custom import path, not the hardcoded model/ path + Path serializersPath = output.toPath().resolve("lib/src/serializers.dart"); + TestUtils.assertFileContains(serializersPath, + "package:my_api/src/custom_models/custom_address.dart"); + TestUtils.assertFileNotContains(serializersPath, + "package:my_api/src/model/custom_address.dart"); + + // The barrel file should use the custom export path, not the hardcoded model/ path + Path barrelPath = output.toPath().resolve("lib/my_api.dart"); + TestUtils.assertFileContains(barrelPath, + "package:my_api/src/custom_models/custom_address.dart"); + TestUtils.assertFileNotContains(barrelPath, + "package:my_api/src/model/custom_address.dart"); + } + @Test public void verifyDartDioGeneratorRuns() throws IOException { File output = Files.createTempDirectory("test").toFile(); diff --git a/modules/openapi-generator/src/test/resources/3_0/dart-dio/import_mapping.yaml b/modules/openapi-generator/src/test/resources/3_0/dart-dio/import_mapping.yaml new file mode 100644 index 000000000000..0785c76f9bf3 --- /dev/null +++ b/modules/openapi-generator/src/test/resources/3_0/dart-dio/import_mapping.yaml @@ -0,0 +1,33 @@ +openapi: "3.1.0" +info: + title: Example + version: "1.0.0" +paths: + /orders: + get: + operationId: getOrders + responses: + "200": + description: OK + content: + application/json: + schema: + $ref: "#/components/schemas/OrderOut" +components: + schemas: + Address: + type: object + required: [street, city] + properties: + street: + type: string + city: + type: string + OrderOut: + type: object + required: [id, shippingAddress] + properties: + id: + type: integer + shippingAddress: + $ref: "#/components/schemas/Address"