Skip to content

Commit c98644a

Browse files
amondnetwing328
authored andcommitted
[dart][dio] add dateLibrary options ( core, timemachine ) (#4716)
* feat(dart-dio): add datelibrary options Signed-off-by: Minsu Lee <[email protected]> * fix: missing semicolon Signed-off-by: Minsu Lee <[email protected]> * enum name * fix test * fix test
1 parent 49022d7 commit c98644a

File tree

10 files changed

+807
-20
lines changed

10 files changed

+807
-20
lines changed

docs/generators/dart-dio.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,3 +17,4 @@ sidebar_label: dart-dio
1717
|sourceFolder|Source folder for generated code| |null|
1818
|supportDart2|Support Dart 2.x (Dart 1.x support has been deprecated)| |true|
1919
|nullableFields|Is the null fields should be in the JSON payload| |null|
20+
|dateLibrary|Option. Date library to use|<dl><dt>**core**</dt><dd>Dart core library (DateTime)</dd><dt>**timemachine**</dt><dd>Time Machine is date and time library for Flutter, Web, and Server with support for timezones, calendars, cultures, formatting and parsing.</dd><dl>|core|

modules/openapi-generator/pom.xml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -243,6 +243,11 @@
243243
<artifactId>slf4j-api</artifactId>
244244
<version>${slf4j-version}</version>
245245
</dependency>
246+
<dependency>
247+
<groupId>org.slf4j</groupId>
248+
<artifactId>slf4j-simple</artifactId>
249+
<version>${slf4j-version}</version>
250+
</dependency>
246251
<dependency>
247252
<groupId>org.apache.commons</groupId>
248253
<artifactId>commons-lang3</artifactId>

modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/DartDioClientCodegen.java

Lines changed: 137 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
package org.openapitools.codegen.languages;
1818

19+
import java.util.HashMap;
1920
import org.apache.commons.lang3.StringUtils;
2021
import org.openapitools.codegen.CliOption;
2122
import org.openapitools.codegen.CodegenConstants;
@@ -44,9 +45,10 @@
4445
public class DartDioClientCodegen extends DartClientCodegen {
4546
private static final Logger LOGGER = LoggerFactory.getLogger(DartDioClientCodegen.class);
4647

47-
private static final String NULLABLE_FIELDS = "nullableFields";
48+
public static final String NULLABLE_FIELDS = "nullableFields";
4849
private static final String IS_FORMAT_JSON = "jsonFormat";
4950
private static final String CLIENT_NAME = "clientName";
51+
public static final String DATE_LIBRARY = "dateLibrary";
5052

5153
private static Set<String> modelToIgnore = new HashSet<>();
5254

@@ -62,6 +64,7 @@ public class DartDioClientCodegen extends DartClientCodegen {
6264
private static final String SERIALIZATION_JSON = "json";
6365

6466
private boolean nullableFields = true;
67+
private String dateLibrary = "core";
6568

6669
public DartDioClientCodegen() {
6770
super();
@@ -74,6 +77,12 @@ public DartDioClientCodegen() {
7477
apiTestTemplateFiles.clear();
7578

7679
cliOptions.add(new CliOption(NULLABLE_FIELDS, "Is the null fields should be in the JSON payload"));
80+
CliOption dateLibrary = new CliOption(DATE_LIBRARY, "Option. Date library to use").defaultValue(this.getDateLibrary());
81+
Map<String, String> dateOptions = new HashMap<>();
82+
dateOptions.put("core", "Dart core library (DateTime)");
83+
dateOptions.put("timemachine", "Time Machine is date and time library for Flutter, Web, and Server with support for timezones, calendars, cultures, formatting and parsing.");
84+
dateLibrary.setEnum(dateOptions);
85+
cliOptions.add(dateLibrary);
7786

7887
typeMapping.put("file", "Uint8List");
7988
typeMapping.put("binary", "Uint8List");
@@ -84,6 +93,23 @@ public DartDioClientCodegen() {
8493
importMapping.put("Uint8List", "dart:typed_data");
8594
}
8695

96+
public String getDateLibrary() {
97+
return dateLibrary;
98+
}
99+
100+
public void setDateLibrary(String library) {
101+
this.dateLibrary = library;
102+
}
103+
104+
public boolean getNullableFields() {
105+
return nullableFields;
106+
}
107+
108+
public void setNullableFields(boolean nullableFields) {
109+
this.nullableFields = nullableFields;
110+
}
111+
112+
87113
@Override
88114
public String getName() {
89115
return "dart-dio";
@@ -94,6 +120,10 @@ public String getHelp() {
94120
return "Generates a Dart Dio client library.";
95121
}
96122

123+
@Override public void setBrowserClient(boolean browserClient) {
124+
super.browserClient = browserClient;
125+
}
126+
97127
@Override
98128
public String toDefaultValue(Schema p) {
99129
if (ModelUtils.isMapSchema(p)) {
@@ -105,47 +135,114 @@ public String toDefaultValue(Schema p) {
105135
}
106136

107137
@Override
108-
public String escapeReservedWord(String name) {
109-
if (this.reservedWordsMappings().containsKey(name)) {
110-
return this.reservedWordsMappings().get(name);
111-
}
112-
return "_" + name;
138+
protected void addAdditionPropertiesToCodeGenModel(CodegenModel codegenModel, Schema schema) {
139+
//super.addAdditionPropertiesToCodeGenModel(codegenModel, schema);
140+
codegenModel.additionalPropertiesType = getSchemaType(ModelUtils.getAdditionalProperties(schema));
141+
addImport(codegenModel, codegenModel.additionalPropertiesType);
113142
}
114143

115144
@Override
116145
public String toEnumVarName(String name, String datatype) {
117146
if (name.length() == 0) {
118147
return "empty";
119148
}
120-
if ("number".equalsIgnoreCase(datatype) ||
121-
"int".equalsIgnoreCase(datatype)) {
149+
if ("number".equalsIgnoreCase(datatype) || "int".equalsIgnoreCase(datatype)) {
122150
name = "Number" + name;
123151
}
124152
name = camelize(name, true);
125-
126153
// for reserved word or word starting with number, append _
127154
if (isReservedWord(name) || name.matches("^\\d.*")) {
128155
name = escapeReservedWord(name);
129156
}
130157
return name;
131158
}
132159

133-
@Override
134-
protected void addAdditionPropertiesToCodeGenModel(CodegenModel codegenModel, Schema schema) {
135-
//super.addAdditionPropertiesToCodeGenModel(codegenModel, schema);
136-
codegenModel.additionalPropertiesType = getSchemaType(ModelUtils.getAdditionalProperties(schema));
137-
addImport(codegenModel, codegenModel.additionalPropertiesType);
138-
}
139-
140160
@Override
141161
public void processOpts() {
162+
if (additionalProperties.containsKey(CodegenConstants.TEMPLATE_DIR)) {
163+
this.setTemplateDir((String) additionalProperties.get(CodegenConstants.TEMPLATE_DIR));
164+
}
165+
166+
if (additionalProperties.containsKey(CodegenConstants.MODEL_PACKAGE)) {
167+
this.setModelPackage((String) additionalProperties.get(CodegenConstants.MODEL_PACKAGE));
168+
}
169+
170+
if (additionalProperties.containsKey(CodegenConstants.API_PACKAGE)) {
171+
this.setApiPackage((String) additionalProperties.get(CodegenConstants.API_PACKAGE));
172+
}
173+
174+
if (additionalProperties.containsKey(CodegenConstants.HIDE_GENERATION_TIMESTAMP)) {
175+
setHideGenerationTimestamp(convertPropertyToBooleanAndWriteBack(CodegenConstants.HIDE_GENERATION_TIMESTAMP));
176+
} else {
177+
additionalProperties.put(CodegenConstants.HIDE_GENERATION_TIMESTAMP, hideGenerationTimestamp);
178+
}
179+
180+
if (additionalProperties.containsKey(CodegenConstants.SORT_PARAMS_BY_REQUIRED_FLAG)) {
181+
this.setSortParamsByRequiredFlag(Boolean.valueOf(additionalProperties
182+
.get(CodegenConstants.SORT_PARAMS_BY_REQUIRED_FLAG).toString()));
183+
}
184+
185+
if (additionalProperties.containsKey(CodegenConstants.PREPEND_FORM_OR_BODY_PARAMETERS)) {
186+
this.setPrependFormOrBodyParameters(Boolean.valueOf(additionalProperties
187+
.get(CodegenConstants.PREPEND_FORM_OR_BODY_PARAMETERS).toString()));
188+
}
189+
190+
if (additionalProperties.containsKey(CodegenConstants.ENSURE_UNIQUE_PARAMS)) {
191+
this.setEnsureUniqueParams(Boolean.valueOf(additionalProperties
192+
.get(CodegenConstants.ENSURE_UNIQUE_PARAMS).toString()));
193+
}
194+
195+
if (additionalProperties.containsKey(CodegenConstants.ALLOW_UNICODE_IDENTIFIERS)) {
196+
this.setAllowUnicodeIdentifiers(Boolean.valueOf(additionalProperties
197+
.get(CodegenConstants.ALLOW_UNICODE_IDENTIFIERS).toString()));
198+
}
199+
200+
if (additionalProperties.containsKey(CodegenConstants.API_NAME_SUFFIX)) {
201+
this.setApiNameSuffix((String) additionalProperties.get(CodegenConstants.API_NAME_SUFFIX));
202+
}
203+
204+
if (additionalProperties.containsKey(CodegenConstants.MODEL_NAME_PREFIX)) {
205+
this.setModelNamePrefix((String) additionalProperties.get(CodegenConstants.MODEL_NAME_PREFIX));
206+
}
207+
208+
if (additionalProperties.containsKey(CodegenConstants.MODEL_NAME_SUFFIX)) {
209+
this.setModelNameSuffix((String) additionalProperties.get(CodegenConstants.MODEL_NAME_SUFFIX));
210+
}
211+
212+
if (additionalProperties.containsKey(CodegenConstants.REMOVE_OPERATION_ID_PREFIX)) {
213+
this.setRemoveOperationIdPrefix(Boolean.valueOf(additionalProperties
214+
.get(CodegenConstants.REMOVE_OPERATION_ID_PREFIX).toString()));
215+
}
216+
217+
if (additionalProperties.containsKey(CodegenConstants.DOCEXTENSION)) {
218+
this.setDocExtension(String.valueOf(additionalProperties
219+
.get(CodegenConstants.DOCEXTENSION).toString()));
220+
}
221+
222+
if (additionalProperties.containsKey(CodegenConstants.ENABLE_POST_PROCESS_FILE)) {
223+
this.setEnablePostProcessFile(Boolean.valueOf(additionalProperties
224+
.get(CodegenConstants.ENABLE_POST_PROCESS_FILE).toString()));
225+
}
226+
227+
if (additionalProperties.containsKey(CodegenConstants.GENERATE_ALIAS_AS_MODEL)) {
228+
ModelUtils.setGenerateAliasAsModel(Boolean.valueOf(additionalProperties
229+
.get(CodegenConstants.GENERATE_ALIAS_AS_MODEL).toString()));
230+
}
231+
142232
if (StringUtils.isEmpty(System.getenv("DART_POST_PROCESS_FILE"))) {
143233
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)");
144234
LOGGER.info("NOTE: To enable file post-processing, 'enablePostProcessFile' must be set to `true` (--enable-post-process-file for CLI).");
145235
}
146236

237+
if (additionalProperties.containsKey(BROWSER_CLIENT)) {
238+
this.setBrowserClient(convertPropertyToBooleanAndWriteBack(BROWSER_CLIENT));
239+
} else {
240+
//not set, use to be passed to template
241+
additionalProperties.put(BROWSER_CLIENT, browserClient);
242+
}
243+
147244
if (additionalProperties.containsKey(NULLABLE_FIELDS)) {
148-
nullableFields = convertPropertyToBooleanAndWriteBack(NULLABLE_FIELDS);
245+
this.setNullableFields(convertPropertyToBooleanAndWriteBack(NULLABLE_FIELDS));
149246
} else {
150247
//not set, use to be passed to template
151248
additionalProperties.put(NULLABLE_FIELDS, nullableFields);
@@ -189,6 +286,9 @@ public void processOpts() {
189286
this.setSourceFolder((String) additionalProperties.get(CodegenConstants.SOURCE_FOLDER));
190287
}
191288

289+
if (additionalProperties.containsKey(DATE_LIBRARY)) {
290+
this.setDateLibrary(additionalProperties.get(DATE_LIBRARY).toString());
291+
}
192292
// make api and model doc path available in mustache template
193293
additionalProperties.put("apiDocPath", apiDocPath);
194294
additionalProperties.put("modelDocPath", modelDocPath);
@@ -201,6 +301,24 @@ public void processOpts() {
201301

202302
supportingFiles.add(new SupportingFile("gitignore.mustache", "", ".gitignore"));
203303
supportingFiles.add(new SupportingFile("README.mustache", "", "README.md"));
304+
305+
if ("core".equals(dateLibrary)) {
306+
additionalProperties.put("core", "true");
307+
typeMapping.put("Date", "DateTime");
308+
typeMapping.put("date", "DateTime");
309+
importMapping.put("DateTime", "DateTime");
310+
importMapping.put("OffsetDateTime", "DateTime");
311+
} else if ("timemachine".equals(dateLibrary)) {
312+
additionalProperties.put("timeMachine", "true");
313+
typeMapping.put("date", "LocalDate");
314+
typeMapping.put("Date", "LocalDate");
315+
typeMapping.put("DateTime", "OffsetDateTime");
316+
typeMapping.put("datetime", "OffsetDateTime");
317+
importMapping.put("LocalDate", "package:time_machine/time_machine.dart");
318+
importMapping.put("OffsetDateTime", "package:time_machine/time_machine.dart");
319+
supportingFiles.add(new SupportingFile("local_date_serializer.mustache", libFolder, "local_date_serializer.dart"));
320+
321+
}
204322
}
205323

206324
@Override
@@ -321,4 +439,6 @@ public Map<String, Object> postProcessOperationsWithModels(Map<String, Object> o
321439

322440
return objs;
323441
}
442+
443+
324444
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import 'package:built_collection/built_collection.dart';
2+
import 'package:built_value/serializer.dart';
3+
import 'package:time_machine/time_machine.dart';
4+
5+
class LocalDateSerializer implements PrimitiveSerializer<LocalDate> {
6+
@override
7+
Iterable<Type> get types => BuiltList<Type>([LocalDate]);
8+
9+
@override
10+
String get wireName => "LocalDate";
11+
12+
@override
13+
LocalDate deserialize(Serializers serializers, Object serialized,
14+
{FullType specifiedType = FullType.unspecified}) {
15+
return LocalDate.dateTime(DateTime.parse(serialized as String));
16+
}
17+
18+
@override
19+
Object serialize(Serializers serializers, LocalDate localDate,
20+
{FullType specifiedType = FullType.unspecified}) {
21+
return localDate.toString('yyyy-MM-dd');
22+
}
23+
}

modules/openapi-generator/src/main/resources/dart-dio/pubspec.mustache

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,10 @@ dependencies:
77
dio: ^3.0.4
88
built_value: ^6.8.2
99
built_collection: ^4.2.2
10+
{{#timeMachine}}
11+
time_machine: ^0.9.12
12+
{{/timeMachine}}
1013
dev_dependencies:
1114
built_value_generator: ^6.8.2
1215
build_runner: ^1.7.1
13-
test: 1.6.5
16+
test: 1.6.5

modules/openapi-generator/src/main/resources/dart-dio/serializers.mustache

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import 'package:built_value/serializer.dart';
44
import 'package:built_collection/built_collection.dart';
55
import 'package:built_value/json_object.dart';
66
import 'package:built_value/standard_json_plugin.dart';
7-
7+
{{#timeMachine}}import 'package:{{pubName}}/local_date_serializer.dart';{{/timeMachine}}
88
{{#models}}{{#model}}import 'package:{{pubName}}/model/{{classFilename}}.dart';
99
{{/model}}{{/models}}
1010

@@ -24,4 +24,5 @@ const FullType(BuiltList, const [const FullType({{classname}})]),
2424
).build();
2525

2626
Serializers standardSerializers =
27-
(serializers.toBuilder()..addPlugin(StandardJsonPlugin())).build();
27+
(serializers.toBuilder()
28+
{{#timeMachine}}..add(LocalDateSerializer()){{/timeMachine}}..addPlugin(StandardJsonPlugin())).build();

0 commit comments

Comments
 (0)