From e8d710735202552b4985c3c14d2f3581046f54fc Mon Sep 17 00:00:00 2001 From: Jeff Mikels Date: Sat, 11 Jun 2022 16:54:38 -0400 Subject: [PATCH 1/6] added returnInnerType for container types, made Dart generator recognize modelNamePrefix and Suffix, added apiClientName option to dart --- .../codegen/CodegenOperation.java | 6 +- .../openapitools/codegen/DefaultCodegen.java | 2 + .../languages/AbstractDartCodegen.java | 135 +++++++++++------- .../codegen/dart/DartClientOptionsTest.java | 1 + .../dart/dio/DartDioClientOptionsTest.java | 1 + .../options/DartClientOptionsProvider.java | 2 + .../options/DartDioClientOptionsProvider.java | 2 + openapi-generator.code-workspace | 14 +- .../org/openapitools/client/model/Order.scala | 4 +- 9 files changed, 106 insertions(+), 61 deletions(-) diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/CodegenOperation.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/CodegenOperation.java index 91cc8141e2f0..84df51b522c0 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/CodegenOperation.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/CodegenOperation.java @@ -31,7 +31,7 @@ public class CodegenOperation { isRestfulIndex, isRestfulShow, isRestfulCreate, isRestfulUpdate, isRestfulDestroy, isRestful, isDeprecated, isCallbackRequest, uniqueItems, hasDefaultResponse = false, hasErrorResponseObject; // if 4xx, 5xx responses have at least one error object defined - public String path, operationId, returnType, returnFormat, httpMethod, returnBaseType, + public String path, operationId, returnType, returnFormat, httpMethod, returnBaseType, returnInnerType, returnContainer, summary, unescapedNotes, notes, baseName, defaultResponse; public CodegenDiscriminator discriminator; public List> consumes, produces, prioritizedContentTypes; @@ -320,6 +320,7 @@ public String toString() { sb.append(", returnType='").append(returnType).append('\''); sb.append(", httpMethod='").append(httpMethod).append('\''); sb.append(", returnBaseType='").append(returnBaseType).append('\''); + sb.append(", returnInnerType='").append(returnInnerType).append('\''); sb.append(", returnContainer='").append(returnContainer).append('\''); sb.append(", summary='").append(summary).append('\''); sb.append(", unescapedNotes='").append(unescapedNotes).append('\''); @@ -397,6 +398,7 @@ public boolean equals(Object o) { Objects.equals(returnType, that.returnType) && Objects.equals(httpMethod, that.httpMethod) && Objects.equals(returnBaseType, that.returnBaseType) && + Objects.equals(returnInnerType, that.returnInnerType) && Objects.equals(returnContainer, that.returnContainer) && Objects.equals(summary, that.summary) && Objects.equals(unescapedNotes, that.unescapedNotes) && @@ -442,7 +444,7 @@ public int hashCode() { isArray, isMultipart, isResponseBinary, isResponseFile, isResponseOptional, hasReference, hasDefaultResponse, isRestfulIndex, isRestfulShow, isRestfulCreate, isRestfulUpdate, isRestfulDestroy, isRestful, isDeprecated, isCallbackRequest, uniqueItems, path, operationId, returnType, httpMethod, - returnBaseType, returnContainer, summary, unescapedNotes, notes, baseName, defaultResponse, + returnBaseType, returnInnerType, returnContainer, summary, unescapedNotes, notes, baseName, defaultResponse, discriminator, consumes, produces, prioritizedContentTypes, servers, bodyParam, allParams, bodyParams, pathParams, queryParams, headerParams, formParams, cookieParams, requiredParams, optionalParams, authMethods, tags, responses, callbacks, imports, examples, requestBodyExamples, externalDocs, diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/DefaultCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/DefaultCodegen.java index e4b539e27117..74b5198c440a 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/DefaultCodegen.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/DefaultCodegen.java @@ -3900,9 +3900,11 @@ protected void handleMethodResponse(Operation operation, ArraySchema as = (ArraySchema) responseSchema; CodegenProperty innerProperty = fromProperty("response", getSchemaItems(as)); op.returnBaseType = innerProperty.baseType; + op.returnInnerType = innerProperty.dataType; } else if (ModelUtils.isMapSchema(responseSchema)) { CodegenProperty innerProperty = fromProperty("response", getAdditionalProperties(responseSchema)); op.returnBaseType = innerProperty.baseType; + op.returnInnerType = innerProperty.dataType; } else { if (cm.complexType != null) { op.returnBaseType = cm.complexType; diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AbstractDartCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AbstractDartCodegen.java index 544d6d690890..a67d3882be44 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AbstractDartCodegen.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AbstractDartCodegen.java @@ -7,6 +7,7 @@ import io.swagger.v3.oas.models.media.Schema; import io.swagger.v3.oas.models.media.StringSchema; import io.swagger.v3.oas.models.servers.Server; +import io.swagger.v3.oas.models.responses.ApiResponse; import org.apache.commons.io.FilenameUtils; import org.apache.commons.lang3.StringUtils; import org.openapitools.codegen.*; @@ -45,6 +46,7 @@ public abstract class AbstractDartCodegen extends DefaultCodegen { public static final String PUB_AUTHOR_EMAIL = "pubAuthorEmail"; public static final String PUB_HOMEPAGE = "pubHomepage"; public static final String USE_ENUM_EXTENSION = "useEnumExtension"; + public static final String API_CLIENT_NAME = "apiClientName"; protected String pubLibrary = "openapi.api"; protected String pubName = "openapi"; @@ -60,6 +62,7 @@ public abstract class AbstractDartCodegen extends DefaultCodegen { protected String modelDocPath = "doc" + File.separator; protected String apiTestPath = "test" + File.separator; protected String modelTestPath = "test" + File.separator; + protected String apiClientName = "ApiClient"; protected Map imports = new HashMap<>(); @@ -72,29 +75,22 @@ public AbstractDartCodegen() { SecurityFeature.OAuth2_Implicit, SecurityFeature.BasicAuth, SecurityFeature.BearerToken, - SecurityFeature.ApiKey - )) + SecurityFeature.ApiKey)) .excludeGlobalFeatures( GlobalFeature.XMLStructureDefinitions, GlobalFeature.Callbacks, GlobalFeature.LinkObjects, - GlobalFeature.ParameterStyling - ) + GlobalFeature.ParameterStyling) .excludeSchemaSupportFeatures( SchemaSupportFeature.Polymorphism, SchemaSupportFeature.Union, - SchemaSupportFeature.Composite - ) + SchemaSupportFeature.Composite) .includeParameterFeatures( - ParameterFeature.Cookie - ) + ParameterFeature.Cookie) .includeClientModificationFeatures( - ClientModificationFeature.BasePath - ) + ClientModificationFeature.BasePath) .excludeWireFormatFeatures( - WireFormatFeature.XML - ) - ); + WireFormatFeature.XML)); outputFolder = "generated-code/dart"; modelTemplateFiles.put("model.mustache", ".dart"); @@ -109,7 +105,7 @@ public AbstractDartCodegen() { apiTestTemplateFiles.put("api_test.mustache", ".dart"); final List reservedWordsList = new ArrayList<>(); - try(BufferedReader reader = new BufferedReader( + try (BufferedReader reader = new BufferedReader( new InputStreamReader(DartClientCodegen.class.getResourceAsStream("/dart/dart-keywords.txt"), StandardCharsets.UTF_8))) { while (reader.ready()) { @@ -126,8 +122,7 @@ public AbstractDartCodegen() { "bool", "int", "num", - "double" - ); + "double"); typeMapping = new HashMap<>(); typeMapping.put("Array", "List"); @@ -154,7 +149,7 @@ public AbstractDartCodegen() { typeMapping.put("UUID", "String"); typeMapping.put("URI", "String"); typeMapping.put("ByteArray", "String"); - typeMapping.put("object", "Object"); + typeMapping.put("object", "Map"); // prefer Dart Map for generic JSON objects typeMapping.put("AnyType", "Object"); // Data types of the above values which are automatically imported @@ -168,8 +163,7 @@ public AbstractDartCodegen() { "Set", "Map", "DateTime", - "Object" - ); + "Object"); imports.put("String", "dart:core"); imports.put("bool", "dart:core"); @@ -190,7 +184,9 @@ public AbstractDartCodegen() { addOption(PUB_AUTHOR, "Author name in generated pubspec", pubAuthor); addOption(PUB_AUTHOR_EMAIL, "Email address of the author in generated pubspec", pubAuthorEmail); addOption(PUB_HOMEPAGE, "Homepage in generated pubspec", pubHomepage); - addOption(USE_ENUM_EXTENSION, "Allow the 'x-enum-values' extension for enums", String.valueOf(useEnumExtension)); + addOption(USE_ENUM_EXTENSION, "Allow the 'x-enum-values' extension for enums", + String.valueOf(useEnumExtension)); + addOption(API_CLIENT_NAME, "Specify the api client class name, defaults to 'ApiClient'", apiClientName); addOption(CodegenConstants.SOURCE_FOLDER, CodegenConstants.SOURCE_FOLDER_DESC, sourceFolder); } @@ -221,56 +217,58 @@ public void processOpts() { additionalProperties.put(CodegenConstants.API_PACKAGE, apiPackage); if (StringUtils.isEmpty(System.getenv("DART_POST_PROCESS_FILE"))) { - LOGGER.info("Environment variable DART_POST_PROCESS_FILE not defined so the Dart code may not be properly formatted. To define it, try `export DART_POST_PROCESS_FILE=\"/usr/local/bin/dartfmt -w\"` (Linux/Mac)"); - LOGGER.info("NOTE: To enable file post-processing, 'enablePostProcessFile' must be set to `true` (--enable-post-process-file for CLI)."); + LOGGER.info( + "Environment variable DART_POST_PROCESS_FILE not defined so the Dart code may not be properly formatted. To define it, try `export DART_POST_PROCESS_FILE=\"/usr/local/bin/dartfmt -w\"` (Linux/Mac)"); + LOGGER.info( + "NOTE: To enable file post-processing, 'enablePostProcessFile' must be set to `true` (--enable-post-process-file for CLI)."); } if (additionalProperties.containsKey(PUB_NAME)) { this.setPubName((String) additionalProperties.get(PUB_NAME)); } else { - //not set, use to be passed to template + // not set, use to be passed to template additionalProperties.put(PUB_NAME, pubName); } if (additionalProperties.containsKey(PUB_LIBRARY)) { this.setPubLibrary((String) additionalProperties.get(PUB_LIBRARY)); } else { - //not set, use to be passed to template + // not set, use to be passed to template additionalProperties.put(PUB_LIBRARY, pubLibrary); } if (additionalProperties.containsKey(PUB_VERSION)) { this.setPubVersion((String) additionalProperties.get(PUB_VERSION)); } else { - //not set, use to be passed to template + // not set, use to be passed to template additionalProperties.put(PUB_VERSION, pubVersion); } if (additionalProperties.containsKey(PUB_DESCRIPTION)) { this.setPubDescription((String) additionalProperties.get(PUB_DESCRIPTION)); } else { - //not set, use to be passed to template + // not set, use to be passed to template additionalProperties.put(PUB_DESCRIPTION, pubDescription); } if (additionalProperties.containsKey(PUB_AUTHOR)) { this.setPubAuthor((String) additionalProperties.get(PUB_AUTHOR)); } else { - //not set, use to be passed to template + // not set, use to be passed to template additionalProperties.put(PUB_AUTHOR, pubAuthor); } if (additionalProperties.containsKey(PUB_AUTHOR_EMAIL)) { this.setPubAuthorEmail((String) additionalProperties.get(PUB_AUTHOR_EMAIL)); } else { - //not set, use to be passed to template + // not set, use to be passed to template additionalProperties.put(PUB_AUTHOR_EMAIL, pubAuthorEmail); } if (additionalProperties.containsKey(PUB_HOMEPAGE)) { this.setPubHomepage((String) additionalProperties.get(PUB_HOMEPAGE)); } else { - //not set, use to be passed to template + // not set, use to be passed to template additionalProperties.put(PUB_HOMEPAGE, pubHomepage); } @@ -281,6 +279,13 @@ public void processOpts() { additionalProperties.put(USE_ENUM_EXTENSION, useEnumExtension); } + if (additionalProperties.containsKey(API_CLIENT_NAME)) { + this.setApiClientName((String) additionalProperties.get(API_CLIENT_NAME)); + } else { + // not set, use to be passed to template + additionalProperties.put(API_CLIENT_NAME, apiClientName); + } + if (additionalProperties.containsKey(CodegenConstants.SOURCE_FOLDER)) { String srcFolder = (String) additionalProperties.get(CodegenConstants.SOURCE_FOLDER); this.setSourceFolder(srcFolder.replace('/', File.separatorChar)); @@ -309,7 +314,8 @@ protected boolean isReservedWord(String word) { // * a keyword // * a word that has been mapped in the reservedWordsMappings // * a default included type or a type include through some library - return super.isReservedWord(word) || reservedWordsMappings().containsKey(word) || defaultIncludes().contains(word); + return super.isReservedWord(word) || reservedWordsMappings().containsKey(word) + || defaultIncludes().contains(word); } @Override @@ -322,12 +328,14 @@ public String escapeReservedWord(String name) { @Override public String apiFileFolder() { - return (outputFolder + File.separator + libPath + sourceFolder + File.separator + apiPackage()).replace('/', File.separatorChar); + return (outputFolder + File.separator + libPath + sourceFolder + File.separator + apiPackage()).replace('/', + File.separatorChar); } @Override public String modelFileFolder() { - return (outputFolder + File.separator + libPath + sourceFolder + File.separator + modelPackage()).replace('/', File.separatorChar); + return (outputFolder + File.separator + libPath + sourceFolder + File.separator + modelPackage()).replace('/', + File.separatorChar); } @Override @@ -358,6 +366,12 @@ public String toVarName(String name) { // always need to replace leading underscores first name = name.replaceAll("^_", ""); + // if the query var was an underscore, the name is now empty. + // fix that with a valid Dart variable name and hope it doesn't conflict. + if (name.matches("")) { + name = "q"; + } + // if it's all upper case, do nothing if (name.matches("^[A-Z_]*$")) { return name; @@ -433,7 +447,8 @@ public String toModelName(final String name) { // model name starts with number if (camelizedName.matches("^\\d.*")) { final String modelName = "Model" + camelizedName; // e.g. 200Response => Model200Response (after camelize) - LOGGER.warn("{} (model name starts with number) cannot be used as model name. Renamed to {}", name, modelName); + LOGGER.warn("{} (model name starts with number) cannot be used as model name. Renamed to {}", name, + modelName); return modelName; } @@ -445,7 +460,8 @@ public String toModelFilename(String name) { return underscore(toModelName(name)); } - @Override public String toModelDocFilename(String name) { + @Override + public String toModelDocFilename(String name) { return toModelName(name); } @@ -495,17 +511,23 @@ public String getTypeDeclaration(Schema p) { return getSchemaType(target) + "<" + getTypeDeclaration(items) + ">"; } if (ModelUtils.isMapSchema(target)) { - // Note: ModelUtils.isMapSchema(p) returns true when p is a composed schema that also defines + // Note: ModelUtils.isMapSchema(p) returns true when p is a composed schema that + // also defines // additionalproperties: true Schema inner = getAdditionalProperties(target); if (inner == null) { - LOGGER.error("`{}` (map property) does not have a proper inner type defined. Default to type:string", p.getName()); + LOGGER.error("`{}` (map property) does not have a proper inner type defined. Default to type:string", + p.getName()); inner = new StringSchema().description("TODO default missing map inner type to string"); p.setAdditionalProperties(inner); } return getSchemaType(target) + ""; } - return super.getTypeDeclaration(p); + + // this code duplicates what is in the super class, so we don't call super + // anymore + // return super.getTypeDeclaration(p); + return getSchemaType(p); } @Override @@ -529,17 +551,22 @@ public ModelsMap postProcessModels(ModelsMap objs) { public void postProcessModelProperty(CodegenModel model, CodegenProperty property) { super.postProcessModelProperty(model, property); if (!model.isEnum && property.isEnum && property.getComposedSchemas() == null) { - // These are inner enums, enums which do not exist as models, just as properties. + // These are inner enums, enums which do not exist as models, just as + // properties. // They are handled via the enum_inline template and are generated in the - // same file as the containing class. To prevent name clashes the inline enum classes + // same file as the containing class. To prevent name clashes the inline enum + // classes // are prefix with the classname of the containing class in the template. - // Here the datatypeWithEnum template variable gets updated to match that scheme. - // Also taking into account potential collection types e.g. List -> List + // Here the datatypeWithEnum template variable gets updated to match that + // scheme. + // Also taking into account potential collection types e.g. List + // -> List final String enumName = model.classname + property.enumName; if (property.items != null) { // inner items e.g. enums in collections, only works for one level // but same is the case for DefaultCodegen - property.setDatatypeWithEnum(property.datatypeWithEnum.replace(property.items.datatypeWithEnum, enumName)); + property.setDatatypeWithEnum( + property.datatypeWithEnum.replace(property.items.datatypeWithEnum, enumName)); property.items.setDatatypeWithEnum(enumName); property.items.setEnumName(enumName); } else { @@ -585,8 +612,10 @@ public CodegenProperty fromProperty(String name, Schema p) { public CodegenOperation fromOperation(String path, String httpMethod, Operation operation, List servers) { final CodegenOperation op = super.fromOperation(path, httpMethod, operation, servers); for (CodegenResponse r : op.responses) { - // By default, only set types are automatically added to operation imports, not sure why. - // Add all container type imports here, by default 'dart:core' imports are skipped + // By default, only set types are automatically added to operation imports, not + // sure why. + // Add all container type imports here, by default 'dart:core' imports are + // skipped // but other sub-classes may require specific container type imports. if (r.containerType != null && typeMapping().containsKey(r.containerType)) { final String value = typeMapping().get(r.containerType); @@ -629,7 +658,9 @@ public OperationsMap postProcessOperationsWithModels(OperationsMap objs, List> prioritizeContentTypes(List> enumVars, Map vendorExtensions, String dataType) { + protected void updateEnumVarsWithExtensions(List> enumVars, + Map vendorExtensions, String dataType) { if (vendorExtensions != null && useEnumExtension && vendorExtensions.containsKey("x-enum-values")) { // Use the x-enum-values extension for this enum // Existing enumVars added by the default handling need to be removed first @@ -732,7 +764,8 @@ public String toOperationId(String operationId) { // operationId starts with a number if (operationId.matches("^\\d.*")) { String newOperationId = camelize("call_" + operationId, true); - LOGGER.warn("{} (starting with a number) cannot be used as method name. Renamed to {}", operationId, newOperationId); + LOGGER.warn("{} (starting with a number) cannot be used as method name. Renamed to {}", operationId, + newOperationId); operationId = newOperationId; } @@ -771,6 +804,10 @@ public void setUseEnumExtension(boolean useEnumExtension) { this.useEnumExtension = useEnumExtension; } + public void setApiClientName(String apiClientName) { + this.apiClientName = apiClientName; + } + public void setSourceFolder(String sourceFolder) { this.sourceFolder = sourceFolder; } @@ -819,5 +856,7 @@ public void postProcessFile(File file, String fileType) { } @Override - public GeneratorLanguage generatorLanguage() { return GeneratorLanguage.DART; } + public GeneratorLanguage generatorLanguage() { + return GeneratorLanguage.DART; + } } diff --git a/modules/openapi-generator/src/test/java/org/openapitools/codegen/dart/DartClientOptionsTest.java b/modules/openapi-generator/src/test/java/org/openapitools/codegen/dart/DartClientOptionsTest.java index 1b268561e52a..828b5d6d0d7a 100644 --- a/modules/openapi-generator/src/test/java/org/openapitools/codegen/dart/DartClientOptionsTest.java +++ b/modules/openapi-generator/src/test/java/org/openapitools/codegen/dart/DartClientOptionsTest.java @@ -49,6 +49,7 @@ protected void verifyOptions() { verify(clientCodegen).setPubAuthorEmail(DartClientOptionsProvider.PUB_AUTHOR_EMAIL_VALUE); verify(clientCodegen).setPubHomepage(DartClientOptionsProvider.PUB_HOMEPAGE_VALUE); verify(clientCodegen).setSourceFolder(DartClientOptionsProvider.SOURCE_FOLDER_VALUE); + verify(clientCodegen).setApiClientName(DartClientOptionsProvider.API_CLIENT_NAME_VALUE); verify(clientCodegen).setUseEnumExtension(Boolean.parseBoolean(DartClientOptionsProvider.USE_ENUM_EXTENSION)); verify(clientCodegen).setEnumUnknownDefaultCase(Boolean.parseBoolean(DartClientOptionsProvider.ENUM_UNKNOWN_DEFAULT_CASE_VALUE)); } diff --git a/modules/openapi-generator/src/test/java/org/openapitools/codegen/dart/dio/DartDioClientOptionsTest.java b/modules/openapi-generator/src/test/java/org/openapitools/codegen/dart/dio/DartDioClientOptionsTest.java index 2292d1109898..8ebe7468f085 100644 --- a/modules/openapi-generator/src/test/java/org/openapitools/codegen/dart/dio/DartDioClientOptionsTest.java +++ b/modules/openapi-generator/src/test/java/org/openapitools/codegen/dart/dio/DartDioClientOptionsTest.java @@ -48,6 +48,7 @@ protected void verifyOptions() { verify(clientCodegen).setPubAuthorEmail(DartDioClientOptionsProvider.PUB_AUTHOR_EMAIL_VALUE); verify(clientCodegen).setPubHomepage(DartDioClientOptionsProvider.PUB_HOMEPAGE_VALUE); verify(clientCodegen).setSourceFolder(DartDioClientOptionsProvider.SOURCE_FOLDER_VALUE); + verify(clientCodegen).setApiClientName(DartDioClientOptionsProvider.API_CLIENT_NAME_VALUE); verify(clientCodegen).setUseEnumExtension(Boolean.parseBoolean(DartDioClientOptionsProvider.USE_ENUM_EXTENSION)); verify(clientCodegen).setDateLibrary(DartDioClientCodegen.DATE_LIBRARY_DEFAULT); verify(clientCodegen).setLibrary(DartDioClientCodegen.SERIALIZATION_LIBRARY_DEFAULT); diff --git a/modules/openapi-generator/src/test/java/org/openapitools/codegen/options/DartClientOptionsProvider.java b/modules/openapi-generator/src/test/java/org/openapitools/codegen/options/DartClientOptionsProvider.java index 5e468090bed6..db003c62ae64 100644 --- a/modules/openapi-generator/src/test/java/org/openapitools/codegen/options/DartClientOptionsProvider.java +++ b/modules/openapi-generator/src/test/java/org/openapitools/codegen/options/DartClientOptionsProvider.java @@ -40,6 +40,7 @@ public class DartClientOptionsProvider implements OptionsProvider { public static final String ALLOW_UNICODE_IDENTIFIERS_VALUE = "false"; public static final String PREPEND_FORM_OR_BODY_PARAMETERS_VALUE = "true"; public static final String ENUM_UNKNOWN_DEFAULT_CASE_VALUE = "false"; + public static final String API_CLIENT_NAME_VALUE = "ApiClient"; @Override public String getLanguage() { @@ -59,6 +60,7 @@ public Map createOptions() { .put(DartClientCodegen.PUB_AUTHOR, PUB_AUTHOR_VALUE) .put(DartClientCodegen.PUB_AUTHOR_EMAIL, PUB_AUTHOR_EMAIL_VALUE) .put(DartClientCodegen.PUB_HOMEPAGE, PUB_HOMEPAGE_VALUE) + .put(DartClientCodegen.API_CLIENT_NAME, API_CLIENT_NAME_VALUE) .put(CodegenConstants.SOURCE_FOLDER, SOURCE_FOLDER_VALUE) .put(DartClientCodegen.USE_ENUM_EXTENSION, USE_ENUM_EXTENSION) .put(CodegenConstants.ALLOW_UNICODE_IDENTIFIERS, ALLOW_UNICODE_IDENTIFIERS_VALUE) diff --git a/modules/openapi-generator/src/test/java/org/openapitools/codegen/options/DartDioClientOptionsProvider.java b/modules/openapi-generator/src/test/java/org/openapitools/codegen/options/DartDioClientOptionsProvider.java index 0072e04e0c15..8489e9466ea1 100644 --- a/modules/openapi-generator/src/test/java/org/openapitools/codegen/options/DartDioClientOptionsProvider.java +++ b/modules/openapi-generator/src/test/java/org/openapitools/codegen/options/DartDioClientOptionsProvider.java @@ -37,6 +37,7 @@ public class DartDioClientOptionsProvider implements OptionsProvider { public static final String PUB_AUTHOR_VALUE = "Author"; public static final String PUB_AUTHOR_EMAIL_VALUE = "author@homepage"; public static final String PUB_HOMEPAGE_VALUE = "Homepage"; + public static final String API_CLIENT_NAME_VALUE = "Homepage"; public static final String ENUM_UNKNOWN_DEFAULT_CASE_VALUE = "false"; @Override @@ -57,6 +58,7 @@ public Map createOptions() { .put(DartDioClientCodegen.PUB_AUTHOR, PUB_AUTHOR_VALUE) .put(DartDioClientCodegen.PUB_AUTHOR_EMAIL, PUB_AUTHOR_EMAIL_VALUE) .put(DartDioClientCodegen.PUB_HOMEPAGE, PUB_HOMEPAGE_VALUE) + .put(DartDioClientCodegen.API_CLIENT_NAME, API_CLIENT_NAME_VALUE) .put(CodegenConstants.SERIALIZATION_LIBRARY, DartDioClientCodegen.SERIALIZATION_LIBRARY_DEFAULT) .put(DartDioClientCodegen.DATE_LIBRARY, DartDioClientCodegen.DATE_LIBRARY_DEFAULT) .put(DartDioClientCodegen.FINAL_PROPERTIES, DartDioClientCodegen.FINAL_PROPERTIES_DEFAULT_VALUE) diff --git a/openapi-generator.code-workspace b/openapi-generator.code-workspace index 94b0864b5d8d..0b764e515730 100644 --- a/openapi-generator.code-workspace +++ b/openapi-generator.code-workspace @@ -26,7 +26,7 @@ }, ], "settings": { - "editor.formatOnType": true, + "editor.formatOnType": false, "editor.linkedEditing": true, "editor.tabCompletion": "on", "editor.tabSize": 4, @@ -35,7 +35,6 @@ "editor.suggestSelection": "first", "editor.semanticHighlighting.enabled": true, "explorer.confirmDelete": true, - "files.autoSave": "onFocusChange", "files.exclude": { "**/.classpath": true, @@ -45,24 +44,22 @@ }, "files.trimFinalNewlines": false, "files.trimTrailingWhitespace": true, - "task.saveBeforeRun": "always", - "java.autobuild.enabled": false, "java.completion.enabled": true, "java.completion.guessMethodArguments": true, "java.completion.maxResults": 5, "java.format.onType.enabled": true, - "java.referencesCodeLens.enabled": true, "java.saveActions.organizeImports": true, "java.showBuildStatusOnStart.enabled": true, - "java.dependency.autoRefresh": true, "java.dependency.refreshDelay": 3000, "java.format.enabled": true, - "maven.pomfile.autoUpdateEffectivePOM": true, + "workspace.isHidden": false, + "editor.formatOnSave": false, + "editor.formatOnPaste": false, }, "extensions": { "recommendations": [ @@ -72,7 +69,6 @@ "visualstudioexptteam.vscodeintellicode", "42crunch.vscode-openapi", "mermade.openapi-lint" - ] } -} \ No newline at end of file +} diff --git a/samples/client/petstore/scala-gatling/bin/gatling/org/openapitools/client/model/Order.scala b/samples/client/petstore/scala-gatling/bin/gatling/org/openapitools/client/model/Order.scala index ba6967f0e176..526d8d6b07f4 100644 --- a/samples/client/petstore/scala-gatling/bin/gatling/org/openapitools/client/model/Order.scala +++ b/samples/client/petstore/scala-gatling/bin/gatling/org/openapitools/client/model/Order.scala @@ -1,13 +1,13 @@ package org.openapitools.client.model -import java.util.Date +import java.time.OffsetDateTime case class Order ( _id: Option[Long], _petId: Option[Long], _quantity: Option[Integer], - _shipDate: Option[Date], + _shipDate: Option[OffsetDateTime], /* Order Status */ _status: Option[String], _complete: Option[Boolean] From f1babda2f0688e88482317684e1957df90c29263 Mon Sep 17 00:00:00 2001 From: Jeff Mikels Date: Sat, 11 Jun 2022 16:58:47 -0400 Subject: [PATCH 2/6] added returnInnerType for container types, made Dart generator recognize modelNamePrefix and Suffix, added apiClientName option to dart --- .../bin/gatling/org/openapitools/client/model/Order.scala | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/samples/client/petstore/scala-gatling/bin/gatling/org/openapitools/client/model/Order.scala b/samples/client/petstore/scala-gatling/bin/gatling/org/openapitools/client/model/Order.scala index 526d8d6b07f4..ba6967f0e176 100644 --- a/samples/client/petstore/scala-gatling/bin/gatling/org/openapitools/client/model/Order.scala +++ b/samples/client/petstore/scala-gatling/bin/gatling/org/openapitools/client/model/Order.scala @@ -1,13 +1,13 @@ package org.openapitools.client.model -import java.time.OffsetDateTime +import java.util.Date case class Order ( _id: Option[Long], _petId: Option[Long], _quantity: Option[Integer], - _shipDate: Option[OffsetDateTime], + _shipDate: Option[Date], /* Order Status */ _status: Option[String], _complete: Option[Boolean] From 7fd619df1f885d3bafcc7c702e2f86946e82bcd3 Mon Sep 17 00:00:00 2001 From: Jeff Mikels Date: Sat, 11 Jun 2022 17:02:04 -0400 Subject: [PATCH 3/6] added returnInnerType for container types, made Dart generator recognize modelNamePrefix and Suffix, added apiClientName option to dart --- .../src/main/resources/dart2/README.mustache | 14 ++++----- .../src/main/resources/dart2/api.mustache | 10 +++---- .../main/resources/dart2/api_client.mustache | 30 +++++++++---------- .../src/main/resources/dart2/api_doc.mustache | 14 ++++----- .../resources/dart2/api_exception.mustache | 12 ++++---- .../main/resources/dart2/api_helper.mustache | 14 ++++----- .../src/main/resources/dart2/apilib.mustache | 2 +- .../dart2/auth/api_key_auth.mustache | 4 +-- .../dart2/auth/authentication.mustache | 2 +- .../dart2/auth/http_basic_auth.mustache | 2 +- .../dart2/auth/http_bearer_auth.mustache | 2 +- .../main/resources/dart2/auth/oauth.mustache | 2 +- .../main/resources/dart2/git_push.sh.mustache | 0 13 files changed, 54 insertions(+), 54 deletions(-) mode change 100755 => 100644 modules/openapi-generator/src/main/resources/dart2/git_push.sh.mustache diff --git a/modules/openapi-generator/src/main/resources/dart2/README.mustache b/modules/openapi-generator/src/main/resources/dart2/README.mustache index ba99ace33f36..cfb6f6855e6a 100644 --- a/modules/openapi-generator/src/main/resources/dart2/README.mustache +++ b/modules/openapi-generator/src/main/resources/dart2/README.mustache @@ -55,27 +55,27 @@ import 'package:{{{pubName}}}/api.dart'; {{#isBasic}} {{#isBasicBasic}} // TODO Configure HTTP basic authorization: {{{name}}} -//defaultApiClient.getAuthentication('{{{name}}}').username = 'YOUR_USERNAME' -//defaultApiClient.getAuthentication('{{{name}}}').password = 'YOUR_PASSWORD'; +//default{{#apiClientName}}{{.}}{{/apiClientName}}{{^apiClientName}}{{{modelNamePrefix}}}ApiClient{{{modelNameSuffix}}}{{/apiClientName}}.getAuthentication('{{{name}}}').username = 'YOUR_USERNAME' +//default{{#apiClientName}}{{.}}{{/apiClientName}}{{^apiClientName}}{{{modelNamePrefix}}}ApiClient{{{modelNameSuffix}}}{{/apiClientName}}.getAuthentication('{{{name}}}').password = 'YOUR_PASSWORD'; {{/isBasicBasic}} {{#isBasicBearer}} // TODO Configure HTTP Bearer authorization: {{{name}}} // Case 1. Use String Token -//defaultApiClient.getAuthentication('{{{name}}}').setAccessToken('YOUR_ACCESS_TOKEN'); +//default{{#apiClientName}}{{.}}{{/apiClientName}}{{^apiClientName}}{{{modelNamePrefix}}}ApiClient{{{modelNameSuffix}}}{{/apiClientName}}.getAuthentication('{{{name}}}').setAccessToken('YOUR_ACCESS_TOKEN'); // Case 2. Use Function which generate token. // String yourTokenGeneratorFunction() { ... } -//defaultApiClient.getAuthentication('{{{name}}}').setAccessToken(yourTokenGeneratorFunction); +//default{{#apiClientName}}{{.}}{{/apiClientName}}{{^apiClientName}}{{{modelNamePrefix}}}ApiClient{{{modelNameSuffix}}}{{/apiClientName}}.getAuthentication('{{{name}}}').setAccessToken(yourTokenGeneratorFunction); {{/isBasicBearer}} {{/isBasic}} {{#isApiKey}} // TODO Configure API key authorization: {{{name}}} -//defaultApiClient.getAuthentication('{{{name}}}').apiKey = 'YOUR_API_KEY'; +//default{{#apiClientName}}{{.}}{{/apiClientName}}{{^apiClientName}}{{{modelNamePrefix}}}ApiClient{{{modelNameSuffix}}}{{/apiClientName}}.getAuthentication('{{{name}}}').apiKey = 'YOUR_API_KEY'; // uncomment below to setup prefix (e.g. Bearer) for API key, if needed -//defaultApiClient.getAuthentication('{{{name}}}').apiKeyPrefix = 'Bearer'; +//default{{#apiClientName}}{{.}}{{/apiClientName}}{{^apiClientName}}{{{modelNamePrefix}}}ApiClient{{{modelNameSuffix}}}{{/apiClientName}}.getAuthentication('{{{name}}}').apiKeyPrefix = 'Bearer'; {{/isApiKey}} {{#isOAuth}} // TODO Configure OAuth2 access token for authorization: {{{name}}} -//defaultApiClient.getAuthentication('{{{name}}}').accessToken = 'YOUR_ACCESS_TOKEN'; +//default{{#apiClientName}}{{.}}{{/apiClientName}}{{^apiClientName}}{{{modelNamePrefix}}}ApiClient{{{modelNameSuffix}}}{{/apiClientName}}.getAuthentication('{{{name}}}').accessToken = 'YOUR_ACCESS_TOKEN'; {{/isOAuth}} {{/authMethods}} {{/hasAuthMethods}} diff --git a/modules/openapi-generator/src/main/resources/dart2/api.mustache b/modules/openapi-generator/src/main/resources/dart2/api.mustache index e40ebac39408..8656016497eb 100644 --- a/modules/openapi-generator/src/main/resources/dart2/api.mustache +++ b/modules/openapi-generator/src/main/resources/dart2/api.mustache @@ -3,9 +3,9 @@ {{#operations}} class {{{classname}}} { - {{{classname}}}([ApiClient? apiClient]) : apiClient = apiClient ?? defaultApiClient; + {{{classname}}}([{{#apiClientName}}{{.}}{{/apiClientName}}{{^apiClientName}}{{{modelNamePrefix}}}ApiClient{{{modelNameSuffix}}}{{/apiClientName}}? apiClient]) : apiClient = apiClient ?? default{{#apiClientName}}{{.}}{{/apiClientName}}{{^apiClientName}}{{{modelNamePrefix}}}ApiClient{{{modelNameSuffix}}}{{/apiClientName}}; - final ApiClient apiClient; + final {{#apiClientName}}{{.}}{{/apiClientName}}{{^apiClientName}}{{{modelNamePrefix}}}ApiClient{{{modelNameSuffix}}}{{/apiClientName}} apiClient; {{#operation}} {{#summary}} @@ -57,7 +57,7 @@ class {{{classname}}} { // ignore: prefer_final_locals Object? postBody{{#bodyParam}} = {{{paramName}}}{{/bodyParam}}; - final queryParams = []; + final queryParams = <{{{modelNamePrefix}}}QueryParam{{{modelNameSuffix}}}>[]; final headerParams = {}; final formParams = {}; {{#hasQueryParams}} @@ -164,7 +164,7 @@ class {{{classname}}} { Future<{{#returnType}}{{{.}}}?{{/returnType}}{{^returnType}}void{{/returnType}}> {{{nickname}}}({{#allParams}}{{#required}}{{{dataType}}} {{{paramName}}},{{^-last}} {{/-last}}{{/required}}{{/allParams}}{{#hasOptionalParams}}{ {{#allParams}}{{^required}}{{{dataType}}}? {{{paramName}}},{{^-last}} {{/-last}}{{/required}}{{/allParams}} }{{/hasOptionalParams}}) async { final response = await {{{nickname}}}WithHttpInfo({{#allParams}}{{#required}}{{{paramName}}},{{^-last}} {{/-last}}{{/required}}{{/allParams}}{{#hasOptionalParams}} {{#allParams}}{{^required}}{{{paramName}}}: {{{paramName}}},{{^-last}} {{/-last}}{{/required}}{{/allParams}} {{/hasOptionalParams}}); if (response.statusCode >= HttpStatus.badRequest) { - throw ApiException(response.statusCode, await _decodeBodyBytes(response)); + throw {{{modelNamePrefix}}}ApiException{{{modelNameSuffix}}}(response.statusCode, await _decodeBodyBytes(response)); } {{#returnType}} // When a remote server returns no body with a status of 204, we shall not decode it. @@ -175,7 +175,7 @@ class {{{classname}}} { {{#isArray}} final responseBody = await _decodeBodyBytes(response); return (await apiClient.deserializeAsync(responseBody, '{{{returnType}}}') as List) - .cast<{{{returnBaseType}}}>() + .cast<{{{returnInnerType}}}>() .{{#uniqueItems}}toSet(){{/uniqueItems}}{{^uniqueItems}}toList(){{/uniqueItems}}; {{/isArray}} {{^isArray}} diff --git a/modules/openapi-generator/src/main/resources/dart2/api_client.mustache b/modules/openapi-generator/src/main/resources/dart2/api_client.mustache index d8db09013b90..685215a48dd7 100644 --- a/modules/openapi-generator/src/main/resources/dart2/api_client.mustache +++ b/modules/openapi-generator/src/main/resources/dart2/api_client.mustache @@ -1,7 +1,7 @@ {{>header}} {{>part_of}} -class ApiClient { - ApiClient({this.basePath = '{{{basePath}}}', this.authentication}); +class {{#apiClientName}}{{.}}{{/apiClientName}}{{^apiClientName}}{{{modelNamePrefix}}}ApiClient{{{modelNameSuffix}}}{{/apiClientName}} { + {{#apiClientName}}{{.}}{{/apiClientName}}{{^apiClientName}}{{{modelNamePrefix}}}ApiClient{{{modelNameSuffix}}}{{/apiClientName}}({this.basePath = '{{{basePath}}}', this.authentication}); final String basePath; @@ -31,7 +31,7 @@ class ApiClient { Future invokeAPI( String path, String method, - List queryParams, + List<{{{modelNamePrefix}}}QueryParam{{{modelNameSuffix}}}> queryParams, Object? body, Map headerParams, Map formParams, @@ -44,8 +44,8 @@ class ApiClient { headerParams['Content-Type'] = contentType; } - final urlEncodedQueryParams = queryParams.map((param) => '$param'); - final queryString = urlEncodedQueryParams.isNotEmpty ? '?${urlEncodedQueryParams.join('&')}' : ''; + final urlEncoded{{{modelNamePrefix}}}QueryParam{{{modelNameSuffix}}}s = queryParams.map((param) => '$param'); + final queryString = urlEncoded{{{modelNamePrefix}}}QueryParam{{{modelNameSuffix}}}s.isNotEmpty ? '?${urlEncoded{{{modelNamePrefix}}}QueryParam{{{modelNameSuffix}}}s.join('&')}' : ''; final uri = Uri.parse('$basePath$path$queryString'); try { @@ -92,35 +92,35 @@ class ApiClient { case 'GET': return await _client.get(uri, headers: nullableHeaderParams,); } } on SocketException catch (error, trace) { - throw ApiException.withInner( + throw {{{modelNamePrefix}}}ApiException{{{modelNameSuffix}}}.withInner( HttpStatus.badRequest, 'Socket operation failed: $method $path', error, trace, ); } on TlsException catch (error, trace) { - throw ApiException.withInner( + throw {{{modelNamePrefix}}}ApiException{{{modelNameSuffix}}}.withInner( HttpStatus.badRequest, 'TLS/SSL communication failed: $method $path', error, trace, ); } on IOException catch (error, trace) { - throw ApiException.withInner( + throw {{{modelNamePrefix}}}ApiException{{{modelNameSuffix}}}.withInner( HttpStatus.badRequest, 'I/O operation failed: $method $path', error, trace, ); } on ClientException catch (error, trace) { - throw ApiException.withInner( + throw {{{modelNamePrefix}}}ApiException{{{modelNameSuffix}}}.withInner( HttpStatus.badRequest, 'HTTP connection failed: $method $path', error, trace, ); } on Exception catch (error, trace) { - throw ApiException.withInner( + throw {{{modelNamePrefix}}}ApiException{{{modelNameSuffix}}}.withInner( HttpStatus.badRequest, 'Exception occurred: $method $path', error, @@ -128,7 +128,7 @@ class ApiClient { ); } - throw ApiException( + throw {{{modelNamePrefix}}}ApiException{{{modelNameSuffix}}}( HttpStatus.badRequest, 'Invalid HTTP operation: $method $path', ); @@ -159,7 +159,7 @@ class ApiClient { /// Update query and header parameters based on authentication settings. void _updateParamsForAuth( - List queryParams, + List<{{{modelNamePrefix}}}QueryParam{{{modelNameSuffix}}}> queryParams, Map headerParams, ) { if (authentication != null) { @@ -216,9 +216,9 @@ class ApiClient { } } } on Exception catch (error, trace) { - throw ApiException.withInner(HttpStatus.internalServerError, 'Exception during deserialization.', error, trace,); + throw {{{modelNamePrefix}}}ApiException{{{modelNameSuffix}}}.withInner(HttpStatus.internalServerError, 'Exception during deserialization.', error, trace,); } - throw ApiException(HttpStatus.internalServerError, 'Could not find a suitable class for deserialization',); + throw {{{modelNamePrefix}}}ApiException{{{modelNameSuffix}}}(HttpStatus.internalServerError, 'Could not find a suitable class for deserialization',); } {{/native_serialization}} } @@ -250,7 +250,7 @@ Future deserializeAsync(DeserializationMessage message) async { // If the expected target type is String, nothing to do... return targetType == 'String' ? message.json - : ApiClient._deserialize( + : {{#apiClientName}}{{.}}{{/apiClientName}}{{^apiClientName}}{{{modelNamePrefix}}}ApiClient{{{modelNameSuffix}}}{{/apiClientName}}._deserialize( jsonDecode(message.json), targetType, growable: message.growable, diff --git a/modules/openapi-generator/src/main/resources/dart2/api_doc.mustache b/modules/openapi-generator/src/main/resources/dart2/api_doc.mustache index 3332ff1f205d..50c589b1bc30 100644 --- a/modules/openapi-generator/src/main/resources/dart2/api_doc.mustache +++ b/modules/openapi-generator/src/main/resources/dart2/api_doc.mustache @@ -30,27 +30,27 @@ import 'package:{{{pubName}}}/api.dart'; {{#isBasic}} {{#isBasicBasic}} // TODO Configure HTTP basic authorization: {{{name}}} -//defaultApiClient.getAuthentication('{{{name}}}').username = 'YOUR_USERNAME' -//defaultApiClient.getAuthentication('{{{name}}}').password = 'YOUR_PASSWORD'; +//default{{#apiClientName}}{{.}}{{/apiClientName}}{{^apiClientName}}{{{modelNamePrefix}}}ApiClient{{{modelNameSuffix}}}{{/apiClientName}}.getAuthentication('{{{name}}}').username = 'YOUR_USERNAME' +//default{{#apiClientName}}{{.}}{{/apiClientName}}{{^apiClientName}}{{{modelNamePrefix}}}ApiClient{{{modelNameSuffix}}}{{/apiClientName}}.getAuthentication('{{{name}}}').password = 'YOUR_PASSWORD'; {{/isBasicBasic}} {{#isBasicBearer}} // TODO Configure HTTP Bearer authorization: {{{name}}} // Case 1. Use String Token -//defaultApiClient.getAuthentication('{{{name}}}').setAccessToken('YOUR_ACCESS_TOKEN'); +//default{{#apiClientName}}{{.}}{{/apiClientName}}{{^apiClientName}}{{{modelNamePrefix}}}ApiClient{{{modelNameSuffix}}}{{/apiClientName}}.getAuthentication('{{{name}}}').setAccessToken('YOUR_ACCESS_TOKEN'); // Case 2. Use Function which generate token. // String yourTokenGeneratorFunction() { ... } -//defaultApiClient.getAuthentication('{{{name}}}').setAccessToken(yourTokenGeneratorFunction); +//default{{#apiClientName}}{{.}}{{/apiClientName}}{{^apiClientName}}{{{modelNamePrefix}}}ApiClient{{{modelNameSuffix}}}{{/apiClientName}}.getAuthentication('{{{name}}}').setAccessToken(yourTokenGeneratorFunction); {{/isBasicBearer}} {{/isBasic}} {{#isApiKey}} // TODO Configure API key authorization: {{{name}}} -//defaultApiClient.getAuthentication('{{{name}}}').apiKey = 'YOUR_API_KEY'; +//default{{#apiClientName}}{{.}}{{/apiClientName}}{{^apiClientName}}{{{modelNamePrefix}}}ApiClient{{{modelNameSuffix}}}{{/apiClientName}}.getAuthentication('{{{name}}}').apiKey = 'YOUR_API_KEY'; // uncomment below to setup prefix (e.g. Bearer) for API key, if needed -//defaultApiClient.getAuthentication('{{{name}}}').apiKeyPrefix = 'Bearer'; +//default{{#apiClientName}}{{.}}{{/apiClientName}}{{^apiClientName}}{{{modelNamePrefix}}}ApiClient{{{modelNameSuffix}}}{{/apiClientName}}.getAuthentication('{{{name}}}').apiKeyPrefix = 'Bearer'; {{/isApiKey}} {{#isOAuth}} // TODO Configure OAuth2 access token for authorization: {{{name}}} -//defaultApiClient.getAuthentication('{{{name}}}').accessToken = 'YOUR_ACCESS_TOKEN'; +//default{{#apiClientName}}{{.}}{{/apiClientName}}{{^apiClientName}}{{{modelNamePrefix}}}ApiClient{{{modelNameSuffix}}}{{/apiClientName}}.getAuthentication('{{{name}}}').accessToken = 'YOUR_ACCESS_TOKEN'; {{/isOAuth}} {{/authMethods}} {{/hasAuthMethods}} diff --git a/modules/openapi-generator/src/main/resources/dart2/api_exception.mustache b/modules/openapi-generator/src/main/resources/dart2/api_exception.mustache index aeb7aa9ce226..445dcc89b535 100644 --- a/modules/openapi-generator/src/main/resources/dart2/api_exception.mustache +++ b/modules/openapi-generator/src/main/resources/dart2/api_exception.mustache @@ -1,9 +1,9 @@ {{>header}} {{>part_of}} -class ApiException implements Exception { - ApiException(this.code, this.message); +class {{{modelNamePrefix}}}ApiException{{{modelNameSuffix}}} implements Exception { + {{{modelNamePrefix}}}ApiException{{{modelNameSuffix}}}(this.code, this.message); - ApiException.withInner(this.code, this.message, this.innerException, this.stackTrace); + {{{modelNamePrefix}}}ApiException{{{modelNameSuffix}}}.withInner(this.code, this.message, this.innerException, this.stackTrace); int code = 0; String? message; @@ -13,11 +13,11 @@ class ApiException implements Exception { @override String toString() { if (message == null) { - return 'ApiException'; + return '{{{modelNamePrefix}}}ApiException{{{modelNameSuffix}}}'; } if (innerException == null) { - return 'ApiException $code: $message'; + return '{{{modelNamePrefix}}}ApiException{{{modelNameSuffix}}} $code: $message'; } - return 'ApiException $code: $message (Inner exception: $innerException)\n\n$stackTrace'; + return '{{{modelNamePrefix}}}ApiException{{{modelNameSuffix}}} $code: $message (Inner exception: $innerException)\n\n$stackTrace'; } } diff --git a/modules/openapi-generator/src/main/resources/dart2/api_helper.mustache b/modules/openapi-generator/src/main/resources/dart2/api_helper.mustache index ec98b7d1d741..df3080bf2771 100644 --- a/modules/openapi-generator/src/main/resources/dart2/api_helper.mustache +++ b/modules/openapi-generator/src/main/resources/dart2/api_helper.mustache @@ -1,7 +1,7 @@ {{>header}} {{>part_of}} -class QueryParam { - const QueryParam(this.name, this.value); +class {{{modelNamePrefix}}}QueryParam{{{modelNameSuffix}}} { + const {{{modelNamePrefix}}}QueryParam{{{modelNameSuffix}}}(this.name, this.value); final String name; final String value; @@ -11,15 +11,15 @@ class QueryParam { } // Ported from the Java version. -Iterable _queryParams(String collectionFormat, String name, dynamic value,) { +Iterable<{{{modelNamePrefix}}}QueryParam{{{modelNameSuffix}}}> _queryParams(String collectionFormat, String name, dynamic value,) { // Assertions to run in debug mode only. assert(name.isNotEmpty, 'Parameter cannot be an empty string.'); - final params = []; + final params = <{{{modelNamePrefix}}}QueryParam{{{modelNameSuffix}}}>[]; if (value is List) { if (collectionFormat == 'multi') { - return value.map((dynamic v) => QueryParam(name, parameterToString(v)),); + return value.map((dynamic v) => {{{modelNamePrefix}}}QueryParam{{{modelNameSuffix}}}(name, parameterToString(v)),); } // Default collection format is 'csv'. @@ -29,9 +29,9 @@ Iterable _queryParams(String collectionFormat, String name, dynamic final delimiter = _delimiters[collectionFormat] ?? ','; - params.add(QueryParam(name, value.map(parameterToString).join(delimiter),)); + params.add({{{modelNamePrefix}}}QueryParam{{{modelNameSuffix}}}(name, value.map(parameterToString).join(delimiter),)); } else if (value != null) { - params.add(QueryParam(name, parameterToString(value))); + params.add({{{modelNamePrefix}}}QueryParam{{{modelNameSuffix}}}(name, parameterToString(value))); } return params; diff --git a/modules/openapi-generator/src/main/resources/dart2/apilib.mustache b/modules/openapi-generator/src/main/resources/dart2/apilib.mustache index 2fcebda4ea46..524607f96980 100644 --- a/modules/openapi-generator/src/main/resources/dart2/apilib.mustache +++ b/modules/openapi-generator/src/main/resources/dart2/apilib.mustache @@ -30,4 +30,4 @@ final _regList = RegExp(r'^List<(.*)>$'); final _regSet = RegExp(r'^Set<(.*)>$'); final _regMap = RegExp(r'^Map$'); -ApiClient defaultApiClient = ApiClient(); +{{#apiClientName}}{{.}}{{/apiClientName}}{{^apiClientName}}{{{modelNamePrefix}}}ApiClient{{{modelNameSuffix}}}{{/apiClientName}} default{{#apiClientName}}{{.}}{{/apiClientName}}{{^apiClientName}}{{{modelNamePrefix}}}ApiClient{{{modelNameSuffix}}}{{/apiClientName}} = {{#apiClientName}}{{.}}{{/apiClientName}}{{^apiClientName}}{{{modelNamePrefix}}}ApiClient{{{modelNameSuffix}}}{{/apiClientName}}(); diff --git a/modules/openapi-generator/src/main/resources/dart2/auth/api_key_auth.mustache b/modules/openapi-generator/src/main/resources/dart2/auth/api_key_auth.mustache index b4f5a4587246..3edecb1246db 100644 --- a/modules/openapi-generator/src/main/resources/dart2/auth/api_key_auth.mustache +++ b/modules/openapi-generator/src/main/resources/dart2/auth/api_key_auth.mustache @@ -10,12 +10,12 @@ class ApiKeyAuth implements Authentication { String apiKey = ''; @override - void applyToParams(List queryParams, Map headerParams) { + void applyToParams(List<{{{modelNamePrefix}}}QueryParam{{{modelNameSuffix}}}> queryParams, Map headerParams) { final paramValue = apiKeyPrefix.isEmpty ? apiKey : '$apiKeyPrefix $apiKey'; if (paramValue.isNotEmpty) { if (location == 'query') { - queryParams.add(QueryParam(paramName, paramValue)); + queryParams.add({{{modelNamePrefix}}}QueryParam{{{modelNameSuffix}}}(paramName, paramValue)); } else if (location == 'header') { headerParams[paramName] = paramValue; } else if (location == 'cookie') { diff --git a/modules/openapi-generator/src/main/resources/dart2/auth/authentication.mustache b/modules/openapi-generator/src/main/resources/dart2/auth/authentication.mustache index e8aaaa4d5411..807abc505a83 100644 --- a/modules/openapi-generator/src/main/resources/dart2/auth/authentication.mustache +++ b/modules/openapi-generator/src/main/resources/dart2/auth/authentication.mustache @@ -3,5 +3,5 @@ // ignore: one_member_abstracts abstract class Authentication { /// Apply authentication settings to header and query params. - void applyToParams(List queryParams, Map headerParams); + void applyToParams(List<{{{modelNamePrefix}}}QueryParam{{{modelNameSuffix}}}> queryParams, Map headerParams); } diff --git a/modules/openapi-generator/src/main/resources/dart2/auth/http_basic_auth.mustache b/modules/openapi-generator/src/main/resources/dart2/auth/http_basic_auth.mustache index 544219733921..d2818027a3cc 100644 --- a/modules/openapi-generator/src/main/resources/dart2/auth/http_basic_auth.mustache +++ b/modules/openapi-generator/src/main/resources/dart2/auth/http_basic_auth.mustache @@ -7,7 +7,7 @@ class HttpBasicAuth implements Authentication { String password; @override - void applyToParams(List queryParams, Map headerParams) { + void applyToParams(List<{{{modelNamePrefix}}}QueryParam{{{modelNameSuffix}}}> queryParams, Map headerParams) { if (username.isNotEmpty && password.isNotEmpty) { final credentials = '$username:$password'; headerParams['Authorization'] = 'Basic ${base64.encode(utf8.encode(credentials))}'; diff --git a/modules/openapi-generator/src/main/resources/dart2/auth/http_bearer_auth.mustache b/modules/openapi-generator/src/main/resources/dart2/auth/http_bearer_auth.mustache index 7c480c5e81d3..4fa3ebba1699 100644 --- a/modules/openapi-generator/src/main/resources/dart2/auth/http_bearer_auth.mustache +++ b/modules/openapi-generator/src/main/resources/dart2/auth/http_bearer_auth.mustache @@ -17,7 +17,7 @@ class HttpBearerAuth implements Authentication { } @override - void applyToParams(List queryParams, Map headerParams) { + void applyToParams(List<{{{modelNamePrefix}}}QueryParam{{{modelNameSuffix}}}> queryParams, Map headerParams) { if (_accessToken == null) { return; } diff --git a/modules/openapi-generator/src/main/resources/dart2/auth/oauth.mustache b/modules/openapi-generator/src/main/resources/dart2/auth/oauth.mustache index c5c64d522184..4ebde3d3a133 100644 --- a/modules/openapi-generator/src/main/resources/dart2/auth/oauth.mustache +++ b/modules/openapi-generator/src/main/resources/dart2/auth/oauth.mustache @@ -6,7 +6,7 @@ class OAuth implements Authentication { String accessToken; @override - void applyToParams(List queryParams, Map headerParams) { + void applyToParams(List<{{{modelNamePrefix}}}QueryParam{{{modelNameSuffix}}}> queryParams, Map headerParams) { if (accessToken.isNotEmpty) { headerParams['Authorization'] = 'Bearer $accessToken'; } diff --git a/modules/openapi-generator/src/main/resources/dart2/git_push.sh.mustache b/modules/openapi-generator/src/main/resources/dart2/git_push.sh.mustache old mode 100755 new mode 100644 From 57a5a27f7f40e520461b62594fad86b7de0982dc Mon Sep 17 00:00:00 2001 From: Jeff Mikels Date: Sat, 11 Jun 2022 17:26:54 -0400 Subject: [PATCH 4/6] added returnInnerType for container types, made Dart generator recognize modelNamePrefix and Suffix, added apiClientName option to dart --- docs/generators/dart-dio.md | 1 + docs/generators/dart.md | 1 + .../codegen/dart/DartModelTest.java | 7 ++++-- .../doc/NullableClass.md | 12 +++++----- .../lib/src/model/nullable_class.dart | 12 +++++----- .../doc/NullableClass.md | 12 +++++----- .../lib/model/nullable_class.dart | 24 +++++++++---------- 7 files changed, 37 insertions(+), 32 deletions(-) diff --git a/docs/generators/dart-dio.md b/docs/generators/dart-dio.md index eee69cd87eae..bbe5289102ea 100644 --- a/docs/generators/dart-dio.md +++ b/docs/generators/dart-dio.md @@ -19,6 +19,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl | Option | Description | Values | Default | | ------ | ----------- | ------ | ------- | |allowUnicodeIdentifiers|boolean, toggles whether unicode identifiers are allowed in names or not, default is false| |false| +|apiClientName|Specify the api client class name, defaults to 'ApiClient'| |ApiClient| |dateLibrary|Specify Date library|
**core**
[DEFAULT] Dart core library (DateTime)
**timemachine**
Time Machine is date and time library for Flutter, Web, and Server with support for timezones, calendars, cultures, formatting and parsing.
|core| |disallowAdditionalPropertiesIfNotPresent|If false, the 'additionalProperties' implementation (set to true by default) is compliant with the OAS and JSON schema specifications. If true (default), keep the old (incorrect) behaviour that 'additionalProperties' is set to false by default.|
**false**
The 'additionalProperties' implementation is compliant with the OAS and JSON schema specifications.
**true**
Keep the old (incorrect) behaviour that 'additionalProperties' is set to false by default.
|true| |ensureUniqueParams|Whether to ensure parameter names are unique in an operation (rename parameters that are not).| |true| diff --git a/docs/generators/dart.md b/docs/generators/dart.md index cbc19071638a..14276964abe9 100644 --- a/docs/generators/dart.md +++ b/docs/generators/dart.md @@ -19,6 +19,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl | Option | Description | Values | Default | | ------ | ----------- | ------ | ------- | |allowUnicodeIdentifiers|boolean, toggles whether unicode identifiers are allowed in names or not, default is false| |false| +|apiClientName|Specify the api client class name, defaults to 'ApiClient'| |ApiClient| |disallowAdditionalPropertiesIfNotPresent|If false, the 'additionalProperties' implementation (set to true by default) is compliant with the OAS and JSON schema specifications. If true (default), keep the old (incorrect) behaviour that 'additionalProperties' is set to false by default.|
**false**
The 'additionalProperties' implementation is compliant with the OAS and JSON schema specifications.
**true**
Keep the old (incorrect) behaviour that 'additionalProperties' is set to false by default.
|true| |ensureUniqueParams|Whether to ensure parameter names are unique in an operation (rename parameters that are not).| |true| |enumUnknownDefaultCase|If the server adds new enum cases, that are unknown by an old spec/client, the client will fail to parse the network response.With this option enabled, each enum will have a new case, 'unknown_default_open_api', so that when the server sends an enum case that is not known by the client/spec, they can safely fallback to this case.|
**false**
No changes to the enum's are made, this is the default option.
**true**
With this option enabled, each enum will have a new case, 'unknown_default_open_api', so that when the enum case sent by the server is not known by the client/spec, can safely be decoded to this case.
|false| diff --git a/modules/openapi-generator/src/test/java/org/openapitools/codegen/dart/DartModelTest.java b/modules/openapi-generator/src/test/java/org/openapitools/codegen/dart/DartModelTest.java index 03848b4f802b..50e61649a953 100644 --- a/modules/openapi-generator/src/test/java/org/openapitools/codegen/dart/DartModelTest.java +++ b/modules/openapi-generator/src/test/java/org/openapitools/codegen/dart/DartModelTest.java @@ -33,7 +33,7 @@ @SuppressWarnings("static-method") public class DartModelTest { - @Test(description = "convert a simple php model") + @Test(description = "convert a simple dart model") public void simpleModelTest() { final Schema model = new Schema() .description("a sample model") @@ -46,12 +46,15 @@ public void simpleModelTest() { .addRequiredItem("id") .addRequiredItem("name"); final DefaultCodegen codegen = new DartClientCodegen(); + codegen.setModelNamePrefix("Prefix"); + codegen.setModelNameSuffix("Suffix"); + OpenAPI openAPI = TestUtils.createOpenAPIWithOneSchema("sample", model); codegen.setOpenAPI(openAPI); final CodegenModel cm = codegen.fromModel("sample", model); Assert.assertEquals(cm.name, "sample"); - Assert.assertEquals(cm.classname, "Sample"); + Assert.assertEquals(cm.classname, "PrefixSampleSuffix"); Assert.assertEquals(cm.description, "a sample model"); Assert.assertEquals(cm.vars.size(), 6); diff --git a/samples/openapi3/client/petstore/dart-dio/petstore_client_lib_fake-json_serializable/doc/NullableClass.md b/samples/openapi3/client/petstore/dart-dio/petstore_client_lib_fake-json_serializable/doc/NullableClass.md index 70ac1091d417..31bca081ade2 100644 --- a/samples/openapi3/client/petstore/dart-dio/petstore_client_lib_fake-json_serializable/doc/NullableClass.md +++ b/samples/openapi3/client/petstore/dart-dio/petstore_client_lib_fake-json_serializable/doc/NullableClass.md @@ -14,12 +14,12 @@ Name | Type | Description | Notes **stringProp** | **String** | | [optional] **dateProp** | [**DateTime**](DateTime.md) | | [optional] **datetimeProp** | [**DateTime**](DateTime.md) | | [optional] -**arrayNullableProp** | **List<Object>** | | [optional] -**arrayAndItemsNullableProp** | **List<Object>** | | [optional] -**arrayItemsNullable** | **List<Object>** | | [optional] -**objectNullableProp** | **Map<String, Object>** | | [optional] -**objectAndItemsNullableProp** | **Map<String, Object>** | | [optional] -**objectItemsNullable** | **Map<String, Object>** | | [optional] +**arrayNullableProp** | [**List<Map>**](Map.md) | | [optional] +**arrayAndItemsNullableProp** | [**List<Map>**](Map.md) | | [optional] +**arrayItemsNullable** | [**List<Map>**](Map.md) | | [optional] +**objectNullableProp** | [**Map<String, Map>**](Map.md) | | [optional] +**objectAndItemsNullableProp** | [**Map<String, Map>**](Map.md) | | [optional] +**objectItemsNullable** | [**Map<String, Map>**](Map.md) | | [optional] [[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) diff --git a/samples/openapi3/client/petstore/dart-dio/petstore_client_lib_fake-json_serializable/lib/src/model/nullable_class.dart b/samples/openapi3/client/petstore/dart-dio/petstore_client_lib_fake-json_serializable/lib/src/model/nullable_class.dart index 3816bb33839e..307479401847 100644 --- a/samples/openapi3/client/petstore/dart-dio/petstore_client_lib_fake-json_serializable/lib/src/model/nullable_class.dart +++ b/samples/openapi3/client/petstore/dart-dio/petstore_client_lib_fake-json_serializable/lib/src/model/nullable_class.dart @@ -122,7 +122,7 @@ class NullableClass { ) - final List? arrayNullableProp; + final List? arrayNullableProp; @@ -134,7 +134,7 @@ class NullableClass { ) - final List? arrayAndItemsNullableProp; + final List? arrayAndItemsNullableProp; @@ -146,7 +146,7 @@ class NullableClass { ) - final List? arrayItemsNullable; + final List? arrayItemsNullable; @@ -158,7 +158,7 @@ class NullableClass { ) - final Map? objectNullableProp; + final Map? objectNullableProp; @@ -170,7 +170,7 @@ class NullableClass { ) - final Map? objectAndItemsNullableProp; + final Map? objectAndItemsNullableProp; @@ -182,7 +182,7 @@ class NullableClass { ) - final Map? objectItemsNullable; + final Map? objectItemsNullable; diff --git a/samples/openapi3/client/petstore/dart2/petstore_client_lib_fake/doc/NullableClass.md b/samples/openapi3/client/petstore/dart2/petstore_client_lib_fake/doc/NullableClass.md index 9b2e46df0a09..c190f0ab458f 100644 --- a/samples/openapi3/client/petstore/dart2/petstore_client_lib_fake/doc/NullableClass.md +++ b/samples/openapi3/client/petstore/dart2/petstore_client_lib_fake/doc/NullableClass.md @@ -14,12 +14,12 @@ Name | Type | Description | Notes **stringProp** | **String** | | [optional] **dateProp** | [**DateTime**](DateTime.md) | | [optional] **datetimeProp** | [**DateTime**](DateTime.md) | | [optional] -**arrayNullableProp** | [**List**](Object.md) | | [optional] [default to const []] -**arrayAndItemsNullableProp** | [**List**](Object.md) | | [optional] [default to const []] -**arrayItemsNullable** | [**List**](Object.md) | | [optional] [default to const []] -**objectNullableProp** | [**Map**](Object.md) | | [optional] [default to const {}] -**objectAndItemsNullableProp** | [**Map**](Object.md) | | [optional] [default to const {}] -**objectItemsNullable** | [**Map**](Object.md) | | [optional] [default to const {}] +**arrayNullableProp** | [**List**](Map.md) | | [optional] [default to const []] +**arrayAndItemsNullableProp** | [**List**](Map.md) | | [optional] [default to const []] +**arrayItemsNullable** | [**List**](Map.md) | | [optional] [default to const []] +**objectNullableProp** | [**Map**](Map.md) | | [optional] [default to const {}] +**objectAndItemsNullableProp** | [**Map**](Map.md) | | [optional] [default to const {}] +**objectItemsNullable** | [**Map**](Map.md) | | [optional] [default to const {}] [[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) diff --git a/samples/openapi3/client/petstore/dart2/petstore_client_lib_fake/lib/model/nullable_class.dart b/samples/openapi3/client/petstore/dart2/petstore_client_lib_fake/lib/model/nullable_class.dart index b8a0878b3056..85bc0f870adc 100644 --- a/samples/openapi3/client/petstore/dart2/petstore_client_lib_fake/lib/model/nullable_class.dart +++ b/samples/openapi3/client/petstore/dart2/petstore_client_lib_fake/lib/model/nullable_class.dart @@ -39,17 +39,17 @@ class NullableClass { DateTime? datetimeProp; - List? arrayNullableProp; + List? arrayNullableProp; - List? arrayAndItemsNullableProp; + List? arrayAndItemsNullableProp; - List arrayItemsNullable; + List arrayItemsNullable; - Map? objectNullableProp; + Map? objectNullableProp; - Map? objectAndItemsNullableProp; + Map? objectAndItemsNullableProp; - Map objectItemsNullable; + Map objectItemsNullable; @override bool operator ==(Object other) => identical(this, other) || other is NullableClass && @@ -149,12 +149,12 @@ class NullableClass { stringProp: mapValueOfType(json, r'string_prop'), dateProp: mapDateTime(json, r'date_prop', ''), datetimeProp: mapDateTime(json, r'datetime_prop', ''), - arrayNullableProp: Object.listFromJson(json[r'array_nullable_prop']) ?? const [], - arrayAndItemsNullableProp: Object.listFromJson(json[r'array_and_items_nullable_prop']) ?? const [], - arrayItemsNullable: Object.listFromJson(json[r'array_items_nullable']) ?? const [], - objectNullableProp: mapCastOfType(json, r'object_nullable_prop') ?? const {}, - objectAndItemsNullableProp: mapCastOfType(json, r'object_and_items_nullable_prop') ?? const {}, - objectItemsNullable: mapCastOfType(json, r'object_items_nullable') ?? const {}, + arrayNullableProp: Map.listFromJson(json[r'array_nullable_prop']) ?? const [], + arrayAndItemsNullableProp: Map.listFromJson(json[r'array_and_items_nullable_prop']) ?? const [], + arrayItemsNullable: Map.listFromJson(json[r'array_items_nullable']) ?? const [], + objectNullableProp: mapCastOfType(json, r'object_nullable_prop') ?? const {}, + objectAndItemsNullableProp: mapCastOfType(json, r'object_and_items_nullable_prop') ?? const {}, + objectItemsNullable: mapCastOfType(json, r'object_items_nullable') ?? const {}, ); } return null; From 3afd82a7b0202aca2eca27af4d718c6b3a90e07a Mon Sep 17 00:00:00 2001 From: Jeff Mikels Date: Mon, 13 Jun 2022 14:36:55 -0400 Subject: [PATCH 5/6] making sure modelNamePrefix is honored throughout the library --- .../dart-handlebars/README.handlebars | 144 +++++++++ .../analysis_options.handlebars | 0 .../resources/dart-handlebars/api.handlebars | 194 ++++++++++++ .../dart-handlebars/api_client.handlebars | 262 +++++++++++++++ .../dart-handlebars/api_doc.handlebars | 96 ++++++ .../dart-handlebars/api_exception.handlebars | 23 ++ .../dart-handlebars/api_helper.handlebars | 100 ++++++ .../dart-handlebars/api_test.handlebars | 29 ++ .../dart-handlebars/apilib.handlebars | 41 +++ .../auth/api_key_auth.handlebars | 30 ++ .../auth/authentication.handlebars | 7 + .../dart-handlebars/auth/header.handlebars | 9 + .../auth/http_basic_auth.handlebars | 16 + .../auth/http_bearer_auth.handlebars | 45 +++ .../dart-handlebars/auth/oauth.handlebars | 14 + .../dart-handlebars/auth/part_of.handlebars | 1 + .../dart_constructor.handlebars | 10 + .../dart-handlebars/git_push.sh.handlebars | 57 ++++ .../dart-handlebars/gitignore.handlebars | 17 + .../dart-handlebars/header.handlebars | 9 + .../dart-handlebars/model.handlebars | 16 + .../dart-handlebars/model_test.handlebars | 29 ++ .../dart-handlebars/object_doc.handlebars | 16 + .../dart-handlebars/part_of.handlebars | 1 + .../dart-handlebars/pubspec.handlebars | 19 ++ .../native/native_class.handlebars | 299 ++++++++++++++++++ .../native/native_enum.handlebars | 81 +++++ .../native/native_enum_inline.handlebars | 81 +++++ .../dart-handlebars/travis.handlebars | 14 + .../main/resources/dart2/api_client.mustache | 2 +- .../src/main/resources/dart2/apilib.mustache | 8 + .../dart2/auth/api_key_auth.mustache | 4 +- .../dart2/auth/authentication.mustache | 2 +- .../dart2/auth/http_basic_auth.mustache | 4 +- .../dart2/auth/http_bearer_auth.mustache | 16 +- .../main/resources/dart2/auth/oauth.mustache | 4 +- .../native/native_class.mustache | 4 +- 37 files changed, 1689 insertions(+), 15 deletions(-) create mode 100644 modules/openapi-generator/src/main/resources/dart-handlebars/README.handlebars create mode 100644 modules/openapi-generator/src/main/resources/dart-handlebars/analysis_options.handlebars create mode 100644 modules/openapi-generator/src/main/resources/dart-handlebars/api.handlebars create mode 100644 modules/openapi-generator/src/main/resources/dart-handlebars/api_client.handlebars create mode 100644 modules/openapi-generator/src/main/resources/dart-handlebars/api_doc.handlebars create mode 100644 modules/openapi-generator/src/main/resources/dart-handlebars/api_exception.handlebars create mode 100644 modules/openapi-generator/src/main/resources/dart-handlebars/api_helper.handlebars create mode 100644 modules/openapi-generator/src/main/resources/dart-handlebars/api_test.handlebars create mode 100644 modules/openapi-generator/src/main/resources/dart-handlebars/apilib.handlebars create mode 100644 modules/openapi-generator/src/main/resources/dart-handlebars/auth/api_key_auth.handlebars create mode 100644 modules/openapi-generator/src/main/resources/dart-handlebars/auth/authentication.handlebars create mode 100644 modules/openapi-generator/src/main/resources/dart-handlebars/auth/header.handlebars create mode 100644 modules/openapi-generator/src/main/resources/dart-handlebars/auth/http_basic_auth.handlebars create mode 100644 modules/openapi-generator/src/main/resources/dart-handlebars/auth/http_bearer_auth.handlebars create mode 100644 modules/openapi-generator/src/main/resources/dart-handlebars/auth/oauth.handlebars create mode 100644 modules/openapi-generator/src/main/resources/dart-handlebars/auth/part_of.handlebars create mode 100644 modules/openapi-generator/src/main/resources/dart-handlebars/dart_constructor.handlebars create mode 100644 modules/openapi-generator/src/main/resources/dart-handlebars/git_push.sh.handlebars create mode 100644 modules/openapi-generator/src/main/resources/dart-handlebars/gitignore.handlebars create mode 100644 modules/openapi-generator/src/main/resources/dart-handlebars/header.handlebars create mode 100644 modules/openapi-generator/src/main/resources/dart-handlebars/model.handlebars create mode 100644 modules/openapi-generator/src/main/resources/dart-handlebars/model_test.handlebars create mode 100644 modules/openapi-generator/src/main/resources/dart-handlebars/object_doc.handlebars create mode 100644 modules/openapi-generator/src/main/resources/dart-handlebars/part_of.handlebars create mode 100644 modules/openapi-generator/src/main/resources/dart-handlebars/pubspec.handlebars create mode 100644 modules/openapi-generator/src/main/resources/dart-handlebars/serialization/native/native_class.handlebars create mode 100644 modules/openapi-generator/src/main/resources/dart-handlebars/serialization/native/native_enum.handlebars create mode 100644 modules/openapi-generator/src/main/resources/dart-handlebars/serialization/native/native_enum_inline.handlebars create mode 100644 modules/openapi-generator/src/main/resources/dart-handlebars/travis.handlebars diff --git a/modules/openapi-generator/src/main/resources/dart-handlebars/README.handlebars b/modules/openapi-generator/src/main/resources/dart-handlebars/README.handlebars new file mode 100644 index 000000000000..447a09ec31c9 --- /dev/null +++ b/modules/openapi-generator/src/main/resources/dart-handlebars/README.handlebars @@ -0,0 +1,144 @@ +# {{{pubName}}} +{{#each appDescriptionWithNewLines}} +{{{.}}} +{{/each}} + +This Dart package is automatically generated by the [OpenAPI Generator](https://openapi-generator.tech) project: + +- API version: {{{appVersion}}} +{{#with artifactVersion}} +- Package version: {{{.}}} +{{/with}} +{{#unless hideGenerationTimestamp}} +- Build date: {{{generatedDate}}} +{{/unless}} +- Build package: {{{generatorClass}}} +{{#with infoUrl}} +For more information, please visit [{{{infoUrl}}}]({{{infoUrl}}}) +{{/with}} + +## Requirements + +Dart 2.12 or later + +## Installation & Usage + +### Github +If this Dart package is published to Github, add the following dependency to your pubspec.yaml +``` +dependencies: + {{{pubName}}}: + git: https://{{{gitHost}}}/{{{gitUserId}}}/{{{gitRepoId}}}.git +``` + +### Local +To use the package in your local drive, add the following dependency to your pubspec.yaml +``` +dependencies: + {{{pubName}}}: + path: /path/to/{{{pubName}}} +``` + +## Tests + +TODO + +## Getting Started + +Please follow the [installation procedure](#installation--usage) and then run the following: + +```dart +import 'package:{{{pubName}}}/api.dart'; +{{#with apiInfo}}{{#each apis}}{{#if @first}}{{#each operations}}{{#with operation}}{{#if @first}} +{{#if hasAuthMethods}} +{{#each authMethods}} +{{#if isBasic}} +{{#if isBasicBasic}} +// TODO Configure HTTP basic authorization: {{{name}}} +//default{{#with apiClientName}}{{.}}{{/with}}{{#unless apiClientName}}{{{modelNamePrefix}}}ApiClient{{{modelNameSuffix}}}{{/unless}}.getAuthentication('{{{name}}}').username = 'YOUR_USERNAME' +//default{{#with apiClientName}}{{.}}{{/with}}{{#unless apiClientName}}{{{modelNamePrefix}}}ApiClient{{{modelNameSuffix}}}{{/unless}}.getAuthentication('{{{name}}}').password = 'YOUR_PASSWORD'; +{{/if}} +{{#if isBasicBearer}} +// TODO Configure HTTP Bearer authorization: {{{name}}} +// Case 1. Use String Token +//default{{#with apiClientName}}{{.}}{{/with}}{{#unless apiClientName}}{{{modelNamePrefix}}}ApiClient{{{modelNameSuffix}}}{{/unless}}.getAuthentication('{{{name}}}').setAccessToken('YOUR_ACCESS_TOKEN'); +// Case 2. Use Function which generate token. +// String yourTokenGeneratorFunction() { ... } +//default{{#with apiClientName}}{{.}}{{/with}}{{#unless apiClientName}}{{{modelNamePrefix}}}ApiClient{{{modelNameSuffix}}}{{/unless}}.getAuthentication('{{{name}}}').setAccessToken(yourTokenGeneratorFunction); +{{/if}} +{{/if}} +{{#if isApiKey}} +// TODO Configure API key authorization: {{{name}}} +//default{{#with apiClientName}}{{.}}{{/with}}{{#unless apiClientName}}{{{modelNamePrefix}}}ApiClient{{{modelNameSuffix}}}{{/unless}}.getAuthentication('{{{name}}}').apiKey = 'YOUR_API_KEY'; +// uncomment below to setup prefix (e.g. Bearer) for API key, if needed +//default{{#with apiClientName}}{{.}}{{/with}}{{#unless apiClientName}}{{{modelNamePrefix}}}ApiClient{{{modelNameSuffix}}}{{/unless}}.getAuthentication('{{{name}}}').apiKeyPrefix = 'Bearer'; +{{/if}} +{{#if isOAuth}} +// TODO Configure OAuth2 access token for authorization: {{{name}}} +//default{{#with apiClientName}}{{.}}{{/with}}{{#unless apiClientName}}{{{modelNamePrefix}}}ApiClient{{{modelNameSuffix}}}{{/unless}}.getAuthentication('{{{name}}}').accessToken = 'YOUR_ACCESS_TOKEN'; +{{/if}} +{{/each}} +{{/if}} + +final api_instance = {{{classname}}}(); +{{#each allParams}} +final {{{paramName}}} = {{#if isArray}}[{{/if}}{{#if isBodyParam}}{{{dataType}}}(){{/if}}{{#unless isBodyParam}}{{{example}}}{{/unless}}{{#if isArray}}]{{/if}}; // {{{dataType}}} | {{{description}}} +{{/each}} + +try { + {{#with returnType}}final result = {{/with}}api_instance.{{{operationId}}}({{#each allParams}}{{{paramName}}}{{#unless @last}}, {{/unless}}{{/each}}); + {{#with returnType}} + print(result); + {{/with}} +} catch (e) { + print('Exception when calling {{{classname}}}->{{{operationId}}}: $e\n'); +} +{{/if}}{{/with}}{{/each}}{{/if}}{{/each}}{{/with}} +``` + +## Documentation for API Endpoints + +All URIs are relative to *{{{basePath}}}* + +Class | Method | HTTP request | Description +------------ | ------------- | ------------- | ------------- +{{#with apiInfo}}{{#each apis}}{{#each operations}}{{#with operation}}*{{{classname}}}* | [**{{{operationId}}}**]({{{apiDocPath}}}/{{{classname}}}.md#{{{operationIdLowerCase}}}) | **{{{httpMethod}}}** {{{path}}} | {{{summary}}} +{{/with}}{{/each}}{{/each}}{{/with}} + +## Documentation For Models + +{{#each models}}{{#with model}} - [{{{classname}}}]({{{modelDocPath}}}/{{{classname}}}.md) +{{/with}}{{/each}} + +## Documentation For Authorization + +{{#unless authMethods}} All endpoints do not require authorization. +{{/unless}}{{#each authMethods}}{{#with last}} Authentication schemes defined for the API:{{/with}}{{/each}} +{{#each authMethods}}## {{{name}}} + +{{#if isApiKey}}- **Type**: API key +- **API key parameter name**: {{{keyParamName}}} +- **Location**: {{#if isKeyInQuery}}URL query string{{/if}}{{#if isKeyInHeader}}HTTP header{{/if}} +{{/if}} +{{#if isBasic}} +{{#if isBasicBasic}} +- **Type**: HTTP Basic authentication +{{/if}} +{{#if isBasicBearer}} +- **Type**: HTTP Bearer authentication +{{/if}} +{{/if}} +{{#if isOAuth}}- **Type**: OAuth +- **Flow**: {{{flow}}} +- **Authorization URL**: {{{authorizationUrl}}} +- **Scopes**: {{#unless scopes}}N/A{{/unless}} +{{#each scopes}} - **{{{scope}}}**: {{{description}}} +{{/each}} +{{/if}} + +{{/each}} + +## Author + +{{#with apiInfo}}{{#each apis}}{{#if @last}}{{{infoEmail}}} +{{/if}}{{/each}}{{/with}} diff --git a/modules/openapi-generator/src/main/resources/dart-handlebars/analysis_options.handlebars b/modules/openapi-generator/src/main/resources/dart-handlebars/analysis_options.handlebars new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/modules/openapi-generator/src/main/resources/dart-handlebars/api.handlebars b/modules/openapi-generator/src/main/resources/dart-handlebars/api.handlebars new file mode 100644 index 000000000000..0118205b2372 --- /dev/null +++ b/modules/openapi-generator/src/main/resources/dart-handlebars/api.handlebars @@ -0,0 +1,194 @@ +{{>header}} +{{>part_of}} +{{#each operations}} + +class {{{classname}}} { + {{{classname}}}([{{#with apiClientName}}{{.}}{{/with}}{{#unless apiClientName}}{{{modelNamePrefix}}}ApiClient{{{modelNameSuffix}}}{{/unless}}? apiClient]) : apiClient = apiClient ?? default{{#with apiClientName}}{{.}}{{/with}}{{#unless apiClientName}}{{{modelNamePrefix}}}ApiClient{{{modelNameSuffix}}}{{/unless}}; + + final {{#with apiClientName}}{{.}}{{/with}}{{#unless apiClientName}}{{{modelNamePrefix}}}ApiClient{{{modelNameSuffix}}}{{/unless}} apiClient; + {{#with operation}} + + {{#with summary}} + /// {{{.}}} + {{/with}} + {{#each notes}} + {{#with summary}} + /// + {{/with}} + /// {{{notes}}} + /// + /// Note: This method returns the HTTP [Response]. + {{/each}} + {{#unless notes}} + {{#with summary}} + /// + /// Note: This method returns the HTTP [Response]. + {{/with}} + {{#unless summary}} + /// Performs an HTTP '{{{httpMethod}}} {{{path}}}' operation and returns the [Response]. + {{/unless}} + {{/unless}} + {{#if hasParams}} + {{#with summary}} + /// + {{/with}} + {{#unless summary}} + {{#each notes}} + /// + {{/each}} + {{/unless}} + /// Parameters: + /// + {{/if}} + {{#each allParams}} + /// * [{{{dataType}}}] {{{paramName}}}{{#with required}} (required){{/with}}{{#with optional}} (optional){{/with}}: + {{#with description}} + /// {{{.}}} + {{/with}} + {{#unless @last}} + /// + {{/unless}} + {{/each}} + Future {{{nickname}}}WithHttpInfo({{#each allParams}}{{#with required}}{{{dataType}}} {{{paramName}}},{{#unless @last}} {{/unless}}{{/with}}{{/each}}{{#if hasOptionalParams}}{ {{#each allParams}}{{#unless required}}{{{dataType}}}? {{{paramName}}},{{#unless @last}} {{/unless}}{{/unless}}{{/each}} }{{/if}}) async { + // ignore: prefer_const_declarations + final path = r'{{{path}}}'{{#each pathParams}} + .replaceAll({{=<% %>=}}'{<% baseName %>}'<%={{ }}=%>, {{{paramName}}}{{#unless isString}}.toString(){{/unless}}){{/each}}; + + // ignore: prefer_final_locals + Object? postBody{{#with bodyParam}} = {{{paramName}}}{{/with}}; + + final queryParams = <{{{modelNamePrefix}}}QueryParam{{{modelNameSuffix}}}>[]; + final headerParams = {}; + final formParams = {}; + {{#if hasQueryParams}} + + {{#each queryParams}} + {{#unless required}} + if ({{{paramName}}} != null) { + {{/unless}} + queryParams.addAll(_queryParams('{{{collectionFormat}}}', '{{{baseName}}}', {{{paramName}}})); + {{#unless required}} + } + {{/unless}} + {{/each}} + {{/if}} + {{#if hasHeaderParams}} + + {{#each headerParams}} + {{#with required}} + headerParams[r'{{{baseName}}}'] = parameterToString({{{paramName}}}); + {{/with}} + {{#unless required}} + if ({{{paramName}}} != null) { + headerParams[r'{{{baseName}}}'] = parameterToString({{{paramName}}}); + } + {{/unless}} + {{/each}} + {{/if}} + + const contentTypes = [{{#each prioritizedContentTypes}}'{{{mediaType}}}'{{#unless @last}}, {{/unless}}{{/each}}]; + + {{#if isMultipart}} + bool hasFields = false; + final mp = MultipartRequest('{{{httpMethod}}}', Uri.parse(path)); + {{#each formParams}} + {{#unless isFile}} + if ({{{paramName}}} != null) { + hasFields = true; + mp.fields[r'{{{baseName}}}'] = parameterToString({{{paramName}}}); + } + {{/unless}} + {{#if isFile}} + if ({{{paramName}}} != null) { + hasFields = true; + mp.fields[r'{{{baseName}}}'] = {{{paramName}}}.field; + mp.files.add({{{paramName}}}); + } + {{/if}} + {{/each}} + if (hasFields) { + postBody = mp; + } + {{/if}} + {{#unless isMultipart}} + {{#each formParams}} + {{#unless isFile}} + if ({{{paramName}}} != null) { + formParams[r'{{{baseName}}}'] = parameterToString({{{paramName}}}); + } + {{/unless}} + {{/each}} + {{/unless}} + + return apiClient.invokeAPI( + path, + '{{{httpMethod}}}', + queryParams, + postBody, + headerParams, + formParams, + contentTypes.isEmpty ? null : contentTypes.first, + ); + } + + {{#with summary}} + /// {{{.}}} + {{/with}} + {{#each notes}} + {{#with summary}} + /// + {{/with}} + /// {{{notes}}} + {{/each}} + {{#if hasParams}} + {{#with summary}} + /// + {{/with}} + {{#unless summary}} + {{#each notes}} + /// + {{/each}} + {{/unless}} + /// Parameters: + /// + {{/if}} + {{#each allParams}} + /// * [{{{dataType}}}] {{{paramName}}}{{#with required}} (required){{/with}}{{#with optional}} (optional){{/with}}: + {{#with description}} + /// {{{.}}} + {{/with}} + {{#unless @last}} + /// + {{/unless}} + {{/each}} + Future<{{#with returnType}}{{{.}}}?{{/with}}{{#unless returnType}}void{{/unless}}> {{{nickname}}}({{#each allParams}}{{#with required}}{{{dataType}}} {{{paramName}}},{{#unless @last}} {{/unless}}{{/with}}{{/each}}{{#if hasOptionalParams}}{ {{#each allParams}}{{#unless required}}{{{dataType}}}? {{{paramName}}},{{#unless @last}} {{/unless}}{{/unless}}{{/each}} }{{/if}}) async { + final response = await {{{nickname}}}WithHttpInfo({{#each allParams}}{{#with required}}{{{paramName}}},{{#unless @last}} {{/unless}}{{/with}}{{/each}}{{#if hasOptionalParams}} {{#each allParams}}{{#unless required}}{{{paramName}}}: {{{paramName}}},{{#unless @last}} {{/unless}}{{/unless}}{{/each}} {{/if}}); + if (response.statusCode >= HttpStatus.badRequest) { + throw {{{modelNamePrefix}}}ApiException{{{modelNameSuffix}}}(response.statusCode, await _decodeBodyBytes(response)); + } + {{#with returnType}} + // When a remote server returns no body with a status of 204, we shall not decode it. + // At the time of writing this, `dart:convert` will throw an "Unexpected end of input" + // FormatException when trying to decode an empty string. + if (response.body.isNotEmpty && response.statusCode != HttpStatus.noContent) { + {{#with native_serialization}} + {{#if isArray}} + final responseBody = await _decodeBodyBytes(response); + return (await apiClient.deserializeAsync(responseBody, '{{{returnType}}}') as List) + .cast<{{{returnInnerType}}}>() + .{{#each uniqueItems}}toSet(){{/each}}{{#unless uniqueItems}}toList(){{/unless}}; + {{/if}} + {{#unless isArray}} + {{#if isMap}} + return {{{returnType}}}.from(await apiClient.deserializeAsync(await _decodeBodyBytes(response), '{{{returnType}}}'),); + {{/if}} + {{#unless isMap}} + return await apiClient.deserializeAsync(await _decodeBodyBytes(response), '{{{returnType}}}',) as {{{returnType}}}; + {{/unless}}{{/unless}}{{/with}} + } + return null; + {{/with}} + } + {{/with}} +} +{{/each}} diff --git a/modules/openapi-generator/src/main/resources/dart-handlebars/api_client.handlebars b/modules/openapi-generator/src/main/resources/dart-handlebars/api_client.handlebars new file mode 100644 index 000000000000..1a38924a25ab --- /dev/null +++ b/modules/openapi-generator/src/main/resources/dart-handlebars/api_client.handlebars @@ -0,0 +1,262 @@ +{{>header}} +{{>part_of}} +class {{#with apiClientName}}{{.}}{{/with}}{{#unless apiClientName}}{{{modelNamePrefix}}}ApiClient{{{modelNameSuffix}}}{{/unless}} { + {{#with apiClientName}}{{.}}{{/with}}{{#unless apiClientName}}{{{modelNamePrefix}}}ApiClient{{{modelNameSuffix}}}{{/unless}}({this.basePath = '{{{basePath}}}', this.authentication}); + + final String basePath; + + var _client = Client(); + + /// Returns the current HTTP [Client] instance to use in this class. + /// + /// The return value is guaranteed to never be null. + Client get client => _client; + + /// Requests to use a new HTTP [Client] in this class. + set client(Client newClient) { + _client = newClient; + } + + final _defaultHeaderMap = {}; + final {{{modelNamePrefix}}}Authentication{{{modelNameSuffix}}}? authentication; + + void addDefaultHeader(String key, String value) { + _defaultHeaderMap[key] = value; + } + + Map get defaultHeaderMap => _defaultHeaderMap; + + // We don't use a Map for queryParams. + // If collectionFormat is 'multi', a key might appear multiple times. + Future invokeAPI( + String path, + String method, + List<{{{modelNamePrefix}}}QueryParam{{{modelNameSuffix}}}> queryParams, + Object? body, + Map headerParams, + Map formParams, + String? contentType, + ) async { + _updateParamsForAuth(queryParams, headerParams); + + headerParams.addAll(_defaultHeaderMap); + if (contentType != null) { + headerParams['Content-Type'] = contentType; + } + + final urlEncoded{{{modelNamePrefix}}}QueryParam{{{modelNameSuffix}}}s = queryParams.map((param) => '$param'); + final queryString = urlEncoded{{{modelNamePrefix}}}QueryParam{{{modelNameSuffix}}}s.isNotEmpty ? '?${urlEncoded{{{modelNamePrefix}}}QueryParam{{{modelNameSuffix}}}s.join('&')}' : ''; + final uri = Uri.parse('$basePath$path$queryString'); + + try { + // Special case for uploading a single file which isn't a 'multipart/form-data'. + if ( + body is MultipartFile && (contentType == null || + !contentType.toLowerCase().startsWith('multipart/form-data')) + ) { + final request = StreamedRequest(method, uri); + request.headers.addAll(headerParams); + request.contentLength = body.length; + body.finalize().listen( + request.sink.add, + onDone: request.sink.close, + // ignore: avoid_types_on_closure_parameters + onError: (Object error, StackTrace trace) => request.sink.close(), + cancelOnError: true, + ); + final response = await _client.send(request); + return Response.fromStream(response); + } + + if (body is MultipartRequest) { + final request = MultipartRequest(method, uri); + request.fields.addAll(body.fields); + request.files.addAll(body.files); + request.headers.addAll(body.headers); + request.headers.addAll(headerParams); + final response = await _client.send(request); + return Response.fromStream(response); + } + + final msgBody = contentType == 'application/x-www-form-urlencoded' + ? formParams + : await serializeAsync(body); + final nullableHeaderParams = headerParams.isEmpty ? null : headerParams; + + switch(method) { + case 'POST': return await _client.post(uri, headers: nullableHeaderParams, body: msgBody,); + case 'PUT': return await _client.put(uri, headers: nullableHeaderParams, body: msgBody,); + case 'DELETE': return await _client.delete(uri, headers: nullableHeaderParams, body: msgBody,); + case 'PATCH': return await _client.patch(uri, headers: nullableHeaderParams, body: msgBody,); + case 'HEAD': return await _client.head(uri, headers: nullableHeaderParams,); + case 'GET': return await _client.get(uri, headers: nullableHeaderParams,); + } + } on SocketException catch (error, trace) { + throw {{{modelNamePrefix}}}ApiException{{{modelNameSuffix}}}.withInner( + HttpStatus.badRequest, + 'Socket operation failed: $method $path', + error, + trace, + ); + } on TlsException catch (error, trace) { + throw {{{modelNamePrefix}}}ApiException{{{modelNameSuffix}}}.withInner( + HttpStatus.badRequest, + 'TLS/SSL communication failed: $method $path', + error, + trace, + ); + } on IOException catch (error, trace) { + throw {{{modelNamePrefix}}}ApiException{{{modelNameSuffix}}}.withInner( + HttpStatus.badRequest, + 'I/O operation failed: $method $path', + error, + trace, + ); + } on ClientException catch (error, trace) { + throw {{{modelNamePrefix}}}ApiException{{{modelNameSuffix}}}.withInner( + HttpStatus.badRequest, + 'HTTP connection failed: $method $path', + error, + trace, + ); + } on Exception catch (error, trace) { + throw {{{modelNamePrefix}}}ApiException{{{modelNameSuffix}}}.withInner( + HttpStatus.badRequest, + 'Exception occurred: $method $path', + error, + trace, + ); + } + + throw {{{modelNamePrefix}}}ApiException{{{modelNameSuffix}}}( + HttpStatus.badRequest, + 'Invalid HTTP operation: $method $path', + ); + } +{{#with native_serialization}} + + Future deserializeAsync(String json, String targetType, {bool growable = false,}) async => + // ignore: deprecated_member_use_from_same_package + deserialize(json, targetType, growable: growable); + + @Deprecated('Scheduled for removal in OpenAPI Generator 6.x. Use deserializeAsync() instead.') + dynamic deserialize(String json, String targetType, {bool growable = false,}) { + // Remove all spaces. Necessary for regular expressions as well. + targetType = targetType.replaceAll(' ', ''); // ignore: parameter_assignments + + // If the expected target type is String, nothing to do... + return targetType == 'String' + ? json + : _deserialize(jsonDecode(json), targetType, growable: growable); + } +{{/with}} + + // ignore: deprecated_member_use_from_same_package + Future serializeAsync(Object? value) async => serialize(value); + + @Deprecated('Scheduled for removal in OpenAPI Generator 6.x. Use serializeAsync() instead.') + String serialize(Object? value) => value == null ? '' : json.encode(value); + + /// Update query and header parameters based on authentication settings. + void _updateParamsForAuth( + List<{{{modelNamePrefix}}}QueryParam{{{modelNameSuffix}}}> queryParams, + Map headerParams, + ) { + if (authentication != null) { + authentication!.applyToParams(queryParams, headerParams); + } + } + +{{#with native_serialization}} + static dynamic _deserialize(dynamic value, String targetType, {bool growable = false}) { + try { + switch (targetType) { + case 'String': + return value is String ? value : value.toString(); + case 'int': + return value is int ? value : int.parse('$value'); + case 'double': + return value is double ? value : double.parse('$value'); + case 'bool': + if (value is bool) { + return value; + } + final valueString = '$value'.toLowerCase(); + return valueString == 'true' || valueString == '1'; + case 'DateTime': + return value is DateTime ? value : DateTime.tryParse(value); + {{#each models}} + {{#with model}} + case '{{{classname}}}': + {{#if isEnum}} + {{#with native_serialization}}return {{{classname}}}TypeTransformer().decode(value);{{/with}} + {{/if}} + {{#unless isEnum}} + return {{{classname}}}.fromJson(value); + {{/unless}} + {{/with}} + {{/each}} + default: + dynamic match; + if (value is List && (match = _regList.firstMatch(targetType)?.group(1)) != null) { + return value + .map((dynamic v) => _deserialize(v, match, growable: growable,)) + .toList(growable: growable); + } + if (value is Set && (match = _regSet.firstMatch(targetType)?.group(1)) != null) { + return value + .map((dynamic v) => _deserialize(v, match, growable: growable,)) + .toSet(); + } + if (value is Map && (match = _regMap.firstMatch(targetType)?.group(1)) != null) { + return Map.fromIterables( + value.keys.cast(), + value.values.map((dynamic v) => _deserialize(v, match, growable: growable,)), + ); + } + } + } on Exception catch (error, trace) { + throw {{{modelNamePrefix}}}ApiException{{{modelNameSuffix}}}.withInner(HttpStatus.internalServerError, 'Exception during deserialization.', error, trace,); + } + throw {{{modelNamePrefix}}}ApiException{{{modelNameSuffix}}}(HttpStatus.internalServerError, 'Could not find a suitable class for deserialization',); + } +{{/with}} +} +{{#with native_serialization}} + +/// Primarily intended for use in an isolate. +class DeserializationMessage { + const DeserializationMessage({ + required this.json, + required this.targetType, + this.growable = false, + }); + + /// The JSON value to deserialize. + final String json; + + /// Target type to deserialize to. + final String targetType; + + /// Whether to make deserialized lists or maps growable. + final bool growable; +} + +/// Primarily intended for use in an isolate. +Future deserializeAsync(DeserializationMessage message) async { + // Remove all spaces. Necessary for regular expressions as well. + final targetType = message.targetType.replaceAll(' ', ''); + + // If the expected target type is String, nothing to do... + return targetType == 'String' + ? message.json + : {{#with apiClientName}}{{.}}{{/with}}{{#unless apiClientName}}{{{modelNamePrefix}}}ApiClient{{{modelNameSuffix}}}{{/unless}}._deserialize( + jsonDecode(message.json), + targetType, + growable: message.growable, + ); +} +{{/with}} + +/// Primarily intended for use in an isolate. +Future serializeAsync(Object? value) async => value == null ? '' : json.encode(value); diff --git a/modules/openapi-generator/src/main/resources/dart-handlebars/api_doc.handlebars b/modules/openapi-generator/src/main/resources/dart-handlebars/api_doc.handlebars new file mode 100644 index 000000000000..4776f32a8a29 --- /dev/null +++ b/modules/openapi-generator/src/main/resources/dart-handlebars/api_doc.handlebars @@ -0,0 +1,96 @@ +# {{{pubName}}}.api.{{{classname}}}{{#with description}} +{{{.}}}{{/with}} + +## Load the API package +```dart +import 'package:{{{pubName}}}/api.dart'; +``` + +All URIs are relative to *{{{basePath}}}* + +Method | HTTP request | Description +------------- | ------------- | ------------- +{{#each operations}}{{#with operation}}[**{{{operationId}}}**]({{{classname}}}.md#{{{operationIdLowerCase}}}) | **{{{httpMethod}}}** {{{path}}} | {{{summary}}} +{{/with}}{{/each}} + +{{#each operations}} +{{#with operation}} +# **{{{operationId}}}** +> {{#with returnType}}{{{.}}} {{/with}}{{{operationId}}}({{#each allParams}}{{{paramName}}}{{#unless @last}}, {{/unless}}{{/each}}) + +{{{summary}}}{{#each notes}} + +{{{.}}}{{/each}} + +### Example +```dart +import 'package:{{{pubName}}}/api.dart'; +{{#if hasAuthMethods}} +{{#each authMethods}} +{{#if isBasic}} +{{#if isBasicBasic}} +// TODO Configure HTTP basic authorization: {{{name}}} +//default{{#with apiClientName}}{{.}}{{/with}}{{#unless apiClientName}}{{{modelNamePrefix}}}ApiClient{{{modelNameSuffix}}}{{/unless}}.getAuthentication('{{{name}}}').username = 'YOUR_USERNAME' +//default{{#with apiClientName}}{{.}}{{/with}}{{#unless apiClientName}}{{{modelNamePrefix}}}ApiClient{{{modelNameSuffix}}}{{/unless}}.getAuthentication('{{{name}}}').password = 'YOUR_PASSWORD'; +{{/if}} +{{#if isBasicBearer}} +// TODO Configure HTTP Bearer authorization: {{{name}}} +// Case 1. Use String Token +//default{{#with apiClientName}}{{.}}{{/with}}{{#unless apiClientName}}{{{modelNamePrefix}}}ApiClient{{{modelNameSuffix}}}{{/unless}}.getAuthentication('{{{name}}}').setAccessToken('YOUR_ACCESS_TOKEN'); +// Case 2. Use Function which generate token. +// String yourTokenGeneratorFunction() { ... } +//default{{#with apiClientName}}{{.}}{{/with}}{{#unless apiClientName}}{{{modelNamePrefix}}}ApiClient{{{modelNameSuffix}}}{{/unless}}.getAuthentication('{{{name}}}').setAccessToken(yourTokenGeneratorFunction); +{{/if}} +{{/if}} +{{#if isApiKey}} +// TODO Configure API key authorization: {{{name}}} +//default{{#with apiClientName}}{{.}}{{/with}}{{#unless apiClientName}}{{{modelNamePrefix}}}ApiClient{{{modelNameSuffix}}}{{/unless}}.getAuthentication('{{{name}}}').apiKey = 'YOUR_API_KEY'; +// uncomment below to setup prefix (e.g. Bearer) for API key, if needed +//default{{#with apiClientName}}{{.}}{{/with}}{{#unless apiClientName}}{{{modelNamePrefix}}}ApiClient{{{modelNameSuffix}}}{{/unless}}.getAuthentication('{{{name}}}').apiKeyPrefix = 'Bearer'; +{{/if}} +{{#if isOAuth}} +// TODO Configure OAuth2 access token for authorization: {{{name}}} +//default{{#with apiClientName}}{{.}}{{/with}}{{#unless apiClientName}}{{{modelNamePrefix}}}ApiClient{{{modelNameSuffix}}}{{/unless}}.getAuthentication('{{{name}}}').accessToken = 'YOUR_ACCESS_TOKEN'; +{{/if}} +{{/each}} +{{/if}} + +final api_instance = {{{classname}}}(); +{{#each allParams}} +final {{{paramName}}} = {{#if isArray}}[{{/if}}{{#if isBodyParam}}{{{dataType}}}(){{/if}}{{#unless isBodyParam}}{{{example}}}{{/unless}}{{#if isArray}}]{{/if}}; // {{{dataType}}} | {{{description}}} +{{/each}} + +try { + {{#with returnType}}final result = {{/with}}api_instance.{{{operationId}}}({{#each allParams}}{{{paramName}}}{{#unless @last}}, {{/unless}}{{/each}}); + {{#with returnType}} + print(result); + {{/with}} +} catch (e) { + print('Exception when calling {{{classname}}}->{{{operationId}}}: $e\n'); +} +``` + +### Parameters +{{#unless allParams}}This endpoint does not need any parameter.{{/unless}}{{#each allParams}}{{#if @last}} +Name | Type | Description | Notes +------------- | ------------- | ------------- | -------------{{/if}}{{/each}} +{{#each allParams}} **{{{paramName}}}** | {{#if isPrimitiveType}}**{{{dataType}}}**{{/if}}{{#unless isPrimitiveType}}[**{{{dataType}}}**]({{{baseType}}}.md){{/unless}}| {{{description}}} | {{#unless required}}[optional] {{/unless}}{{#with defaultValue}}[default to {{{.}}}]{{/with}} +{{/each}} + +### Return type + +{{#with returnType}}{{#with returnTypeIsPrimitive}}**{{{returnType}}}**{{/with}}{{#unless returnTypeIsPrimitive}}[**{{{returnType}}}**]({{{returnBaseType}}}.md){{/unless}}{{/with}}{{#unless returnType}}void (empty response body){{/unless}} + +### Authorization + +{{#unless authMethods}}No authorization required{{/unless}}{{#each authMethods}}[{{{name}}}](../README.md#{{{name}}}){{#unless @last}}, {{/unless}}{{/each}} + +### HTTP request headers + + - **Content-Type**: {{#each consumes}}{{{mediaType}}}{{#unless @last}}, {{/unless}}{{/each}}{{#unless consumes}}Not defined{{/unless}} + - **Accept**: {{#each produces}}{{{mediaType}}}{{#unless @last}}, {{/unless}}{{/each}}{{#unless produces}}Not defined{{/unless}} + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + +{{/with}} +{{/each}} diff --git a/modules/openapi-generator/src/main/resources/dart-handlebars/api_exception.handlebars b/modules/openapi-generator/src/main/resources/dart-handlebars/api_exception.handlebars new file mode 100644 index 000000000000..445dcc89b535 --- /dev/null +++ b/modules/openapi-generator/src/main/resources/dart-handlebars/api_exception.handlebars @@ -0,0 +1,23 @@ +{{>header}} +{{>part_of}} +class {{{modelNamePrefix}}}ApiException{{{modelNameSuffix}}} implements Exception { + {{{modelNamePrefix}}}ApiException{{{modelNameSuffix}}}(this.code, this.message); + + {{{modelNamePrefix}}}ApiException{{{modelNameSuffix}}}.withInner(this.code, this.message, this.innerException, this.stackTrace); + + int code = 0; + String? message; + Exception? innerException; + StackTrace? stackTrace; + + @override + String toString() { + if (message == null) { + return '{{{modelNamePrefix}}}ApiException{{{modelNameSuffix}}}'; + } + if (innerException == null) { + return '{{{modelNamePrefix}}}ApiException{{{modelNameSuffix}}} $code: $message'; + } + return '{{{modelNamePrefix}}}ApiException{{{modelNameSuffix}}} $code: $message (Inner exception: $innerException)\n\n$stackTrace'; + } +} diff --git a/modules/openapi-generator/src/main/resources/dart-handlebars/api_helper.handlebars b/modules/openapi-generator/src/main/resources/dart-handlebars/api_helper.handlebars new file mode 100644 index 000000000000..9450e513e75b --- /dev/null +++ b/modules/openapi-generator/src/main/resources/dart-handlebars/api_helper.handlebars @@ -0,0 +1,100 @@ +{{>header}} +{{>part_of}} +class {{{modelNamePrefix}}}QueryParam{{{modelNameSuffix}}} { + const {{{modelNamePrefix}}}QueryParam{{{modelNameSuffix}}}(this.name, this.value); + + final String name; + final String value; + + @override + String toString() => '${Uri.encodeQueryComponent(name)}=${Uri.encodeQueryComponent(value)}'; +} + +// Ported from the Java version. +Iterable<{{{modelNamePrefix}}}QueryParam{{{modelNameSuffix}}}> _queryParams(String collectionFormat, String name, dynamic value,) { + // Assertions to run in debug mode only. + assert(name.isNotEmpty, 'Parameter cannot be an empty string.'); + + final params = <{{{modelNamePrefix}}}QueryParam{{{modelNameSuffix}}}>[]; + + if (value is List) { + if (collectionFormat == 'multi') { + return value.map((dynamic v) => {{{modelNamePrefix}}}QueryParam{{{modelNameSuffix}}}(name, parameterToString(v)),); + } + + // Default collection format is 'csv'. + if (collectionFormat.isEmpty) { + collectionFormat = 'csv'; // ignore: parameter_assignments + } + + final delimiter = _delimiters[collectionFormat] ?? ','; + + params.add({{{modelNamePrefix}}}QueryParam{{{modelNameSuffix}}}(name, value.map(parameterToString).join(delimiter),)); + } else if (value != null) { + params.add({{{modelNamePrefix}}}QueryParam{{{modelNameSuffix}}}(name, parameterToString(value))); + } + + return params; +} + +/// Format the given parameter object into a [String]. +String parameterToString(dynamic value) { + if (value == null) { + return ''; + } + if (value is DateTime) { + return value.toUtc().toIso8601String(); + } + {{#each models}} + {{#with model}} + {{#if isEnum}} + if (value is {{{classname}}}) { +{{#with native_serialization}} return {{{classname}}}TypeTransformer().encode(value).toString();{{/with}} + } + {{/if}} + {{/with}} + {{/each}} + return value.toString(); +} + +/// Returns the decoded body as UTF-8 if the given headers indicate an 'application/json' +/// content type. Otherwise, returns the decoded body as decoded by dart:http package. +Future _decodeBodyBytes(Response response) async { + final contentType = response.headers['content-type']; + return contentType != null && contentType.toLowerCase().startsWith('application/json') + ? response.bodyBytes.isEmpty ? '' : utf8.decode(response.bodyBytes) + : response.body; +} + +/// Returns a valid [T] value found at the specified Map [key], null otherwise. +T? mapValueOfType(dynamic map, String key) { + final dynamic value = map is Map ? map[key] : null; + return value is T ? value : null; +} + +/// Returns a valid Map found at the specified Map [key], null otherwise. +Map? mapCastOfType(dynamic map, String key) { + final dynamic value = map is Map ? map[key] : null; + return value is Map ? value.cast() : null; +} + +/// Returns a valid [DateTime] found at the specified Map [key], null otherwise. +DateTime? mapDateTime(dynamic map, String key, [String? pattern]) { + final dynamic value = map is Map ? map[key] : null; + if (value != null) { + int? millis; + if (value is int) { + millis = value; + } else if (value is String) { + if (pattern == _dateEpochMarker) { + millis = int.tryParse(value); + } else { + return DateTime.tryParse(value); + } + } + if (millis != null) { + return DateTime.fromMillisecondsSinceEpoch(millis, isUtc: true); + } + } + return null; +} diff --git a/modules/openapi-generator/src/main/resources/dart-handlebars/api_test.handlebars b/modules/openapi-generator/src/main/resources/dart-handlebars/api_test.handlebars new file mode 100644 index 000000000000..41ce8e1ba4a6 --- /dev/null +++ b/modules/openapi-generator/src/main/resources/dart-handlebars/api_test.handlebars @@ -0,0 +1,29 @@ +{{>header}} +import 'package:{{{pubName}}}/api.dart'; +import 'package:test/test.dart'; + +{{#each operations}} + +/// tests for {{{classname}}} +void main() { + // final instance = {{{classname}}}(); + + group('tests for {{{classname}}}', () { + {{#with operation}} + {{#with summary}} + // {{{.}}} + // + {{/with}} + {{#each notes}} + // {{{.}}} + // + {{/each}} + //{{#with returnType}}Future<{{{.}}}> {{/with}}{{#unless returnType}}Future {{/unless}}{{{operationId}}}({{#each allParams}}{{#with required}}{{{dataType}}} {{{paramName}}}{{#unless @last}}, {{/unless}}{{/with}}{{/each}}{{#if hasOptionalParams}}{ {{#each allParams}}{{#unless required}}{{{dataType}}} {{{paramName}}}{{#unless @last}}, {{/unless}}{{/unless}}{{/each}} }{{/if}}) async + test('test {{{operationId}}}', () async { + // TODO + }); + + {{/with}} + }); +} +{{/each}} diff --git a/modules/openapi-generator/src/main/resources/dart-handlebars/apilib.handlebars b/modules/openapi-generator/src/main/resources/dart-handlebars/apilib.handlebars new file mode 100644 index 000000000000..0c6ea524f7d9 --- /dev/null +++ b/modules/openapi-generator/src/main/resources/dart-handlebars/apilib.handlebars @@ -0,0 +1,41 @@ +{{>header}} +{{#with pubLibrary}}library {{{.}}};{{/with}}{{#unless pubLibrary}}library {{{pubName}}}.api;{{/unless}} + +import 'dart:async'; +import 'dart:convert'; +import 'dart:io'; + +import 'package:http/http.dart'; +import 'package:intl/intl.dart'; +import 'package:meta/meta.dart'; + +part 'api_client.dart'; +part 'api_helper.dart'; +part 'api_exception.dart'; +part 'auth/authentication.dart'; +part 'auth/api_key_auth.dart'; +part 'auth/oauth.dart'; +part 'auth/http_basic_auth.dart'; +part 'auth/http_bearer_auth.dart'; + +{{#with apiInfo}}{{#each apis}}part 'api/{{{classFilename}}}.dart'; +{{/each}}{{/with}} +{{#each models}}{{#with model}}part 'model/{{{classFilename}}}.dart'; +{{/with}}{{/each}} + +const _delimiters = {'csv': ',', 'ssv': ' ', 'tsv': '\t', 'pipes': '|'}; +const _dateEpochMarker = 'epoch'; +final _dateFormatter = DateFormat('yyyy-MM-dd'); +final _regList = RegExp(r'^List<(.*)>$'); +final _regSet = RegExp(r'^Set<(.*)>$'); +final _regMap = RegExp(r'^Map$'); + +/// also add individual apis as getters on the primary default api client +extension {{#with apiClientName}}{{.}}{{/with}}{{#unless apiClientName}}{{{modelNamePrefix}}}ApiClient{{{modelNameSuffix}}}{{/unless}}Extension on {{#with apiClientName}}{{.}}{{/with}}{{#unless apiClientName}}{{{modelNamePrefix}}}ApiClient{{{modelNameSuffix}}}{{/unless}} { + {{#with apiInfo}}{{#each apis}} + {{{classname}}} get {{{classVarName}}} => {{{classname}}}(this); + {{/each}}{{/with}} +} + + +{{#with apiClientName}}{{.}}{{/with}}{{#unless apiClientName}}{{{modelNamePrefix}}}ApiClient{{{modelNameSuffix}}}{{/unless}} default{{#with apiClientName}}{{.}}{{/with}}{{#unless apiClientName}}{{{modelNamePrefix}}}ApiClient{{{modelNameSuffix}}}{{/unless}} = {{#with apiClientName}}{{.}}{{/with}}{{#unless apiClientName}}{{{modelNamePrefix}}}ApiClient{{{modelNameSuffix}}}{{/unless}}(); diff --git a/modules/openapi-generator/src/main/resources/dart-handlebars/auth/api_key_auth.handlebars b/modules/openapi-generator/src/main/resources/dart-handlebars/auth/api_key_auth.handlebars new file mode 100644 index 000000000000..30bc5a6ecd43 --- /dev/null +++ b/modules/openapi-generator/src/main/resources/dart-handlebars/auth/api_key_auth.handlebars @@ -0,0 +1,30 @@ +{{>header}} +{{>part_of}} +class {{{modelNamePrefix}}}ApiKeyAuth{{{modelNameSuffix}}} implements {{{modelNamePrefix}}}Authentication{{{modelNameSuffix}}} { + {{{modelNamePrefix}}}ApiKeyAuth{{{modelNameSuffix}}}(this.location, this.paramName); + + final String location; + final String paramName; + + String apiKeyPrefix = ''; + String apiKey = ''; + + @override + void applyToParams(List<{{{modelNamePrefix}}}QueryParam{{{modelNameSuffix}}}> queryParams, Map headerParams) { + final paramValue = apiKeyPrefix.isEmpty ? apiKey : '$apiKeyPrefix $apiKey'; + + if (paramValue.isNotEmpty) { + if (location == 'query') { + queryParams.add({{{modelNamePrefix}}}QueryParam{{{modelNameSuffix}}}(paramName, paramValue)); + } else if (location == 'header') { + headerParams[paramName] = paramValue; + } else if (location == 'cookie') { + headerParams.update( + 'Cookie', + (existingCookie) => '$existingCookie; $paramName=$paramValue', + ifAbsent: () => '$paramName=$paramValue', + ); + } + } + } +} diff --git a/modules/openapi-generator/src/main/resources/dart-handlebars/auth/authentication.handlebars b/modules/openapi-generator/src/main/resources/dart-handlebars/auth/authentication.handlebars new file mode 100644 index 000000000000..0704665327f8 --- /dev/null +++ b/modules/openapi-generator/src/main/resources/dart-handlebars/auth/authentication.handlebars @@ -0,0 +1,7 @@ +{{>header}} +{{>part_of}} +// ignore: one_member_abstracts +abstract class {{{modelNamePrefix}}}Authentication{{{modelNameSuffix}}} { + /// Apply authentication settings to header and query params. + void applyToParams(List<{{{modelNamePrefix}}}QueryParam{{{modelNameSuffix}}}> queryParams, Map headerParams); +} diff --git a/modules/openapi-generator/src/main/resources/dart-handlebars/auth/header.handlebars b/modules/openapi-generator/src/main/resources/dart-handlebars/auth/header.handlebars new file mode 100644 index 000000000000..3799d9d04658 --- /dev/null +++ b/modules/openapi-generator/src/main/resources/dart-handlebars/auth/header.handlebars @@ -0,0 +1,9 @@ +// +// AUTO-GENERATED FILE, DO NOT MODIFY! +// +// @dart=2.12 + +// ignore_for_file: unused_element, unused_import +// ignore_for_file: always_put_required_named_parameters_first +// ignore_for_file: constant_identifier_names +// ignore_for_file: lines_longer_than_80_chars diff --git a/modules/openapi-generator/src/main/resources/dart-handlebars/auth/http_basic_auth.handlebars b/modules/openapi-generator/src/main/resources/dart-handlebars/auth/http_basic_auth.handlebars new file mode 100644 index 000000000000..1d39280f45c9 --- /dev/null +++ b/modules/openapi-generator/src/main/resources/dart-handlebars/auth/http_basic_auth.handlebars @@ -0,0 +1,16 @@ +{{>header}} +{{>part_of}} +class {{{modelNamePrefix}}}HttpBasicAuthentication{{{modelNameSuffix}}} implements {{{modelNamePrefix}}}Authentication{{{modelNameSuffix}}} { + {{{modelNamePrefix}}}HttpBasicAuthentication{{{modelNameSuffix}}}({this.username = '', this.password = ''}); + + String username; + String password; + + @override + void applyToParams(List<{{{modelNamePrefix}}}QueryParam{{{modelNameSuffix}}}> queryParams, Map headerParams) { + if (username.isNotEmpty && password.isNotEmpty) { + final credentials = '$username:$password'; + headerParams['Authorization'] = 'Basic ${base64.encode(utf8.encode(credentials))}'; + } + } +} diff --git a/modules/openapi-generator/src/main/resources/dart-handlebars/auth/http_bearer_auth.handlebars b/modules/openapi-generator/src/main/resources/dart-handlebars/auth/http_bearer_auth.handlebars new file mode 100644 index 000000000000..0b56af1726a2 --- /dev/null +++ b/modules/openapi-generator/src/main/resources/dart-handlebars/auth/http_bearer_auth.handlebars @@ -0,0 +1,45 @@ +{{>header}} +{{>part_of}} +typedef {{{modelNamePrefix}}}HttpBearerAuthProvider{{{modelNameSuffix}}} = String Function(); + +class {{{modelNamePrefix}}}HttpBearerAuthentication{{{modelNameSuffix}}} implements {{{modelNamePrefix}}}Authentication{{{modelNameSuffix}}} { + + /// Constucts [HttpBearerAuthentication] from an optional [accessToken] which will be included in request headers + /// using the `Authorization: Bearer [token]` method. + {{{modelNamePrefix}}}HttpBearerAuthentication{{{modelNameSuffix}}}([dynamic accessToken]) { + this.accessToken = accessToken; + } + + dynamic _accessToken; + + dynamic get accessToken => _accessToken; + + /// may be a String or a Function that returns a string. + set accessToken(dynamic accessToken) { + if (accessToken is! String && accessToken is! {{{modelNamePrefix}}}HttpBearerAuthProvider{{{modelNameSuffix}}}) { + throw ArgumentError('accessToken value must be either a String or a String Function().'); + } + _accessToken = accessToken; + } + + @override + void applyToParams(List<{{{modelNamePrefix}}}QueryParam{{{modelNameSuffix}}}> queryParams, Map headerParams) { + if (_accessToken == null) { + return; + } + + String accessToken; + + if (_accessToken is String) { + accessToken = _accessToken; + } else if (_accessToken is {{{modelNamePrefix}}}HttpBearerAuthProvider{{{modelNameSuffix}}}) { + accessToken = _accessToken!(); + } else { + return; + } + + if (accessToken.isNotEmpty) { + headerParams['Authorization'] = 'Bearer $accessToken'; + } + } +} diff --git a/modules/openapi-generator/src/main/resources/dart-handlebars/auth/oauth.handlebars b/modules/openapi-generator/src/main/resources/dart-handlebars/auth/oauth.handlebars new file mode 100644 index 000000000000..b108f1a35cfc --- /dev/null +++ b/modules/openapi-generator/src/main/resources/dart-handlebars/auth/oauth.handlebars @@ -0,0 +1,14 @@ +{{>header}} +{{>part_of}} +class {{{modelNamePrefix}}}OAuth{{{modelNameSuffix}}} implements {{{modelNamePrefix}}}Authentication{{{modelNameSuffix}}} { + {{{modelNamePrefix}}}OAuth{{{modelNameSuffix}}}({this.accessToken = ''}); + + String accessToken; + + @override + void applyToParams(List<{{{modelNamePrefix}}}QueryParam{{{modelNameSuffix}}}> queryParams, Map headerParams) { + if (accessToken.isNotEmpty) { + headerParams['Authorization'] = 'Bearer $accessToken'; + } + } +} diff --git a/modules/openapi-generator/src/main/resources/dart-handlebars/auth/part_of.handlebars b/modules/openapi-generator/src/main/resources/dart-handlebars/auth/part_of.handlebars new file mode 100644 index 000000000000..e4014cd65b65 --- /dev/null +++ b/modules/openapi-generator/src/main/resources/dart-handlebars/auth/part_of.handlebars @@ -0,0 +1 @@ +{{#with pubLibrary}}part of {{{.}}};{{/with}}{{#unless pubLibrary}}part of {{{pubName}}}.api;{{/unless}} diff --git a/modules/openapi-generator/src/main/resources/dart-handlebars/dart_constructor.handlebars b/modules/openapi-generator/src/main/resources/dart-handlebars/dart_constructor.handlebars new file mode 100644 index 000000000000..119978ac0624 --- /dev/null +++ b/modules/openapi-generator/src/main/resources/dart-handlebars/dart_constructor.handlebars @@ -0,0 +1,10 @@ + /// Returns a new [{{{classname}}}] instance. + {{{classname}}}({ + {{#each vars}} + {{! + A field is required in Dart when it is + required && !defaultValue in OAS + }} + {{#with required}}{{#unless defaultValue}}required {{/unless}}{{/with}}this.{{{name}}}{{#with defaultValue}} = {{#if isEnum}}{{#unless isContainer}}const {{{enumName}}}._({{/unless}}{{/if}}{{{.}}}{{#if isEnum}}{{#unless isContainer}}){{/unless}}{{/if}}{{/with}}, + {{/each}} + }); diff --git a/modules/openapi-generator/src/main/resources/dart-handlebars/git_push.sh.handlebars b/modules/openapi-generator/src/main/resources/dart-handlebars/git_push.sh.handlebars new file mode 100644 index 000000000000..0e3776ae6dd4 --- /dev/null +++ b/modules/openapi-generator/src/main/resources/dart-handlebars/git_push.sh.handlebars @@ -0,0 +1,57 @@ +#!/bin/sh +# ref: https://help.github.com/articles/adding-an-existing-project-to-github-using-the-command-line/ +# +# Usage example: /bin/sh ./git_push.sh wing328 openapi-petstore-perl "minor update" "gitlab.com" + +git_user_id=$1 +git_repo_id=$2 +release_note=$3 +git_host=$4 + +if [ "$git_host" = "" ]; then + git_host="{{{gitHost}}}" + echo "[INFO] No command line input provided. Set \$git_host to $git_host" +fi + +if [ "$git_user_id" = "" ]; then + git_user_id="{{{gitUserId}}}" + echo "[INFO] No command line input provided. Set \$git_user_id to $git_user_id" +fi + +if [ "$git_repo_id" = "" ]; then + git_repo_id="{{{gitRepoId}}}" + echo "[INFO] No command line input provided. Set \$git_repo_id to $git_repo_id" +fi + +if [ "$release_note" = "" ]; then + release_note="{{{releaseNote}}}" + echo "[INFO] No command line input provided. Set \$release_note to $release_note" +fi + +# Initialize the local directory as a Git repository +git init + +# Adds the files in the local repository and stages them for commit. +git add . + +# Commits the tracked changes and prepares them to be pushed to a remote repository. +git commit -m "$release_note" + +# Sets the new remote +git_remote=$(git remote) +if [ "$git_remote" = "" ]; then # git remote not defined + + if [ "$GIT_TOKEN" = "" ]; then + echo "[INFO] \$GIT_TOKEN (environment variable) is not set. Using the git credential in your environment." + git remote add origin https://${git_host}/${git_user_id}/${git_repo_id}.git + else + git remote add origin https://${git_user_id}:"${GIT_TOKEN}"@${git_host}/${git_user_id}/${git_repo_id}.git + fi + +fi + +git pull origin master + +# Pushes (Forces) the changes in the local repository up to the remote repository +echo "Git pushing to https://${git_host}/${git_user_id}/${git_repo_id}.git" +git push origin master 2>&1 | grep -v 'To https' diff --git a/modules/openapi-generator/src/main/resources/dart-handlebars/gitignore.handlebars b/modules/openapi-generator/src/main/resources/dart-handlebars/gitignore.handlebars new file mode 100644 index 000000000000..1be28ced0940 --- /dev/null +++ b/modules/openapi-generator/src/main/resources/dart-handlebars/gitignore.handlebars @@ -0,0 +1,17 @@ +# See https://dart.dev/guides/libraries/private-files + +.dart_tool/ +.packages +build/ +pubspec.lock # Except for application packages + +doc/api/ + +# IntelliJ +*.iml +*.ipr +*.iws +.idea/ + +# Mac +.DS_Store diff --git a/modules/openapi-generator/src/main/resources/dart-handlebars/header.handlebars b/modules/openapi-generator/src/main/resources/dart-handlebars/header.handlebars new file mode 100644 index 000000000000..3799d9d04658 --- /dev/null +++ b/modules/openapi-generator/src/main/resources/dart-handlebars/header.handlebars @@ -0,0 +1,9 @@ +// +// AUTO-GENERATED FILE, DO NOT MODIFY! +// +// @dart=2.12 + +// ignore_for_file: unused_element, unused_import +// ignore_for_file: always_put_required_named_parameters_first +// ignore_for_file: constant_identifier_names +// ignore_for_file: lines_longer_than_80_chars diff --git a/modules/openapi-generator/src/main/resources/dart-handlebars/model.handlebars b/modules/openapi-generator/src/main/resources/dart-handlebars/model.handlebars new file mode 100644 index 000000000000..7bc110d41606 --- /dev/null +++ b/modules/openapi-generator/src/main/resources/dart-handlebars/model.handlebars @@ -0,0 +1,16 @@ +{{>header}} +{{>part_of}} +{{#each models}} +{{#with model}} +{{#if isEnum}} +{{#with native_serialization}} +{{>serialization/native/native_enum}} +{{/with}} +{{/if}} +{{#unless isEnum}} +{{#with native_serialization}} +{{>serialization/native/native_class}} +{{/with}} +{{/unless}} +{{/with}} +{{/each}} diff --git a/modules/openapi-generator/src/main/resources/dart-handlebars/model_test.handlebars b/modules/openapi-generator/src/main/resources/dart-handlebars/model_test.handlebars new file mode 100644 index 000000000000..c0a5263047e5 --- /dev/null +++ b/modules/openapi-generator/src/main/resources/dart-handlebars/model_test.handlebars @@ -0,0 +1,29 @@ +{{>header}} +{{#each models}} +{{#with model}} +import 'package:{{{pubName}}}/api.dart'; +import 'package:test/test.dart'; + +// tests for {{{classname}}} +void main() { + {{#unless isEnum}} + // final instance = {{{classname}}}(); + {{/unless}} + + group('test {{{classname}}}', () { + {{#each vars}} + {{#with description}} + // {{{.}}} + {{/with}} + // {{{dataType}}} {{{name}}}{{#with defaultValue}} (default value: {{{.}}}){{/with}} + test('to test the property `{{{name}}}`', () async { + // TODO + }); + + {{/each}} + + }); + +} +{{/with}} +{{/each}} diff --git a/modules/openapi-generator/src/main/resources/dart-handlebars/object_doc.handlebars b/modules/openapi-generator/src/main/resources/dart-handlebars/object_doc.handlebars new file mode 100644 index 000000000000..977cddc02269 --- /dev/null +++ b/modules/openapi-generator/src/main/resources/dart-handlebars/object_doc.handlebars @@ -0,0 +1,16 @@ +{{#each models}}{{#with model}}# {{{pubName}}}.model.{{{classname}}} + +## Load the model package +```dart +import 'package:{{{pubName}}}/api.dart'; +``` + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +{{#each vars}}**{{{name}}}** | {{#if isPrimitiveType}}**{{{dataType}}}**{{/if}}{{#unless isPrimitiveType}}[**{{{dataType}}}**]({{{complexType}}}.md){{/unless}} | {{{description}}} | {{#unless required}}[optional] {{/unless}}{{#if isReadOnly}}[readonly] {{/if}}{{#with defaultValue}}[default to {{{.}}}]{{/with}} +{{/each}} + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + +{{/with}}{{/each}} diff --git a/modules/openapi-generator/src/main/resources/dart-handlebars/part_of.handlebars b/modules/openapi-generator/src/main/resources/dart-handlebars/part_of.handlebars new file mode 100644 index 000000000000..e4014cd65b65 --- /dev/null +++ b/modules/openapi-generator/src/main/resources/dart-handlebars/part_of.handlebars @@ -0,0 +1 @@ +{{#with pubLibrary}}part of {{{.}}};{{/with}}{{#unless pubLibrary}}part of {{{pubName}}}.api;{{/unless}} diff --git a/modules/openapi-generator/src/main/resources/dart-handlebars/pubspec.handlebars b/modules/openapi-generator/src/main/resources/dart-handlebars/pubspec.handlebars new file mode 100644 index 000000000000..5a08fd512b24 --- /dev/null +++ b/modules/openapi-generator/src/main/resources/dart-handlebars/pubspec.handlebars @@ -0,0 +1,19 @@ +# +# AUTO-GENERATED FILE, DO NOT MODIFY! +# + +name: '{{{pubName}}}' +version: '{{{pubVersion}}}' +description: '{{{pubDescription}}}' +homepage: '{{{pubHomepage}}}' +environment: + sdk: '>=2.12.0 <3.0.0' +dependencies: + http: '>=0.13.0 <0.14.0' + intl: '^0.17.0' + meta: '^1.1.8' +dev_dependencies: + test: '>=1.16.0 <1.18.0' +{{#with json_serializable}} + build_runner: '^1.10.9' + json_serializable: '^3.5.1'{{/with}} \ No newline at end of file diff --git a/modules/openapi-generator/src/main/resources/dart-handlebars/serialization/native/native_class.handlebars b/modules/openapi-generator/src/main/resources/dart-handlebars/serialization/native/native_class.handlebars new file mode 100644 index 000000000000..a2a4297cec16 --- /dev/null +++ b/modules/openapi-generator/src/main/resources/dart-handlebars/serialization/native/native_class.handlebars @@ -0,0 +1,299 @@ +class {{{classname}}} { +{{>dart_constructor}} +{{#each vars}} + {{#with description}} + /// {{{.}}} + {{/with}} + {{#unless isEnum}} + {{#with minimum}} + {{#with description}} + /// + {{/with}} + /// Minimum value: {{{.}}} + {{/with}} + {{#with maximum}} + {{#with description}} + {{#unless minimum}} + /// + {{/unless}} + {{/with}} + /// Maximum value: {{{.}}} + {{/with}} + {{#unless isNullable}} + {{#unless required}} + {{#unless defaultValue}} + /// + /// Please note: This property should have been non-nullable! Since the specification file + /// does not include a default value (using the "default:" property), however, the generated + /// source code must fall back to having a nullable type. + /// Consider adding a "default:" property in the specification file to hide this note. + /// + {{/unless}} + {{/unless}} + {{/unless}} + {{/unless}} + {{{datatypeWithEnum}}}{{#if isNullable}}?{{/if}}{{#unless isNullable}}{{#unless required}}{{#unless defaultValue}}?{{/unless}}{{/unless}}{{/unless}} {{{name}}}; + +{{/each}} + @override + bool operator ==(Object other) => identical(this, other) || other is {{{classname}}} && + {{#each vars}} + other.{{{name}}} == {{{name}}}{{#unless @last}} &&{{/unless}}{{#if @last}};{{/if}} + {{/each}} + + @override + int get hashCode => + // ignore: unnecessary_parenthesis + {{#each vars}} + ({{#if isNullable}}{{{name}}} == null ? 0 : {{/if}}{{#unless isNullable}}{{#unless required}}{{#unless defaultValue}}{{{name}}} == null ? 0 : {{/unless}}{{/unless}}{{/unless}}{{{name}}}{{#if isNullable}}!{{/if}}{{#unless isNullable}}{{#unless required}}{{#unless defaultValue}}!{{/unless}}{{/unless}}{{/unless}}.hashCode){{#unless @last}} +{{/unless}}{{#if @last}};{{/if}} + {{/each}} + + @override + String toString() => '{{{classname}}}[{{#each vars}}{{{name}}}=${{{name}}}{{#unless @last}}, {{/unless}}{{/each}}]'; + + Map toJson() { + final _json = {}; + {{#each vars}} + {{#if isNullable}} + if ({{{name}}} != null) { + {{/if}} + {{#unless isNullable}} + {{#unless required}} + {{#unless defaultValue}} + if ({{{name}}} != null) { + {{/unless}} + {{/unless}} + {{/unless}} + {{#if isDateTime}} + {{#with pattern}} + _json[r'{{{baseName}}}'] = _dateEpochMarker == '{{{pattern}}}' + ? {{{name}}}{{#if isNullable}}!{{/if}}{{#unless isNullable}}{{#unless required}}{{#unless defaultValue}}!{{/unless}}{{/unless}}{{/unless}}.millisecondsSinceEpoch + : {{{name}}}{{#if isNullable}}!{{/if}}{{#unless isNullable}}{{#unless required}}{{#unless defaultValue}}!{{/unless}}{{/unless}}{{/unless}}.toUtc().toIso8601String(); + {{/with}} + {{#unless pattern}} + _json[r'{{{baseName}}}'] = {{{name}}}{{#if isNullable}}!{{/if}}{{#unless isNullable}}{{#unless required}}{{#unless defaultValue}}!{{/unless}}{{/unless}}{{/unless}}.toUtc().toIso8601String(); + {{/unless}} + {{/if}} + {{#if isDate}} + {{#with pattern}} + _json[r'{{{baseName}}}'] = _dateEpochMarker == '{{{pattern}}}' + ? {{{name}}}{{#if isNullable}}!{{/if}}{{#unless isNullable}}{{#unless required}}{{#unless defaultValue}}!{{/unless}}{{/unless}}{{/unless}}.millisecondsSinceEpoch + : _dateFormatter.format({{{name}}}{{#if isNullable}}!{{/if}}{{#unless isNullable}}{{#unless required}}{{#unless defaultValue}}!{{/unless}}{{/unless}}{{/unless}}.toUtc()); + {{/with}} + {{#unless pattern}} + _json[r'{{{baseName}}}'] = _dateFormatter.format({{{name}}}{{#if isNullable}}!{{/if}}{{#unless isNullable}}{{#unless required}}{{#unless defaultValue}}!{{/unless}}{{/unless}}{{/unless}}.toUtc()); + {{/unless}} + {{/if}} + {{#unless isDateTime}} + {{#unless isDate}} + _json[r'{{{baseName}}}'] = {{{name}}}; + {{/unless}} + {{/unless}} + {{#if isNullable}} + } + {{/if}} + {{#unless isNullable}} + {{#unless required}} + {{#unless defaultValue}} + } + {{/unless}} + {{/unless}} + {{/unless}} + {{/each}} + return _json; + } + + /// Returns a new [{{{classname}}}] instance and imports its values from + /// [value] if it's a [Map], null otherwise. + // ignore: prefer_constructors_over_static_methods + static {{{classname}}}? fromJson(dynamic value) { + if (value is Map) { + final json = value.cast(); + + // Ensure that the map contains the required keys. + // Note 1: the values aren't checked for validity beyond being non-null. + // Note 2: this code is stripped in release mode! + assert(() { + requiredKeys.forEach((key) { + assert(json.containsKey(key), 'Required key "{{{classname}}}[$key]" is missing from JSON.'); + assert(json[key] != null, 'Required key "{{{classname}}}[$key]" has a null value in JSON.'); + }); + return true; + }()); + + return {{{classname}}}( + {{#each vars}} + {{#if isDateTime}} + {{{name}}}: mapDateTime(json, r'{{{baseName}}}', '{{{pattern}}}'){{#with required}}{{#unless isNullable}}!{{/unless}}{{/with}}{{#unless required}}{{#with defaultValue}} ?? {{{.}}}{{/with}}{{/unless}}, + {{/if}} + {{#if isDate}} + {{{name}}}: mapDateTime(json, r'{{{baseName}}}', '{{{pattern}}}'){{#with required}}{{#unless isNullable}}!{{/unless}}{{/with}}{{#unless required}}{{#with defaultValue}} ?? {{{.}}}{{/with}}{{/unless}}, + {{/if}} + {{#unless isDateTime}} + {{#unless isDate}} + {{#with complexType}} + {{#if isArray}} + {{#with items.isArray}} + {{{name}}}: json[r'{{{baseName}}}'] is List + ? (json[r'{{{baseName}}}'] as List).map( + {{#with items.complexType}} + {{items.complexType}}.listFromJson(json[r'{{{baseName}}}']) + {{/with}} + {{#unless items.complexType}} + (e) => e == null ? null : (e as List).cast<{{items.items.dataType}}>() + {{/unless}} + ).toList() + : null, + {{/with}} + {{#unless items.isArray}} + {{{name}}}: {{{complexType}}}.listFromJson(json[r'{{{baseName}}}']){{#with required}}{{#unless isNullable}}!{{/unless}}{{/with}}{{#unless required}}{{#with defaultValue}} ?? {{{.}}}{{/with}}{{/unless}}, + {{/unless}} + {{/if}} + {{#unless isArray}} + {{#if isMap}} + {{#with items.isArray}} + {{{name}}}: json[r'{{{baseName}}}'] == null + ? {{#with defaultValue}}{{{.}}}{{/with}}{{#unless defaultValue}}null{{/unless}} + {{#with items.complexType}} + : {{items.complexType}}.mapListFromJson(json[r'{{{baseName}}}']), + {{/with}} + {{#unless items.complexType}} + : mapCastOfType(json, r'{{{baseName}}}'), + {{/unless}} + {{/with}} + {{#unless items.isArray}} + {{#with items.isMap}} + {{#with items.complexType}} + {{{name}}}: {{items.complexType}}.mapFromJson(json[r'{{{baseName}}}']{{#with required}}{{#unless isNullable}}!{{/unless}}{{/with}}{{#unless required}}{{#with defaultValue}} ?? {{{.}}}{{/with}}{{/unless}}), + {{/with}} + {{#unless items.complexType}} + {{{name}}}: mapCastOfType(json, r'{{{baseName}}}'){{#with required}}{{#unless isNullable}}!{{/unless}}{{/with}}{{#unless required}}{{#with defaultValue}} ?? {{{.}}}{{/with}}{{/unless}}, + {{/unless}} + {{/with}} + {{#unless items.isMap}} + {{#with items.complexType}} + {{{name}}}: {{{items.complexType}}}.mapFromJson(json[r'{{{baseName}}}']{{#with required}}{{#unless isNullable}}!{{/unless}}{{/with}}{{#unless required}}{{#with defaultValue}} ?? {{{.}}}{{/with}}{{/unless}}), + {{/with}} + {{#unless items.complexType}} + {{{name}}}: mapCastOfType(json, r'{{{baseName}}}'){{#with required}}{{#unless isNullable}}!{{/unless}}{{/with}}{{#unless required}}{{#with defaultValue}} ?? {{{.}}}{{/with}}{{/unless}}, + {{/unless}} + {{/unless}} + {{/unless}} + {{/if}} + {{#unless isMap}} + {{#if isBinary}} + {{{name}}}: null, // No support for decoding binary content from JSON + {{/if}} + {{#unless isBinary}} + {{{name}}}: {{{complexType}}}.fromJson(json[r'{{{baseName}}}']){{#with required}}{{#unless isNullable}}!{{/unless}}{{/with}}{{#unless required}}{{#with defaultValue}} ?? {{{.}}}{{/with}}{{/unless}}, + {{/unless}} + {{/unless}} + {{/unless}} + {{/with}} + {{#unless complexType}} + {{#if isArray}} + {{#if isEnum}} + {{{name}}}: {{{items.datatypeWithEnum}}}.listFromJson(json[r'{{{baseName}}}']){{#with required}}{{#unless isNullable}}!{{/unless}}{{/with}}{{#unless required}}{{#with defaultValue}} ?? {{{.}}}{{/with}}{{/unless}}, + {{/if}} + {{#unless isEnum}} + {{{name}}}: json[r'{{{baseName}}}'] is {{#each uniqueItems}}Set{{/each}}{{#unless uniqueItems}}List{{/unless}} + ? (json[r'{{{baseName}}}'] as {{#each uniqueItems}}Set{{/each}}{{#unless uniqueItems}}List{{/unless}}).cast<{{{items.datatype}}}>() + : {{#with defaultValue}}{{{.}}}{{/with}}{{#unless defaultValue}}null{{/unless}}, + {{/unless}} + {{/if}} + {{#unless isArray}} + {{#if isMap}} + {{{name}}}: mapCastOfType(json, r'{{{baseName}}}'){{#with required}}{{#unless isNullable}}!{{/unless}}{{/with}}{{#unless required}}{{#with defaultValue}} ?? {{{.}}}{{/with}}{{/unless}}, + {{/if}} + {{#unless isMap}} + {{#if isNumber}} + {{{name}}}: json[r'{{{baseName}}}'] == null + ? {{#with defaultValue}}{{{.}}}{{/with}}{{#unless defaultValue}}null{{/unless}} + : {{{datatypeWithEnum}}}.parse(json[r'{{{baseName}}}'].toString()), + {{/if}} + {{#unless isNumber}} + {{#unless isEnum}} + {{{name}}}: mapValueOfType<{{{datatypeWithEnum}}}>(json, r'{{{baseName}}}'){{#with required}}{{#unless isNullable}}!{{/unless}}{{/with}}{{#unless required}}{{#with defaultValue}} ?? {{{.}}}{{/with}}{{/unless}}, + {{/unless}} + {{#if isEnum}} + {{{name}}}: {{{enumName}}}.fromJson(json[r'{{{baseName}}}']){{#with required}}{{#unless isNullable}}!{{/unless}}{{/with}}{{#unless required}}{{#with defaultValue}} ?? {{{.}}}{{/with}}{{/unless}}, + {{/if}} + {{/unless}} + {{/unless}} + {{/unless}} + {{/unless}} + {{/unless}} + {{/unless}} + {{/each}} + ); + } + return null; + } + + static List<{{{classname}}}>? listFromJson(dynamic json, {bool growable = false,}) { + final result = <{{{classname}}}>[]; + if (json is List && json.isNotEmpty) { + for (final row in json) { + final value = {{{classname}}}.fromJson(row); + if (value != null) { + result.add(value); + } + } + } + return result.toList(growable: growable); + } + + static Map mapFromJson(dynamic json) { + final map = {}; + if (json is Map && json.isNotEmpty) { + json = json.cast(); // ignore: parameter_assignments + for (final entry in json.entries) { + final value = {{{classname}}}.fromJson(entry.value); + if (value != null) { + map[entry.key] = value; + } + } + } + return map; + } + + // maps a json object with a list of {{{classname}}}-objects as value to a dart map + static Map> mapListFromJson(dynamic json, {bool growable = false,}) { + final map = >{}; + if (json is Map && json.isNotEmpty) { + json = json.cast(); // ignore: parameter_assignments + for (final entry in json.entries) { + final value = {{{classname}}}.listFromJson(entry.value, growable: growable,); + if (value != null) { + map[entry.key] = value; + } + } + } + return map; + } + + /// The list of required keys that must be present in a JSON. + static const requiredKeys = { +{{#each vars}} + {{#with required}} + '{{{baseName}}}', + {{/with}} +{{/each}} + }; +} +{{#each vars}} + {{#unless isModel}} + {{#if isEnum}} + {{#unless isContainer}} + +{{>serialization/native/native_enum_inline}} + {{/unless}} + {{#if isContainer}} + {{#each mostInnerItems}} + +{{>serialization/native/native_enum_inline}} + {{/each}} + {{/if}} + {{/if}} + {{/unless}} +{{/each}} diff --git a/modules/openapi-generator/src/main/resources/dart-handlebars/serialization/native/native_enum.handlebars b/modules/openapi-generator/src/main/resources/dart-handlebars/serialization/native/native_enum.handlebars new file mode 100644 index 000000000000..8a8f59ff776a --- /dev/null +++ b/modules/openapi-generator/src/main/resources/dart-handlebars/serialization/native/native_enum.handlebars @@ -0,0 +1,81 @@ +{{#with description}}/// {{{.}}}{{/with}} +class {{{classname}}} { + /// Instantiate a new enum with the provided [value]. + const {{{classname}}}._(this.value); + + /// The underlying value of this enum member. + final {{{dataType}}} value; + + @override + String toString() => {{#if isString}}value{{/if}}{{#unless isString}}value.toString(){{/unless}}; + + {{{dataType}}} toJson() => value; + + {{#each allowableValues}} + {{#each enumVars}} + static const {{{name}}} = {{{classname}}}._({{#if isString}}r{{/if}}{{{value}}}); + {{/each}} + {{/each}} + + /// List of all possible values in this [enum][{{{classname}}}]. + static const values = <{{{classname}}}>[ + {{#each allowableValues}} + {{#each enumVars}} + {{{name}}}, + {{/each}} + {{/each}} + ]; + + static {{{classname}}}? fromJson(dynamic value) => {{{classname}}}TypeTransformer().decode(value); + + static List<{{{classname}}}>? listFromJson(dynamic json, {bool growable = false,}) { + final result = <{{{classname}}}>[]; + if (json is List && json.isNotEmpty) { + for (final row in json) { + final value = {{{classname}}}.fromJson(row); + if (value != null) { + result.add(value); + } + } + } + return result.toList(growable: growable); + } +} + +/// Transformation class that can [encode] an instance of [{{{classname}}}] to {{{dataType}}}, +/// and [decode] dynamic data back to [{{{classname}}}]. +class {{{classname}}}TypeTransformer { + factory {{{classname}}}TypeTransformer() => _instance ??= const {{{classname}}}TypeTransformer._(); + + const {{{classname}}}TypeTransformer._(); + + {{{dataType}}} encode({{{classname}}} data) => data.value; + + /// Decodes a [dynamic value][data] to a {{{classname}}}. + /// + /// If [allowNull] is true and the [dynamic value][data] cannot be decoded successfully, + /// then null is returned. However, if [allowNull] is false and the [dynamic value][data] + /// cannot be decoded successfully, then an [UnimplementedError] is thrown. + /// + /// The [allowNull] is very handy when an API changes and a new enum value is added or removed, + /// and users are still using an old app with the old code. + {{{classname}}}? decode(dynamic data, {bool allowNull = true}) { + if (data != null) { + switch (data.toString()) { + {{#each allowableValues}} + {{#each enumVars}} + case {{#if isString}}r{{/if}}{{{value}}}: return {{{classname}}}.{{{name}}}; + {{/each}} + {{/each}} + default: + if (!allowNull) { + throw ArgumentError('Unknown enum value to decode: $data'); + } + } + } + return null; + } + + /// Singleton [{{{classname}}}TypeTransformer] instance. + static {{{classname}}}TypeTransformer? _instance; +} diff --git a/modules/openapi-generator/src/main/resources/dart-handlebars/serialization/native/native_enum_inline.handlebars b/modules/openapi-generator/src/main/resources/dart-handlebars/serialization/native/native_enum_inline.handlebars new file mode 100644 index 000000000000..f1f4da8ef095 --- /dev/null +++ b/modules/openapi-generator/src/main/resources/dart-handlebars/serialization/native/native_enum_inline.handlebars @@ -0,0 +1,81 @@ +{{#with description}}/// {{{.}}}{{/with}} +class {{{enumName}}} { + /// Instantiate a new enum with the provided [value]. + const {{{enumName}}}._(this.value); + + /// The underlying value of this enum member. + final {{{dataType}}} value; + + @override + String toString() => {{#if isString}}value{{/if}}{{#unless isString}}value.toString(){{/unless}}; + + {{{dataType}}} toJson() => value; + + {{#each allowableValues}} + {{#each enumVars}} + static const {{{name}}} = {{{enumName}}}._({{#if isString}}r{{/if}}{{{value}}}); + {{/each}} + {{/each}} + + /// List of all possible values in this [enum][{{{enumName}}}]. + static const values = <{{{enumName}}}>[ + {{#each allowableValues}} + {{#each enumVars}} + {{{name}}}, + {{/each}} + {{/each}} + ]; + + static {{{enumName}}}? fromJson(dynamic value) => {{{enumName}}}TypeTransformer().decode(value); + + static List<{{{enumName}}}>? listFromJson(dynamic json, {bool growable = false,}) { + final result = <{{{enumName}}}>[]; + if (json is List && json.isNotEmpty) { + for (final row in json) { + final value = {{{enumName}}}.fromJson(row); + if (value != null) { + result.add(value); + } + } + } + return result.toList(growable: growable); + } +} + +/// Transformation class that can [encode] an instance of [{{{enumName}}}] to {{{dataType}}}, +/// and [decode] dynamic data back to [{{{enumName}}}]. +class {{{enumName}}}TypeTransformer { + factory {{{enumName}}}TypeTransformer() => _instance ??= const {{{enumName}}}TypeTransformer._(); + + const {{{enumName}}}TypeTransformer._(); + + {{{dataType}}} encode({{{enumName}}} data) => data.value; + + /// Decodes a [dynamic value][data] to a {{{enumName}}}. + /// + /// If [allowNull] is true and the [dynamic value][data] cannot be decoded successfully, + /// then null is returned. However, if [allowNull] is false and the [dynamic value][data] + /// cannot be decoded successfully, then an [UnimplementedError] is thrown. + /// + /// The [allowNull] is very handy when an API changes and a new enum value is added or removed, + /// and users are still using an old app with the old code. + {{{enumName}}}? decode(dynamic data, {bool allowNull = true}) { + if (data != null) { + switch (data.toString()) { + {{#each allowableValues}} + {{#each enumVars}} + case {{#if isString}}r{{/if}}{{{value}}}: return {{{enumName}}}.{{{name}}}; + {{/each}} + {{/each}} + default: + if (!allowNull) { + throw ArgumentError('Unknown enum value to decode: $data'); + } + } + } + return null; + } + + /// Singleton [{{{enumName}}}TypeTransformer] instance. + static {{{enumName}}}TypeTransformer? _instance; +} diff --git a/modules/openapi-generator/src/main/resources/dart-handlebars/travis.handlebars b/modules/openapi-generator/src/main/resources/dart-handlebars/travis.handlebars new file mode 100644 index 000000000000..2774ccbba0e9 --- /dev/null +++ b/modules/openapi-generator/src/main/resources/dart-handlebars/travis.handlebars @@ -0,0 +1,14 @@ +# +# AUTO-GENERATED FILE, DO NOT MODIFY! +# +# https://docs.travis-ci.com/user/languages/dart/ +# +language: dart +dart: +# Install a specific stable release +- "2.12" +install: +- pub get + +script: +- pub run test diff --git a/modules/openapi-generator/src/main/resources/dart2/api_client.mustache b/modules/openapi-generator/src/main/resources/dart2/api_client.mustache index 685215a48dd7..7b3fa6f35022 100644 --- a/modules/openapi-generator/src/main/resources/dart2/api_client.mustache +++ b/modules/openapi-generator/src/main/resources/dart2/api_client.mustache @@ -18,7 +18,7 @@ class {{#apiClientName}}{{.}}{{/apiClientName}}{{^apiClientName}}{{{modelNamePre } final _defaultHeaderMap = {}; - final Authentication? authentication; + final {{{modelNamePrefix}}}Authentication{{{modelNameSuffix}}}? authentication; void addDefaultHeader(String key, String value) { _defaultHeaderMap[key] = value; diff --git a/modules/openapi-generator/src/main/resources/dart2/apilib.mustache b/modules/openapi-generator/src/main/resources/dart2/apilib.mustache index 524607f96980..f87ec29ad2a4 100644 --- a/modules/openapi-generator/src/main/resources/dart2/apilib.mustache +++ b/modules/openapi-generator/src/main/resources/dart2/apilib.mustache @@ -30,4 +30,12 @@ final _regList = RegExp(r'^List<(.*)>$'); final _regSet = RegExp(r'^Set<(.*)>$'); final _regMap = RegExp(r'^Map$'); +/// also add individual apis as getters on the primary default api client +extension {{#apiClientName}}{{.}}{{/apiClientName}}{{^apiClientName}}{{{modelNamePrefix}}}ApiClient{{{modelNameSuffix}}}{{/apiClientName}}Extension on {{#apiClientName}}{{.}}{{/apiClientName}}{{^apiClientName}}{{{modelNamePrefix}}}ApiClient{{{modelNameSuffix}}}{{/apiClientName}} { + {{#apiInfo}}{{#apis}} + {{{classname}}} get {{{classVarName}}} => {{{classname}}}(this); + {{/apis}}{{/apiInfo}} +} + + {{#apiClientName}}{{.}}{{/apiClientName}}{{^apiClientName}}{{{modelNamePrefix}}}ApiClient{{{modelNameSuffix}}}{{/apiClientName}} default{{#apiClientName}}{{.}}{{/apiClientName}}{{^apiClientName}}{{{modelNamePrefix}}}ApiClient{{{modelNameSuffix}}}{{/apiClientName}} = {{#apiClientName}}{{.}}{{/apiClientName}}{{^apiClientName}}{{{modelNamePrefix}}}ApiClient{{{modelNameSuffix}}}{{/apiClientName}}(); diff --git a/modules/openapi-generator/src/main/resources/dart2/auth/api_key_auth.mustache b/modules/openapi-generator/src/main/resources/dart2/auth/api_key_auth.mustache index 3edecb1246db..30bc5a6ecd43 100644 --- a/modules/openapi-generator/src/main/resources/dart2/auth/api_key_auth.mustache +++ b/modules/openapi-generator/src/main/resources/dart2/auth/api_key_auth.mustache @@ -1,7 +1,7 @@ {{>header}} {{>part_of}} -class ApiKeyAuth implements Authentication { - ApiKeyAuth(this.location, this.paramName); +class {{{modelNamePrefix}}}ApiKeyAuth{{{modelNameSuffix}}} implements {{{modelNamePrefix}}}Authentication{{{modelNameSuffix}}} { + {{{modelNamePrefix}}}ApiKeyAuth{{{modelNameSuffix}}}(this.location, this.paramName); final String location; final String paramName; diff --git a/modules/openapi-generator/src/main/resources/dart2/auth/authentication.mustache b/modules/openapi-generator/src/main/resources/dart2/auth/authentication.mustache index 807abc505a83..0704665327f8 100644 --- a/modules/openapi-generator/src/main/resources/dart2/auth/authentication.mustache +++ b/modules/openapi-generator/src/main/resources/dart2/auth/authentication.mustache @@ -1,7 +1,7 @@ {{>header}} {{>part_of}} // ignore: one_member_abstracts -abstract class Authentication { +abstract class {{{modelNamePrefix}}}Authentication{{{modelNameSuffix}}} { /// Apply authentication settings to header and query params. void applyToParams(List<{{{modelNamePrefix}}}QueryParam{{{modelNameSuffix}}}> queryParams, Map headerParams); } diff --git a/modules/openapi-generator/src/main/resources/dart2/auth/http_basic_auth.mustache b/modules/openapi-generator/src/main/resources/dart2/auth/http_basic_auth.mustache index d2818027a3cc..1d39280f45c9 100644 --- a/modules/openapi-generator/src/main/resources/dart2/auth/http_basic_auth.mustache +++ b/modules/openapi-generator/src/main/resources/dart2/auth/http_basic_auth.mustache @@ -1,7 +1,7 @@ {{>header}} {{>part_of}} -class HttpBasicAuth implements Authentication { - HttpBasicAuth({this.username = '', this.password = ''}); +class {{{modelNamePrefix}}}HttpBasicAuthentication{{{modelNameSuffix}}} implements {{{modelNamePrefix}}}Authentication{{{modelNameSuffix}}} { + {{{modelNamePrefix}}}HttpBasicAuthentication{{{modelNameSuffix}}}({this.username = '', this.password = ''}); String username; String password; diff --git a/modules/openapi-generator/src/main/resources/dart2/auth/http_bearer_auth.mustache b/modules/openapi-generator/src/main/resources/dart2/auth/http_bearer_auth.mustache index 4fa3ebba1699..0b56af1726a2 100644 --- a/modules/openapi-generator/src/main/resources/dart2/auth/http_bearer_auth.mustache +++ b/modules/openapi-generator/src/main/resources/dart2/auth/http_bearer_auth.mustache @@ -1,16 +1,22 @@ {{>header}} {{>part_of}} -typedef HttpBearerAuthProvider = String Function(); +typedef {{{modelNamePrefix}}}HttpBearerAuthProvider{{{modelNameSuffix}}} = String Function(); -class HttpBearerAuth implements Authentication { - HttpBearerAuth(); +class {{{modelNamePrefix}}}HttpBearerAuthentication{{{modelNameSuffix}}} implements {{{modelNamePrefix}}}Authentication{{{modelNameSuffix}}} { + + /// Constucts [HttpBearerAuthentication] from an optional [accessToken] which will be included in request headers + /// using the `Authorization: Bearer [token]` method. + {{{modelNamePrefix}}}HttpBearerAuthentication{{{modelNameSuffix}}}([dynamic accessToken]) { + this.accessToken = accessToken; + } dynamic _accessToken; dynamic get accessToken => _accessToken; + /// may be a String or a Function that returns a string. set accessToken(dynamic accessToken) { - if (accessToken is! String && accessToken is! HttpBearerAuthProvider) { + if (accessToken is! String && accessToken is! {{{modelNamePrefix}}}HttpBearerAuthProvider{{{modelNameSuffix}}}) { throw ArgumentError('accessToken value must be either a String or a String Function().'); } _accessToken = accessToken; @@ -26,7 +32,7 @@ class HttpBearerAuth implements Authentication { if (_accessToken is String) { accessToken = _accessToken; - } else if (_accessToken is HttpBearerAuthProvider) { + } else if (_accessToken is {{{modelNamePrefix}}}HttpBearerAuthProvider{{{modelNameSuffix}}}) { accessToken = _accessToken!(); } else { return; diff --git a/modules/openapi-generator/src/main/resources/dart2/auth/oauth.mustache b/modules/openapi-generator/src/main/resources/dart2/auth/oauth.mustache index 4ebde3d3a133..b108f1a35cfc 100644 --- a/modules/openapi-generator/src/main/resources/dart2/auth/oauth.mustache +++ b/modules/openapi-generator/src/main/resources/dart2/auth/oauth.mustache @@ -1,7 +1,7 @@ {{>header}} {{>part_of}} -class OAuth implements Authentication { - OAuth({this.accessToken = ''}); +class {{{modelNamePrefix}}}OAuth{{{modelNameSuffix}}} implements {{{modelNamePrefix}}}Authentication{{{modelNameSuffix}}} { + {{{modelNamePrefix}}}OAuth{{{modelNameSuffix}}}({this.accessToken = ''}); String accessToken; diff --git a/modules/openapi-generator/src/main/resources/dart2/serialization/native/native_class.mustache b/modules/openapi-generator/src/main/resources/dart2/serialization/native/native_class.mustache index 872dc9e8ee7c..d8549662f09a 100644 --- a/modules/openapi-generator/src/main/resources/dart2/serialization/native/native_class.mustache +++ b/modules/openapi-generator/src/main/resources/dart2/serialization/native/native_class.mustache @@ -164,7 +164,7 @@ class {{{classname}}} { {{^items.isArray}} {{#items.isMap}} {{#items.complexType}} - {{{name}}}: {{items.complexType}}.mapFromJson(json[r'{{{baseName}}}']){{#required}}{{^isNullable}}!{{/isNullable}}{{/required}}{{^required}}{{#defaultValue}} ?? {{{.}}}{{/defaultValue}}{{/required}}, + {{{name}}}: {{items.complexType}}.mapFromJson(json[r'{{{baseName}}}']{{#required}}{{^isNullable}}!{{/isNullable}}{{/required}}{{^required}}{{#defaultValue}} ?? {{{.}}}{{/defaultValue}}{{/required}}), {{/items.complexType}} {{^items.complexType}} {{{name}}}: mapCastOfType(json, r'{{{baseName}}}'){{#required}}{{^isNullable}}!{{/isNullable}}{{/required}}{{^required}}{{#defaultValue}} ?? {{{.}}}{{/defaultValue}}{{/required}}, @@ -172,7 +172,7 @@ class {{{classname}}} { {{/items.isMap}} {{^items.isMap}} {{#items.complexType}} - {{{name}}}: {{{items.complexType}}}.mapFromJson(json[r'{{{baseName}}}'{{#required}}{{^isNullable}}!{{/isNullable}}{{/required}}{{^required}}{{#defaultValue}}]) ?? {{{.}}}{{/defaultValue}}{{/required}}, + {{{name}}}: {{{items.complexType}}}.mapFromJson(json[r'{{{baseName}}}']{{#required}}{{^isNullable}}!{{/isNullable}}{{/required}}{{^required}}{{#defaultValue}} ?? {{{.}}}{{/defaultValue}}{{/required}}), {{/items.complexType}} {{^items.complexType}} {{{name}}}: mapCastOfType(json, r'{{{baseName}}}'){{#required}}{{^isNullable}}!{{/isNullable}}{{/required}}{{^required}}{{#defaultValue}} ?? {{{.}}}{{/defaultValue}}{{/required}}, From fc9037e68ee074d46aed053f9ed0d52912bf3d3f Mon Sep 17 00:00:00 2001 From: Jeff Mikels Date: Thu, 16 Jun 2022 16:03:10 -0400 Subject: [PATCH 6/6] fixed the default option for API_CLIENT_NAME when testing the DartDio class --- .../dart-handlebars/README.handlebars | 144 --------- .../analysis_options.handlebars | 0 .../resources/dart-handlebars/api.handlebars | 194 ------------ .../dart-handlebars/api_client.handlebars | 262 --------------- .../dart-handlebars/api_doc.handlebars | 96 ------ .../dart-handlebars/api_exception.handlebars | 23 -- .../dart-handlebars/api_helper.handlebars | 100 ------ .../dart-handlebars/api_test.handlebars | 29 -- .../dart-handlebars/apilib.handlebars | 41 --- .../auth/api_key_auth.handlebars | 30 -- .../auth/authentication.handlebars | 7 - .../dart-handlebars/auth/header.handlebars | 9 - .../auth/http_basic_auth.handlebars | 16 - .../auth/http_bearer_auth.handlebars | 45 --- .../dart-handlebars/auth/oauth.handlebars | 14 - .../dart-handlebars/auth/part_of.handlebars | 1 - .../dart_constructor.handlebars | 10 - .../dart-handlebars/git_push.sh.handlebars | 57 ---- .../dart-handlebars/gitignore.handlebars | 17 - .../dart-handlebars/header.handlebars | 9 - .../dart-handlebars/model.handlebars | 16 - .../dart-handlebars/model_test.handlebars | 29 -- .../dart-handlebars/object_doc.handlebars | 16 - .../dart-handlebars/part_of.handlebars | 1 - .../dart-handlebars/pubspec.handlebars | 19 -- .../native/native_class.handlebars | 299 ------------------ .../native/native_enum.handlebars | 81 ----- .../native/native_enum_inline.handlebars | 81 ----- .../dart-handlebars/travis.handlebars | 14 - .../options/DartDioClientOptionsProvider.java | 2 +- 30 files changed, 1 insertion(+), 1661 deletions(-) delete mode 100644 modules/openapi-generator/src/main/resources/dart-handlebars/README.handlebars delete mode 100644 modules/openapi-generator/src/main/resources/dart-handlebars/analysis_options.handlebars delete mode 100644 modules/openapi-generator/src/main/resources/dart-handlebars/api.handlebars delete mode 100644 modules/openapi-generator/src/main/resources/dart-handlebars/api_client.handlebars delete mode 100644 modules/openapi-generator/src/main/resources/dart-handlebars/api_doc.handlebars delete mode 100644 modules/openapi-generator/src/main/resources/dart-handlebars/api_exception.handlebars delete mode 100644 modules/openapi-generator/src/main/resources/dart-handlebars/api_helper.handlebars delete mode 100644 modules/openapi-generator/src/main/resources/dart-handlebars/api_test.handlebars delete mode 100644 modules/openapi-generator/src/main/resources/dart-handlebars/apilib.handlebars delete mode 100644 modules/openapi-generator/src/main/resources/dart-handlebars/auth/api_key_auth.handlebars delete mode 100644 modules/openapi-generator/src/main/resources/dart-handlebars/auth/authentication.handlebars delete mode 100644 modules/openapi-generator/src/main/resources/dart-handlebars/auth/header.handlebars delete mode 100644 modules/openapi-generator/src/main/resources/dart-handlebars/auth/http_basic_auth.handlebars delete mode 100644 modules/openapi-generator/src/main/resources/dart-handlebars/auth/http_bearer_auth.handlebars delete mode 100644 modules/openapi-generator/src/main/resources/dart-handlebars/auth/oauth.handlebars delete mode 100644 modules/openapi-generator/src/main/resources/dart-handlebars/auth/part_of.handlebars delete mode 100644 modules/openapi-generator/src/main/resources/dart-handlebars/dart_constructor.handlebars delete mode 100644 modules/openapi-generator/src/main/resources/dart-handlebars/git_push.sh.handlebars delete mode 100644 modules/openapi-generator/src/main/resources/dart-handlebars/gitignore.handlebars delete mode 100644 modules/openapi-generator/src/main/resources/dart-handlebars/header.handlebars delete mode 100644 modules/openapi-generator/src/main/resources/dart-handlebars/model.handlebars delete mode 100644 modules/openapi-generator/src/main/resources/dart-handlebars/model_test.handlebars delete mode 100644 modules/openapi-generator/src/main/resources/dart-handlebars/object_doc.handlebars delete mode 100644 modules/openapi-generator/src/main/resources/dart-handlebars/part_of.handlebars delete mode 100644 modules/openapi-generator/src/main/resources/dart-handlebars/pubspec.handlebars delete mode 100644 modules/openapi-generator/src/main/resources/dart-handlebars/serialization/native/native_class.handlebars delete mode 100644 modules/openapi-generator/src/main/resources/dart-handlebars/serialization/native/native_enum.handlebars delete mode 100644 modules/openapi-generator/src/main/resources/dart-handlebars/serialization/native/native_enum_inline.handlebars delete mode 100644 modules/openapi-generator/src/main/resources/dart-handlebars/travis.handlebars diff --git a/modules/openapi-generator/src/main/resources/dart-handlebars/README.handlebars b/modules/openapi-generator/src/main/resources/dart-handlebars/README.handlebars deleted file mode 100644 index 447a09ec31c9..000000000000 --- a/modules/openapi-generator/src/main/resources/dart-handlebars/README.handlebars +++ /dev/null @@ -1,144 +0,0 @@ -# {{{pubName}}} -{{#each appDescriptionWithNewLines}} -{{{.}}} -{{/each}} - -This Dart package is automatically generated by the [OpenAPI Generator](https://openapi-generator.tech) project: - -- API version: {{{appVersion}}} -{{#with artifactVersion}} -- Package version: {{{.}}} -{{/with}} -{{#unless hideGenerationTimestamp}} -- Build date: {{{generatedDate}}} -{{/unless}} -- Build package: {{{generatorClass}}} -{{#with infoUrl}} -For more information, please visit [{{{infoUrl}}}]({{{infoUrl}}}) -{{/with}} - -## Requirements - -Dart 2.12 or later - -## Installation & Usage - -### Github -If this Dart package is published to Github, add the following dependency to your pubspec.yaml -``` -dependencies: - {{{pubName}}}: - git: https://{{{gitHost}}}/{{{gitUserId}}}/{{{gitRepoId}}}.git -``` - -### Local -To use the package in your local drive, add the following dependency to your pubspec.yaml -``` -dependencies: - {{{pubName}}}: - path: /path/to/{{{pubName}}} -``` - -## Tests - -TODO - -## Getting Started - -Please follow the [installation procedure](#installation--usage) and then run the following: - -```dart -import 'package:{{{pubName}}}/api.dart'; -{{#with apiInfo}}{{#each apis}}{{#if @first}}{{#each operations}}{{#with operation}}{{#if @first}} -{{#if hasAuthMethods}} -{{#each authMethods}} -{{#if isBasic}} -{{#if isBasicBasic}} -// TODO Configure HTTP basic authorization: {{{name}}} -//default{{#with apiClientName}}{{.}}{{/with}}{{#unless apiClientName}}{{{modelNamePrefix}}}ApiClient{{{modelNameSuffix}}}{{/unless}}.getAuthentication('{{{name}}}').username = 'YOUR_USERNAME' -//default{{#with apiClientName}}{{.}}{{/with}}{{#unless apiClientName}}{{{modelNamePrefix}}}ApiClient{{{modelNameSuffix}}}{{/unless}}.getAuthentication('{{{name}}}').password = 'YOUR_PASSWORD'; -{{/if}} -{{#if isBasicBearer}} -// TODO Configure HTTP Bearer authorization: {{{name}}} -// Case 1. Use String Token -//default{{#with apiClientName}}{{.}}{{/with}}{{#unless apiClientName}}{{{modelNamePrefix}}}ApiClient{{{modelNameSuffix}}}{{/unless}}.getAuthentication('{{{name}}}').setAccessToken('YOUR_ACCESS_TOKEN'); -// Case 2. Use Function which generate token. -// String yourTokenGeneratorFunction() { ... } -//default{{#with apiClientName}}{{.}}{{/with}}{{#unless apiClientName}}{{{modelNamePrefix}}}ApiClient{{{modelNameSuffix}}}{{/unless}}.getAuthentication('{{{name}}}').setAccessToken(yourTokenGeneratorFunction); -{{/if}} -{{/if}} -{{#if isApiKey}} -// TODO Configure API key authorization: {{{name}}} -//default{{#with apiClientName}}{{.}}{{/with}}{{#unless apiClientName}}{{{modelNamePrefix}}}ApiClient{{{modelNameSuffix}}}{{/unless}}.getAuthentication('{{{name}}}').apiKey = 'YOUR_API_KEY'; -// uncomment below to setup prefix (e.g. Bearer) for API key, if needed -//default{{#with apiClientName}}{{.}}{{/with}}{{#unless apiClientName}}{{{modelNamePrefix}}}ApiClient{{{modelNameSuffix}}}{{/unless}}.getAuthentication('{{{name}}}').apiKeyPrefix = 'Bearer'; -{{/if}} -{{#if isOAuth}} -// TODO Configure OAuth2 access token for authorization: {{{name}}} -//default{{#with apiClientName}}{{.}}{{/with}}{{#unless apiClientName}}{{{modelNamePrefix}}}ApiClient{{{modelNameSuffix}}}{{/unless}}.getAuthentication('{{{name}}}').accessToken = 'YOUR_ACCESS_TOKEN'; -{{/if}} -{{/each}} -{{/if}} - -final api_instance = {{{classname}}}(); -{{#each allParams}} -final {{{paramName}}} = {{#if isArray}}[{{/if}}{{#if isBodyParam}}{{{dataType}}}(){{/if}}{{#unless isBodyParam}}{{{example}}}{{/unless}}{{#if isArray}}]{{/if}}; // {{{dataType}}} | {{{description}}} -{{/each}} - -try { - {{#with returnType}}final result = {{/with}}api_instance.{{{operationId}}}({{#each allParams}}{{{paramName}}}{{#unless @last}}, {{/unless}}{{/each}}); - {{#with returnType}} - print(result); - {{/with}} -} catch (e) { - print('Exception when calling {{{classname}}}->{{{operationId}}}: $e\n'); -} -{{/if}}{{/with}}{{/each}}{{/if}}{{/each}}{{/with}} -``` - -## Documentation for API Endpoints - -All URIs are relative to *{{{basePath}}}* - -Class | Method | HTTP request | Description ------------- | ------------- | ------------- | ------------- -{{#with apiInfo}}{{#each apis}}{{#each operations}}{{#with operation}}*{{{classname}}}* | [**{{{operationId}}}**]({{{apiDocPath}}}/{{{classname}}}.md#{{{operationIdLowerCase}}}) | **{{{httpMethod}}}** {{{path}}} | {{{summary}}} -{{/with}}{{/each}}{{/each}}{{/with}} - -## Documentation For Models - -{{#each models}}{{#with model}} - [{{{classname}}}]({{{modelDocPath}}}/{{{classname}}}.md) -{{/with}}{{/each}} - -## Documentation For Authorization - -{{#unless authMethods}} All endpoints do not require authorization. -{{/unless}}{{#each authMethods}}{{#with last}} Authentication schemes defined for the API:{{/with}}{{/each}} -{{#each authMethods}}## {{{name}}} - -{{#if isApiKey}}- **Type**: API key -- **API key parameter name**: {{{keyParamName}}} -- **Location**: {{#if isKeyInQuery}}URL query string{{/if}}{{#if isKeyInHeader}}HTTP header{{/if}} -{{/if}} -{{#if isBasic}} -{{#if isBasicBasic}} -- **Type**: HTTP Basic authentication -{{/if}} -{{#if isBasicBearer}} -- **Type**: HTTP Bearer authentication -{{/if}} -{{/if}} -{{#if isOAuth}}- **Type**: OAuth -- **Flow**: {{{flow}}} -- **Authorization URL**: {{{authorizationUrl}}} -- **Scopes**: {{#unless scopes}}N/A{{/unless}} -{{#each scopes}} - **{{{scope}}}**: {{{description}}} -{{/each}} -{{/if}} - -{{/each}} - -## Author - -{{#with apiInfo}}{{#each apis}}{{#if @last}}{{{infoEmail}}} -{{/if}}{{/each}}{{/with}} diff --git a/modules/openapi-generator/src/main/resources/dart-handlebars/analysis_options.handlebars b/modules/openapi-generator/src/main/resources/dart-handlebars/analysis_options.handlebars deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/modules/openapi-generator/src/main/resources/dart-handlebars/api.handlebars b/modules/openapi-generator/src/main/resources/dart-handlebars/api.handlebars deleted file mode 100644 index 0118205b2372..000000000000 --- a/modules/openapi-generator/src/main/resources/dart-handlebars/api.handlebars +++ /dev/null @@ -1,194 +0,0 @@ -{{>header}} -{{>part_of}} -{{#each operations}} - -class {{{classname}}} { - {{{classname}}}([{{#with apiClientName}}{{.}}{{/with}}{{#unless apiClientName}}{{{modelNamePrefix}}}ApiClient{{{modelNameSuffix}}}{{/unless}}? apiClient]) : apiClient = apiClient ?? default{{#with apiClientName}}{{.}}{{/with}}{{#unless apiClientName}}{{{modelNamePrefix}}}ApiClient{{{modelNameSuffix}}}{{/unless}}; - - final {{#with apiClientName}}{{.}}{{/with}}{{#unless apiClientName}}{{{modelNamePrefix}}}ApiClient{{{modelNameSuffix}}}{{/unless}} apiClient; - {{#with operation}} - - {{#with summary}} - /// {{{.}}} - {{/with}} - {{#each notes}} - {{#with summary}} - /// - {{/with}} - /// {{{notes}}} - /// - /// Note: This method returns the HTTP [Response]. - {{/each}} - {{#unless notes}} - {{#with summary}} - /// - /// Note: This method returns the HTTP [Response]. - {{/with}} - {{#unless summary}} - /// Performs an HTTP '{{{httpMethod}}} {{{path}}}' operation and returns the [Response]. - {{/unless}} - {{/unless}} - {{#if hasParams}} - {{#with summary}} - /// - {{/with}} - {{#unless summary}} - {{#each notes}} - /// - {{/each}} - {{/unless}} - /// Parameters: - /// - {{/if}} - {{#each allParams}} - /// * [{{{dataType}}}] {{{paramName}}}{{#with required}} (required){{/with}}{{#with optional}} (optional){{/with}}: - {{#with description}} - /// {{{.}}} - {{/with}} - {{#unless @last}} - /// - {{/unless}} - {{/each}} - Future {{{nickname}}}WithHttpInfo({{#each allParams}}{{#with required}}{{{dataType}}} {{{paramName}}},{{#unless @last}} {{/unless}}{{/with}}{{/each}}{{#if hasOptionalParams}}{ {{#each allParams}}{{#unless required}}{{{dataType}}}? {{{paramName}}},{{#unless @last}} {{/unless}}{{/unless}}{{/each}} }{{/if}}) async { - // ignore: prefer_const_declarations - final path = r'{{{path}}}'{{#each pathParams}} - .replaceAll({{=<% %>=}}'{<% baseName %>}'<%={{ }}=%>, {{{paramName}}}{{#unless isString}}.toString(){{/unless}}){{/each}}; - - // ignore: prefer_final_locals - Object? postBody{{#with bodyParam}} = {{{paramName}}}{{/with}}; - - final queryParams = <{{{modelNamePrefix}}}QueryParam{{{modelNameSuffix}}}>[]; - final headerParams = {}; - final formParams = {}; - {{#if hasQueryParams}} - - {{#each queryParams}} - {{#unless required}} - if ({{{paramName}}} != null) { - {{/unless}} - queryParams.addAll(_queryParams('{{{collectionFormat}}}', '{{{baseName}}}', {{{paramName}}})); - {{#unless required}} - } - {{/unless}} - {{/each}} - {{/if}} - {{#if hasHeaderParams}} - - {{#each headerParams}} - {{#with required}} - headerParams[r'{{{baseName}}}'] = parameterToString({{{paramName}}}); - {{/with}} - {{#unless required}} - if ({{{paramName}}} != null) { - headerParams[r'{{{baseName}}}'] = parameterToString({{{paramName}}}); - } - {{/unless}} - {{/each}} - {{/if}} - - const contentTypes = [{{#each prioritizedContentTypes}}'{{{mediaType}}}'{{#unless @last}}, {{/unless}}{{/each}}]; - - {{#if isMultipart}} - bool hasFields = false; - final mp = MultipartRequest('{{{httpMethod}}}', Uri.parse(path)); - {{#each formParams}} - {{#unless isFile}} - if ({{{paramName}}} != null) { - hasFields = true; - mp.fields[r'{{{baseName}}}'] = parameterToString({{{paramName}}}); - } - {{/unless}} - {{#if isFile}} - if ({{{paramName}}} != null) { - hasFields = true; - mp.fields[r'{{{baseName}}}'] = {{{paramName}}}.field; - mp.files.add({{{paramName}}}); - } - {{/if}} - {{/each}} - if (hasFields) { - postBody = mp; - } - {{/if}} - {{#unless isMultipart}} - {{#each formParams}} - {{#unless isFile}} - if ({{{paramName}}} != null) { - formParams[r'{{{baseName}}}'] = parameterToString({{{paramName}}}); - } - {{/unless}} - {{/each}} - {{/unless}} - - return apiClient.invokeAPI( - path, - '{{{httpMethod}}}', - queryParams, - postBody, - headerParams, - formParams, - contentTypes.isEmpty ? null : contentTypes.first, - ); - } - - {{#with summary}} - /// {{{.}}} - {{/with}} - {{#each notes}} - {{#with summary}} - /// - {{/with}} - /// {{{notes}}} - {{/each}} - {{#if hasParams}} - {{#with summary}} - /// - {{/with}} - {{#unless summary}} - {{#each notes}} - /// - {{/each}} - {{/unless}} - /// Parameters: - /// - {{/if}} - {{#each allParams}} - /// * [{{{dataType}}}] {{{paramName}}}{{#with required}} (required){{/with}}{{#with optional}} (optional){{/with}}: - {{#with description}} - /// {{{.}}} - {{/with}} - {{#unless @last}} - /// - {{/unless}} - {{/each}} - Future<{{#with returnType}}{{{.}}}?{{/with}}{{#unless returnType}}void{{/unless}}> {{{nickname}}}({{#each allParams}}{{#with required}}{{{dataType}}} {{{paramName}}},{{#unless @last}} {{/unless}}{{/with}}{{/each}}{{#if hasOptionalParams}}{ {{#each allParams}}{{#unless required}}{{{dataType}}}? {{{paramName}}},{{#unless @last}} {{/unless}}{{/unless}}{{/each}} }{{/if}}) async { - final response = await {{{nickname}}}WithHttpInfo({{#each allParams}}{{#with required}}{{{paramName}}},{{#unless @last}} {{/unless}}{{/with}}{{/each}}{{#if hasOptionalParams}} {{#each allParams}}{{#unless required}}{{{paramName}}}: {{{paramName}}},{{#unless @last}} {{/unless}}{{/unless}}{{/each}} {{/if}}); - if (response.statusCode >= HttpStatus.badRequest) { - throw {{{modelNamePrefix}}}ApiException{{{modelNameSuffix}}}(response.statusCode, await _decodeBodyBytes(response)); - } - {{#with returnType}} - // When a remote server returns no body with a status of 204, we shall not decode it. - // At the time of writing this, `dart:convert` will throw an "Unexpected end of input" - // FormatException when trying to decode an empty string. - if (response.body.isNotEmpty && response.statusCode != HttpStatus.noContent) { - {{#with native_serialization}} - {{#if isArray}} - final responseBody = await _decodeBodyBytes(response); - return (await apiClient.deserializeAsync(responseBody, '{{{returnType}}}') as List) - .cast<{{{returnInnerType}}}>() - .{{#each uniqueItems}}toSet(){{/each}}{{#unless uniqueItems}}toList(){{/unless}}; - {{/if}} - {{#unless isArray}} - {{#if isMap}} - return {{{returnType}}}.from(await apiClient.deserializeAsync(await _decodeBodyBytes(response), '{{{returnType}}}'),); - {{/if}} - {{#unless isMap}} - return await apiClient.deserializeAsync(await _decodeBodyBytes(response), '{{{returnType}}}',) as {{{returnType}}}; - {{/unless}}{{/unless}}{{/with}} - } - return null; - {{/with}} - } - {{/with}} -} -{{/each}} diff --git a/modules/openapi-generator/src/main/resources/dart-handlebars/api_client.handlebars b/modules/openapi-generator/src/main/resources/dart-handlebars/api_client.handlebars deleted file mode 100644 index 1a38924a25ab..000000000000 --- a/modules/openapi-generator/src/main/resources/dart-handlebars/api_client.handlebars +++ /dev/null @@ -1,262 +0,0 @@ -{{>header}} -{{>part_of}} -class {{#with apiClientName}}{{.}}{{/with}}{{#unless apiClientName}}{{{modelNamePrefix}}}ApiClient{{{modelNameSuffix}}}{{/unless}} { - {{#with apiClientName}}{{.}}{{/with}}{{#unless apiClientName}}{{{modelNamePrefix}}}ApiClient{{{modelNameSuffix}}}{{/unless}}({this.basePath = '{{{basePath}}}', this.authentication}); - - final String basePath; - - var _client = Client(); - - /// Returns the current HTTP [Client] instance to use in this class. - /// - /// The return value is guaranteed to never be null. - Client get client => _client; - - /// Requests to use a new HTTP [Client] in this class. - set client(Client newClient) { - _client = newClient; - } - - final _defaultHeaderMap = {}; - final {{{modelNamePrefix}}}Authentication{{{modelNameSuffix}}}? authentication; - - void addDefaultHeader(String key, String value) { - _defaultHeaderMap[key] = value; - } - - Map get defaultHeaderMap => _defaultHeaderMap; - - // We don't use a Map for queryParams. - // If collectionFormat is 'multi', a key might appear multiple times. - Future invokeAPI( - String path, - String method, - List<{{{modelNamePrefix}}}QueryParam{{{modelNameSuffix}}}> queryParams, - Object? body, - Map headerParams, - Map formParams, - String? contentType, - ) async { - _updateParamsForAuth(queryParams, headerParams); - - headerParams.addAll(_defaultHeaderMap); - if (contentType != null) { - headerParams['Content-Type'] = contentType; - } - - final urlEncoded{{{modelNamePrefix}}}QueryParam{{{modelNameSuffix}}}s = queryParams.map((param) => '$param'); - final queryString = urlEncoded{{{modelNamePrefix}}}QueryParam{{{modelNameSuffix}}}s.isNotEmpty ? '?${urlEncoded{{{modelNamePrefix}}}QueryParam{{{modelNameSuffix}}}s.join('&')}' : ''; - final uri = Uri.parse('$basePath$path$queryString'); - - try { - // Special case for uploading a single file which isn't a 'multipart/form-data'. - if ( - body is MultipartFile && (contentType == null || - !contentType.toLowerCase().startsWith('multipart/form-data')) - ) { - final request = StreamedRequest(method, uri); - request.headers.addAll(headerParams); - request.contentLength = body.length; - body.finalize().listen( - request.sink.add, - onDone: request.sink.close, - // ignore: avoid_types_on_closure_parameters - onError: (Object error, StackTrace trace) => request.sink.close(), - cancelOnError: true, - ); - final response = await _client.send(request); - return Response.fromStream(response); - } - - if (body is MultipartRequest) { - final request = MultipartRequest(method, uri); - request.fields.addAll(body.fields); - request.files.addAll(body.files); - request.headers.addAll(body.headers); - request.headers.addAll(headerParams); - final response = await _client.send(request); - return Response.fromStream(response); - } - - final msgBody = contentType == 'application/x-www-form-urlencoded' - ? formParams - : await serializeAsync(body); - final nullableHeaderParams = headerParams.isEmpty ? null : headerParams; - - switch(method) { - case 'POST': return await _client.post(uri, headers: nullableHeaderParams, body: msgBody,); - case 'PUT': return await _client.put(uri, headers: nullableHeaderParams, body: msgBody,); - case 'DELETE': return await _client.delete(uri, headers: nullableHeaderParams, body: msgBody,); - case 'PATCH': return await _client.patch(uri, headers: nullableHeaderParams, body: msgBody,); - case 'HEAD': return await _client.head(uri, headers: nullableHeaderParams,); - case 'GET': return await _client.get(uri, headers: nullableHeaderParams,); - } - } on SocketException catch (error, trace) { - throw {{{modelNamePrefix}}}ApiException{{{modelNameSuffix}}}.withInner( - HttpStatus.badRequest, - 'Socket operation failed: $method $path', - error, - trace, - ); - } on TlsException catch (error, trace) { - throw {{{modelNamePrefix}}}ApiException{{{modelNameSuffix}}}.withInner( - HttpStatus.badRequest, - 'TLS/SSL communication failed: $method $path', - error, - trace, - ); - } on IOException catch (error, trace) { - throw {{{modelNamePrefix}}}ApiException{{{modelNameSuffix}}}.withInner( - HttpStatus.badRequest, - 'I/O operation failed: $method $path', - error, - trace, - ); - } on ClientException catch (error, trace) { - throw {{{modelNamePrefix}}}ApiException{{{modelNameSuffix}}}.withInner( - HttpStatus.badRequest, - 'HTTP connection failed: $method $path', - error, - trace, - ); - } on Exception catch (error, trace) { - throw {{{modelNamePrefix}}}ApiException{{{modelNameSuffix}}}.withInner( - HttpStatus.badRequest, - 'Exception occurred: $method $path', - error, - trace, - ); - } - - throw {{{modelNamePrefix}}}ApiException{{{modelNameSuffix}}}( - HttpStatus.badRequest, - 'Invalid HTTP operation: $method $path', - ); - } -{{#with native_serialization}} - - Future deserializeAsync(String json, String targetType, {bool growable = false,}) async => - // ignore: deprecated_member_use_from_same_package - deserialize(json, targetType, growable: growable); - - @Deprecated('Scheduled for removal in OpenAPI Generator 6.x. Use deserializeAsync() instead.') - dynamic deserialize(String json, String targetType, {bool growable = false,}) { - // Remove all spaces. Necessary for regular expressions as well. - targetType = targetType.replaceAll(' ', ''); // ignore: parameter_assignments - - // If the expected target type is String, nothing to do... - return targetType == 'String' - ? json - : _deserialize(jsonDecode(json), targetType, growable: growable); - } -{{/with}} - - // ignore: deprecated_member_use_from_same_package - Future serializeAsync(Object? value) async => serialize(value); - - @Deprecated('Scheduled for removal in OpenAPI Generator 6.x. Use serializeAsync() instead.') - String serialize(Object? value) => value == null ? '' : json.encode(value); - - /// Update query and header parameters based on authentication settings. - void _updateParamsForAuth( - List<{{{modelNamePrefix}}}QueryParam{{{modelNameSuffix}}}> queryParams, - Map headerParams, - ) { - if (authentication != null) { - authentication!.applyToParams(queryParams, headerParams); - } - } - -{{#with native_serialization}} - static dynamic _deserialize(dynamic value, String targetType, {bool growable = false}) { - try { - switch (targetType) { - case 'String': - return value is String ? value : value.toString(); - case 'int': - return value is int ? value : int.parse('$value'); - case 'double': - return value is double ? value : double.parse('$value'); - case 'bool': - if (value is bool) { - return value; - } - final valueString = '$value'.toLowerCase(); - return valueString == 'true' || valueString == '1'; - case 'DateTime': - return value is DateTime ? value : DateTime.tryParse(value); - {{#each models}} - {{#with model}} - case '{{{classname}}}': - {{#if isEnum}} - {{#with native_serialization}}return {{{classname}}}TypeTransformer().decode(value);{{/with}} - {{/if}} - {{#unless isEnum}} - return {{{classname}}}.fromJson(value); - {{/unless}} - {{/with}} - {{/each}} - default: - dynamic match; - if (value is List && (match = _regList.firstMatch(targetType)?.group(1)) != null) { - return value - .map((dynamic v) => _deserialize(v, match, growable: growable,)) - .toList(growable: growable); - } - if (value is Set && (match = _regSet.firstMatch(targetType)?.group(1)) != null) { - return value - .map((dynamic v) => _deserialize(v, match, growable: growable,)) - .toSet(); - } - if (value is Map && (match = _regMap.firstMatch(targetType)?.group(1)) != null) { - return Map.fromIterables( - value.keys.cast(), - value.values.map((dynamic v) => _deserialize(v, match, growable: growable,)), - ); - } - } - } on Exception catch (error, trace) { - throw {{{modelNamePrefix}}}ApiException{{{modelNameSuffix}}}.withInner(HttpStatus.internalServerError, 'Exception during deserialization.', error, trace,); - } - throw {{{modelNamePrefix}}}ApiException{{{modelNameSuffix}}}(HttpStatus.internalServerError, 'Could not find a suitable class for deserialization',); - } -{{/with}} -} -{{#with native_serialization}} - -/// Primarily intended for use in an isolate. -class DeserializationMessage { - const DeserializationMessage({ - required this.json, - required this.targetType, - this.growable = false, - }); - - /// The JSON value to deserialize. - final String json; - - /// Target type to deserialize to. - final String targetType; - - /// Whether to make deserialized lists or maps growable. - final bool growable; -} - -/// Primarily intended for use in an isolate. -Future deserializeAsync(DeserializationMessage message) async { - // Remove all spaces. Necessary for regular expressions as well. - final targetType = message.targetType.replaceAll(' ', ''); - - // If the expected target type is String, nothing to do... - return targetType == 'String' - ? message.json - : {{#with apiClientName}}{{.}}{{/with}}{{#unless apiClientName}}{{{modelNamePrefix}}}ApiClient{{{modelNameSuffix}}}{{/unless}}._deserialize( - jsonDecode(message.json), - targetType, - growable: message.growable, - ); -} -{{/with}} - -/// Primarily intended for use in an isolate. -Future serializeAsync(Object? value) async => value == null ? '' : json.encode(value); diff --git a/modules/openapi-generator/src/main/resources/dart-handlebars/api_doc.handlebars b/modules/openapi-generator/src/main/resources/dart-handlebars/api_doc.handlebars deleted file mode 100644 index 4776f32a8a29..000000000000 --- a/modules/openapi-generator/src/main/resources/dart-handlebars/api_doc.handlebars +++ /dev/null @@ -1,96 +0,0 @@ -# {{{pubName}}}.api.{{{classname}}}{{#with description}} -{{{.}}}{{/with}} - -## Load the API package -```dart -import 'package:{{{pubName}}}/api.dart'; -``` - -All URIs are relative to *{{{basePath}}}* - -Method | HTTP request | Description -------------- | ------------- | ------------- -{{#each operations}}{{#with operation}}[**{{{operationId}}}**]({{{classname}}}.md#{{{operationIdLowerCase}}}) | **{{{httpMethod}}}** {{{path}}} | {{{summary}}} -{{/with}}{{/each}} - -{{#each operations}} -{{#with operation}} -# **{{{operationId}}}** -> {{#with returnType}}{{{.}}} {{/with}}{{{operationId}}}({{#each allParams}}{{{paramName}}}{{#unless @last}}, {{/unless}}{{/each}}) - -{{{summary}}}{{#each notes}} - -{{{.}}}{{/each}} - -### Example -```dart -import 'package:{{{pubName}}}/api.dart'; -{{#if hasAuthMethods}} -{{#each authMethods}} -{{#if isBasic}} -{{#if isBasicBasic}} -// TODO Configure HTTP basic authorization: {{{name}}} -//default{{#with apiClientName}}{{.}}{{/with}}{{#unless apiClientName}}{{{modelNamePrefix}}}ApiClient{{{modelNameSuffix}}}{{/unless}}.getAuthentication('{{{name}}}').username = 'YOUR_USERNAME' -//default{{#with apiClientName}}{{.}}{{/with}}{{#unless apiClientName}}{{{modelNamePrefix}}}ApiClient{{{modelNameSuffix}}}{{/unless}}.getAuthentication('{{{name}}}').password = 'YOUR_PASSWORD'; -{{/if}} -{{#if isBasicBearer}} -// TODO Configure HTTP Bearer authorization: {{{name}}} -// Case 1. Use String Token -//default{{#with apiClientName}}{{.}}{{/with}}{{#unless apiClientName}}{{{modelNamePrefix}}}ApiClient{{{modelNameSuffix}}}{{/unless}}.getAuthentication('{{{name}}}').setAccessToken('YOUR_ACCESS_TOKEN'); -// Case 2. Use Function which generate token. -// String yourTokenGeneratorFunction() { ... } -//default{{#with apiClientName}}{{.}}{{/with}}{{#unless apiClientName}}{{{modelNamePrefix}}}ApiClient{{{modelNameSuffix}}}{{/unless}}.getAuthentication('{{{name}}}').setAccessToken(yourTokenGeneratorFunction); -{{/if}} -{{/if}} -{{#if isApiKey}} -// TODO Configure API key authorization: {{{name}}} -//default{{#with apiClientName}}{{.}}{{/with}}{{#unless apiClientName}}{{{modelNamePrefix}}}ApiClient{{{modelNameSuffix}}}{{/unless}}.getAuthentication('{{{name}}}').apiKey = 'YOUR_API_KEY'; -// uncomment below to setup prefix (e.g. Bearer) for API key, if needed -//default{{#with apiClientName}}{{.}}{{/with}}{{#unless apiClientName}}{{{modelNamePrefix}}}ApiClient{{{modelNameSuffix}}}{{/unless}}.getAuthentication('{{{name}}}').apiKeyPrefix = 'Bearer'; -{{/if}} -{{#if isOAuth}} -// TODO Configure OAuth2 access token for authorization: {{{name}}} -//default{{#with apiClientName}}{{.}}{{/with}}{{#unless apiClientName}}{{{modelNamePrefix}}}ApiClient{{{modelNameSuffix}}}{{/unless}}.getAuthentication('{{{name}}}').accessToken = 'YOUR_ACCESS_TOKEN'; -{{/if}} -{{/each}} -{{/if}} - -final api_instance = {{{classname}}}(); -{{#each allParams}} -final {{{paramName}}} = {{#if isArray}}[{{/if}}{{#if isBodyParam}}{{{dataType}}}(){{/if}}{{#unless isBodyParam}}{{{example}}}{{/unless}}{{#if isArray}}]{{/if}}; // {{{dataType}}} | {{{description}}} -{{/each}} - -try { - {{#with returnType}}final result = {{/with}}api_instance.{{{operationId}}}({{#each allParams}}{{{paramName}}}{{#unless @last}}, {{/unless}}{{/each}}); - {{#with returnType}} - print(result); - {{/with}} -} catch (e) { - print('Exception when calling {{{classname}}}->{{{operationId}}}: $e\n'); -} -``` - -### Parameters -{{#unless allParams}}This endpoint does not need any parameter.{{/unless}}{{#each allParams}}{{#if @last}} -Name | Type | Description | Notes -------------- | ------------- | ------------- | -------------{{/if}}{{/each}} -{{#each allParams}} **{{{paramName}}}** | {{#if isPrimitiveType}}**{{{dataType}}}**{{/if}}{{#unless isPrimitiveType}}[**{{{dataType}}}**]({{{baseType}}}.md){{/unless}}| {{{description}}} | {{#unless required}}[optional] {{/unless}}{{#with defaultValue}}[default to {{{.}}}]{{/with}} -{{/each}} - -### Return type - -{{#with returnType}}{{#with returnTypeIsPrimitive}}**{{{returnType}}}**{{/with}}{{#unless returnTypeIsPrimitive}}[**{{{returnType}}}**]({{{returnBaseType}}}.md){{/unless}}{{/with}}{{#unless returnType}}void (empty response body){{/unless}} - -### Authorization - -{{#unless authMethods}}No authorization required{{/unless}}{{#each authMethods}}[{{{name}}}](../README.md#{{{name}}}){{#unless @last}}, {{/unless}}{{/each}} - -### HTTP request headers - - - **Content-Type**: {{#each consumes}}{{{mediaType}}}{{#unless @last}}, {{/unless}}{{/each}}{{#unless consumes}}Not defined{{/unless}} - - **Accept**: {{#each produces}}{{{mediaType}}}{{#unless @last}}, {{/unless}}{{/each}}{{#unless produces}}Not defined{{/unless}} - -[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) - -{{/with}} -{{/each}} diff --git a/modules/openapi-generator/src/main/resources/dart-handlebars/api_exception.handlebars b/modules/openapi-generator/src/main/resources/dart-handlebars/api_exception.handlebars deleted file mode 100644 index 445dcc89b535..000000000000 --- a/modules/openapi-generator/src/main/resources/dart-handlebars/api_exception.handlebars +++ /dev/null @@ -1,23 +0,0 @@ -{{>header}} -{{>part_of}} -class {{{modelNamePrefix}}}ApiException{{{modelNameSuffix}}} implements Exception { - {{{modelNamePrefix}}}ApiException{{{modelNameSuffix}}}(this.code, this.message); - - {{{modelNamePrefix}}}ApiException{{{modelNameSuffix}}}.withInner(this.code, this.message, this.innerException, this.stackTrace); - - int code = 0; - String? message; - Exception? innerException; - StackTrace? stackTrace; - - @override - String toString() { - if (message == null) { - return '{{{modelNamePrefix}}}ApiException{{{modelNameSuffix}}}'; - } - if (innerException == null) { - return '{{{modelNamePrefix}}}ApiException{{{modelNameSuffix}}} $code: $message'; - } - return '{{{modelNamePrefix}}}ApiException{{{modelNameSuffix}}} $code: $message (Inner exception: $innerException)\n\n$stackTrace'; - } -} diff --git a/modules/openapi-generator/src/main/resources/dart-handlebars/api_helper.handlebars b/modules/openapi-generator/src/main/resources/dart-handlebars/api_helper.handlebars deleted file mode 100644 index 9450e513e75b..000000000000 --- a/modules/openapi-generator/src/main/resources/dart-handlebars/api_helper.handlebars +++ /dev/null @@ -1,100 +0,0 @@ -{{>header}} -{{>part_of}} -class {{{modelNamePrefix}}}QueryParam{{{modelNameSuffix}}} { - const {{{modelNamePrefix}}}QueryParam{{{modelNameSuffix}}}(this.name, this.value); - - final String name; - final String value; - - @override - String toString() => '${Uri.encodeQueryComponent(name)}=${Uri.encodeQueryComponent(value)}'; -} - -// Ported from the Java version. -Iterable<{{{modelNamePrefix}}}QueryParam{{{modelNameSuffix}}}> _queryParams(String collectionFormat, String name, dynamic value,) { - // Assertions to run in debug mode only. - assert(name.isNotEmpty, 'Parameter cannot be an empty string.'); - - final params = <{{{modelNamePrefix}}}QueryParam{{{modelNameSuffix}}}>[]; - - if (value is List) { - if (collectionFormat == 'multi') { - return value.map((dynamic v) => {{{modelNamePrefix}}}QueryParam{{{modelNameSuffix}}}(name, parameterToString(v)),); - } - - // Default collection format is 'csv'. - if (collectionFormat.isEmpty) { - collectionFormat = 'csv'; // ignore: parameter_assignments - } - - final delimiter = _delimiters[collectionFormat] ?? ','; - - params.add({{{modelNamePrefix}}}QueryParam{{{modelNameSuffix}}}(name, value.map(parameterToString).join(delimiter),)); - } else if (value != null) { - params.add({{{modelNamePrefix}}}QueryParam{{{modelNameSuffix}}}(name, parameterToString(value))); - } - - return params; -} - -/// Format the given parameter object into a [String]. -String parameterToString(dynamic value) { - if (value == null) { - return ''; - } - if (value is DateTime) { - return value.toUtc().toIso8601String(); - } - {{#each models}} - {{#with model}} - {{#if isEnum}} - if (value is {{{classname}}}) { -{{#with native_serialization}} return {{{classname}}}TypeTransformer().encode(value).toString();{{/with}} - } - {{/if}} - {{/with}} - {{/each}} - return value.toString(); -} - -/// Returns the decoded body as UTF-8 if the given headers indicate an 'application/json' -/// content type. Otherwise, returns the decoded body as decoded by dart:http package. -Future _decodeBodyBytes(Response response) async { - final contentType = response.headers['content-type']; - return contentType != null && contentType.toLowerCase().startsWith('application/json') - ? response.bodyBytes.isEmpty ? '' : utf8.decode(response.bodyBytes) - : response.body; -} - -/// Returns a valid [T] value found at the specified Map [key], null otherwise. -T? mapValueOfType(dynamic map, String key) { - final dynamic value = map is Map ? map[key] : null; - return value is T ? value : null; -} - -/// Returns a valid Map found at the specified Map [key], null otherwise. -Map? mapCastOfType(dynamic map, String key) { - final dynamic value = map is Map ? map[key] : null; - return value is Map ? value.cast() : null; -} - -/// Returns a valid [DateTime] found at the specified Map [key], null otherwise. -DateTime? mapDateTime(dynamic map, String key, [String? pattern]) { - final dynamic value = map is Map ? map[key] : null; - if (value != null) { - int? millis; - if (value is int) { - millis = value; - } else if (value is String) { - if (pattern == _dateEpochMarker) { - millis = int.tryParse(value); - } else { - return DateTime.tryParse(value); - } - } - if (millis != null) { - return DateTime.fromMillisecondsSinceEpoch(millis, isUtc: true); - } - } - return null; -} diff --git a/modules/openapi-generator/src/main/resources/dart-handlebars/api_test.handlebars b/modules/openapi-generator/src/main/resources/dart-handlebars/api_test.handlebars deleted file mode 100644 index 41ce8e1ba4a6..000000000000 --- a/modules/openapi-generator/src/main/resources/dart-handlebars/api_test.handlebars +++ /dev/null @@ -1,29 +0,0 @@ -{{>header}} -import 'package:{{{pubName}}}/api.dart'; -import 'package:test/test.dart'; - -{{#each operations}} - -/// tests for {{{classname}}} -void main() { - // final instance = {{{classname}}}(); - - group('tests for {{{classname}}}', () { - {{#with operation}} - {{#with summary}} - // {{{.}}} - // - {{/with}} - {{#each notes}} - // {{{.}}} - // - {{/each}} - //{{#with returnType}}Future<{{{.}}}> {{/with}}{{#unless returnType}}Future {{/unless}}{{{operationId}}}({{#each allParams}}{{#with required}}{{{dataType}}} {{{paramName}}}{{#unless @last}}, {{/unless}}{{/with}}{{/each}}{{#if hasOptionalParams}}{ {{#each allParams}}{{#unless required}}{{{dataType}}} {{{paramName}}}{{#unless @last}}, {{/unless}}{{/unless}}{{/each}} }{{/if}}) async - test('test {{{operationId}}}', () async { - // TODO - }); - - {{/with}} - }); -} -{{/each}} diff --git a/modules/openapi-generator/src/main/resources/dart-handlebars/apilib.handlebars b/modules/openapi-generator/src/main/resources/dart-handlebars/apilib.handlebars deleted file mode 100644 index 0c6ea524f7d9..000000000000 --- a/modules/openapi-generator/src/main/resources/dart-handlebars/apilib.handlebars +++ /dev/null @@ -1,41 +0,0 @@ -{{>header}} -{{#with pubLibrary}}library {{{.}}};{{/with}}{{#unless pubLibrary}}library {{{pubName}}}.api;{{/unless}} - -import 'dart:async'; -import 'dart:convert'; -import 'dart:io'; - -import 'package:http/http.dart'; -import 'package:intl/intl.dart'; -import 'package:meta/meta.dart'; - -part 'api_client.dart'; -part 'api_helper.dart'; -part 'api_exception.dart'; -part 'auth/authentication.dart'; -part 'auth/api_key_auth.dart'; -part 'auth/oauth.dart'; -part 'auth/http_basic_auth.dart'; -part 'auth/http_bearer_auth.dart'; - -{{#with apiInfo}}{{#each apis}}part 'api/{{{classFilename}}}.dart'; -{{/each}}{{/with}} -{{#each models}}{{#with model}}part 'model/{{{classFilename}}}.dart'; -{{/with}}{{/each}} - -const _delimiters = {'csv': ',', 'ssv': ' ', 'tsv': '\t', 'pipes': '|'}; -const _dateEpochMarker = 'epoch'; -final _dateFormatter = DateFormat('yyyy-MM-dd'); -final _regList = RegExp(r'^List<(.*)>$'); -final _regSet = RegExp(r'^Set<(.*)>$'); -final _regMap = RegExp(r'^Map$'); - -/// also add individual apis as getters on the primary default api client -extension {{#with apiClientName}}{{.}}{{/with}}{{#unless apiClientName}}{{{modelNamePrefix}}}ApiClient{{{modelNameSuffix}}}{{/unless}}Extension on {{#with apiClientName}}{{.}}{{/with}}{{#unless apiClientName}}{{{modelNamePrefix}}}ApiClient{{{modelNameSuffix}}}{{/unless}} { - {{#with apiInfo}}{{#each apis}} - {{{classname}}} get {{{classVarName}}} => {{{classname}}}(this); - {{/each}}{{/with}} -} - - -{{#with apiClientName}}{{.}}{{/with}}{{#unless apiClientName}}{{{modelNamePrefix}}}ApiClient{{{modelNameSuffix}}}{{/unless}} default{{#with apiClientName}}{{.}}{{/with}}{{#unless apiClientName}}{{{modelNamePrefix}}}ApiClient{{{modelNameSuffix}}}{{/unless}} = {{#with apiClientName}}{{.}}{{/with}}{{#unless apiClientName}}{{{modelNamePrefix}}}ApiClient{{{modelNameSuffix}}}{{/unless}}(); diff --git a/modules/openapi-generator/src/main/resources/dart-handlebars/auth/api_key_auth.handlebars b/modules/openapi-generator/src/main/resources/dart-handlebars/auth/api_key_auth.handlebars deleted file mode 100644 index 30bc5a6ecd43..000000000000 --- a/modules/openapi-generator/src/main/resources/dart-handlebars/auth/api_key_auth.handlebars +++ /dev/null @@ -1,30 +0,0 @@ -{{>header}} -{{>part_of}} -class {{{modelNamePrefix}}}ApiKeyAuth{{{modelNameSuffix}}} implements {{{modelNamePrefix}}}Authentication{{{modelNameSuffix}}} { - {{{modelNamePrefix}}}ApiKeyAuth{{{modelNameSuffix}}}(this.location, this.paramName); - - final String location; - final String paramName; - - String apiKeyPrefix = ''; - String apiKey = ''; - - @override - void applyToParams(List<{{{modelNamePrefix}}}QueryParam{{{modelNameSuffix}}}> queryParams, Map headerParams) { - final paramValue = apiKeyPrefix.isEmpty ? apiKey : '$apiKeyPrefix $apiKey'; - - if (paramValue.isNotEmpty) { - if (location == 'query') { - queryParams.add({{{modelNamePrefix}}}QueryParam{{{modelNameSuffix}}}(paramName, paramValue)); - } else if (location == 'header') { - headerParams[paramName] = paramValue; - } else if (location == 'cookie') { - headerParams.update( - 'Cookie', - (existingCookie) => '$existingCookie; $paramName=$paramValue', - ifAbsent: () => '$paramName=$paramValue', - ); - } - } - } -} diff --git a/modules/openapi-generator/src/main/resources/dart-handlebars/auth/authentication.handlebars b/modules/openapi-generator/src/main/resources/dart-handlebars/auth/authentication.handlebars deleted file mode 100644 index 0704665327f8..000000000000 --- a/modules/openapi-generator/src/main/resources/dart-handlebars/auth/authentication.handlebars +++ /dev/null @@ -1,7 +0,0 @@ -{{>header}} -{{>part_of}} -// ignore: one_member_abstracts -abstract class {{{modelNamePrefix}}}Authentication{{{modelNameSuffix}}} { - /// Apply authentication settings to header and query params. - void applyToParams(List<{{{modelNamePrefix}}}QueryParam{{{modelNameSuffix}}}> queryParams, Map headerParams); -} diff --git a/modules/openapi-generator/src/main/resources/dart-handlebars/auth/header.handlebars b/modules/openapi-generator/src/main/resources/dart-handlebars/auth/header.handlebars deleted file mode 100644 index 3799d9d04658..000000000000 --- a/modules/openapi-generator/src/main/resources/dart-handlebars/auth/header.handlebars +++ /dev/null @@ -1,9 +0,0 @@ -// -// AUTO-GENERATED FILE, DO NOT MODIFY! -// -// @dart=2.12 - -// ignore_for_file: unused_element, unused_import -// ignore_for_file: always_put_required_named_parameters_first -// ignore_for_file: constant_identifier_names -// ignore_for_file: lines_longer_than_80_chars diff --git a/modules/openapi-generator/src/main/resources/dart-handlebars/auth/http_basic_auth.handlebars b/modules/openapi-generator/src/main/resources/dart-handlebars/auth/http_basic_auth.handlebars deleted file mode 100644 index 1d39280f45c9..000000000000 --- a/modules/openapi-generator/src/main/resources/dart-handlebars/auth/http_basic_auth.handlebars +++ /dev/null @@ -1,16 +0,0 @@ -{{>header}} -{{>part_of}} -class {{{modelNamePrefix}}}HttpBasicAuthentication{{{modelNameSuffix}}} implements {{{modelNamePrefix}}}Authentication{{{modelNameSuffix}}} { - {{{modelNamePrefix}}}HttpBasicAuthentication{{{modelNameSuffix}}}({this.username = '', this.password = ''}); - - String username; - String password; - - @override - void applyToParams(List<{{{modelNamePrefix}}}QueryParam{{{modelNameSuffix}}}> queryParams, Map headerParams) { - if (username.isNotEmpty && password.isNotEmpty) { - final credentials = '$username:$password'; - headerParams['Authorization'] = 'Basic ${base64.encode(utf8.encode(credentials))}'; - } - } -} diff --git a/modules/openapi-generator/src/main/resources/dart-handlebars/auth/http_bearer_auth.handlebars b/modules/openapi-generator/src/main/resources/dart-handlebars/auth/http_bearer_auth.handlebars deleted file mode 100644 index 0b56af1726a2..000000000000 --- a/modules/openapi-generator/src/main/resources/dart-handlebars/auth/http_bearer_auth.handlebars +++ /dev/null @@ -1,45 +0,0 @@ -{{>header}} -{{>part_of}} -typedef {{{modelNamePrefix}}}HttpBearerAuthProvider{{{modelNameSuffix}}} = String Function(); - -class {{{modelNamePrefix}}}HttpBearerAuthentication{{{modelNameSuffix}}} implements {{{modelNamePrefix}}}Authentication{{{modelNameSuffix}}} { - - /// Constucts [HttpBearerAuthentication] from an optional [accessToken] which will be included in request headers - /// using the `Authorization: Bearer [token]` method. - {{{modelNamePrefix}}}HttpBearerAuthentication{{{modelNameSuffix}}}([dynamic accessToken]) { - this.accessToken = accessToken; - } - - dynamic _accessToken; - - dynamic get accessToken => _accessToken; - - /// may be a String or a Function that returns a string. - set accessToken(dynamic accessToken) { - if (accessToken is! String && accessToken is! {{{modelNamePrefix}}}HttpBearerAuthProvider{{{modelNameSuffix}}}) { - throw ArgumentError('accessToken value must be either a String or a String Function().'); - } - _accessToken = accessToken; - } - - @override - void applyToParams(List<{{{modelNamePrefix}}}QueryParam{{{modelNameSuffix}}}> queryParams, Map headerParams) { - if (_accessToken == null) { - return; - } - - String accessToken; - - if (_accessToken is String) { - accessToken = _accessToken; - } else if (_accessToken is {{{modelNamePrefix}}}HttpBearerAuthProvider{{{modelNameSuffix}}}) { - accessToken = _accessToken!(); - } else { - return; - } - - if (accessToken.isNotEmpty) { - headerParams['Authorization'] = 'Bearer $accessToken'; - } - } -} diff --git a/modules/openapi-generator/src/main/resources/dart-handlebars/auth/oauth.handlebars b/modules/openapi-generator/src/main/resources/dart-handlebars/auth/oauth.handlebars deleted file mode 100644 index b108f1a35cfc..000000000000 --- a/modules/openapi-generator/src/main/resources/dart-handlebars/auth/oauth.handlebars +++ /dev/null @@ -1,14 +0,0 @@ -{{>header}} -{{>part_of}} -class {{{modelNamePrefix}}}OAuth{{{modelNameSuffix}}} implements {{{modelNamePrefix}}}Authentication{{{modelNameSuffix}}} { - {{{modelNamePrefix}}}OAuth{{{modelNameSuffix}}}({this.accessToken = ''}); - - String accessToken; - - @override - void applyToParams(List<{{{modelNamePrefix}}}QueryParam{{{modelNameSuffix}}}> queryParams, Map headerParams) { - if (accessToken.isNotEmpty) { - headerParams['Authorization'] = 'Bearer $accessToken'; - } - } -} diff --git a/modules/openapi-generator/src/main/resources/dart-handlebars/auth/part_of.handlebars b/modules/openapi-generator/src/main/resources/dart-handlebars/auth/part_of.handlebars deleted file mode 100644 index e4014cd65b65..000000000000 --- a/modules/openapi-generator/src/main/resources/dart-handlebars/auth/part_of.handlebars +++ /dev/null @@ -1 +0,0 @@ -{{#with pubLibrary}}part of {{{.}}};{{/with}}{{#unless pubLibrary}}part of {{{pubName}}}.api;{{/unless}} diff --git a/modules/openapi-generator/src/main/resources/dart-handlebars/dart_constructor.handlebars b/modules/openapi-generator/src/main/resources/dart-handlebars/dart_constructor.handlebars deleted file mode 100644 index 119978ac0624..000000000000 --- a/modules/openapi-generator/src/main/resources/dart-handlebars/dart_constructor.handlebars +++ /dev/null @@ -1,10 +0,0 @@ - /// Returns a new [{{{classname}}}] instance. - {{{classname}}}({ - {{#each vars}} - {{! - A field is required in Dart when it is - required && !defaultValue in OAS - }} - {{#with required}}{{#unless defaultValue}}required {{/unless}}{{/with}}this.{{{name}}}{{#with defaultValue}} = {{#if isEnum}}{{#unless isContainer}}const {{{enumName}}}._({{/unless}}{{/if}}{{{.}}}{{#if isEnum}}{{#unless isContainer}}){{/unless}}{{/if}}{{/with}}, - {{/each}} - }); diff --git a/modules/openapi-generator/src/main/resources/dart-handlebars/git_push.sh.handlebars b/modules/openapi-generator/src/main/resources/dart-handlebars/git_push.sh.handlebars deleted file mode 100644 index 0e3776ae6dd4..000000000000 --- a/modules/openapi-generator/src/main/resources/dart-handlebars/git_push.sh.handlebars +++ /dev/null @@ -1,57 +0,0 @@ -#!/bin/sh -# ref: https://help.github.com/articles/adding-an-existing-project-to-github-using-the-command-line/ -# -# Usage example: /bin/sh ./git_push.sh wing328 openapi-petstore-perl "minor update" "gitlab.com" - -git_user_id=$1 -git_repo_id=$2 -release_note=$3 -git_host=$4 - -if [ "$git_host" = "" ]; then - git_host="{{{gitHost}}}" - echo "[INFO] No command line input provided. Set \$git_host to $git_host" -fi - -if [ "$git_user_id" = "" ]; then - git_user_id="{{{gitUserId}}}" - echo "[INFO] No command line input provided. Set \$git_user_id to $git_user_id" -fi - -if [ "$git_repo_id" = "" ]; then - git_repo_id="{{{gitRepoId}}}" - echo "[INFO] No command line input provided. Set \$git_repo_id to $git_repo_id" -fi - -if [ "$release_note" = "" ]; then - release_note="{{{releaseNote}}}" - echo "[INFO] No command line input provided. Set \$release_note to $release_note" -fi - -# Initialize the local directory as a Git repository -git init - -# Adds the files in the local repository and stages them for commit. -git add . - -# Commits the tracked changes and prepares them to be pushed to a remote repository. -git commit -m "$release_note" - -# Sets the new remote -git_remote=$(git remote) -if [ "$git_remote" = "" ]; then # git remote not defined - - if [ "$GIT_TOKEN" = "" ]; then - echo "[INFO] \$GIT_TOKEN (environment variable) is not set. Using the git credential in your environment." - git remote add origin https://${git_host}/${git_user_id}/${git_repo_id}.git - else - git remote add origin https://${git_user_id}:"${GIT_TOKEN}"@${git_host}/${git_user_id}/${git_repo_id}.git - fi - -fi - -git pull origin master - -# Pushes (Forces) the changes in the local repository up to the remote repository -echo "Git pushing to https://${git_host}/${git_user_id}/${git_repo_id}.git" -git push origin master 2>&1 | grep -v 'To https' diff --git a/modules/openapi-generator/src/main/resources/dart-handlebars/gitignore.handlebars b/modules/openapi-generator/src/main/resources/dart-handlebars/gitignore.handlebars deleted file mode 100644 index 1be28ced0940..000000000000 --- a/modules/openapi-generator/src/main/resources/dart-handlebars/gitignore.handlebars +++ /dev/null @@ -1,17 +0,0 @@ -# See https://dart.dev/guides/libraries/private-files - -.dart_tool/ -.packages -build/ -pubspec.lock # Except for application packages - -doc/api/ - -# IntelliJ -*.iml -*.ipr -*.iws -.idea/ - -# Mac -.DS_Store diff --git a/modules/openapi-generator/src/main/resources/dart-handlebars/header.handlebars b/modules/openapi-generator/src/main/resources/dart-handlebars/header.handlebars deleted file mode 100644 index 3799d9d04658..000000000000 --- a/modules/openapi-generator/src/main/resources/dart-handlebars/header.handlebars +++ /dev/null @@ -1,9 +0,0 @@ -// -// AUTO-GENERATED FILE, DO NOT MODIFY! -// -// @dart=2.12 - -// ignore_for_file: unused_element, unused_import -// ignore_for_file: always_put_required_named_parameters_first -// ignore_for_file: constant_identifier_names -// ignore_for_file: lines_longer_than_80_chars diff --git a/modules/openapi-generator/src/main/resources/dart-handlebars/model.handlebars b/modules/openapi-generator/src/main/resources/dart-handlebars/model.handlebars deleted file mode 100644 index 7bc110d41606..000000000000 --- a/modules/openapi-generator/src/main/resources/dart-handlebars/model.handlebars +++ /dev/null @@ -1,16 +0,0 @@ -{{>header}} -{{>part_of}} -{{#each models}} -{{#with model}} -{{#if isEnum}} -{{#with native_serialization}} -{{>serialization/native/native_enum}} -{{/with}} -{{/if}} -{{#unless isEnum}} -{{#with native_serialization}} -{{>serialization/native/native_class}} -{{/with}} -{{/unless}} -{{/with}} -{{/each}} diff --git a/modules/openapi-generator/src/main/resources/dart-handlebars/model_test.handlebars b/modules/openapi-generator/src/main/resources/dart-handlebars/model_test.handlebars deleted file mode 100644 index c0a5263047e5..000000000000 --- a/modules/openapi-generator/src/main/resources/dart-handlebars/model_test.handlebars +++ /dev/null @@ -1,29 +0,0 @@ -{{>header}} -{{#each models}} -{{#with model}} -import 'package:{{{pubName}}}/api.dart'; -import 'package:test/test.dart'; - -// tests for {{{classname}}} -void main() { - {{#unless isEnum}} - // final instance = {{{classname}}}(); - {{/unless}} - - group('test {{{classname}}}', () { - {{#each vars}} - {{#with description}} - // {{{.}}} - {{/with}} - // {{{dataType}}} {{{name}}}{{#with defaultValue}} (default value: {{{.}}}){{/with}} - test('to test the property `{{{name}}}`', () async { - // TODO - }); - - {{/each}} - - }); - -} -{{/with}} -{{/each}} diff --git a/modules/openapi-generator/src/main/resources/dart-handlebars/object_doc.handlebars b/modules/openapi-generator/src/main/resources/dart-handlebars/object_doc.handlebars deleted file mode 100644 index 977cddc02269..000000000000 --- a/modules/openapi-generator/src/main/resources/dart-handlebars/object_doc.handlebars +++ /dev/null @@ -1,16 +0,0 @@ -{{#each models}}{{#with model}}# {{{pubName}}}.model.{{{classname}}} - -## Load the model package -```dart -import 'package:{{{pubName}}}/api.dart'; -``` - -## Properties -Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- -{{#each vars}}**{{{name}}}** | {{#if isPrimitiveType}}**{{{dataType}}}**{{/if}}{{#unless isPrimitiveType}}[**{{{dataType}}}**]({{{complexType}}}.md){{/unless}} | {{{description}}} | {{#unless required}}[optional] {{/unless}}{{#if isReadOnly}}[readonly] {{/if}}{{#with defaultValue}}[default to {{{.}}}]{{/with}} -{{/each}} - -[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) - -{{/with}}{{/each}} diff --git a/modules/openapi-generator/src/main/resources/dart-handlebars/part_of.handlebars b/modules/openapi-generator/src/main/resources/dart-handlebars/part_of.handlebars deleted file mode 100644 index e4014cd65b65..000000000000 --- a/modules/openapi-generator/src/main/resources/dart-handlebars/part_of.handlebars +++ /dev/null @@ -1 +0,0 @@ -{{#with pubLibrary}}part of {{{.}}};{{/with}}{{#unless pubLibrary}}part of {{{pubName}}}.api;{{/unless}} diff --git a/modules/openapi-generator/src/main/resources/dart-handlebars/pubspec.handlebars b/modules/openapi-generator/src/main/resources/dart-handlebars/pubspec.handlebars deleted file mode 100644 index 5a08fd512b24..000000000000 --- a/modules/openapi-generator/src/main/resources/dart-handlebars/pubspec.handlebars +++ /dev/null @@ -1,19 +0,0 @@ -# -# AUTO-GENERATED FILE, DO NOT MODIFY! -# - -name: '{{{pubName}}}' -version: '{{{pubVersion}}}' -description: '{{{pubDescription}}}' -homepage: '{{{pubHomepage}}}' -environment: - sdk: '>=2.12.0 <3.0.0' -dependencies: - http: '>=0.13.0 <0.14.0' - intl: '^0.17.0' - meta: '^1.1.8' -dev_dependencies: - test: '>=1.16.0 <1.18.0' -{{#with json_serializable}} - build_runner: '^1.10.9' - json_serializable: '^3.5.1'{{/with}} \ No newline at end of file diff --git a/modules/openapi-generator/src/main/resources/dart-handlebars/serialization/native/native_class.handlebars b/modules/openapi-generator/src/main/resources/dart-handlebars/serialization/native/native_class.handlebars deleted file mode 100644 index a2a4297cec16..000000000000 --- a/modules/openapi-generator/src/main/resources/dart-handlebars/serialization/native/native_class.handlebars +++ /dev/null @@ -1,299 +0,0 @@ -class {{{classname}}} { -{{>dart_constructor}} -{{#each vars}} - {{#with description}} - /// {{{.}}} - {{/with}} - {{#unless isEnum}} - {{#with minimum}} - {{#with description}} - /// - {{/with}} - /// Minimum value: {{{.}}} - {{/with}} - {{#with maximum}} - {{#with description}} - {{#unless minimum}} - /// - {{/unless}} - {{/with}} - /// Maximum value: {{{.}}} - {{/with}} - {{#unless isNullable}} - {{#unless required}} - {{#unless defaultValue}} - /// - /// Please note: This property should have been non-nullable! Since the specification file - /// does not include a default value (using the "default:" property), however, the generated - /// source code must fall back to having a nullable type. - /// Consider adding a "default:" property in the specification file to hide this note. - /// - {{/unless}} - {{/unless}} - {{/unless}} - {{/unless}} - {{{datatypeWithEnum}}}{{#if isNullable}}?{{/if}}{{#unless isNullable}}{{#unless required}}{{#unless defaultValue}}?{{/unless}}{{/unless}}{{/unless}} {{{name}}}; - -{{/each}} - @override - bool operator ==(Object other) => identical(this, other) || other is {{{classname}}} && - {{#each vars}} - other.{{{name}}} == {{{name}}}{{#unless @last}} &&{{/unless}}{{#if @last}};{{/if}} - {{/each}} - - @override - int get hashCode => - // ignore: unnecessary_parenthesis - {{#each vars}} - ({{#if isNullable}}{{{name}}} == null ? 0 : {{/if}}{{#unless isNullable}}{{#unless required}}{{#unless defaultValue}}{{{name}}} == null ? 0 : {{/unless}}{{/unless}}{{/unless}}{{{name}}}{{#if isNullable}}!{{/if}}{{#unless isNullable}}{{#unless required}}{{#unless defaultValue}}!{{/unless}}{{/unless}}{{/unless}}.hashCode){{#unless @last}} +{{/unless}}{{#if @last}};{{/if}} - {{/each}} - - @override - String toString() => '{{{classname}}}[{{#each vars}}{{{name}}}=${{{name}}}{{#unless @last}}, {{/unless}}{{/each}}]'; - - Map toJson() { - final _json = {}; - {{#each vars}} - {{#if isNullable}} - if ({{{name}}} != null) { - {{/if}} - {{#unless isNullable}} - {{#unless required}} - {{#unless defaultValue}} - if ({{{name}}} != null) { - {{/unless}} - {{/unless}} - {{/unless}} - {{#if isDateTime}} - {{#with pattern}} - _json[r'{{{baseName}}}'] = _dateEpochMarker == '{{{pattern}}}' - ? {{{name}}}{{#if isNullable}}!{{/if}}{{#unless isNullable}}{{#unless required}}{{#unless defaultValue}}!{{/unless}}{{/unless}}{{/unless}}.millisecondsSinceEpoch - : {{{name}}}{{#if isNullable}}!{{/if}}{{#unless isNullable}}{{#unless required}}{{#unless defaultValue}}!{{/unless}}{{/unless}}{{/unless}}.toUtc().toIso8601String(); - {{/with}} - {{#unless pattern}} - _json[r'{{{baseName}}}'] = {{{name}}}{{#if isNullable}}!{{/if}}{{#unless isNullable}}{{#unless required}}{{#unless defaultValue}}!{{/unless}}{{/unless}}{{/unless}}.toUtc().toIso8601String(); - {{/unless}} - {{/if}} - {{#if isDate}} - {{#with pattern}} - _json[r'{{{baseName}}}'] = _dateEpochMarker == '{{{pattern}}}' - ? {{{name}}}{{#if isNullable}}!{{/if}}{{#unless isNullable}}{{#unless required}}{{#unless defaultValue}}!{{/unless}}{{/unless}}{{/unless}}.millisecondsSinceEpoch - : _dateFormatter.format({{{name}}}{{#if isNullable}}!{{/if}}{{#unless isNullable}}{{#unless required}}{{#unless defaultValue}}!{{/unless}}{{/unless}}{{/unless}}.toUtc()); - {{/with}} - {{#unless pattern}} - _json[r'{{{baseName}}}'] = _dateFormatter.format({{{name}}}{{#if isNullable}}!{{/if}}{{#unless isNullable}}{{#unless required}}{{#unless defaultValue}}!{{/unless}}{{/unless}}{{/unless}}.toUtc()); - {{/unless}} - {{/if}} - {{#unless isDateTime}} - {{#unless isDate}} - _json[r'{{{baseName}}}'] = {{{name}}}; - {{/unless}} - {{/unless}} - {{#if isNullable}} - } - {{/if}} - {{#unless isNullable}} - {{#unless required}} - {{#unless defaultValue}} - } - {{/unless}} - {{/unless}} - {{/unless}} - {{/each}} - return _json; - } - - /// Returns a new [{{{classname}}}] instance and imports its values from - /// [value] if it's a [Map], null otherwise. - // ignore: prefer_constructors_over_static_methods - static {{{classname}}}? fromJson(dynamic value) { - if (value is Map) { - final json = value.cast(); - - // Ensure that the map contains the required keys. - // Note 1: the values aren't checked for validity beyond being non-null. - // Note 2: this code is stripped in release mode! - assert(() { - requiredKeys.forEach((key) { - assert(json.containsKey(key), 'Required key "{{{classname}}}[$key]" is missing from JSON.'); - assert(json[key] != null, 'Required key "{{{classname}}}[$key]" has a null value in JSON.'); - }); - return true; - }()); - - return {{{classname}}}( - {{#each vars}} - {{#if isDateTime}} - {{{name}}}: mapDateTime(json, r'{{{baseName}}}', '{{{pattern}}}'){{#with required}}{{#unless isNullable}}!{{/unless}}{{/with}}{{#unless required}}{{#with defaultValue}} ?? {{{.}}}{{/with}}{{/unless}}, - {{/if}} - {{#if isDate}} - {{{name}}}: mapDateTime(json, r'{{{baseName}}}', '{{{pattern}}}'){{#with required}}{{#unless isNullable}}!{{/unless}}{{/with}}{{#unless required}}{{#with defaultValue}} ?? {{{.}}}{{/with}}{{/unless}}, - {{/if}} - {{#unless isDateTime}} - {{#unless isDate}} - {{#with complexType}} - {{#if isArray}} - {{#with items.isArray}} - {{{name}}}: json[r'{{{baseName}}}'] is List - ? (json[r'{{{baseName}}}'] as List).map( - {{#with items.complexType}} - {{items.complexType}}.listFromJson(json[r'{{{baseName}}}']) - {{/with}} - {{#unless items.complexType}} - (e) => e == null ? null : (e as List).cast<{{items.items.dataType}}>() - {{/unless}} - ).toList() - : null, - {{/with}} - {{#unless items.isArray}} - {{{name}}}: {{{complexType}}}.listFromJson(json[r'{{{baseName}}}']){{#with required}}{{#unless isNullable}}!{{/unless}}{{/with}}{{#unless required}}{{#with defaultValue}} ?? {{{.}}}{{/with}}{{/unless}}, - {{/unless}} - {{/if}} - {{#unless isArray}} - {{#if isMap}} - {{#with items.isArray}} - {{{name}}}: json[r'{{{baseName}}}'] == null - ? {{#with defaultValue}}{{{.}}}{{/with}}{{#unless defaultValue}}null{{/unless}} - {{#with items.complexType}} - : {{items.complexType}}.mapListFromJson(json[r'{{{baseName}}}']), - {{/with}} - {{#unless items.complexType}} - : mapCastOfType(json, r'{{{baseName}}}'), - {{/unless}} - {{/with}} - {{#unless items.isArray}} - {{#with items.isMap}} - {{#with items.complexType}} - {{{name}}}: {{items.complexType}}.mapFromJson(json[r'{{{baseName}}}']{{#with required}}{{#unless isNullable}}!{{/unless}}{{/with}}{{#unless required}}{{#with defaultValue}} ?? {{{.}}}{{/with}}{{/unless}}), - {{/with}} - {{#unless items.complexType}} - {{{name}}}: mapCastOfType(json, r'{{{baseName}}}'){{#with required}}{{#unless isNullable}}!{{/unless}}{{/with}}{{#unless required}}{{#with defaultValue}} ?? {{{.}}}{{/with}}{{/unless}}, - {{/unless}} - {{/with}} - {{#unless items.isMap}} - {{#with items.complexType}} - {{{name}}}: {{{items.complexType}}}.mapFromJson(json[r'{{{baseName}}}']{{#with required}}{{#unless isNullable}}!{{/unless}}{{/with}}{{#unless required}}{{#with defaultValue}} ?? {{{.}}}{{/with}}{{/unless}}), - {{/with}} - {{#unless items.complexType}} - {{{name}}}: mapCastOfType(json, r'{{{baseName}}}'){{#with required}}{{#unless isNullable}}!{{/unless}}{{/with}}{{#unless required}}{{#with defaultValue}} ?? {{{.}}}{{/with}}{{/unless}}, - {{/unless}} - {{/unless}} - {{/unless}} - {{/if}} - {{#unless isMap}} - {{#if isBinary}} - {{{name}}}: null, // No support for decoding binary content from JSON - {{/if}} - {{#unless isBinary}} - {{{name}}}: {{{complexType}}}.fromJson(json[r'{{{baseName}}}']){{#with required}}{{#unless isNullable}}!{{/unless}}{{/with}}{{#unless required}}{{#with defaultValue}} ?? {{{.}}}{{/with}}{{/unless}}, - {{/unless}} - {{/unless}} - {{/unless}} - {{/with}} - {{#unless complexType}} - {{#if isArray}} - {{#if isEnum}} - {{{name}}}: {{{items.datatypeWithEnum}}}.listFromJson(json[r'{{{baseName}}}']){{#with required}}{{#unless isNullable}}!{{/unless}}{{/with}}{{#unless required}}{{#with defaultValue}} ?? {{{.}}}{{/with}}{{/unless}}, - {{/if}} - {{#unless isEnum}} - {{{name}}}: json[r'{{{baseName}}}'] is {{#each uniqueItems}}Set{{/each}}{{#unless uniqueItems}}List{{/unless}} - ? (json[r'{{{baseName}}}'] as {{#each uniqueItems}}Set{{/each}}{{#unless uniqueItems}}List{{/unless}}).cast<{{{items.datatype}}}>() - : {{#with defaultValue}}{{{.}}}{{/with}}{{#unless defaultValue}}null{{/unless}}, - {{/unless}} - {{/if}} - {{#unless isArray}} - {{#if isMap}} - {{{name}}}: mapCastOfType(json, r'{{{baseName}}}'){{#with required}}{{#unless isNullable}}!{{/unless}}{{/with}}{{#unless required}}{{#with defaultValue}} ?? {{{.}}}{{/with}}{{/unless}}, - {{/if}} - {{#unless isMap}} - {{#if isNumber}} - {{{name}}}: json[r'{{{baseName}}}'] == null - ? {{#with defaultValue}}{{{.}}}{{/with}}{{#unless defaultValue}}null{{/unless}} - : {{{datatypeWithEnum}}}.parse(json[r'{{{baseName}}}'].toString()), - {{/if}} - {{#unless isNumber}} - {{#unless isEnum}} - {{{name}}}: mapValueOfType<{{{datatypeWithEnum}}}>(json, r'{{{baseName}}}'){{#with required}}{{#unless isNullable}}!{{/unless}}{{/with}}{{#unless required}}{{#with defaultValue}} ?? {{{.}}}{{/with}}{{/unless}}, - {{/unless}} - {{#if isEnum}} - {{{name}}}: {{{enumName}}}.fromJson(json[r'{{{baseName}}}']){{#with required}}{{#unless isNullable}}!{{/unless}}{{/with}}{{#unless required}}{{#with defaultValue}} ?? {{{.}}}{{/with}}{{/unless}}, - {{/if}} - {{/unless}} - {{/unless}} - {{/unless}} - {{/unless}} - {{/unless}} - {{/unless}} - {{/each}} - ); - } - return null; - } - - static List<{{{classname}}}>? listFromJson(dynamic json, {bool growable = false,}) { - final result = <{{{classname}}}>[]; - if (json is List && json.isNotEmpty) { - for (final row in json) { - final value = {{{classname}}}.fromJson(row); - if (value != null) { - result.add(value); - } - } - } - return result.toList(growable: growable); - } - - static Map mapFromJson(dynamic json) { - final map = {}; - if (json is Map && json.isNotEmpty) { - json = json.cast(); // ignore: parameter_assignments - for (final entry in json.entries) { - final value = {{{classname}}}.fromJson(entry.value); - if (value != null) { - map[entry.key] = value; - } - } - } - return map; - } - - // maps a json object with a list of {{{classname}}}-objects as value to a dart map - static Map> mapListFromJson(dynamic json, {bool growable = false,}) { - final map = >{}; - if (json is Map && json.isNotEmpty) { - json = json.cast(); // ignore: parameter_assignments - for (final entry in json.entries) { - final value = {{{classname}}}.listFromJson(entry.value, growable: growable,); - if (value != null) { - map[entry.key] = value; - } - } - } - return map; - } - - /// The list of required keys that must be present in a JSON. - static const requiredKeys = { -{{#each vars}} - {{#with required}} - '{{{baseName}}}', - {{/with}} -{{/each}} - }; -} -{{#each vars}} - {{#unless isModel}} - {{#if isEnum}} - {{#unless isContainer}} - -{{>serialization/native/native_enum_inline}} - {{/unless}} - {{#if isContainer}} - {{#each mostInnerItems}} - -{{>serialization/native/native_enum_inline}} - {{/each}} - {{/if}} - {{/if}} - {{/unless}} -{{/each}} diff --git a/modules/openapi-generator/src/main/resources/dart-handlebars/serialization/native/native_enum.handlebars b/modules/openapi-generator/src/main/resources/dart-handlebars/serialization/native/native_enum.handlebars deleted file mode 100644 index 8a8f59ff776a..000000000000 --- a/modules/openapi-generator/src/main/resources/dart-handlebars/serialization/native/native_enum.handlebars +++ /dev/null @@ -1,81 +0,0 @@ -{{#with description}}/// {{{.}}}{{/with}} -class {{{classname}}} { - /// Instantiate a new enum with the provided [value]. - const {{{classname}}}._(this.value); - - /// The underlying value of this enum member. - final {{{dataType}}} value; - - @override - String toString() => {{#if isString}}value{{/if}}{{#unless isString}}value.toString(){{/unless}}; - - {{{dataType}}} toJson() => value; - - {{#each allowableValues}} - {{#each enumVars}} - static const {{{name}}} = {{{classname}}}._({{#if isString}}r{{/if}}{{{value}}}); - {{/each}} - {{/each}} - - /// List of all possible values in this [enum][{{{classname}}}]. - static const values = <{{{classname}}}>[ - {{#each allowableValues}} - {{#each enumVars}} - {{{name}}}, - {{/each}} - {{/each}} - ]; - - static {{{classname}}}? fromJson(dynamic value) => {{{classname}}}TypeTransformer().decode(value); - - static List<{{{classname}}}>? listFromJson(dynamic json, {bool growable = false,}) { - final result = <{{{classname}}}>[]; - if (json is List && json.isNotEmpty) { - for (final row in json) { - final value = {{{classname}}}.fromJson(row); - if (value != null) { - result.add(value); - } - } - } - return result.toList(growable: growable); - } -} - -/// Transformation class that can [encode] an instance of [{{{classname}}}] to {{{dataType}}}, -/// and [decode] dynamic data back to [{{{classname}}}]. -class {{{classname}}}TypeTransformer { - factory {{{classname}}}TypeTransformer() => _instance ??= const {{{classname}}}TypeTransformer._(); - - const {{{classname}}}TypeTransformer._(); - - {{{dataType}}} encode({{{classname}}} data) => data.value; - - /// Decodes a [dynamic value][data] to a {{{classname}}}. - /// - /// If [allowNull] is true and the [dynamic value][data] cannot be decoded successfully, - /// then null is returned. However, if [allowNull] is false and the [dynamic value][data] - /// cannot be decoded successfully, then an [UnimplementedError] is thrown. - /// - /// The [allowNull] is very handy when an API changes and a new enum value is added or removed, - /// and users are still using an old app with the old code. - {{{classname}}}? decode(dynamic data, {bool allowNull = true}) { - if (data != null) { - switch (data.toString()) { - {{#each allowableValues}} - {{#each enumVars}} - case {{#if isString}}r{{/if}}{{{value}}}: return {{{classname}}}.{{{name}}}; - {{/each}} - {{/each}} - default: - if (!allowNull) { - throw ArgumentError('Unknown enum value to decode: $data'); - } - } - } - return null; - } - - /// Singleton [{{{classname}}}TypeTransformer] instance. - static {{{classname}}}TypeTransformer? _instance; -} diff --git a/modules/openapi-generator/src/main/resources/dart-handlebars/serialization/native/native_enum_inline.handlebars b/modules/openapi-generator/src/main/resources/dart-handlebars/serialization/native/native_enum_inline.handlebars deleted file mode 100644 index f1f4da8ef095..000000000000 --- a/modules/openapi-generator/src/main/resources/dart-handlebars/serialization/native/native_enum_inline.handlebars +++ /dev/null @@ -1,81 +0,0 @@ -{{#with description}}/// {{{.}}}{{/with}} -class {{{enumName}}} { - /// Instantiate a new enum with the provided [value]. - const {{{enumName}}}._(this.value); - - /// The underlying value of this enum member. - final {{{dataType}}} value; - - @override - String toString() => {{#if isString}}value{{/if}}{{#unless isString}}value.toString(){{/unless}}; - - {{{dataType}}} toJson() => value; - - {{#each allowableValues}} - {{#each enumVars}} - static const {{{name}}} = {{{enumName}}}._({{#if isString}}r{{/if}}{{{value}}}); - {{/each}} - {{/each}} - - /// List of all possible values in this [enum][{{{enumName}}}]. - static const values = <{{{enumName}}}>[ - {{#each allowableValues}} - {{#each enumVars}} - {{{name}}}, - {{/each}} - {{/each}} - ]; - - static {{{enumName}}}? fromJson(dynamic value) => {{{enumName}}}TypeTransformer().decode(value); - - static List<{{{enumName}}}>? listFromJson(dynamic json, {bool growable = false,}) { - final result = <{{{enumName}}}>[]; - if (json is List && json.isNotEmpty) { - for (final row in json) { - final value = {{{enumName}}}.fromJson(row); - if (value != null) { - result.add(value); - } - } - } - return result.toList(growable: growable); - } -} - -/// Transformation class that can [encode] an instance of [{{{enumName}}}] to {{{dataType}}}, -/// and [decode] dynamic data back to [{{{enumName}}}]. -class {{{enumName}}}TypeTransformer { - factory {{{enumName}}}TypeTransformer() => _instance ??= const {{{enumName}}}TypeTransformer._(); - - const {{{enumName}}}TypeTransformer._(); - - {{{dataType}}} encode({{{enumName}}} data) => data.value; - - /// Decodes a [dynamic value][data] to a {{{enumName}}}. - /// - /// If [allowNull] is true and the [dynamic value][data] cannot be decoded successfully, - /// then null is returned. However, if [allowNull] is false and the [dynamic value][data] - /// cannot be decoded successfully, then an [UnimplementedError] is thrown. - /// - /// The [allowNull] is very handy when an API changes and a new enum value is added or removed, - /// and users are still using an old app with the old code. - {{{enumName}}}? decode(dynamic data, {bool allowNull = true}) { - if (data != null) { - switch (data.toString()) { - {{#each allowableValues}} - {{#each enumVars}} - case {{#if isString}}r{{/if}}{{{value}}}: return {{{enumName}}}.{{{name}}}; - {{/each}} - {{/each}} - default: - if (!allowNull) { - throw ArgumentError('Unknown enum value to decode: $data'); - } - } - } - return null; - } - - /// Singleton [{{{enumName}}}TypeTransformer] instance. - static {{{enumName}}}TypeTransformer? _instance; -} diff --git a/modules/openapi-generator/src/main/resources/dart-handlebars/travis.handlebars b/modules/openapi-generator/src/main/resources/dart-handlebars/travis.handlebars deleted file mode 100644 index 2774ccbba0e9..000000000000 --- a/modules/openapi-generator/src/main/resources/dart-handlebars/travis.handlebars +++ /dev/null @@ -1,14 +0,0 @@ -# -# AUTO-GENERATED FILE, DO NOT MODIFY! -# -# https://docs.travis-ci.com/user/languages/dart/ -# -language: dart -dart: -# Install a specific stable release -- "2.12" -install: -- pub get - -script: -- pub run test diff --git a/modules/openapi-generator/src/test/java/org/openapitools/codegen/options/DartDioClientOptionsProvider.java b/modules/openapi-generator/src/test/java/org/openapitools/codegen/options/DartDioClientOptionsProvider.java index 8489e9466ea1..077ee62492c2 100644 --- a/modules/openapi-generator/src/test/java/org/openapitools/codegen/options/DartDioClientOptionsProvider.java +++ b/modules/openapi-generator/src/test/java/org/openapitools/codegen/options/DartDioClientOptionsProvider.java @@ -37,7 +37,7 @@ public class DartDioClientOptionsProvider implements OptionsProvider { public static final String PUB_AUTHOR_VALUE = "Author"; public static final String PUB_AUTHOR_EMAIL_VALUE = "author@homepage"; public static final String PUB_HOMEPAGE_VALUE = "Homepage"; - public static final String API_CLIENT_NAME_VALUE = "Homepage"; + public static final String API_CLIENT_NAME_VALUE = "ApiClient"; public static final String ENUM_UNKNOWN_DEFAULT_CASE_VALUE = "false"; @Override