From 9cb663aa651bc1921b99894110f5c84774dc5a23 Mon Sep 17 00:00:00 2001 From: Nikolay <46225163+vigdorov@users.noreply.github.com> Date: Mon, 28 Dec 2020 14:05:21 +0300 Subject: [PATCH] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB=D0=B5?= =?UTF-8?q?=D0=BD=D0=B8=D0=B5=20=D1=84=D1=83=D0=BD=D0=BA=D1=86=D0=B8=D0=B8?= =?UTF-8?q?=20=D0=B2=D1=80=D0=B0=D0=BF=D0=BF=D0=B5=D1=80=D0=B0=20=D0=B4?= =?UTF-8?q?=D0=BB=D1=8F=20api=20=D0=BE=D0=B1=D1=8A=D0=B5=D0=BA=D1=82=D0=BE?= =?UTF-8?q?=D0=B2,=20=D0=B4=D0=BE=D1=80=D0=B0=D0=B1=D0=BE=D1=82=D0=BA?= =?UTF-8?q?=D0=B0=20http=20=D0=BE=D0=B1=D1=8A=D0=B5=D0=BA=D1=82=D0=B0=20(#?= =?UTF-8?q?36)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .eslintrc.json | 2 + src/core/api/RegionsApi.ts | 70 ------------------ src/core/api/StorageApi.ts | 44 ------------ src/core/api/usersTestApi.ts | 29 ++++++++ src/core/infrastructure/Http.ts | 94 ++++++++++++------------- src/core/utils/makeApi.ts | 20 ++++++ src/pages/tags/components/page/Page.tsx | 12 +++- 7 files changed, 108 insertions(+), 163 deletions(-) delete mode 100644 src/core/api/RegionsApi.ts delete mode 100644 src/core/api/StorageApi.ts create mode 100644 src/core/api/usersTestApi.ts create mode 100644 src/core/utils/makeApi.ts diff --git a/.eslintrc.json b/.eslintrc.json index fe9c331..d6a48e9 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -55,6 +55,7 @@ "class-methods-use-this": 0, "react/prefer-stateless-function": 0, "react/jsx-fragments": 0, + "react/jsx-key": "warn", "react/no-array-index-key": 0, "react/destructuring-assignment": 0, "no-console": [ @@ -95,6 +96,7 @@ "@typescript-eslint/no-namespace": "off", "@typescript-eslint/explicit-module-boundary-types": "off", "@typescript-eslint/no-unused-vars": ["error"], + "@typescript-eslint/no-explicit-any": "off", "array-bracket-spacing": ["warn", "never"], "block-spacing": ["warn", "never"], "brace-style": ["warn", "1tbs", {"allowSingleLine": true}], diff --git a/src/core/api/RegionsApi.ts b/src/core/api/RegionsApi.ts deleted file mode 100644 index 8711a58..0000000 --- a/src/core/api/RegionsApi.ts +++ /dev/null @@ -1,70 +0,0 @@ -import {makeStorageApi} from './StorageApi'; - -type Region = { - name: string; - subject_number: number; - gibdd_codes: Array; -}; - -type ResponseRegions = { - regions: Array; -} - -const api = makeStorageApi({ - key: 'russian_regions', - hook: '26502372-6bc4-4cdf-bbcc-41b3b71cb386', - description: 'Регионы России', - service_name: 'geo_services', -}); - -export const regionsApi = { - request: async (): Promise => { - const {value: {regions}} = await api.request(); - return regions; - }, - find: async (name: string): Promise> => { - const regions = await regionsApi.request(); - return regions.find(region => region.name === name); - }, - create: async (newRegion: Region): Promise => { - const regions = await regionsApi.request(); - const findedRegion = regions.find(region => region.name === newRegion.name); - if (findedRegion) { - throw new Error(`Город с именем "${newRegion.name}" уже существует`); - } - await api.update({ - regions: [ - ...regions, - newRegion, - ], - }); - return newRegion; - }, - update: async (updatedRegion: Region): Promise => { - const regions = await regionsApi.request(); - const findedIndex = regions.findIndex(region => region.name === updatedRegion.name); - if (findedIndex === -1) { - throw new Error(`Город с именем "${updatedRegion.name}" не найден`); - } - await api.update({ - regions: regions.map((region, index) => { - if (findedIndex === index) { - return updatedRegion; - } - return region; - }), - }); - return updatedRegion; - }, - remove: async (name: string): Promise => { - const regions = await regionsApi.request(); - const findedIndex = regions.findIndex(region => region.name === name); - if (findedIndex === -1) { - throw new Error(`Город с именем "${name}" не найден`); - } - await api.update({ - regions: regions.filter(region => region.name === name), - }); - return name; - } -}; diff --git a/src/core/api/StorageApi.ts b/src/core/api/StorageApi.ts deleted file mode 100644 index d9b9f24..0000000 --- a/src/core/api/StorageApi.ts +++ /dev/null @@ -1,44 +0,0 @@ -import {http} from '../infrastructure/Http'; - -type QueryRequest = { - hook: string; -} - -type ResponseData = { - key: string; - value: T; - description: string; - service_name: string; - author: string; -}; - -type RequestData = Omit, 'author'>; - -type ApiConfig = Omit, 'value' | 'author'> & { - hook: string; -}; - -type Api = { - request: () => Promise>; - update: (updateValue: T) => Promise>; -}; - -const ROOT_URL = 'https://api.storage.vigdorov.ru/store'; - -export const makeStorageApi = ({key, hook, ...body}: ApiConfig): Api => { - const config = {params: {hook}}; - return { - request: async (): Promise> => { - const {data} = await http.get>(`${ROOT_URL}/${key}`, config); - return data; - }, - update: async (updateValue: T): Promise> => { - const {data} = await http.put, ResponseData>(ROOT_URL, { - ...body, - key, - value: updateValue, - }, config); - return data; - }, - }; -}; diff --git a/src/core/api/usersTestApi.ts b/src/core/api/usersTestApi.ts new file mode 100644 index 0000000..09cbaf0 --- /dev/null +++ b/src/core/api/usersTestApi.ts @@ -0,0 +1,29 @@ +import {http} from '../infrastructure/Http'; +import {makeApi} from '../utils/makeApi'; + +type User = { + id: number; + avatar: string; + email: string; + first_name: string; + last_name: string; +}; + +type UserReponse = { + data: Array; + page: number; + per_page: number; + support: { + text: string; + url: string; + } + total: number; + total_pages: number; +}; + +export const usersApi = makeApi({ + request: async () => { + const {data} = await http.get('https://reqres.in/api/users'); + return data; + }, +}); diff --git a/src/core/infrastructure/Http.ts b/src/core/infrastructure/Http.ts index 2d3e308..6887d6c 100644 --- a/src/core/infrastructure/Http.ts +++ b/src/core/infrastructure/Http.ts @@ -1,53 +1,51 @@ -import axios, {AxiosRequestConfig, AxiosResponse} from 'axios'; +import axios, {AxiosRequestConfig} from 'axios'; -type RequestConfig = Omit & { - params: Q; +enum Method { + Get = 'get', + Delete = 'delete', + Head = 'head', + Options = 'options', + Post = 'post', + Put = 'put', + Patch = 'patch', +} + +type RequestConfig = Omit & { + params?: Q; + data?: B; +}; + +const requestMiddleware = async (config: RequestConfig): Promise => { + const axiosResponse = await axios.request(config); + // Добавить обработку ошибок + return axiosResponse.data; +}; + +const request = (config: RequestConfig) => requestMiddleware(config); + +const requestWithoutBody = (method: Method) => (url: string, query?: Q) => { + return request({ + method, + url, + params: query, + }); +}; + +const requestWithBody = (method: Method) => (url: string, query?: Q, body?: B) => { + return request({ + method, + url, + params: query, + data: body, + }); }; export const http = { - get: ( - url: string, - config: RequestConfig - ): Promise> => { - return axios.get(url, config); - }, - delete: ( - url: string, - config: RequestConfig - ): Promise> => { - return axios.delete(url, config); - }, - head: ( - url: string, - config: RequestConfig - ): Promise> => { - return axios.head(url, config); - }, - options: ( - url: string, - config: RequestConfig - ): Promise> => { - return axios.options(url, config); - }, - post: ( - url: string, - body: Body, - config: RequestConfig - ): Promise> => { - return axios.post(url, body, config); - }, - put: ( - url: string, - body: Body, - config: RequestConfig - ): Promise> => { - return axios.post(url, body, config); - }, - patch: ( - url: string, - body: Body, - config: RequestConfig - ): Promise> => { - return axios.post(url, body, config); - }, + get: requestWithoutBody(Method.Get), + delete: requestWithoutBody(Method.Delete), + head: requestWithoutBody(Method.Head), + options: requestWithoutBody(Method.Options), + post: requestWithBody(Method.Post), + put: requestWithBody(Method.Put), + patch: requestWithBody(Method.Patch), }; diff --git a/src/core/utils/makeApi.ts b/src/core/utils/makeApi.ts new file mode 100644 index 0000000..bb24f14 --- /dev/null +++ b/src/core/utils/makeApi.ts @@ -0,0 +1,20 @@ +import {fromPromise} from '@most/core'; +import {Stream} from '@most/types'; +import {objectEntries} from './objectEntries'; + +type PromiseApi = Record Promise>; + +type StreamApi = { + [K in keyof T]: (...params: Parameters) => ( + T[K] extends (...args: any[]) => Promise ? Stream : never + ); +}; + +export const makeApi = (apiObj: T) => { + return objectEntries(apiObj).reduce((streamObj, [apiKey, apiMethod]) => { + return { + ...streamObj, + [apiKey]: (...args: Parameters) => fromPromise(apiMethod(...args)), + }; + }, {} as StreamApi); +}; diff --git a/src/pages/tags/components/page/Page.tsx b/src/pages/tags/components/page/Page.tsx index f3f301e..b33f68f 100644 --- a/src/pages/tags/components/page/Page.tsx +++ b/src/pages/tags/components/page/Page.tsx @@ -1,8 +1,18 @@ import React, {memo} from 'react'; +import {usersApi} from '../../../../core/api/usersTestApi'; +import {useStream} from '../../../../core/utils/useStream'; + +const userList$ = usersApi.request(); const Page: React.FC = () => { + const users = useStream(userList$, []); return ( -
tags
+
+ tags + {users.map(user => ( +
{user.first_name}, {user.last_name}
+ ))} +
); };