Пользовательский REST-клиент Admin-On-REST не может скомпилировать

Начав с учебника Admin-On-REST, я попытался привязать приложение к моей существующей серверной части ArangoDB с помощью пользовательской реализации REST-Client. Бэкэнд предоставляет простой автоматически сгенерированный по умолчанию HTTP-интерфейс FOXX.

Это в основном работало с simple client, Для лучшей интеграции я стремлюсь использовать собственный клиент, основанный на json client, Поэтому я скопировал admin-on-rest/src/rest/jsonServer.js файл в мой проект. Я изменил его для содержимого этого файла:

import { stringify } from 'query-string';
import { fetchJson, flattenObject } from 'admin-on-rest';
import {
    GET_LIST,
    GET_ONE,
    GET_MANY,
    GET_MANY_REFERENCE,
    CREATE,
    UPDATE,
    DELETE,
} from 'admin-on-rest';

/**
 * Maps admin-on-rest queries to a json-server powered REST API
 *
 * @see https://github.com/typicode/json-server
 * @example
 * GET_LIST     => GET http://my.api.url/posts?_sort=title&_order=ASC&_start=0&_end=24
 * GET_ONE      => GET http://my.api.url/posts/123
 * GET_MANY     => GET http://my.api.url/posts/123, GET http://my.api.url/posts/456, GET http://my.api.url/posts/789
 * 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 = {};
        switch (type) {
            case GET_LIST: {
                const { page, perPage } = params.pagination;
                const { field, order } = params.sort;
                const query = {
                    ...flattenObject(params.filter),
                    _sort: field,
                    _order: order,
                    _start: (page - 1) * perPage,
                    _end: page * perPage,
                };
                url = `${apiUrl}/${resource}?${stringify(query)}`;
                break;
            }
            case GET_ONE:
                url = `${apiUrl}/${resource}/${params.id}`;
                break;
            case GET_MANY_REFERENCE: {
                const { page, perPage } = params.pagination;
                const { field, order } = params.sort;
                const query = {
                    ...flattenObject(params.filter),
                    [params.target]: params.id,
                    _sort: field,
                    _order: order,
                    _start: (page - 1) * perPage,
                    _end: page * perPage,
                };
                url = `${apiUrl}/${resource}?${stringify(query)}`;
                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.map((obj) => {
                  obj.id = obj._key;
                  delete obj['_key'];
                  return obj;
                }),
                total: headers.get('X-Total-Count')
            };
            case GET_MANY_REFERENCE:
                if (!headers.has('x-total-count')) {
                    throw new Error(
                        'The X-Total-Count header is missing in the HTTP Response. The jsonServer REST client expects responses for lists of resources to contain this header with the total number of results to build the pagination. If you are using CORS, did you declare X-Total-Count in the Access-Control-Expose-Headers header?'
                    );
                }
                return {
                    data: json,
                    total: parseInt(
                        headers
                            .get('x-total-count')
                            .split('/')
                            .pop(),
                        10
                    ),
                };
            case CREATE:
                return { data: { ...params.data, id: json.id } };
            default:
                return { data: 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) => {
        // json-server doesn't handle WHERE IN requests, so we fallback to calling GET_ONE n times instead
        if (type === GET_MANY) {
            return Promise.all(
                params.ids.map(id => httpClient(`${apiUrl}/${resource}/${id}`))
            ).then(responses => ({
                data: responses.map(response => response.json),
            }));
        }

        const { url, options } = convertRESTRequestToHTTP(
            type,
            resource,
            params
        );

        return httpClient(url, options).then(response =>
            convertHTTPResponseToREST(response, type, resource, params)
        );
    };
};

Это очень похоже на оригинал - я только отредактировал:

  • import раздел наверху
  • convertHTTPResponseToRESTметод для GET_LIST раздел.

Наконец, я связал его в приложение, импортировав его через App.js файл, чтобы он выглядел так:

import CustomRestClientJson from './CustomRestClientJson'

const App = () => (
    <Admin restClient={CustomRestClientJson('http://localhost:8529/_db/orgraph/admin')}>
      <Resource name="assets" list={AssetList} />
    </Admin>
);

Проблема в том, что:

а) либо приложение не работает в браузере с Object(...) is not a function ошибка (выбрасывается при вызове ...flattenObject(params.filter) звонок из клиентов convertRESTRequestToHTTP метод) при попытке загрузить данные.

б.) или yarn сборка / компиляция завершается неудачно, когда я изменяю операторы импорта моего клиента с:

import { stringify } from 'query-string';
import { fetchJson, flattenObject } from 'admin-on-rest';
import {
    GET_LIST,
    GET_ONE,
    GET_MANY,
    GET_MANY_REFERENCE,
    CREATE,
    UPDATE,
    DELETE,
} from 'admin-on-rest';

чтобы:

import { stringify } from 'query-string';
import { fetchJson, flattenObject } from 'admin-on-rest/src/util/fetch';
import {
    GET_LIST,
    GET_ONE,
    GET_MANY,
    GET_MANY_REFERENCE,
    CREATE,
    UPDATE,
    DELETE
} from 'admin-on-rest/src/rest/types';

со следующей ошибкой:

Failed to compile.

./node_modules/admin-on-rest/src/util/fetch.js
Module parse failed: Unexpected token (20:24)
You may need an appropriate loader to handle this file type.
|     }
|
|     return fetch(url, { ...options, headers: requestHeaders })
|         .then(response =>
|             response.text().then(text => ({

Поэтому, поскольку я не являюсь программистом React, мне очень хотелось бы услышать о том, как я могу исправить эту проблему, чтобы иметь возможность привязываться к моему бэкэнду для дальнейшего тестирования.

;-)

Спасибо за любые советы!

1 ответ

Я не прочитал полное описание, но полученная ошибка должна быть исправлена ​​путем изменения

import { fetchJson, flattenObject } from 'admin-on-rest/src/util/fetch';

чтобы:

import { fetchJson, flattenObject } from 'admin-on-rest/lib/util/fetch';

Ваш проект babel не будет передавать какой-либо код под node_modules, Все, что вы импортируете из-за пределов вашего src должно быть уже перенесено.

Другие вопросы по тегам