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
9 changes: 6 additions & 3 deletions .github/workflows/code_quality.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@ jobs:
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Start Docker compose containers
if: ${{ matrix.work_dir == 'openapi-generator' }}
run: docker-compose -f "docker-compose.yaml" up -d --build
- name: Setup Dart
uses: dart-lang/[email protected]
with:
Expand All @@ -33,9 +36,6 @@ jobs:
run: dart pub get
- name: Validate formatting
run: dart format ./ --set-exit-if-changed
- name: Generate Mocks
if: ${{ matrix.work_dir == 'openapi-generator' }}
run: dart run build_runner build --delete-conflicting-outputs
- name: Run analyzer
run: dart analyze --fatal-warnings
- name: Run tests
Expand All @@ -51,6 +51,9 @@ jobs:
verbose: true
flags: ${{ matrix.work_dir }}
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
- name: Stop Docker Container
if: ${{ matrix.work_dir == 'openapi-generator' && always() }}
run: docker-compose -f "docker-compose.yaml" down

build:
name: Build example project 🛠️
Expand Down
6 changes: 1 addition & 5 deletions example/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,7 @@ dependency_overrides:
path: ../openapi-generator
openapi_generator_cli:
path: ../openapi-generator-cli
source_gen:
git:
ref: reviver
url: https://github.com/Nexushunter/source_gen
path: source_gen


# Dependencies specify other packages that your package needs in order to work.
# To automatically upgrade your package dependencies to the latest versions
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,8 @@
library openapi_generator_annotations;

import 'dart:convert';
import 'dart:io';

import 'package:crypto/crypto.dart';
import 'package:meta/meta.dart';
import 'package:source_gen/source_gen.dart';

/// Config base class
/// Your annotated class must extend this config class
Expand Down Expand Up @@ -229,6 +226,11 @@ class RemoteSpec extends InputSpec {
const RemoteSpec.empty() : this(path: 'http://localhost:8080/');

Uri get url => Uri.parse(path);

RemoteSpec.fromMap(Map<String, dynamic> map)
: headerDelegate =
map['headerDelegate'] ?? const RemoteSpecHeaderDelegate(),
super.fromMap(map);
}

/// Default [RemoteSpecHeaderDelegate] used when retrieving a remote OAS spec.
Expand Down Expand Up @@ -264,6 +266,12 @@ class AWSRemoteSpecHeaderDelegate extends RemoteSpecHeaderDelegate {
this.accessKeyId = null,
}) : super();

AWSRemoteSpecHeaderDelegate.fromMap(Map<String, dynamic> map)
: bucket = map['bucket'],
accessKeyId = map['accessKeyId'],
secretAccessKey = map['secretAccessKey'],
super.fromMap(map);

/// Generates the [header] map used within the GET request.
///
/// Assumes that the user's auth AWS credentials
Expand Down
8 changes: 0 additions & 8 deletions openapi-generator-annotations/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,8 @@ environment:
dependencies:
crypto: '>=3.0.0 <4.0.0'
meta: '>=1.3.0 <2.0.0'
source_gen:

dev_dependencies:
test:
source_gen_test:
lint:

dependency_overrides:
source_gen:
git:
ref: reviver
url: https://github.com/Nexushunter/source_gen.git
path: source_gen
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,6 @@ void main() {
expect(remote.path, 'http://localhost:8080/');
expect(remote.headerDelegate, isA<RemoteSpecHeaderDelegate>());
});

test('uses path', () {
final remote = RemoteSpec(path: 'https://example.com/path');
expect(remote.path, 'https://example.com/path');
Expand All @@ -113,6 +112,7 @@ void main() {
accessKeyId: 'test',
secretAccessKey: 'test',
);

test('signs the url correctly', () {
final now = DateTime.now();
final actual = delegate.authHeaderContent(
Expand Down Expand Up @@ -176,7 +176,6 @@ void main() {
}
});
test('uses the provided environment', () async {
print(Directory.current.path);
final result = Process.runSync(
'dart',
[
Expand Down
4 changes: 1 addition & 3 deletions openapi-generator/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,4 @@ example/.dart_tool

# Generated test output
test/specs/test-cached.json
test/specs/commands-cache.json
test/specs/localstack
test/mocks.mocks.dart
test/specs/localstack/**
4 changes: 0 additions & 4 deletions openapi-generator/Makefile

This file was deleted.

13 changes: 13 additions & 0 deletions openapi-generator/docker-compose.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
version: '3'
services:
local-s3:
container_name: localstack
image: localstack/localstack:latest
ports:
- "4566:4566"
environment:
- SERVICES=S3
- AWS_DEFAULT_REGION=us-east-1
volumes:
- './test/specs/localstack:/var/lib/localstack'
- './test/specs/buckets.sh:/etc/localstack/init/ready.d/buckets.sh'
99 changes: 99 additions & 0 deletions openapi-generator/lib/src/extensions/type_methods.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import 'dart:mirrors';

import 'package:analyzer/dart/element/type.dart';
import 'package:openapi_generator/src/utils.dart';
import 'package:openapi_generator_annotations/openapi_generator_annotations.dart';
import 'package:source_gen/source_gen.dart' show ConstantReader, TypeChecker;

/// Extension adding the type methods to `ConstantReader`.
Expand Down Expand Up @@ -71,3 +73,100 @@ extension TypeMethods on ConstantReader {
return values[enumIndex];
}
}

extension ReadProperty on ConstantReader {
T readPropertyOrDefault<T>(String name, T defaultValue) {
final v = peek(name);
if (v == null) {
return defaultValue;
}

if (isA(v, InputSpec)) {
final revived = v.revive();

if (isA(v, RemoteSpec)) {
final map = revived.namedArguments;
final delegate = map['headerDelegate'];
final mapped = <String, dynamic>{
'path': convertToPropertyValue(map['path']!),
};
if (delegate?.isNull ?? true) {
return RemoteSpec.fromMap(mapped) as T;
} else {
final delegateReader = ConstantReader(delegate);
if (isA(delegateReader, AWSRemoteSpecHeaderDelegate)) {
mapped['headerDelegate'] = AWSRemoteSpecHeaderDelegate.fromMap(
delegateReader.revive().namedArguments.map(
(key, value) => MapEntry(
key,
convertToPropertyValue(value),
),
),
);
}
return RemoteSpec.fromMap(mapped) as T;
}
} else {
final map = revived.namedArguments.map(
(key, value) => MapEntry(
key,
convertToPropertyValue(value),
),
);
return InputSpec.fromMap(map) as T;
}
}

if (isA(v, AdditionalProperties)) {
final map = v.revive().namedArguments.map(
(key, value) => MapEntry(
key,
convertToPropertyValue(value),
),
);
if (isA(v, DioProperties)) {
return DioProperties.fromMap(map) as T;
} else if (isA(v, DioAltProperties)) {
return DioAltProperties.fromMap(map) as T;
} else {
return AdditionalProperties.fromMap(map) as T;
}
}

if (isA(v, InlineSchemaOptions)) {
return InlineSchemaOptions.fromMap(
v.revive().namedArguments.map(
(key, value) => MapEntry(
key,
convertToPropertyValue(value),
),
),
) as T;
}

if (isA(v, Map<String, String>)) {
return v.mapValue.map((key, value) => MapEntry(
convertToPropertyValue(key!) as String,
convertToPropertyValue(value!) as String)) as T;
} else if (isA(v, bool)) {
return v.boolValue as T;
} else if (isA(v, double)) {
return v.doubleValue as T;
} else if (isA(v, int)) {
return v.intValue as T;
} else if (isA(v, String)) {
return v.stringValue as T;
} else if (isA(v, Set)) {
return v.setValue.map(convertToPropertyValue) as T;
} else if (isA(v, List)) {
return v.listValue.map(convertToPropertyValue) as T;
} else if (isA(v, Enum)) {
return v.enumValue();
} else {
return defaultValue;
}
}
}

bool isA(ConstantReader? v, Type t) =>
v?.instanceOf(TypeChecker.fromRuntime(t)) ?? false;
34 changes: 17 additions & 17 deletions openapi-generator/lib/src/gen_on_spec_changes.dart
Original file line number Diff line number Diff line change
Expand Up @@ -59,23 +59,23 @@ FutureOr<Map<String, dynamic>> loadSpec(
}
} else {
Map<String, String>? headers;
// if (specConfig.headerDelegate is AWSRemoteSpecHeaderDelegate) {
// try {
// headers = (specConfig.headerDelegate as AWSRemoteSpecHeaderDelegate)
// .header(path: specConfig.url.path);
// } catch (e, st) {
// return Future.error(
// OutputMessage(
// message: 'failed to generate AWS headers',
// additionalContext: e,
// stackTrace: st,
// level: Level.SEVERE,
// ),
// );
// }
// } else {
// headers = specConfig.headerDelegate.header();
// }
if (specConfig.headerDelegate is AWSRemoteSpecHeaderDelegate) {
try {
headers = (specConfig.headerDelegate as AWSRemoteSpecHeaderDelegate)
.header(path: specConfig.url.path);
} catch (e, st) {
return Future.error(
OutputMessage(
message: 'failed to generate AWS headers',
additionalContext: e,
stackTrace: st,
level: Level.SEVERE,
),
);
}
} else {
headers = specConfig.headerDelegate.header();
}

final resp = await http.get(specConfig.url, headers: headers);
if (resp.statusCode == 200) {
Expand Down
53 changes: 0 additions & 53 deletions openapi-generator/lib/src/models/command.dart
Original file line number Diff line number Diff line change
@@ -1,7 +1,3 @@
import 'dart:io';

import 'package:openapi_generator/src/determine_flutter_project_status.dart';
import 'package:openapi_generator/src/gen_on_spec_changes.dart';
import 'package:openapi_generator_annotations/openapi_generator_annotations.dart';

/// Creates a representation of a cli request for Flutter or Dart.
Expand Down Expand Up @@ -33,52 +29,3 @@ class Command {
arguments,
);
}

/// CommandRunner provides an abstraction layer to external functions / processes.
class CommandRunner {
const CommandRunner();

Future<ProcessResult> runCommand({
required Command command,
required String workingDirectory,
}) async =>
Process.run(
command.executable,
command.arguments,
workingDirectory: workingDirectory,
runInShell: Platform.isWindows,
);

Future<List<String>> loadAnnotatedFile({required String path}) async {
final f = File(path);
return f.readAsLines();
}

Future<void> writeAnnotatedFile(
{required String path, required List<String> content}) async {
final f = File(path);
return f.writeAsStringSync(content.join('\n'), flush: true);
}

Future<void> cacheSpecFile({
required Map<String, dynamic> updatedSpec,
required String cachedPath,
}) async =>
cacheSpec(outputLocation: cachedPath, spec: updatedSpec);

Future<Map<String, dynamic>> loadSpecFile(
{required InputSpec specConfig, bool isCached = false}) async =>
loadSpec(specConfig: specConfig);

Future<bool> isSpecFileDirty({
required Map<String, dynamic> cachedSpec,
required Map<String, dynamic> loadedSpec,
}) async =>
isSpecDirty(cachedSpec: cachedSpec, loadedSpec: loadedSpec);

Future<bool> checkForFlutterEnvironemt(
{Wrapper? wrapper = Wrapper.none,
String? providedPubspecPath}) async =>
checkPubspecAndWrapperForFlutterSupport(
wrapper: wrapper, providedPubspecPath: providedPubspecPath);
}
Loading