Browse Source

Merge pull request #199 from provokateurin/fix/dynamite

Fix a few dynamite things
pull/200/head
Kate 2 years ago committed by GitHub
parent
commit
b23fe7cb44
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 29
      packages/dynamite/lib/src/models/schema.dart
  2. 12
      packages/dynamite/lib/src/models/schema.g.dart
  3. 132
      packages/dynamite/lib/src/openapi_builder.dart

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

@ -24,6 +24,8 @@ class Schema {
this.contentSchema, this.contentSchema,
this.discriminator, this.discriminator,
this.pattern, this.pattern,
this.minLength,
this.maxLength,
}); });
factory Schema.fromJson(final Map<String, dynamic> json) => _$SchemaFromJson(json); factory Schema.fromJson(final Map<String, dynamic> json) => _$SchemaFromJson(json);
@ -60,7 +62,10 @@ class Schema {
final Schema? items; final Schema? items;
final bool? additionalProperties; @JsonKey(
fromJson: _parseAdditionalProperties,
)
final Schema? additionalProperties;
final String? contentMediaType; final String? contentMediaType;
@ -70,5 +75,27 @@ class Schema {
final String? pattern; final String? pattern;
final int? minLength;
final int? maxLength;
bool get isContentString => type == 'string' && (contentMediaType?.isNotEmpty ?? false) && contentSchema != null; bool get isContentString => type == 'string' && (contentMediaType?.isNotEmpty ?? false) && contentSchema != null;
} }
class EmptySchema extends Schema {}
Schema? _parseAdditionalProperties(final dynamic data) {
if (data == null) {
return null;
}
if (data is bool) {
return data ? EmptySchema() : null;
}
if (data is Map<String, dynamic>) {
return Schema.fromJson(data);
}
throw Exception('Can not parse additionalProperties from $data');
}

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

@ -27,7 +27,9 @@ Schema _$SchemaFromJson(Map<String, dynamic> json) {
'contentMediaType', 'contentMediaType',
'contentSchema', 'contentSchema',
'discriminator', 'discriminator',
'pattern' 'pattern',
'minLength',
'maxLength'
], ],
); );
return Schema( return Schema(
@ -46,13 +48,15 @@ Schema _$SchemaFromJson(Map<String, dynamic> json) {
), ),
required: (json['required'] as List<dynamic>?)?.map((e) => e as String).toList(), required: (json['required'] as List<dynamic>?)?.map((e) => e as String).toList(),
items: json['items'] == null ? null : Schema.fromJson(json['items'] as Map<String, dynamic>), items: json['items'] == null ? null : Schema.fromJson(json['items'] as Map<String, dynamic>),
additionalProperties: json['additionalProperties'] as bool?, additionalProperties: _parseAdditionalProperties(json['additionalProperties']),
contentMediaType: json['contentMediaType'] as String?, contentMediaType: json['contentMediaType'] as String?,
contentSchema: contentSchema:
json['contentSchema'] == null ? null : Schema.fromJson(json['contentSchema'] as Map<String, dynamic>), json['contentSchema'] == null ? null : Schema.fromJson(json['contentSchema'] as Map<String, dynamic>),
discriminator: discriminator:
json['discriminator'] == null ? null : Discriminator.fromJson(json['discriminator'] as Map<String, dynamic>), json['discriminator'] == null ? null : Discriminator.fromJson(json['discriminator'] as Map<String, dynamic>),
pattern: json['pattern'] as String?, pattern: json['pattern'] as String?,
minLength: json['minLength'] as int?,
maxLength: json['maxLength'] as int?,
); );
} }
@ -78,10 +82,12 @@ Map<String, dynamic> _$SchemaToJson(Schema instance) {
writeNotNull('properties', instance.properties?.map((k, e) => MapEntry(k, e.toJson()))); writeNotNull('properties', instance.properties?.map((k, e) => MapEntry(k, e.toJson())));
writeNotNull('required', instance.required); writeNotNull('required', instance.required);
writeNotNull('items', instance.items?.toJson()); writeNotNull('items', instance.items?.toJson());
writeNotNull('additionalProperties', instance.additionalProperties); writeNotNull('additionalProperties', instance.additionalProperties?.toJson());
writeNotNull('contentMediaType', instance.contentMediaType); writeNotNull('contentMediaType', instance.contentMediaType);
writeNotNull('contentSchema', instance.contentSchema?.toJson()); writeNotNull('contentSchema', instance.contentSchema?.toJson());
writeNotNull('discriminator', instance.discriminator?.toJson()); writeNotNull('discriminator', instance.discriminator?.toJson());
writeNotNull('pattern', instance.pattern); writeNotNull('pattern', instance.pattern);
writeNotNull('minLength', instance.minLength);
writeNotNull('maxLength', instance.maxLength);
return val; return val;
} }

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

@ -582,12 +582,28 @@ class OpenAPIBuilder implements Builder {
parameter.schema!, parameter.schema!,
); );
if (result.name == 'String' && parameter.schema?.pattern != null) { if (result.name == 'String') {
code.write(''' if (parameter.schema?.pattern != null) {
if (!RegExp(r'${parameter.schema!.pattern!}').hasMatch(${_toDartName(parameter.name)})) { code.write('''
throw Exception('Invalid value "\$${_toDartName(parameter.name)}" for parameter "${_toDartName(parameter.name)}" with pattern "' r'${parameter.schema!.pattern!}"'); // coverage:ignore-line if (!RegExp(r'${parameter.schema!.pattern!}').hasMatch(${_toDartName(parameter.name)})) {
throw Exception('Invalid value "\$${_toDartName(parameter.name)}" for parameter "${_toDartName(parameter.name)}" with pattern "' r'${parameter.schema!.pattern!}"'); // coverage:ignore-line
}
''');
}
if (parameter.schema?.minLength != null) {
code.write('''
if (${_toDartName(parameter.name)}.length < ${parameter.schema!.minLength!}) {
throw Exception('Parameter "${_toDartName(parameter.name)}" has to be at least ${parameter.schema!.minLength!} characters long'); // coverage:ignore-line
}
''');
}
if (parameter.schema?.maxLength != null) {
code.write('''
if (${_toDartName(parameter.name)}.length > ${parameter.schema!.maxLength!}) {
throw Exception('Parameter "${_toDartName(parameter.name)}" has to be at most ${parameter.schema!.maxLength!} characters long'); // coverage:ignore-line
}
''');
} }
''');
} }
final defaultValueCode = parameter.schema?.default_ != null final defaultValueCode = parameter.schema?.default_ != null
@ -1082,7 +1098,7 @@ TypeResult resolveObject(
refer('JsonSerializable').call( refer('JsonSerializable').call(
[], [],
{ {
if (schema.additionalProperties ?? false) ...{ if (schema.additionalProperties != null) ...{
'disallowUnrecognizedKeys': refer('false'), 'disallowUnrecognizedKeys': refer('false'),
}, },
if (extraJsonSerializableValues != null) ...{ if (extraJsonSerializableValues != null) ...{
@ -1351,7 +1367,7 @@ TypeResult resolveType(
final s = schema.ofs![results.indexOf(result)]; final s = schema.ofs![results.indexOf(result)];
b b
..name = fields[result.name] ..name = fields[result.name]
..type = refer(_makeNullable(result.name, true)) ..type = refer(_makeNullable(result.name, !(schema.allOf?.contains(s) ?? false)))
..modifier = FieldModifier.final$ ..modifier = FieldModifier.final$
..docs.addAll(_descriptionToDocs(s.description)); ..docs.addAll(_descriptionToDocs(s.description));
}, },
@ -1374,7 +1390,8 @@ TypeResult resolveType(
(final b) => b (final b) => b
..name = fields[result.name]! ..name = fields[result.name]!
..toThis = true ..toThis = true
..named = true, ..named = true
..required = schema.allOf != null,
), ),
], ],
]), ]),
@ -1393,48 +1410,54 @@ TypeResult resolveType(
) )
..body = Code( ..body = Code(
<String>[ <String>[
for (final result in results) ...[ if (schema.allOf != null) ...[
'${result.name}? ${fields[result.name]!};', 'return ${state.prefix}$identifier(',
], 'data,',
for (final result in results) ...[ for (final result in results) ...[
if (schema.discriminator != null) ...[ '${fields[result.name]!}: ${result.deserialize('data')},',
"if (data['${schema.discriminator!.propertyName}'] == '${result.name.replaceFirst(state.prefix, '')}'", ],
if (schema.discriminator!.mapping != null && ');',
schema.discriminator!.mapping!.isNotEmpty) ...[ ] else ...[
for (final key in schema.discriminator!.mapping!.entries for (final result in results) ...[
.where( '${result.name}? ${fields[result.name]!};',
(final entry) => ],
entry.value.endsWith('/${result.name.replaceFirst(state.prefix, '')}'), for (final result in results) ...[
) if (schema.discriminator != null) ...[
.map((final entry) => entry.key)) ...[ "if (data['${schema.discriminator!.propertyName}'] == '${result.name.replaceFirst(state.prefix, '')}'",
" || data['${schema.discriminator!.propertyName}'] == '$key'", if (schema.discriminator!.mapping != null &&
schema.discriminator!.mapping!.isNotEmpty) ...[
for (final key in schema.discriminator!.mapping!.entries
.where(
(final entry) =>
entry.value.endsWith('/${result.name.replaceFirst(state.prefix, '')}'),
)
.map((final entry) => entry.key)) ...[
" || data['${schema.discriminator!.propertyName}'] == '$key'",
],
], ],
') {',
],
'try {',
'${fields[result.name]!} = ${result.deserialize('data')};',
'} catch (_) {',
if (schema.discriminator != null) ...[
'rethrow;',
],
'}',
if (schema.discriminator != null) ...[
'}',
], ],
') {',
], ],
'try {', if (schema.oneOf != null) ...[
'${fields[result.name]!} = ${result.deserialize('data')};', "assert([${fields.values.join(',')}].where((final x) => x != null).length == 1, 'Need oneOf for \$data');",
'} catch (_) {',
if (schema.discriminator != null) ...[
'rethrow;',
], ],
'}', 'return ${state.prefix}$identifier(',
if (schema.discriminator != null) ...[ 'data,',
'}', for (final result in results) ...[
'${fields[result.name]!}: ${fields[result.name]!},',
], ],
');',
], ],
if (schema.oneOf != null) ...[
"assert([${fields.values.join(',')}].where((final x) => x != null).length == 1, 'Need oneOf for \$data');",
],
if (schema.allOf != null) ...[
"assert([${fields.values.join(',')}].where((final x) => x != null).length == ${fields.length}, 'Need allOf for \$data');",
],
'return ${state.prefix}$identifier(',
'data,',
for (final result in results) ...[
'${fields[result.name]!}: ${fields[result.name]!},',
],
');',
].join(), ].join(),
); );
}, },
@ -1543,6 +1566,27 @@ TypeResult resolveType(
break; break;
case 'object': case 'object':
if (schema.properties == null) { if (schema.properties == null) {
if (schema.additionalProperties != null) {
if (schema.additionalProperties is EmptySchema) {
result = TypeResultMap(
'Map<String, dynamic>',
TypeResultBase('dynamic'),
);
} else {
final subResult = resolveType(
spec,
state,
identifier,
schema.additionalProperties!,
extraJsonSerializableValues: extraJsonSerializableValues,
);
result = TypeResultMap(
'Map<String, ${subResult.name}>',
TypeResultBase('dynamic'),
);
}
break;
}
result = TypeResultBase('dynamic'); result = TypeResultBase('dynamic');
break; break;
} }

Loading…
Cancel
Save