Finish after YoDesk
This commit is contained in:
parent
29ecf461dd
commit
319e195faa
8 changed files with 125 additions and 38 deletions
|
@ -2,6 +2,7 @@
|
|||
library angel_client;
|
||||
|
||||
import 'dart:async';
|
||||
import 'auth_types.dart' as auth_types;
|
||||
|
||||
/// A function that configures an [Angel] client in some way.
|
||||
typedef Future AngelConfigurer(Angel app);
|
||||
|
@ -12,6 +13,8 @@ abstract class Angel {
|
|||
|
||||
Angel(String this.basePath);
|
||||
|
||||
Future<AngelAuthResult> authenticate({String type: auth_types.LOCAL, credentials, String authEndpoint: '/auth'});
|
||||
|
||||
/// Applies an [AngelConfigurer] to this instance.
|
||||
Future configure(AngelConfigurer configurer) async {
|
||||
await configurer(this);
|
||||
|
@ -20,10 +23,16 @@ abstract class Angel {
|
|||
Service service(Pattern path, {Type type});
|
||||
}
|
||||
|
||||
/// Represents the result of authentication with an Angel server.
|
||||
abstract class AngelAuthResult {
|
||||
Map<String, dynamic> get data;
|
||||
String get token;
|
||||
}
|
||||
|
||||
/// Queries a service on an Angel server, with the same API.
|
||||
abstract class Service {
|
||||
/// The Angel instance powering this service.
|
||||
Angel app;
|
||||
Angel get app;
|
||||
|
||||
/// Retrieves all resources.
|
||||
Future<List> index([Map params]);
|
||||
|
|
2
lib/auth_types.dart
Normal file
2
lib/auth_types.dart
Normal file
|
@ -0,0 +1,2 @@
|
|||
const String GOOGLE = 'google';
|
||||
const String LOCAL = 'local';
|
143
lib/browser.dart
143
lib/browser.dart
|
@ -1,92 +1,169 @@
|
|||
/// Browser library for the Angel framework.
|
||||
library angel_client.browser;
|
||||
|
||||
import 'dart:async';
|
||||
import 'dart:async' show Completer, Future;
|
||||
import 'dart:convert' show JSON;
|
||||
import 'dart:html';
|
||||
import 'dart:html' show HttpRequest;
|
||||
import 'angel_client.dart';
|
||||
import 'auth_types.dart' as auth_types;
|
||||
export 'angel_client.dart';
|
||||
|
||||
_buildQuery(Map params) {
|
||||
if (params == null || params == {})
|
||||
return "";
|
||||
if (params == null || params == {}) return "";
|
||||
|
||||
String result = "";
|
||||
return result;
|
||||
}
|
||||
|
||||
_send(HttpRequest request, [data]) {
|
||||
final completer = new Completer<HttpRequest>();
|
||||
|
||||
request
|
||||
..onLoadEnd.listen((_) {
|
||||
completer.complete(request.response);
|
||||
})
|
||||
..onError.listen((_) {
|
||||
try {
|
||||
throw new Exception(
|
||||
'Request failed with status code ${request.status}.');
|
||||
} catch (e, st) {
|
||||
completer.completeError(e, st);
|
||||
}
|
||||
});
|
||||
|
||||
request.send(data);
|
||||
return completer.future;
|
||||
}
|
||||
|
||||
/// Queries an Angel server via REST.
|
||||
class Rest extends Angel {
|
||||
Rest(String basePath) :super(basePath);
|
||||
String _authToken;
|
||||
|
||||
Rest(String basePath) : super(basePath);
|
||||
|
||||
@override
|
||||
Future<AngelAuthResult> authenticate(
|
||||
{String type: auth_types.LOCAL,
|
||||
credentials,
|
||||
String authEndpoint: '/auth'}) async {
|
||||
final url = '$authEndpoint/$type';
|
||||
|
||||
if (type == auth_types.LOCAL) {
|
||||
final completer = new Completer();
|
||||
final request = new HttpRequest();
|
||||
request.open('POST', url);
|
||||
request.responseType = 'json';
|
||||
request.setRequestHeader("Accept", "application/json");
|
||||
request.setRequestHeader("Content-Type", "application/json");
|
||||
|
||||
request
|
||||
..onLoadEnd.listen((_) {
|
||||
completer
|
||||
.complete(new _AngelAuthResultImpl.fromMap(request.response));
|
||||
})
|
||||
..onError.listen((_) {
|
||||
try {
|
||||
throw new Exception(
|
||||
'Request failed with status code ${request.status}.');
|
||||
} catch (e, st) {
|
||||
completer.completeError(e, st);
|
||||
}
|
||||
});
|
||||
|
||||
request.send(credentials);
|
||||
|
||||
return completer.future;
|
||||
} else {
|
||||
throw new Exception('angel_client cannot authenticate as "$type" yet.');
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
RestService service(String path, {Type type}) {
|
||||
String uri = path.replaceAll(new RegExp(r"(^\/)|(\/+$)"), "");
|
||||
return new RestService("$basePath/$uri")
|
||||
..app = this;
|
||||
return new _RestServiceImpl(this, "$basePath/$uri");
|
||||
}
|
||||
}
|
||||
|
||||
/// Queries an Angel service via REST.
|
||||
class RestService extends Service {
|
||||
String basePath;
|
||||
abstract class RestService extends Service {
|
||||
RestService._(String basePath);
|
||||
}
|
||||
|
||||
RestService(Pattern path) {
|
||||
this.basePath = (path is RegExp) ? path.pattern : path;
|
||||
class _AngelAuthResultImpl implements AngelAuthResult {
|
||||
final Map<String, dynamic> data = {};
|
||||
final String token;
|
||||
|
||||
_AngelAuthResultImpl({this.token, Map<String, dynamic> data: const {}}) {
|
||||
this.data.addAll(data ?? {});
|
||||
}
|
||||
|
||||
factory _AngelAuthResultImpl.fromMap(Map data) =>
|
||||
new _AngelAuthResultImpl(token: data['token'], data: data['data']);
|
||||
}
|
||||
|
||||
/// Queries an Angel service via REST.
|
||||
class _RestServiceImpl extends RestService {
|
||||
final Rest app;
|
||||
String _basePath;
|
||||
String get basePath => _basePath;
|
||||
|
||||
_RestServiceImpl(this.app, String basePath) : super._(basePath) {
|
||||
_basePath = basePath;
|
||||
}
|
||||
|
||||
_makeBody(data) {
|
||||
return JSON.encode(data);
|
||||
}
|
||||
|
||||
HttpRequest buildRequest(String url,
|
||||
{String method: "POST", bool write: true}) {
|
||||
Future<HttpRequest> buildRequest(String url,
|
||||
{String method: "POST", bool write: true}) async {
|
||||
HttpRequest request = new HttpRequest();
|
||||
request.open(method, url, async: false);
|
||||
request.open(method, url);
|
||||
request.responseType = "json";
|
||||
request.setRequestHeader("Accept", "application/json");
|
||||
if (write)
|
||||
request.setRequestHeader("Content-Type", "application/json");
|
||||
if (write) request.setRequestHeader("Content-Type", "application/json");
|
||||
if (app._authToken != null)
|
||||
request.setRequestHeader("Authorization", "Bearer ${app._authToken}");
|
||||
return request;
|
||||
}
|
||||
|
||||
@override
|
||||
Future<List> index([Map params]) async {
|
||||
return JSON.decode(
|
||||
await HttpRequest.getString("$basePath/${_buildQuery(params)}"));
|
||||
final request = await buildRequest('$basePath/${_buildQuery(params)}',
|
||||
method: 'GET', write: false);
|
||||
return await _send(request);
|
||||
}
|
||||
|
||||
@override
|
||||
Future read(id, [Map params]) async {
|
||||
return JSON.decode(
|
||||
await HttpRequest.getString("$basePath/$id${_buildQuery(params)}"));
|
||||
final request = await buildRequest('$basePath/$id${_buildQuery(params)}',
|
||||
method: 'GET', write: false);
|
||||
return await _send(request);
|
||||
}
|
||||
|
||||
@override
|
||||
Future create(data, [Map params]) async {
|
||||
var request = buildRequest("$basePath/${_buildQuery(params)}");
|
||||
request.send(_makeBody(data));
|
||||
return request.response;
|
||||
final request = await buildRequest("$basePath/${_buildQuery(params)}");
|
||||
return await _send(request, _makeBody(data));
|
||||
}
|
||||
|
||||
@override
|
||||
Future modify(id, data, [Map params]) async {
|
||||
var request = buildRequest("$basePath/$id${_buildQuery(params)}", method: "PATCH");
|
||||
request.send(_makeBody(data));
|
||||
return request.response;
|
||||
final request = await buildRequest("$basePath/$id${_buildQuery(params)}",
|
||||
method: "PATCH");
|
||||
return await _send(request, _makeBody(data));
|
||||
}
|
||||
|
||||
@override
|
||||
Future update(id, data, [Map params]) async {
|
||||
var request = buildRequest("$basePath/$id${_buildQuery(params)}");
|
||||
request.send(_makeBody(data));
|
||||
return request.response;
|
||||
final request = await buildRequest("$basePath/$id${_buildQuery(params)}");
|
||||
return await _send(request, _makeBody(data));
|
||||
}
|
||||
|
||||
@override
|
||||
Future remove(id, [Map params]) async {
|
||||
var request = buildRequest("$basePath/$id${_buildQuery(params)}", method: "DELETE");
|
||||
request.send();
|
||||
return request.response;
|
||||
final request = await buildRequest("$basePath/$id${_buildQuery(params)}",
|
||||
method: "DELETE");
|
||||
return await _send(request);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
name: angel_client
|
||||
version: 1.0.0-dev+7
|
||||
version: 1.0.0-dev+8
|
||||
description: Client library for the Angel framework.
|
||||
author: Tobe O <thosakwe@gmail.com>
|
||||
homepage: https://github.com/angel-dart/angel_client
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import 'dart:io';
|
||||
import "package:angel_framework/angel_framework.dart";
|
||||
import "package:angel_framework/defs.dart";
|
||||
import "package:angel_framework/src/defs.dart";
|
||||
|
||||
main() async {
|
||||
Angel app = new Angel();
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import 'dart:io';
|
||||
import 'package:angel_client/cli.dart' as client;
|
||||
import 'package:angel_client/io.dart' as client;
|
||||
import 'package:angel_framework/angel_framework.dart' as server;
|
||||
import 'package:http/http.dart' as http;
|
||||
import 'package:json_god/json_god.dart' as god;
|
|
@ -1 +0,0 @@
|
|||
../packages
|
Loading…
Reference in a new issue