Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
import org.openapitools.codegen.model.ModelsMap;
import org.openapitools.codegen.model.OperationMap;
import org.openapitools.codegen.model.OperationsMap;
import org.openapitools.codegen.model.WebhooksMap;
import org.openapitools.codegen.templating.CommonTemplateContentLocator;
import org.openapitools.codegen.templating.GeneratorTemplateContentLocator;
import org.openapitools.codegen.templating.MustacheEngineAdapter;
Expand Down Expand Up @@ -649,8 +650,25 @@ public void postProcessModelProperty(CodegenModel model, CodegenProperty propert
public OperationsMap postProcessOperationsWithModels(OperationsMap objs, List<ModelMap> allModels) {
super.postProcessOperationsWithModels(objs, allModels);
OperationMap operations = objs.getOperations();
List<CodegenOperation> operationList = operations.getOperation();
processImports(operations.getOperation(), imports -> objs.put("imports", imports));
return objs;
}

@Override
public WebhooksMap postProcessWebhooksWithModels(WebhooksMap objs, List<ModelMap> allModels) {
super.postProcessWebhooksWithModels(objs, allModels);
OperationMap operations = objs.getWebhooks();
processImports(operations.getOperation(), imports -> objs.put("imports", imports));
return objs;
}

/**
* Processes imports for operations or webhooks, applying the same logic to both.
*
* @param operationList the list of CodegenOperation to process
* @param setImports the handler to apply the processed imports
*/
private void processImports(List<CodegenOperation> operationList, java.util.function.Consumer<List<String>> setImports) {
Set<String> resultImports = new HashSet<>();

for (CodegenOperation op : operationList) {
Expand Down Expand Up @@ -687,7 +705,7 @@ public OperationsMap postProcessOperationsWithModels(OperationsMap objs, List<Mo
if (SERIALIZATION_LIBRARY_JSON_SERIALIZABLE.equals(library)) {
// built_value serialization uses Uint8List for all MultipartFile types
// in json_serialization, MultipartFile is used as the file parameter type, but
// MultipartFile isn't readable, instead we convert this to a Uin8List
// MultipartFile isn't readable, instead we convert this to a Uint8List
if (op.isResponseFile) {
op.imports.add("Uint8List");
op.returnType = "Uint8List";
Expand Down Expand Up @@ -729,9 +747,7 @@ public OperationsMap postProcessOperationsWithModels(OperationsMap objs, List<Mo
}
}
// for some reason "import" structure is changed ..
objs.put("imports", resultImports.stream().sorted().collect(Collectors.toList()));

return objs;
setImports.accept(resultImports.stream().sorted().collect(Collectors.toList()));
}

private void addBuiltValueSerializerImport(String type) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -115,4 +115,41 @@ public void verifyDartDioGeneratorRuns() throws IOException {
TestUtils.ensureContainsFile(files, output, "README.md");
TestUtils.ensureContainsFile(files, output, "lib/src/api.dart");
}

@Test
public void verifyWebhookImports() throws IOException {
File output = Files.createTempDirectory("test").toFile();
output.deleteOnExit();

final CodegenConfigurator configurator = new CodegenConfigurator()
.setGeneratorName("dart-dio")
.setGitUserId("my-user")
.setGitRepoId("my-repo")
.setPackageName("my-package")
.setInputSpec("src/test/resources/3_1/webhooks.yaml")
.setOutputDir(output.getAbsolutePath().replace("\\", "/"));

ClientOptInput opts = configurator.toClientOptInput();

Generator generator = new DefaultGenerator().opts(opts);
List<File> files = generator.generate();
files.forEach(File::deleteOnExit);

// Find webhook API file (default_api.dart for 'newPet' webhook)
File apiDir = new File(output, "lib/src/api");
Assert.assertTrue(apiDir.exists() && apiDir.isDirectory(), "API directory should exist");

File apiFile = new File(apiDir, "default_api.dart");
Assert.assertTrue(apiFile.exists(), "default_api.dart should be generated for webhook");

String apiContent = Files.readString(apiFile.toPath(), StandardCharsets.UTF_8);

// Bug symptom #22586: Map-style import with HTML entity encoding
// Before fix: import '{import&#x3D;model.Pet, classname&#x3D;Pet}';
// After fix: import 'package:my-package/src/model/pet.dart';
Assert.assertFalse(apiContent.contains("import '{"),
"Webhook should not contain Map-style import (bug #22586 symptom)");
Assert.assertFalse(apiContent.contains("&#x3D;"),
"Webhook should not contain HTML entity encoding (bug #22586 symptom)");
}
}
Loading