Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix replacement rules for OpenAPI 2.0 #267

Merged
merged 2 commits into from
Oct 12, 2024
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
10 changes: 8 additions & 2 deletions swagger_parser/lib/src/parser/corrector/open_api_corrector.dart
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,19 @@ class OpenApiCorrector {
? json.decode(fileContent) as Map<String, dynamic>
: (loadYaml(fileContent) as YamlMap).toMap();

// OpenAPI 3.0 and 3.1
final components =
definitionFileContent['components'] as Map<String, dynamic>?;
final schemes = components?['schemas'] as Map<String, dynamic>?;
// OpenAPI 2.0
final definitions =
definitionFileContent['definitions'] as Map<String, dynamic>?;

if (schemes != null) {
final models = schemes ?? definitions;

if (models != null) {
// Apply replacement rules to all class names and format to PascalCase
for (final type in schemes.keys) {
for (final type in models.keys) {
var correctType = type;

for (final rule in config.replacementRules) {
Expand Down
33 changes: 33 additions & 0 deletions swagger_parser/test/e2e/e2e_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,39 @@ void main() {
);
});

test('replacement_rules.2.0', () async {
await e2eTest(
'basic/replacement_rules.2.0',
(outputDirectory, schemaPath) => SWPConfig(
outputDirectory: outputDirectory,
schemaPath: schemaPath,
putClientsInFolder: true,
replacementRules: [
ReplacementRule(pattern: RegExp('List'), replacement: 'Lizt'),
ReplacementRule(pattern: RegExp(r'$'), replacement: 'DTO'),
],
),
schemaFileName: 'openapi.yaml',
);
});

test('replacement_rules.3.1', () async {
await e2eTest(
'basic/replacement_rules.3.1',
(outputDirectory, schemaPath) => SWPConfig(
outputDirectory: outputDirectory,
schemaPath: schemaPath,
jsonSerializer: JsonSerializer.freezed,
putClientsInFolder: true,
replacementRules: [
ReplacementRule(pattern: RegExp('V1'), replacement: ''),
ReplacementRule(pattern: RegExp(r'$'), replacement: 'DTO'),
],
),
schemaFileName: 'openapi.yaml',
);
});

test('wrapping_collections.2.0', () async {
await e2eTest(
'basic/wrapping_collections.2.0',
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
// coverage:ignore-file
// GENERATED CODE - DO NOT MODIFY BY HAND
// ignore_for_file: type=lint, unused_import

import 'package:dio/dio.dart';
import 'package:retrofit/retrofit.dart';

import '../models/new_pet_dto.dart';
import '../models/pet_dto.dart';

part 'client_client.g.dart';

@RestApi()
abstract class ClientClient {
factory ClientClient(Dio dio, {String? baseUrl}) = _ClientClient;

/// Returns all pets from the system that the user has access to.
///
/// [tags] - tags to filter by.
///
/// [limit] - maximum number of results to return.
@GET('/pets')
Future<List<PetDto>> findPets({
@Query('tags') List<String>? tags,
@Query('limit') int? limit,
});

/// Creates a new pet in the store. Duplicates are allowed.
///
/// [pet] - PetDto to add to the store.
@POST('/pets')
Future<PetDto> addPet({
@Body() required NewPetDto pet,
});

/// Returns a user based on a single ID, if the user does not have access to the pet.
///
/// [id] - ID of pet to fetch.
@GET('/pets/{id}')
Future<PetDto> findPetById({
@Path('id') required int id,
});

/// deletes a single pet based on the ID supplied.
///
/// [id] - ID of pet to delete.
@DELETE('/pets/{id}')
Future<void> deletePet({
@Path('id') required int id,
});
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// coverage:ignore-file
// GENERATED CODE - DO NOT MODIFY BY HAND
// ignore_for_file: type=lint, unused_import

// Clients
export 'clients/client_client.dart';
// Data classes
export 'models/pet_dto.dart';
export 'models/new_pet_dto.dart';
export 'models/error_dto.dart';
export 'models/lizt_dto.dart';
export 'models/new_pet_dto_action_dto.dart';
// Root client
export 'rest_client.dart';
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// coverage:ignore-file
// GENERATED CODE - DO NOT MODIFY BY HAND
// ignore_for_file: type=lint, unused_import

import 'package:json_annotation/json_annotation.dart';

part 'error_dto.g.dart';

@JsonSerializable()
class ErrorDto {
const ErrorDto({
required this.code,
required this.message,
});

factory ErrorDto.fromJson(Map<String, Object?> json) =>
_$ErrorDtoFromJson(json);

final int code;
final String message;

Map<String, Object?> toJson() => _$ErrorDtoToJson(this);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// coverage:ignore-file
// GENERATED CODE - DO NOT MODIFY BY HAND
// ignore_for_file: type=lint, unused_import

import 'package:json_annotation/json_annotation.dart';

part 'lizt_dto.g.dart';

@JsonSerializable()
class LiztDto {
const LiztDto({
required this.message,
});

factory LiztDto.fromJson(Map<String, Object?> json) =>
_$LiztDtoFromJson(json);

final String message;

Map<String, Object?> toJson() => _$LiztDtoToJson(this);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// coverage:ignore-file
// GENERATED CODE - DO NOT MODIFY BY HAND
// ignore_for_file: type=lint, unused_import

import 'package:json_annotation/json_annotation.dart';

import 'new_pet_dto_action_dto.dart';

part 'new_pet_dto.g.dart';

@JsonSerializable()
class NewPetDto {
const NewPetDto({
required this.name,
required this.tag,
required this.action,
});

factory NewPetDto.fromJson(Map<String, Object?> json) =>
_$NewPetDtoFromJson(json);

final String name;
final String tag;
final NewPetDtoActionDto action;

Map<String, Object?> toJson() => _$NewPetDtoToJson(this);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// coverage:ignore-file
// GENERATED CODE - DO NOT MODIFY BY HAND
// ignore_for_file: type=lint, unused_import

import 'package:json_annotation/json_annotation.dart';

@JsonEnum()
enum NewPetDtoActionDto {
@JsonValue('one')
one('one'),
@JsonValue('other')
other('other'),
@JsonValue('another')
another('another'),

/// Default value for all unparsed values, allows backward compatibility when adding new values on the backend.
$unknown(null);

const NewPetDtoActionDto(this.json);

factory NewPetDtoActionDto.fromJson(String json) => values.firstWhere(
(e) => e.json == json,
orElse: () => $unknown,
);

final String? json;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// coverage:ignore-file
// GENERATED CODE - DO NOT MODIFY BY HAND
// ignore_for_file: type=lint, unused_import

import 'package:json_annotation/json_annotation.dart';

import 'new_pet_dto_action_dto.dart';

part 'pet_dto.g.dart';

@JsonSerializable()
class PetDto {
const PetDto({
required this.name,
required this.tag,
required this.action,
required this.id,
});

factory PetDto.fromJson(Map<String, Object?> json) => _$PetDtoFromJson(json);

final String name;
final String tag;
final NewPetDtoActionDto action;
final int id;

Map<String, Object?> toJson() => _$PetDtoToJson(this);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// coverage:ignore-file
// GENERATED CODE - DO NOT MODIFY BY HAND
// ignore_for_file: type=lint, unused_import

import 'package:dio/dio.dart';

import 'clients/client_client.dart';

/// Swagger Petstore `v1.0.0`
class RestClient {
RestClient(
Dio dio, {
String? baseUrl,
}) : _dio = dio,
_baseUrl = baseUrl;

final Dio _dio;
final String? _baseUrl;

static String get version => '1.0.0';

ClientClient? _client;

ClientClient get client => _client ??= ClientClient(_dio, baseUrl: _baseUrl);
}
Loading