2017-01-30 02:39:11 +00:00
|
|
|
import 'dart:async';
|
|
|
|
import 'dart:mirrors';
|
|
|
|
import 'package:angel_framework/angel_framework.dart';
|
|
|
|
import 'plural.dart' as pluralize;
|
|
|
|
import 'no_service.dart';
|
|
|
|
|
|
|
|
/// Represents a relationship in which the current [service] "owns"
|
|
|
|
/// a single member of the service at [servicePath]. Use [as] to set the name
|
|
|
|
/// on the target object.
|
|
|
|
///
|
|
|
|
/// Defaults:
|
|
|
|
/// * [foreignKey]: `userId`
|
|
|
|
/// * [localKey]: `id`
|
|
|
|
HookedServiceEventListener hasOne(Pattern servicePath,
|
2021-06-20 12:37:20 +00:00
|
|
|
{String? as,
|
|
|
|
String? foreignKey,
|
|
|
|
String? localKey,
|
|
|
|
Function(dynamic obj)? getLocalKey,
|
|
|
|
Function(dynamic foreign, dynamic obj)? assignForeignObject}) {
|
2017-01-30 02:39:11 +00:00
|
|
|
return (HookedServiceEvent e) async {
|
2021-02-16 02:10:09 +00:00
|
|
|
var ref = e.getService(servicePath);
|
2017-01-30 02:39:11 +00:00
|
|
|
var foreignName = as?.isNotEmpty == true
|
|
|
|
? as
|
|
|
|
: pluralize.singular(servicePath.toString());
|
|
|
|
if (ref == null) throw noService(servicePath);
|
|
|
|
|
2021-06-20 12:37:20 +00:00
|
|
|
dynamic _getLocalKey(obj) {
|
|
|
|
if (getLocalKey != null) {
|
2017-01-30 02:39:11 +00:00
|
|
|
return getLocalKey(obj);
|
2021-06-20 12:37:20 +00:00
|
|
|
} else if (obj is Map) {
|
2017-01-30 02:39:11 +00:00
|
|
|
return obj[localKey ?? 'id'];
|
2021-06-20 12:37:20 +00:00
|
|
|
} else if (localKey == null || localKey == 'id') {
|
2017-01-30 02:39:11 +00:00
|
|
|
return obj.id;
|
2021-06-20 12:37:20 +00:00
|
|
|
} else {
|
|
|
|
return reflect(obj).getField(Symbol(localKey)).reflectee;
|
|
|
|
}
|
2017-01-30 02:39:11 +00:00
|
|
|
}
|
|
|
|
|
2021-06-20 12:37:20 +00:00
|
|
|
dynamic _assignForeignObject(foreign, obj) {
|
|
|
|
if (assignForeignObject != null) {
|
2017-01-30 02:39:11 +00:00
|
|
|
return assignForeignObject(foreign, obj);
|
2021-06-20 12:37:20 +00:00
|
|
|
} else if (obj is Map) {
|
2017-01-30 02:39:11 +00:00
|
|
|
obj[foreignName] = foreign;
|
2021-06-20 12:37:20 +00:00
|
|
|
} else {
|
|
|
|
reflect(obj).setField(Symbol(foreignName!), foreign);
|
|
|
|
}
|
2017-01-30 02:39:11 +00:00
|
|
|
}
|
|
|
|
|
2021-06-20 12:37:20 +00:00
|
|
|
Future _normalize(obj) async {
|
2017-01-30 02:39:11 +00:00
|
|
|
if (obj != null) {
|
|
|
|
var id = await _getLocalKey(obj);
|
2017-07-09 17:11:17 +00:00
|
|
|
|
2017-01-30 02:39:11 +00:00
|
|
|
var indexed = await ref.index({
|
|
|
|
'query': {foreignKey ?? 'userId': id}
|
|
|
|
});
|
|
|
|
|
2021-06-20 12:37:20 +00:00
|
|
|
if (indexed is! List || indexed.isNotEmpty != true) {
|
2017-01-30 02:39:11 +00:00
|
|
|
await _assignForeignObject(null, obj);
|
|
|
|
} else {
|
|
|
|
var child = indexed.first;
|
|
|
|
await _assignForeignObject(child, obj);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (e.result is Iterable) {
|
2021-06-20 12:37:20 +00:00
|
|
|
//await Future.wait(e.result.map(_normalize));
|
|
|
|
await e.result.map(_normalize);
|
|
|
|
} else {
|
2017-01-30 02:39:11 +00:00
|
|
|
await _normalize(e.result);
|
2021-06-20 12:37:20 +00:00
|
|
|
}
|
2017-01-30 02:39:11 +00:00
|
|
|
};
|
|
|
|
}
|