Skip to content

Commit c462c87

Browse files
committed
initial commit
1 parent 66c62e3 commit c462c87

File tree

9 files changed

+785
-62
lines changed

9 files changed

+785
-62
lines changed

README.md

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,3 @@
11
# feathersjs
22

3-
A new Flutter package project.
4-
5-
## Getting Started
6-
7-
This project is a starting point for a Dart
8-
[package](https://flutter.dev/developing-packages/),
9-
a library module containing code that can be shared easily across
10-
multiple Flutter or Dart projects.
11-
12-
For help getting started with Flutter, view our
13-
[online documentation](https://flutter.dev/docs), which offers tutorials,
14-
samples, guidance on mobile development, and a full API reference.
3+
Under dev, please don't use it now.

lib/feathersjs.dart

Lines changed: 45 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,49 @@
11
library feathersjs;
22

3-
//Code to communicate with feathersjs server (via socketio or rest) and use service's method
4-
// and hooks as on the server
3+
import 'package:feathersjs/src/rest_client.dart';
4+
import 'package:feathersjs/src/socketio_client.dart';
5+
import 'package:meta/meta.dart';
6+
import 'package:shared_preferences/shared_preferences.dart';
57

6-
/// A Calculator.
7-
class Calculator {
8-
/// Returns [value] plus 1.
9-
int addOne(int value) => value + 1;
8+
class FeathersJs {
9+
/////////////////////////////////////////////////////////////////////
10+
RestClient restClient;
11+
SocketioClient socketioClient;
12+
////////////////////////////////////////////////////////////////////////
13+
14+
static final FeathersJs _feathersJs = FeathersJs._internal();
15+
16+
factory FeathersJs() {
17+
return _feathersJs;
18+
}
19+
FeathersJs._internal();
20+
21+
init({@required String baseUrl, Map<String, dynamic> extraHeaders}) {
22+
restClient = new RestClient(baseUrl: baseUrl, extraHeaders: extraHeaders);
23+
socketioClient =
24+
new SocketioClient(baseUrl: baseUrl, extraHeaders: extraHeaders);
25+
}
26+
27+
/// Authenticate on or both feathers client
28+
/// {..., client: 'rest' or 'socketio' or 'all' ,...}
29+
Future<bool> authenticate(
30+
{@required String email,
31+
@required String password,
32+
String client = "rest"}) async {
33+
var authSuccess = false;
34+
if (client == "rest") {
35+
authSuccess =
36+
await restClient.authenticate(email: email, password: password);
37+
} else if (client == "socketio") {
38+
authSuccess =
39+
await socketioClient.authenticate(email: email, password: password);
40+
} else if (client == "all") {
41+
var authSuccessRest =
42+
await restClient.authenticate(email: email, password: password);
43+
var authSuccessSocket =
44+
await socketioClient.authenticate(email: email, password: password);
45+
authSuccess = authSuccessSocket & authSuccessRest;
46+
}
47+
return authSuccess;
48+
}
1049
}

lib/src/featherjs_client_base.dart

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
//Base classe for both rest and socketio
2+
3+
class FeathersJsClient {}

lib/src/rest_client.dart

Lines changed: 119 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,119 @@
1-
//Code to communicate with feathers js server through http transport
1+
import 'dart:async';
2+
3+
import 'package:dio/dio.dart';
4+
import 'package:feathersjs/src/featherjs_client_base.dart';
5+
import 'package:meta/meta.dart';
6+
7+
class RestClient extends FeathersJsClient {
8+
/////////////////////////////////////////////////////////////////////
9+
Dio dio;
10+
////////////////////////////////////////////////////////////////////////
11+
12+
RestClient({@required String baseUrl, Map<String, dynamic> extraHeaders}) {
13+
//Setup Http client
14+
dio = Dio(BaseOptions(
15+
baseUrl: baseUrl,
16+
headers: extraHeaders,
17+
));
18+
}
19+
20+
Future<bool> authenticate(
21+
{strategy = "local", String email, String password}) async {
22+
Completer asyncTask = Completer<bool>();
23+
try {
24+
//Making http request to get auth token
25+
var response = await dio.post("/authentication",
26+
data: {"strategy": strategy, "email": email, "password": password});
27+
var token = response.data['accessToken'];
28+
dio.options.headers["Authorization"] = "Bearer $token";
29+
asyncTask.complete(true);
30+
} catch (e) {
31+
asyncTask.complete(false);
32+
}
33+
return asyncTask.future;
34+
}
35+
36+
/// GET /serviceName
37+
/// Retrieves a list of all matching resources from the service
38+
Future<Response<dynamic>> find(
39+
{String serviceName, Map<String, dynamic> query}) async {
40+
var response = await this.dio.get("/$serviceName", queryParameters: query);
41+
return response;
42+
}
43+
44+
/// GET /serviceName/_id
45+
/// Retrieve a single resource from the service.
46+
Future<Response<dynamic>> get({String serviceName, objectId}) async {
47+
var response = await this.dio.get("/$serviceName/$objectId");
48+
return response;
49+
}
50+
51+
/// POST /serviceName
52+
/// Create a new resource with data.
53+
Future<Response<dynamic>> create(
54+
{String serviceName, Map<String, dynamic> data}) async {
55+
var response = await this.dio.post("/$serviceName", data: data);
56+
return response;
57+
}
58+
59+
/* /// POST /serviceName
60+
/// Create multiple ressources simultaneously.
61+
/// NOT TESTED
62+
Future<Response<dynamic>> createBulk(
63+
{String serviceName, List<Map<String, dynamic>> data}) async {
64+
var response = await this.dio.post("/$serviceName", data: data);
65+
return response;
66+
} */
67+
68+
/// PUT /serviceName/_id
69+
/// Completely replace a single resource.
70+
Future<Response<dynamic>> update(
71+
{String serviceName, objectId, Map<String, dynamic> data}) async {
72+
var response =
73+
await this.dio.put("/$serviceName" + "/$objectId", data: data);
74+
return response;
75+
}
76+
77+
/// PATCH /serviceName/_id
78+
/// Merge the existing data of a single resources with the new data.
79+
/// NOT TESTED
80+
Future<Response<dynamic>> patch(
81+
{String serviceName, objectId, Map<String, dynamic> data}) async {
82+
var response =
83+
await this.dio.patch("/$serviceName" + "/$objectId", data: data);
84+
return response;
85+
}
86+
87+
/* /// PATCH /serviceName/_id
88+
/// Merge the existing data of multiple resources with the new data.
89+
/// Note: Multi options requred on server
90+
/// NOT TESTED
91+
Future<Response<dynamic>> patchBulk(
92+
{String serviceName,
93+
Map<String, dynamic> data,
94+
Map<String, dynamic> query}) async {
95+
var response = await this
96+
.dio
97+
.patch("/$serviceName", data: data, queryParameters: query);
98+
return response;
99+
} */
100+
101+
/// DELETE /serviceName/_id
102+
/// Remove a single resources:
103+
Future<Response<dynamic>> remove({String serviceName, objectId}) async {
104+
var response = await this.dio.delete(
105+
"/$serviceName/$objectId",
106+
);
107+
return response;
108+
}
109+
/*
110+
/// DELETE /serviceName
111+
/// Remove multiple resources:
112+
/// NOT TESTED
113+
Future<Response<dynamic>> removeBulk(
114+
{String serviceName, Map<String, dynamic> query}) async {
115+
var response =
116+
await this.dio.delete("/$serviceName", queryParameters: query);
117+
return response;
118+
} */
119+
}

lib/src/socketio_client.dart

Lines changed: 163 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,163 @@
1-
//Code to communicate with feathers js server through socketio
1+
import 'dart:async';
2+
3+
import 'package:feathersjs/src/featherjs_client_base.dart';
4+
import 'package:socket_io_client/socket_io_client.dart' as IO;
5+
import 'package:meta/meta.dart';
6+
7+
class SocketioClient extends FeathersJsClient {
8+
/////////////////////////////////////////////////////////////////////
9+
IO.Socket _socket;
10+
String accesToken;
11+
bool dev = true;
12+
////////////////////////////////////////////////////////////////////////
13+
14+
/// Constructor
15+
/// Connect anonymously to the _socket server througth web _socket
16+
SocketioClient(
17+
{@required String baseUrl, Map<String, dynamic> extraHeaders}) {
18+
_socket = IO.io(baseUrl, <String, dynamic>{
19+
'transports': ['websocket'],
20+
'extraHeaders': extraHeaders,
21+
//'autoConnect': false,
22+
});
23+
//_socket.connect();
24+
25+
if (dev) {
26+
_socket.on('connect', (_) {
27+
print("Socket connection established");
28+
});
29+
30+
_socket.on('connect_error', (e) {
31+
print("Connection error");
32+
print(e);
33+
});
34+
_socket.on('connect_timeout', (data) {
35+
print("Timeout error");
36+
print(data);
37+
});
38+
_socket.on('connecting', (_) => print("Connecting..."));
39+
_socket.on('disconnect', (_) => print("Disconnected..."));
40+
_socket.on('error', (_) => print("An error occured"));
41+
_socket.on('reconnect', (_) => print("Reconnected"));
42+
_socket.on('reconnect_error', (_) => print("Reconnection error..."));
43+
_socket.on(
44+
'reconnect_attempt', (_) => print("Attempting a reconnection"));
45+
_socket.on('reconnect_failed', (_) => print("A reconnection failed"));
46+
_socket.on('reconnecting', (_) => print("Reconnecting..."));
47+
}
48+
}
49+
50+
/// EMIT create authentication
51+
/// Authenticate the _socket connection
52+
Future<bool> authenticate({
53+
String email,
54+
String password,
55+
}) async {
56+
Completer asyncTask = Completer<bool>();
57+
_socket.emitWithAck('create', [
58+
'authentication',
59+
<String, dynamic>{
60+
'strategy': 'local',
61+
'email': email,
62+
'password': password
63+
}
64+
], ack: (authResult) {
65+
try {
66+
accesToken = authResult[1]['accessToken'];
67+
asyncTask.complete(true);
68+
} catch (e) {
69+
asyncTask.complete(false);
70+
}
71+
});
72+
return asyncTask.future;
73+
}
74+
75+
/// EMIT find serviceName
76+
/// Retrieves a list of all matching resources from the service
77+
Future<dynamic> emitFind(
78+
{String serviceName, Map<String, dynamic> query}) async {
79+
Completer asyncTask = Completer<dynamic>();
80+
_socket.emitWithAck("find", [serviceName, query], ack: (response) {
81+
asyncTask.complete(response[1]);
82+
});
83+
return asyncTask.future;
84+
}
85+
86+
/// EMIT create serviceName
87+
/// Create new ressource
88+
Future<dynamic> emitCreate({String serviceName, Map<String, dynamic> data}) {
89+
Completer asyncTask = Completer<dynamic>();
90+
_socket.emitWithAck("create", [serviceName, data], ack: (response) {
91+
asyncTask.complete(response[1]);
92+
});
93+
return asyncTask.future;
94+
}
95+
96+
/// EMIT update serviceName
97+
/// Update a ressource
98+
Future<dynamic> emitUpdate(
99+
{String serviceName, objectId, Map<String, dynamic> data}) {
100+
Completer asyncTask = Completer<dynamic>();
101+
_socket.emitWithAck("update", [serviceName, objectId, data],
102+
ack: (response) {
103+
asyncTask.complete(response[1]);
104+
});
105+
return asyncTask.future;
106+
}
107+
108+
/// EMIT get serviceName
109+
/// Retrieve a single ressource
110+
Future<dynamic> emitGet({String serviceName, objectId}) {
111+
Completer asyncTask = Completer<dynamic>();
112+
_socket.emitWithAck("get", [serviceName, objectId], ack: (response) {
113+
asyncTask.complete(response[1]);
114+
});
115+
return asyncTask.future;
116+
}
117+
118+
/// EMIT patch serviceName
119+
///Merge the existing data of a single or multiple resources with the new data
120+
Future<dynamic> emitPatch(
121+
{String serviceName, objectId, Map<String, dynamic> data}) {
122+
Completer asyncTask = Completer<dynamic>();
123+
_socket.emitWithAck("patch", [serviceName, objectId, data],
124+
ack: (response) {
125+
asyncTask.complete(response[1]);
126+
});
127+
return asyncTask.future;
128+
}
129+
130+
/// EMIT patch serviceName
131+
///Merge the existing data of a single or multiple resources with the new data
132+
Future<dynamic> emitRemove({String serviceName, objectId}) {
133+
Completer asyncTask = Completer<dynamic>();
134+
_socket.emitWithAck("remove", [serviceName, objectId], ack: (response) {
135+
asyncTask.complete(response[1]);
136+
});
137+
return asyncTask.future;
138+
}
139+
140+
/// Listen to create method call
141+
///Get the last created ressource
142+
onCreated({String serviceName, Function callback}) {
143+
_socket.on("$serviceName created", (data) {
144+
callback(data);
145+
});
146+
}
147+
148+
/// Listen to update method
149+
///Get the last updated ressource
150+
onUpdated({String serviceName, Function callback}) {
151+
_socket.on("$serviceName updated", (data) {
152+
callback(data);
153+
});
154+
}
155+
156+
/// Listen to remove method call
157+
///Get the last deleted ressource
158+
onRemoved({String serviceName, Function callback}) {
159+
_socket.on("$serviceName removed", (data) {
160+
callback(data);
161+
});
162+
}
163+
}

0 commit comments

Comments
 (0)