of static method
The plan for fn on route. Throws a StateError when a
parameter type is not known.
Implementation
static ControllerPlan of(Function fn, RouteData route) {
String where = '${route.method} ${route.path}';
List<String> types = ControllerTypes.parameters(fn, where);
List<String> params = route.paramNames;
List<ControllerArg> args = <ControllerArg>[];
int paths = 0;
bool hasDto = false;
for (int i = 0; i < types.length; i++) {
String type = types[i];
bool nullable = type.endsWith('?');
String name = nullable ? type.substring(0, type.length - 1) : type;
if (name == 'DoxRequest' || name == 'IDoxRequest') {
args.add(const ControllerArg(ArgKind.request));
continue;
}
// an untyped first parameter `(req)` is the request
if (name == 'dynamic' && i == 0 && !types.contains('DoxRequest')) {
args.add(const ControllerArg(ArgKind.request));
continue;
}
PathType? pathType = name == 'dynamic' || name == 'Object'
? PathType.string
: _pathTypes[name];
if (pathType != null) {
if (paths >= params.length) {
throw StateError(
'Route $where: the controller has more path params than the '
'route has {...} params (${params.length}).',
);
}
args.add(
ControllerArg(
ArgKind.path,
pathType: pathType,
nullable: nullable || name == 'dynamic',
param: params[paths++],
),
);
continue;
}
DtoSchema<Object>? dto = Dox().dtos.ofName(name);
if (dto == null) {
throw StateError(
'Route $where: the controller parameter type $type is not known. '
'Use DoxRequest, a @Dto class, or String, int, double, num, bool '
'for path params. For a DTO: did you run '
'`dart run build_runner build` and set `dtos: dtos` in AppConfig?',
);
}
if (hasDto) {
throw StateError('Route $where: a controller can have one @Dto only.');
}
hasDto = true;
args.add(ControllerArg(ArgKind.dto, dto: dto));
}
return ControllerPlan(fn, args);
}