Skip to content

Commit 8b2ed5e

Browse files
committed
_
1 parent abc0301 commit 8b2ed5e

File tree

6 files changed

+82
-18
lines changed

6 files changed

+82
-18
lines changed

packages/pharaoh/lib/src/_next/_core/reflector.dart

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -103,8 +103,10 @@ ControllerMethod parseControllerMethod(ControllerMethodDefinition defn) {
103103
);
104104
}
105105

106+
final returnType = getActualType(actualMethod.reflectedReturnType);
107+
106108
final parameters = actualMethod.parameters;
107-
if (parameters.isEmpty) return ControllerMethod(defn);
109+
if (parameters.isEmpty) return ControllerMethod(defn, returnType: returnType);
108110

109111
if (parameters.any((e) => e.metadata.length > 1)) {
110112
throw ArgumentError(
@@ -132,7 +134,17 @@ ControllerMethod parseControllerMethod(ControllerMethodDefinition defn) {
132134
);
133135
});
134136

135-
return ControllerMethod(defn, params);
137+
return ControllerMethod(defn, params: params, returnType: returnType);
138+
}
139+
140+
final _regex = RegExp(r"^(\w+)<(.+)>$");
141+
Type? getActualType(Type type) {
142+
final match = _regex.firstMatch(type.toString());
143+
if (match != null) {
144+
return q.data[inject]!.types
145+
.firstWhereOrNull((type) => type.toString() == match.group(2));
146+
}
147+
return type;
136148
}
137149

138150
BaseDTO? _tryResolveDtoInstance(Type type) {

packages/pharaoh/lib/src/_next/_router/definition.dart

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ class RouteMapping {
2525

2626
typedef OpenApiRoute = ({
2727
List<String> tags,
28+
Type? returnType,
2829
HTTPMethod method,
2930
String route,
3031
List<ControllerMethodParam> args,
@@ -89,14 +90,19 @@ class _MiddlewareDefinition extends RouteDefinition {
8990
typedef ControllerMethodDefinition = (Type controller, Symbol symbol);
9091

9192
class ControllerMethod {
93+
final Type? returnType;
9294
final ControllerMethodDefinition method;
9395
final Iterable<ControllerMethodParam> params;
9496

9597
String get methodName => symbolToString(method.$2);
9698

9799
Type get controller => method.$1;
98100

99-
ControllerMethod(this.method, [this.params = const []]);
101+
ControllerMethod(
102+
this.method, {
103+
this.params = const [],
104+
this.returnType,
105+
});
100106
}
101107

102108
class ControllerMethodParam {
@@ -143,6 +149,7 @@ class ControllerRouteMethodDefinition extends RouteDefinition {
143149
route: route.path,
144150
method: e,
145151
args: method.params.toList(),
152+
returnType: method.returnType,
146153
tags: <String>[if (group != null) group!]
147154
))
148155
.toList();
@@ -244,6 +251,7 @@ class FunctionalRouteDefinition extends RouteDefinition {
244251
List<OpenApiRoute> get openAPIRoutes => [
245252
(
246253
args: [],
254+
returnType: Response,
247255
method: method,
248256
route: route.path,
249257
tags: <String>[if (group != null) group!]

packages/pharaoh/lib/src/_next/core.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import 'dart:io';
66

77
import 'package:pharaoh/pharaoh.dart';
88
import 'package:reflectable/reflectable.dart' as r;
9+
import 'package:reflectable/src/reflectable_builder_based.dart' as q;
910
import 'package:spanner/spanner.dart';
1011
import 'package:spookie/spookie.dart' as spookie;
1112
import 'package:collection/collection.dart';

packages/pharaoh/lib/src/_next/openapi.dart

Lines changed: 44 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import 'package:collection/collection.dart';
2-
import 'package:pharaoh/src/_next/router.dart';
2+
import 'package:pharaoh/pharaoh_next.dart';
33

44
class OpenApiGenerator {
55
static Map<String, dynamic> generateOpenApi(
@@ -38,7 +38,17 @@ class OpenApiGenerator {
3838
if (parameters.isNotEmpty) "parameters": parameters,
3939
if (route.tags.isNotEmpty) "tags": route.tags,
4040
"responses": {
41-
"200": {"description": "Successful response"}
41+
"200": {
42+
"description": "Successful response",
43+
if (route.returnType != null && route.returnType != Response)
44+
"content": {
45+
"application/json": {
46+
"schema": {
47+
"\$ref": "#/components/schemas/${route.returnType}"
48+
},
49+
},
50+
}
51+
}
4252
}
4353
};
4454

@@ -104,18 +114,31 @@ class OpenApiGenerator {
104114
}
105115

106116
static Map<String, dynamic> _typeToOpenApiType(Type type) {
107-
switch (type.toString()) {
108-
case "String":
117+
switch (type) {
118+
case const (String):
109119
return {"type": "string"};
110-
case "int":
120+
case const (int):
111121
return {"type": "integer", "format": "int32"};
112-
case "double":
122+
case const (double):
113123
return {"type": "number", "format": "double"};
114-
case "bool":
124+
case const (bool):
115125
return {"type": "boolean"};
116-
case "DateTime":
126+
case const (DateTime):
117127
return {"type": "string", "format": "date-time"};
118128
default:
129+
final actualType = getActualType(type);
130+
if (actualType == null) return {"type": "object"};
131+
132+
// final properties = <VariableMirror>[];
133+
134+
// ClassMirror? clazz = reflectType(actualType);
135+
// while (clazz?.superclass != null) {
136+
// properties.addAll(clazz!.variables);
137+
// clazz = clazz.superclass;
138+
// }
139+
140+
// print(properties);
141+
119142
return {"type": "object"};
120143
}
121144
}
@@ -124,6 +147,7 @@ class OpenApiGenerator {
124147
final schemas = <String, dynamic>{};
125148

126149
for (final route in routes) {
150+
final returnType = route.returnType;
127151
for (final arg in route.args) {
128152
final dto = arg.dto;
129153
if (dto == null) continue;
@@ -134,6 +158,18 @@ class OpenApiGenerator {
134158
(preV, curr) => preV..[curr.name] = _typeToOpenApiType(curr.type))
135159
};
136160
}
161+
162+
if (returnType == null || returnType == Response) continue;
163+
164+
final properties = reflectType(returnType).variables;
165+
166+
schemas[returnType.toString()] = {
167+
"type": "object",
168+
"properties": properties.fold(
169+
{},
170+
(preV, curr) => preV
171+
..[curr.simpleName] = _typeToOpenApiType(curr.reflectedType))
172+
};
137173
}
138174

139175
return schemas;

packages/pharaoh/lib/src/_next/router.dart

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -73,9 +73,13 @@ abstract interface class Route {
7373
return ControllerRouteMethodDefinition(defn, mapping);
7474
}
7575

76-
static RouteGroupDefinition group(String name, List<RouteDefinition> routes,
77-
{String? prefix}) =>
78-
RouteGroupDefinition._(name, definitions: routes, prefix: prefix);
76+
static RouteGroupDefinition group(
77+
String name,
78+
List<RouteDefinition> routes, {
79+
String? prefix,
80+
}) {
81+
return RouteGroupDefinition._(name, definitions: routes, prefix: prefix);
82+
}
7983

8084
static RouteGroupDefinition resource(String resource, Type controller,
8185
{String? parameterName}) {
@@ -103,6 +107,9 @@ abstract interface class Route {
103107
Route.route(method, '/*', handler);
104108
}
105109

106-
Middleware useAliasedMiddleware(String alias) =>
107-
ApplicationFactory.resolveMiddlewareForGroup(alias)
108-
.reduce((val, e) => val.chain(e));
110+
@inject
111+
abstract mixin class ApiResource {
112+
const ApiResource();
113+
114+
Map<String, dynamic> toJson();
115+
}

packages/pharaoh/test/pharaoh_next/core/application_factory_test.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ void main() {
3535
test('for method with args', () async {
3636
final showMethod = ControllerMethod(
3737
(TestHttpController, #show),
38-
[ControllerMethodParam('userId', int, meta: query)],
38+
params: [ControllerMethodParam('userId', int, meta: query)],
3939
);
4040

4141
final handler = ApplicationFactory.buildControllerMethod(showMethod);

0 commit comments

Comments
 (0)