diff --git a/.editorconfig b/.editorconfig
new file mode 100644
index 0000000..e717f5e
--- /dev/null
+++ b/.editorconfig
@@ -0,0 +1,13 @@
+# http://editorconfig.org
+root = true
+
+[*]
+indent_style = space
+indent_size = 2
+end_of_line = lf
+charset = utf-8
+trim_trailing_whitespace = true
+insert_final_newline = true
+
+[*.md]
+trim_trailing_whitespace = false
diff --git a/README.md b/README.md
index 4100d85..2edb97f 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,6 @@
# feathers rest Client for admin-on-rest
-For using [feathers](https://www.feathersjs.com) with [admin-on-rest](https://github.com/marmelab/admin-on-rest), convert AOR's REST dialect into one compatible with feathers.
+For using [feathers](https://www.feathersjs.com) with [admin-on-rest](https://github.com/marmelab/admin-on-rest).
## Installation
@@ -8,19 +8,80 @@ For using [feathers](https://www.feathersjs.com) with [admin-on-rest](https://gi
npm install aor-feathers-client --save
```
-## Usage
+## Usage with stable
+
+```js
+// in src/feathersClient.js
+import feathers from 'feathers-client';
+
+const host = 'http://localhost:3030';
+
+export default feathers()
+ .configure(feathers.hooks())
+ .configure(feathers.rest(host).fetch(window.fetch.bind(window)))
+ .configure(feathers.authentication({ storage: window.localStorage }));
+```
+
+```js
+// in src/App.js
+import React from 'react';
+import { Admin, Resource } from 'admin-on-rest';
+import { authClient, restClient } from 'aor-feathers-client';
+import feathersClient from './feathersClient';
+import { PostList } from './posts';
+
+const App = () => (
+
+
+
+);
+
+export default App;
+```
+
+## Usage with Auk
+
+```js
+// in src/feathersClient.js
+import feathers from 'feathers-client';
+import hooks from 'feathers-hooks';
+import rest from 'feathers-rest/client';
+import authentication from 'feathers-authentication-client';
+
+const host = 'http://localhost:3030';
+
+export default feathers()
+ .configure(hooks())
+ .configure(rest(host).fetch(window.fetch.bind(window)))
+ .configure(authentication({
+ jwtStrategy: 'jwt',
+ storage: window.localStorage,
+ }));
+```
```js
// in src/App.js
import React from 'react';
import { Admin, Resource } from 'admin-on-rest';
-import feathersClient from 'aor-feathers-client';
+import { authClient, restClient } from 'aor-feathers-client';
+import feathersClient from './feathersClient';
import { PostList } from './posts';
+const authClientOptions = {
+ storageKey: 'feathers-jwt',
+ authenticate: { strategy: 'local' },
+};
+
const App = () => (
-
-
-
+
+
+
);
export default App;
diff --git a/package.json b/package.json
index e036023..9c65868 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "aor-feathers-client",
- "version": "0.1.0",
+ "version": "0.2.0",
"description": "A feathers client for admin-on-rest",
"main": "lib/index.js",
"scripts": {
@@ -33,7 +33,7 @@
},
"homepage": "https://github.com/josx/aor-feathers-client#readme",
"dependencies": {
- "admin-on-rest": "^0.7.0"
+ "admin-on-rest": "^0.9.0"
},
"devDependencies": {
"babel-cli": "^6.18.0",
diff --git a/src/authClient.js b/src/authClient.js
new file mode 100644
index 0000000..99702f3
--- /dev/null
+++ b/src/authClient.js
@@ -0,0 +1,31 @@
+import {
+ AUTH_LOGIN,
+ AUTH_LOGOUT,
+ AUTH_CHECK,
+} from 'admin-on-rest';
+
+export default (client, options = {}) => (type, params) => {
+ const {
+ storageKey,
+ authenticate,
+ } = Object.assign({}, {
+ storageKey: 'token',
+ authenticate: { type: 'local' },
+ }, options);
+
+ switch (type) {
+ case AUTH_LOGIN:
+ const { username, password } = params;
+ return client.authenticate({
+ ...authenticate,
+ email: username,
+ password,
+ });
+ case AUTH_LOGOUT:
+ return client.logout();
+ case AUTH_CHECK:
+ return localStorage.getItem(storageKey) ? Promise.resolve() : Promise.reject();
+ default:
+ throw new Error(`Unsupported FeathersJS authClient action type ${type}`);
+ }
+};
diff --git a/src/index.js b/src/index.js
index fa8951a..8b30986 100644
--- a/src/index.js
+++ b/src/index.js
@@ -1,109 +1,2 @@
-import { queryParameters, fetchJson } from 'admin-on-rest/lib/util/fetch';
-
-import {
- GET_LIST,
- GET_ONE,
- CREATE,
- UPDATE,
- DELETE,
- fetchUtils,
-} from 'admin-on-rest/lib/rest/types';
-
-/**
- * Maps admin-on-rest queries to a feathers REST API
- *
- * @example
- * GET_LIST => GET http://my.api.url/posts?$sort[title]=-1&$limit=10&$skip=10&title=value
- * GET_ONE => GET http://my.api.url/posts/123
- * UPDATE => PUT http://my.api.url/posts/123
- * CREATE => POST http://my.api.url/posts/123
- * DELETE => DELETE http://my.api.url/posts/123
- */
-export default (apiUrl, httpClient = fetchJson) => {
- /**
- * @param {String} type One of the constants appearing at the top if this file, e.g. 'UPDATE'
- * @param {String} resource Name of the resource to fetch, e.g. 'posts'
- * @param {Object} params The REST request params, depending on the type
- * @returns {Object} { url, options } The HTTP request parameters
- */
- const convertRESTRequestToHTTP = (type, resource, params) => {
- let url = '';
- const options = {};
- let query = {};
- switch (type) {
- case GET_LIST: {
- const { page, perPage } = params.pagination;
- const { field, order } = params.sort;
-
- let sortKey = '$sort[' + field + ']';
- let sortVal = (order === 'DESC') ? -1 : 1;
- if(perPage && page) {
- query['$limit'] = perPage;
- query['$skip'] = perPage*(page-1);
- }
- if (order) {
- query[sortKey] = JSON.stringify(sortVal);
- }
-
- Object.assign(query, params.filter);
-
- url = `${apiUrl}/${resource}?${queryParameters(query)}`;
- break;
- }
- case GET_ONE:
- url = `${apiUrl}/${resource}/${params.id}`;
- break;
- case UPDATE:
- url = `${apiUrl}/${resource}/${params.id}`;
- options.method = 'PUT';
- options.body = JSON.stringify(params.data);
- break;
- case CREATE:
- url = `${apiUrl}/${resource}`;
- options.method = 'POST';
- options.body = JSON.stringify(params.data);
- break;
- case DELETE:
- url = `${apiUrl}/${resource}/${params.id}`;
- options.method = 'DELETE';
- break;
- default:
- throw new Error(`Unsupported fetch action type ${type}`);
- }
- return { url, options };
- };
-
- /**
- * @param {Object} response HTTP response from fetch()
- * @param {String} type One of the constants appearing at the top if this file, e.g. 'UPDATE'
- * @param {String} resource Name of the resource to fetch, e.g. 'posts'
- * @param {Object} params The REST request params, depending on the type
- * @returns {Object} REST response
- */
- const convertHTTPResponseToREST = (response, type, resource, params) => {
- const { headers, json } = response;
- switch (type) {
- case GET_LIST:
- return {
- data: json.data,
- total: json.total
- };
- case CREATE:
- return { ...params.data, id: json.id };
- default:
- return json;
- }
- };
-
- /**
- * @param {string} type Request type, e.g GET_LIST
- * @param {string} resource Resource name, e.g. "posts"
- * @param {Object} payload Request parameters. Depends on the request type
- * @returns {Promise} the Promise for a REST response
- */
- return (type, resource, params) => {
- const { url, options } = convertRESTRequestToHTTP(type, resource, params);
- return httpClient(url, options)
- .then(response => convertHTTPResponseToREST(response, type, resource, params));
- };
-};
+export authClient from './authClient';
+export restClient from './restClient';
diff --git a/src/restClient.js b/src/restClient.js
new file mode 100644
index 0000000..0530a3d
--- /dev/null
+++ b/src/restClient.js
@@ -0,0 +1,62 @@
+import {
+ GET_MANY,
+ GET_MANY_REFERENCE,
+ GET_LIST,
+ GET_ONE,
+ CREATE,
+ UPDATE,
+ DELETE,
+} from 'admin-on-rest';
+
+export default client => {
+ const mapRequest = (type, resource, params) => {
+ const service = client.service(resource);
+ let query = {};
+
+ switch (type) {
+ case GET_MANY:
+ case GET_MANY_REFERENCE:
+ case GET_LIST:
+ const {page, perPage} = params.pagination || {};
+ const {field, order} = params.sort || {};
+
+ let sortKey = '$sort[' + field + ']';
+ let sortVal = (order === 'DESC') ? -1 : 1;
+ if (perPage && page) {
+ query['$limit'] = perPage;
+ query['$skip'] = perPage * (page - 1);
+ }
+ if (order) {
+ query[sortKey] = JSON.stringify(sortVal);
+ }
+ Object.assign(query, params.filter);
+ return service.find({ query });
+ case GET_ONE:
+ return service.get(params.id);
+ case UPDATE:
+ return service.update(params.id, params.data);
+ case CREATE:
+ return service.create(params.data);
+ case DELETE:
+ return service.remove(params.id);
+ default:
+ throw new Error(`Unsupported FeathersJS restClient action type ${type}`);
+ }
+ };
+
+ const mapResponse = (response, type, resource, params) => {
+ switch (type) {
+ case GET_ONE:
+ case UPDATE:
+ return { data: response };
+ case CREATE:
+ return { data: {...params.data, id: response.id} };
+ default:
+ return response;
+ }
+ };
+
+ return (type, resource, params) =>
+ mapRequest(type, resource, params)
+ .then(response => mapResponse(response, type, resource, params));
+}