1.0.4
This commit is contained in:
parent
3564fb4e35
commit
f1ce32d07e
8 changed files with 74 additions and 20 deletions
36
README.md
36
README.md
|
@ -1,6 +1,6 @@
|
|||
# angel_client
|
||||
|
||||
[![pub 1.0.3](https://img.shields.io/badge/pub-1.0.3-brightgreen.svg)](https://pub.dartlang.org/packages/angel_client)
|
||||
[![pub 1.0.4](https://img.shields.io/badge/pub-1.0.4-brightgreen.svg)](https://pub.dartlang.org/packages/angel_client)
|
||||
[![build status](https://travis-ci.org/angel-dart/client.svg)](https://travis-ci.org/angel-dart/client)
|
||||
|
||||
Client library for the Angel framework.
|
||||
|
@ -54,3 +54,37 @@ bar() async {
|
|||
|
||||
Just like on the server, services support `index`, `read`, `create`, `modify`, `update` and
|
||||
`remove`.
|
||||
|
||||
## Authentication
|
||||
Local auth:
|
||||
```dart
|
||||
var auth = await app.authenticate(type: 'local', credentials: {username: ..., password: ...});
|
||||
print(auth.token);
|
||||
print(auth.user);
|
||||
```
|
||||
|
||||
Revive an existing jwt:
|
||||
```dart
|
||||
Future<AngelAuthResult> reviveJwt(String jwt) {
|
||||
return app.authenticate(credentials: {'token': jwt});
|
||||
}
|
||||
```
|
||||
|
||||
Via Popup:
|
||||
```dart
|
||||
app.authenticateViaPopup('/auth/google').listen((jwt) {
|
||||
// Do something with the JWT
|
||||
});
|
||||
```
|
||||
|
||||
Resume a session from localStorage (browser only):
|
||||
```dart
|
||||
// Automatically checks for JSON-encoded 'token' in localStorage,
|
||||
// and tries to revive it
|
||||
await app.authenticate();
|
||||
```
|
||||
|
||||
Logout:
|
||||
```dart
|
||||
await app.logout();
|
||||
```
|
1
dart_test.yaml
Normal file
1
dart_test.yaml
Normal file
|
@ -0,0 +1 @@
|
|||
# platforms: [vm, content-shell]
|
|
@ -38,6 +38,9 @@ abstract class Angel {
|
|||
await configurer(this);
|
||||
}
|
||||
|
||||
/// Logs the current user out of the application.
|
||||
Future logout();
|
||||
|
||||
Service service<T>(String path, {Type type, AngelDeserializer deserializer});
|
||||
|
||||
Future<http.Response> delete(String url, {Map<String, String> headers});
|
||||
|
|
|
@ -28,6 +28,11 @@ _buildQuery(Map params) {
|
|||
return '?' + query.join('&');
|
||||
}
|
||||
|
||||
bool _invalid(http.Response response) =>
|
||||
response.statusCode == null ||
|
||||
response.statusCode < 200 ||
|
||||
response.statusCode >= 300;
|
||||
|
||||
AngelHttpException failure(http.Response response, {error, StackTrace stack}) {
|
||||
try {
|
||||
final json = JSON.decode(response.body);
|
||||
|
@ -68,7 +73,7 @@ abstract class BaseAngelClient extends Angel {
|
|||
});
|
||||
|
||||
try {
|
||||
if (response.statusCode != 200) {
|
||||
if (_invalid(response)) {
|
||||
throw failure(response);
|
||||
}
|
||||
|
||||
|
@ -98,7 +103,7 @@ abstract class BaseAngelClient extends Angel {
|
|||
}
|
||||
|
||||
try {
|
||||
if (response.statusCode != 200) {
|
||||
if (_invalid(response)) {
|
||||
throw failure(response);
|
||||
}
|
||||
|
||||
|
@ -123,6 +128,10 @@ abstract class BaseAngelClient extends Angel {
|
|||
client.close();
|
||||
}
|
||||
|
||||
Future logout() async {
|
||||
authToken = null;
|
||||
}
|
||||
|
||||
/// Sends a non-streaming [Request] and returns a non-streaming [Response].
|
||||
Future<http.Response> sendUnstreamed(
|
||||
String method, url, Map<String, String> headers,
|
||||
|
@ -230,7 +239,7 @@ class BaseAngelService extends Service {
|
|||
'GET', '$basePath${_buildQuery(params)}', _readHeaders);
|
||||
|
||||
try {
|
||||
if (response.statusCode != 200) {
|
||||
if (_invalid(response)) {
|
||||
throw failure(response);
|
||||
}
|
||||
|
||||
|
@ -248,7 +257,7 @@ class BaseAngelService extends Service {
|
|||
'GET', '$basePath/$id${_buildQuery(params)}', _readHeaders);
|
||||
|
||||
try {
|
||||
if (response.statusCode != 200) {
|
||||
if (_invalid(response)) {
|
||||
throw failure(response);
|
||||
}
|
||||
|
||||
|
@ -264,7 +273,7 @@ class BaseAngelService extends Service {
|
|||
'$basePath/${_buildQuery(params)}', _writeHeaders, makeBody(data));
|
||||
|
||||
try {
|
||||
if (response.statusCode != 200) {
|
||||
if (_invalid(response)) {
|
||||
throw failure(response);
|
||||
}
|
||||
|
||||
|
@ -280,7 +289,7 @@ class BaseAngelService extends Service {
|
|||
'$basePath/$id${_buildQuery(params)}', _writeHeaders, makeBody(data));
|
||||
|
||||
try {
|
||||
if (response.statusCode != 200) {
|
||||
if (_invalid(response)) {
|
||||
throw failure(response);
|
||||
}
|
||||
|
||||
|
@ -296,7 +305,7 @@ class BaseAngelService extends Service {
|
|||
'$basePath/$id${_buildQuery(params)}', _writeHeaders, makeBody(data));
|
||||
|
||||
try {
|
||||
if (response.statusCode != 200) {
|
||||
if (_invalid(response)) {
|
||||
throw failure(response);
|
||||
}
|
||||
|
||||
|
@ -312,7 +321,7 @@ class BaseAngelService extends Service {
|
|||
'DELETE', '$basePath/$id${_buildQuery(params)}', _readHeaders);
|
||||
|
||||
try {
|
||||
if (response.statusCode != 200) {
|
||||
if (_invalid(response)) {
|
||||
throw failure(response);
|
||||
}
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@ import 'dart:convert' show JSON;
|
|||
import 'dart:html' show CustomEvent, window;
|
||||
import 'package:http/browser_client.dart' as http;
|
||||
import 'angel_client.dart';
|
||||
import 'auth_types.dart' as auth_types;
|
||||
// import 'auth_types.dart' as auth_types;
|
||||
import 'base_angel_client.dart';
|
||||
export 'angel_client.dart';
|
||||
|
||||
|
@ -53,13 +53,15 @@ class Rest extends BaseAngelClient {
|
|||
var ctrl = new StreamController<String>();
|
||||
var wnd = window.open(url, 'angel_client_auth_popup');
|
||||
|
||||
new Timer.periodic(new Duration(milliseconds: 500), (timer) {
|
||||
Timer t;
|
||||
t = new Timer.periodic(new Duration(milliseconds: 500), (timer) {
|
||||
if (!ctrl.isClosed) {
|
||||
if (wnd.closed) {
|
||||
ctrl.addError(new AngelHttpException.notAuthenticated(
|
||||
message:
|
||||
errorMessage ?? 'Authentication via popup window failed.'));
|
||||
ctrl.close();
|
||||
timer.cancel();
|
||||
}
|
||||
} else
|
||||
timer.cancel();
|
||||
|
@ -68,10 +70,17 @@ class Rest extends BaseAngelClient {
|
|||
window.on[eventName ?? 'token'].listen((CustomEvent e) {
|
||||
if (!ctrl.isClosed) {
|
||||
ctrl.add(e.detail);
|
||||
t.cancel();
|
||||
ctrl.close();
|
||||
}
|
||||
});
|
||||
|
||||
return ctrl.stream;
|
||||
}
|
||||
|
||||
@override
|
||||
Future logout() {
|
||||
window.localStorage.remove('token');
|
||||
return super.logout();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
name: angel_client
|
||||
version: 1.0.3
|
||||
version: 1.0.4
|
||||
description: Client library for the Angel framework.
|
||||
author: Tobe O <thosakwe@gmail.com>
|
||||
homepage: https://github.com/angel-dart/angel_client
|
||||
|
|
|
@ -6,8 +6,7 @@ import 'for_browser_tests.dart';
|
|||
main() {
|
||||
test("list todos", () async {
|
||||
var channel = spawnHybridCode(SERVER);
|
||||
int port = await channel.stream.first;
|
||||
var url = "http://localhost:$port";
|
||||
String url = await channel.stream.first;
|
||||
print(url);
|
||||
var app = new Rest(url);
|
||||
var todoService = app.service("todos");
|
||||
|
@ -18,8 +17,7 @@ main() {
|
|||
|
||||
test('create todos', () async {
|
||||
var channel = spawnHybridCode(SERVER);
|
||||
int port = await channel.stream.first;
|
||||
var url = "http://localhost:$port";
|
||||
String url = await channel.stream.first;
|
||||
print(url);
|
||||
var app = new Rest(url);
|
||||
var todoService = app.service("todos");
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
const String SERVER = '''
|
||||
import 'dart:io';
|
||||
import "package:angel_framework/angel_framework.dart";
|
||||
import "package:angel_framework/src/defs.dart";
|
||||
import "package:angel_framework/common.dart";
|
||||
import 'package:stream_channel/stream_channel.dart';
|
||||
|
||||
hybridMain(StreamChannel channel) async {
|
||||
|
@ -12,15 +12,15 @@ hybridMain(StreamChannel channel) async {
|
|||
return true;
|
||||
});
|
||||
|
||||
app.use("/todos", new MemoryService<Todo>());
|
||||
app.use("/todos", new TypedService<Todo>(new MapService()));
|
||||
|
||||
var server = await app.startServer(InternetAddress.LOOPBACK_IP_V4, 0);
|
||||
|
||||
print("Server up; listening at http://localhost:\${server.port}");
|
||||
channel.sink.add(server.port);
|
||||
channel.sink.add('http://\${server.address.address}:\${server.port}');
|
||||
}
|
||||
|
||||
class Todo extends MemoryModel {
|
||||
class Todo extends Model {
|
||||
String hello;
|
||||
|
||||
Todo({int id, this.hello}) {
|
||||
|
|
Loading…
Reference in a new issue