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

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions swagger_parser/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
## 1.45.1

* Fixes OpenAPI 3 schemas without a `required` array generating every property as `required`
when any property uses `allOf`
([#460](https://github.com/Carapacik/swagger_parser/issues/460)).

## 1.45.0

* Adds `freezed_json_serialization` (default `true`) to generate Freezed models
Expand Down
10 changes: 1 addition & 9 deletions swagger_parser/lib/src/parser/parser/open_api_parser.dart
Original file line number Diff line number Diff line change
Expand Up @@ -766,16 +766,8 @@ class OpenApiParser {
final imports = <String>{};

var requiredParameters = <String>[];
var hasAllOfKey = false;
if (map case {_requiredConst: final List<dynamic> rawParameters}) {
requiredParameters = rawParameters.map((e) => e.toString()).toList();
} else if (map case {_propertiesConst: final Map<String, dynamic> props}) {
for (final propertyName in props.keys) {
final propertyValue = props[propertyName] as Map<String, dynamic>;
if (propertyValue.containsKey(_allOfConst)) {
hasAllOfKey = true;
}
}
}

if (map case {_propertiesConst: final Map<String, dynamic> props}) {
Expand Down Expand Up @@ -820,7 +812,7 @@ class OpenApiParser {
additionalName: additionalName,
isRequired: (_apiInfo.schemaVersion == OAS.v2 && !config.useXNullable)
? isRequired
: isRequired || hasAllOfKey || hasDefaultKey,
: isRequired || hasDefaultKey,
);

var validation = propertyValue;
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

100 changes: 100 additions & 0 deletions swagger_parser/test/parser/all_of_property_not_required_test.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
import 'dart:io';

import 'package:path/path.dart' as p;
import 'package:swagger_parser/swagger_parser.dart';
import 'package:test/test.dart';

void main() {
test(
'properties not listed in required stay optional when a sibling uses allOf',
() async {
final root =
await Directory.systemTemp.createTemp('swagger-parser-test-');
addTearDown(() => root.delete(recursive: true));

final schema = File(p.join(root.path, 'openapi.yaml'))
..writeAsStringSync(r'''
openapi: 3.0.0
info:
title: allOf properties without required
version: 1.0.0
paths:
/foo:
get:
operationId: getFoo
responses:
'200':
description: OK
content:
application/json:
schema:
$ref: '#/components/schemas/Foo'
/order:
get:
operationId: getOrder
responses:
'200':
description: OK
content:
application/json:
schema:
$ref: '#/components/schemas/Order'
components:
schemas:
Bar:
type: object
properties:
name:
type: string
required: [name]
Status:
type: string
enum: [active, inactive]
Foo:
type: object
# No required array: every property is optional.
properties:
a:
type: string
b:
allOf:
- $ref: '#/components/schemas/Bar'
Order:
type: object
# No required array: every property is optional.
properties:
id:
type: integer
status:
nullable: true
allOf:
- $ref: '#/components/schemas/Status'
''');

await GenProcessor(
SWPConfig(
schemaPath: schema.path,
outputDirectory: p.join(root.path, 'generated'),
jsonSerializer: JsonSerializer.freezed,
putClientsInFolder: true,
),
).generateFiles();

final foo = File(
p.join(root.path, 'generated', 'models', 'foo.dart'),
).readAsStringSync();
expect(foo, contains('String? a,'));
expect(foo, isNot(contains('required String? a')));
expect(foo, contains('Bar? b,'));
expect(foo, isNot(contains('required Bar? b')));

final order = File(
p.join(root.path, 'generated', 'models', 'order.dart'),
).readAsStringSync();
expect(order, contains('int? id,'));
expect(order, isNot(contains('required int? id')));
expect(order, contains('Status? status,'));
expect(order, isNot(contains('required Status? status')));
},
);
}
Loading