Browse Source

Merge pull request #287 from provokateurin/fix/dynamite-nullable-vs-required

Fix nullable vs. required
pull/289/head
Kate 2 years ago committed by GitHub
parent
commit
86116b5b4d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 3
      packages/dynamite/lib/src/models/schema.dart
  2. 5
      packages/dynamite/lib/src/models/schema.g.dart
  3. 86
      packages/dynamite/lib/src/openapi_builder.dart
  4. 1
      packages/dynamite/pubspec.yaml

3
packages/dynamite/lib/src/models/schema.dart

@ -26,6 +26,7 @@ class Schema {
this.pattern, this.pattern,
this.minLength, this.minLength,
this.maxLength, this.maxLength,
this.nullable,
}); });
factory Schema.fromJson(final Map<String, dynamic> json) => _$SchemaFromJson(json); factory Schema.fromJson(final Map<String, dynamic> json) => _$SchemaFromJson(json);
@ -79,6 +80,8 @@ class Schema {
final int? maxLength; final int? maxLength;
final bool? nullable;
bool get isContentString => type == 'string' && (contentMediaType?.isNotEmpty ?? false) && contentSchema != null; bool get isContentString => type == 'string' && (contentMediaType?.isNotEmpty ?? false) && contentSchema != null;
} }

5
packages/dynamite/lib/src/models/schema.g.dart

@ -29,7 +29,8 @@ Schema _$SchemaFromJson(Map<String, dynamic> json) {
'discriminator', 'discriminator',
'pattern', 'pattern',
'minLength', 'minLength',
'maxLength' 'maxLength',
'nullable'
], ],
); );
return Schema( return Schema(
@ -57,6 +58,7 @@ Schema _$SchemaFromJson(Map<String, dynamic> json) {
pattern: json['pattern'] as String?, pattern: json['pattern'] as String?,
minLength: json['minLength'] as int?, minLength: json['minLength'] as int?,
maxLength: json['maxLength'] as int?, maxLength: json['maxLength'] as int?,
nullable: json['nullable'] as bool?,
); );
} }
@ -89,5 +91,6 @@ Map<String, dynamic> _$SchemaToJson(Schema instance) {
writeNotNull('pattern', instance.pattern); writeNotNull('pattern', instance.pattern);
writeNotNull('minLength', instance.minLength); writeNotNull('minLength', instance.minLength);
writeNotNull('maxLength', instance.maxLength); writeNotNull('maxLength', instance.maxLength);
writeNotNull('nullable', instance.nullable);
return val; return val;
} }

86
packages/dynamite/lib/src/openapi_builder.dart

@ -644,8 +644,14 @@ class OpenAPIBuilder implements Builder {
if (operation.parameters != null) ...operation.parameters!, if (operation.parameters != null) ...operation.parameters!,
]..sort( ]..sort(
(final a, final b) => sortRequiredElements( (final a, final b) => sortRequiredElements(
(a.required ?? false) && a.schema?.default_ == null, _isDartParameterRequired(
(b.required ?? false) && b.schema?.default_ == null, a.required,
a.schema?.default_,
),
_isDartParameterRequired(
b.required,
b.schema?.default_,
),
), ),
); );
b b
@ -706,7 +712,12 @@ class OpenAPIBuilder implements Builder {
} }
for (final parameter in parameters) { for (final parameter in parameters) {
final nullable = _isParameterNullable( final dartParameterNullable = _isDartParameterNullable(
parameter.required,
parameter.schema?.nullable,
parameter.schema?.default_,
);
final dartParameterRequired = _isDartParameterRequired(
parameter.required, parameter.required,
parameter.schema?.default_, parameter.schema?.default_,
); );
@ -755,12 +766,12 @@ class OpenAPIBuilder implements Builder {
b b
..named = true ..named = true
..name = _toDartName(parameter.name) ..name = _toDartName(parameter.name)
..required = (parameter.required ?? false) && defaultValueCode == null; ..required = dartParameterRequired;
if (parameter.schema != null) { if (parameter.schema != null) {
b.type = refer( b.type = refer(
_makeNullable( _makeNullable(
result.name, result.name,
nullable, dartParameterNullable,
), ),
); );
} }
@ -771,7 +782,7 @@ class OpenAPIBuilder implements Builder {
), ),
); );
if (nullable) { if (dartParameterNullable) {
code.write('if (${_toDartName(parameter.name)} != null) {'); code.write('if (${_toDartName(parameter.name)} != null) {');
} }
final isPlainList = result is TypeResultList && !result.fromContentString; final isPlainList = result is TypeResultList && !result.fromContentString;
@ -806,7 +817,7 @@ class OpenAPIBuilder implements Builder {
if (defaultValueCode != null && parameter.in_ == 'query') { if (defaultValueCode != null && parameter.in_ == 'query') {
code.write('}'); code.write('}');
} }
if (nullable) { if (dartParameterNullable) {
code.write('}'); code.write('}');
} }
} }
@ -830,7 +841,12 @@ class OpenAPIBuilder implements Builder {
switch (mimeType) { switch (mimeType) {
case 'application/json': case 'application/json':
case 'application/x-www-form-urlencoded': case 'application/x-www-form-urlencoded':
final nullable = _isParameterNullable( final dartParameterNullable = _isDartParameterNullable(
operation.requestBody!.required,
mediaType.schema?.nullable,
mediaType.schema?.default_,
);
final dartParameterRequired = _isDartParameterRequired(
operation.requestBody!.required, operation.requestBody!.required,
mediaType.schema?.default_, mediaType.schema?.default_,
); );
@ -838,19 +854,19 @@ class OpenAPIBuilder implements Builder {
Parameter( Parameter(
(final b) => b (final b) => b
..name = parameterName ..name = parameterName
..type = refer(_makeNullable(result.name, nullable)) ..type = refer(_makeNullable(result.name, dartParameterNullable))
..named = true ..named = true
..required = operation.requestBody!.required ?? false, ..required = dartParameterRequired,
), ),
); );
if (nullable) { if (dartParameterNullable) {
code.write('if ($parameterName != null) {'); code.write('if ($parameterName != null) {');
} }
code.write( code.write(
'body = Uint8List.fromList(utf8.encode(${result.encode(result.serialize(parameterName), mimeType: mimeType)}));', 'body = Uint8List.fromList(utf8.encode(${result.encode(result.serialize(parameterName), mimeType: mimeType)}));',
); );
if (nullable) { if (dartParameterNullable) {
code.write('}'); code.write('}');
} }
break; break;
@ -1180,7 +1196,18 @@ String _makeNullable(final String type, final bool nullable) => nullable && type
String _toFieldName(final String dartName, final String type) => dartName == type ? '\$$dartName' : dartName; String _toFieldName(final String dartName, final String type) => dartName == type ? '\$$dartName' : dartName;
bool _isParameterNullable(final bool? required, final dynamic default_) => !(required ?? false) && default_ == null; bool _isDartParameterNullable(
final bool? required,
final bool? nullable,
final dynamic default_,
) =>
(!(required ?? false) && default_ == null) || (nullable ?? false);
bool _isDartParameterRequired(
final bool? required,
final dynamic default_,
) =>
(required ?? false) && default_ == null;
String _valueToEscapedValue(final TypeResult result, final dynamic value) { String _valueToEscapedValue(final TypeResult result, final dynamic value) {
if (result is TypeResultBase && result.name == 'String') { if (result is TypeResultBase && result.name == 'String') {
@ -1242,8 +1269,14 @@ TypeResult resolveObject(
final sortedParameterKeys = schema.properties!.keys.toList() final sortedParameterKeys = schema.properties!.keys.toList()
..sort( ..sort(
(final a, final b) => sortRequiredElements( (final a, final b) => sortRequiredElements(
(schema.required ?? []).contains(a) && schema.properties![a]!.default_ == null, _isDartParameterRequired(
(schema.required ?? []).contains(b) && schema.properties![b]!.default_ == null, schema.required?.contains(a),
schema.properties![a]!.default_,
),
_isDartParameterRequired(
schema.required?.contains(b),
schema.properties![b]!.default_,
),
), ),
); );
b b
@ -1277,8 +1310,10 @@ TypeResult resolveObject(
..name = _toDartName(propertyName) ..name = _toDartName(propertyName)
..toThis = true ..toThis = true
..named = true ..named = true
..required = ..required = _isDartParameterRequired(
(schema.required ?? []).contains(propertyName) && propertySchema.default_ == null; schema.required?.contains(propertyName),
propertySchema.default_,
);
if (propertySchema.default_ != null) { if (propertySchema.default_ != null) {
final value = propertySchema.default_!.toString(); final value = propertySchema.default_!.toString();
final result = resolveType( final result = resolveType(
@ -1366,7 +1401,11 @@ TypeResult resolveObject(
..type = refer( ..type = refer(
_makeNullable( _makeNullable(
result.name, result.name,
!(schema.required ?? []).contains(propertyName), _isDartParameterNullable(
schema.required?.contains(propertyName),
propertySchema.nullable,
propertySchema.default_,
),
), ),
) )
..modifier = FieldModifier.final$ ..modifier = FieldModifier.final$
@ -1580,7 +1619,7 @@ TypeResult resolveType(
');', ');',
] else ...[ ] else ...[
for (final result in results) ...[ for (final result in results) ...[
'${result.name}? ${fields[result.name]!};', '${_makeNullable(result.name, true)} ${fields[result.name]!};',
], ],
for (final result in results) ...[ for (final result in results) ...[
if (schema.discriminator != null) ...[ if (schema.discriminator != null) ...[
@ -1703,9 +1742,7 @@ TypeResult resolveType(
break; break;
} }
result = TypeResultBase( result = TypeResultBase('String');
'String',
);
break; break;
case 'array': case 'array':
if (schema.items != null) { if (schema.items != null) {
@ -1869,7 +1906,10 @@ TypeResult resolveType(
), ),
); );
} }
result = TypeResultEnum('${state.prefix}$identifier', result); result = TypeResultEnum(
'${state.prefix}$identifier',
result,
);
} }
return result; return result;

1
packages/dynamite/pubspec.yaml

@ -12,6 +12,7 @@ dependencies:
path: ^1.8.2 path: ^1.8.2
dev_dependencies: dev_dependencies:
build_runner: ^2.2.1
json_serializable: ^6.3.2 json_serializable: ^6.3.2
nit_picking: nit_picking:
git: git:

Loading…
Cancel
Save