@foxford/services 1.0.0-beta-5bdc8181-20230605
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +81 -0
- package/api/index.d.ts +77 -0
- package/api/index.js +1 -0
- package/api/index.js.flow +48 -0
- package/api/index.mjs +1 -0
- package/api/index.mjs.flow +48 -0
- package/api/interceptors/request.js +1 -0
- package/api/interceptors/request.mjs +1 -0
- package/api/interceptors/response.js +1 -0
- package/api/interceptors/response.mjs +1 -0
- package/api/interceptors/responseFail.js +1 -0
- package/api/interceptors/responseFail.mjs +1 -0
- package/api/plugins/AbstractApiRequestPlugin.js +1 -0
- package/api/plugins/AbstractApiRequestPlugin.mjs +1 -0
- package/api/plugins/AbstractApiResponseFailPlugin.js +1 -0
- package/api/plugins/AbstractApiResponseFailPlugin.mjs +1 -0
- package/api/plugins/AbstractApiResponseSuccessPlugin.js +1 -0
- package/api/plugins/AbstractApiResponseSuccessPlugin.mjs +1 -0
- package/index.d.ts +9 -0
- package/index.js +1 -0
- package/index.js.flow +17 -0
- package/index.mjs +1 -0
- package/index.mjs.flow +17 -0
- package/package.json +91 -0
- package/recaptcha/index.d.ts +17 -0
- package/recaptcha/index.js +1 -0
- package/recaptcha/index.js.flow +19 -0
- package/recaptcha/index.mjs +1 -0
- package/recaptcha/index.mjs.flow +19 -0
- package/utils/uuid.js +1 -0
- package/utils/uuid.mjs +1 -0
package/README.md
ADDED
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
### Сервисы Foxford
|
|
2
|
+
|
|
3
|
+
Библиотека фронтовых сервисов, которые помогут реализовать тот или иной функционал на уровне приложения.
|
|
4
|
+
Здесь будут появляться сервисы фокса, которые будут "отвязаны" от других сервисов и функций, не принадлежащих им.
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
### Recaptcha Service
|
|
9
|
+
|
|
10
|
+
Сервис для работы с Google-капчей.
|
|
11
|
+
|
|
12
|
+
Пример использования:
|
|
13
|
+
|
|
14
|
+
```js static
|
|
15
|
+
const recaptcha: RecaptchaService = new RecaptchaService({
|
|
16
|
+
locale: locale,
|
|
17
|
+
sitekey: process.env.RECAPTCHA_SITEKEY,
|
|
18
|
+
})
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
А далее в необходимом месте:
|
|
22
|
+
|
|
23
|
+
```js static
|
|
24
|
+
async function submitHandler() {
|
|
25
|
+
const tokenPayload = await recaptcha.execute() // <TOKEN>
|
|
26
|
+
}
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
---
|
|
30
|
+
|
|
31
|
+
### ApiService. Сервис для получения инстанса Api
|
|
32
|
+
|
|
33
|
+
Имеет один статичный метод `createAxiosInstance`, который может принимать параметры:
|
|
34
|
+
|
|
35
|
+
```typescript
|
|
36
|
+
type ApiConfig = {
|
|
37
|
+
apiConfig: AxiosRequestConfig
|
|
38
|
+
isBase?: boolean
|
|
39
|
+
plugins?: Array<ApiRequestPlugin | ApiResponseSuccessPlugin | ApiResponseFailPlugin>
|
|
40
|
+
}
|
|
41
|
+
```
|
|
42
|
+
где:
|
|
43
|
+
- `apiConfig` - Конфиг для Axios
|
|
44
|
+
- `isBase` - Флаг, по которому определяется добавлять ли для создаваемого инстанса `interceptor`-ы. Если `true`, то их не будет
|
|
45
|
+
- `plugins` - Массив плагинов, которые относятся к какому либо из `interceptor`-ов
|
|
46
|
+
|
|
47
|
+
#### Пример инициализации инстанса
|
|
48
|
+
```javascript
|
|
49
|
+
export { ApiService } from '@foxford/services'
|
|
50
|
+
|
|
51
|
+
const someAxiosConfig = {...}
|
|
52
|
+
const apiInstance = new ApiService().createAxiosInstance({
|
|
53
|
+
apiConfig: someAxiosConfig,
|
|
54
|
+
})
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
### Плагины
|
|
58
|
+
Предназначены для обработки и преобразования данных внутри перехватчиков запросов Axios
|
|
59
|
+
|
|
60
|
+
Плагины должны иплементитьтся от абстрактного класса, своего для разных перехватчиков:
|
|
61
|
+
- `ApiRequestPlugin` для `RequestInterceptor`
|
|
62
|
+
- `ApiResponseSuccessPlugin` для `ResponseInterceptorSuccess`
|
|
63
|
+
- `ApiResponseFailPlugin` для `ResponseInterceptorFail`
|
|
64
|
+
|
|
65
|
+
Например: для перехватчика запроса `RequestInterceptor` плагин должен иплементиться от `ApiRequestPlugin`
|
|
66
|
+
|
|
67
|
+
### Пример использования плагина
|
|
68
|
+
Можно посмотреть в файле `client/src/packages/services/api/plugins/CaptchaRequestPlugin.ts`
|
|
69
|
+
```javascript
|
|
70
|
+
import { CamelizeRequestPlugin } from '@@foxford/services'
|
|
71
|
+
export { ApiService } from '@foxford/services'
|
|
72
|
+
|
|
73
|
+
const someAxiosConfig = {...}
|
|
74
|
+
|
|
75
|
+
const camelizeRequestPlugin: CamelizeRequestPlugin = new CamelizeRequestPlugin()
|
|
76
|
+
|
|
77
|
+
const apiInstance = new ApiService().createAxiosInstance({
|
|
78
|
+
apiConfig: someAxiosConfig,
|
|
79
|
+
plugins: [camelizeRequestPlugin],
|
|
80
|
+
})
|
|
81
|
+
```
|
package/api/index.d.ts
ADDED
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { AxiosInstance, AxiosRequestConfig, AxiosResponse, AxiosError } from 'axios'
|
|
2
|
+
|
|
3
|
+
export interface ResponseError {
|
|
4
|
+
status: AxiosResponse['status']
|
|
5
|
+
statusText: AxiosResponse['statusText']
|
|
6
|
+
errorText: string
|
|
7
|
+
headers: AxiosResponse['headers']
|
|
8
|
+
data: AxiosResponse['data']
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export type AxiosErrorExtended = AxiosError & {
|
|
12
|
+
config: AxiosRequestConfig & { _retry?: boolean }
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export type AxiosConfig = AxiosRequestConfig & { camelize?: boolean; withReferrer?: boolean }
|
|
16
|
+
|
|
17
|
+
export interface AbstractApiRequestPluginInterface {
|
|
18
|
+
// eslint-disable-next-line no-unused-vars
|
|
19
|
+
execute(config: AxiosConfig): Promise<AxiosConfig>
|
|
20
|
+
// eslint-disable-next-line no-unused-vars
|
|
21
|
+
isApplicable(config: AxiosConfig): boolean
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export abstract class AbstractApiRequestPlugin implements AbstractApiRequestPluginInterface {
|
|
25
|
+
// eslint-disable-next-line no-unused-vars
|
|
26
|
+
abstract execute(config: AxiosConfig): Promise<AxiosConfig>
|
|
27
|
+
// eslint-disable-next-line no-unused-vars
|
|
28
|
+
abstract isApplicable(config: AxiosConfig): boolean
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export interface AbstractApiResponseSuccessPluginInterface {
|
|
32
|
+
// eslint-disable-next-line no-unused-vars
|
|
33
|
+
execute(axios: AxiosResponse): Promise<AxiosResponse>
|
|
34
|
+
// eslint-disable-next-line no-unused-vars
|
|
35
|
+
isApplicable(axios: AxiosResponse): boolean
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export abstract class AbstractApiResponseSuccessPlugin implements AbstractApiResponseSuccessPluginInterface {
|
|
39
|
+
// eslint-disable-next-line no-unused-vars
|
|
40
|
+
abstract execute(axios: AxiosResponse): Promise<AxiosResponse>
|
|
41
|
+
// eslint-disable-next-line no-unused-vars
|
|
42
|
+
abstract isApplicable(axios: AxiosResponse): boolean
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export interface AbstractApiResponseFailPluginInterface {
|
|
46
|
+
// eslint-disable-next-line no-unused-vars
|
|
47
|
+
execute(error: AxiosErrorExtended): Promise<AxiosErrorExtended>
|
|
48
|
+
// eslint-disable-next-line no-unused-vars
|
|
49
|
+
isApplicable(error: AxiosErrorExtended): boolean
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export abstract class AbstractApiResponseFailPlugin implements AbstractApiResponseFailPluginInterface {
|
|
53
|
+
// eslint-disable-next-line no-unused-vars
|
|
54
|
+
abstract execute(error: AxiosErrorExtended): Promise<AxiosErrorExtended>
|
|
55
|
+
// eslint-disable-next-line no-unused-vars
|
|
56
|
+
abstract isApplicable(error: AxiosErrorExtended): boolean
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
export type ApiConfig = {
|
|
60
|
+
apiConfig: AxiosRequestConfig
|
|
61
|
+
isBase?: boolean
|
|
62
|
+
plugins?: {
|
|
63
|
+
request?: AbstractApiRequestPlugin[]
|
|
64
|
+
responseSuccess?: AbstractApiResponseSuccessPlugin[]
|
|
65
|
+
responseFail?: AbstractApiResponseFailPlugin[]
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
export abstract class AbstractApiService {
|
|
70
|
+
// eslint-disable-next-line no-unused-vars
|
|
71
|
+
public abstract createAxiosInstance(params: ApiConfig): AxiosInstance
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
export class ApiService implements AbstractApiService {
|
|
75
|
+
// eslint-disable-next-line no-unused-vars
|
|
76
|
+
createAxiosInstance(params: ApiConfig): AxiosInstance
|
|
77
|
+
}
|
package/api/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
'use strict';Object.defineProperty(exports,'__esModule',{value:true});var e=require('axios');var r=require('axios-retry');var s=require('./interceptors/request.js');var t=require('./interceptors/response.js');var i=require('./interceptors/responseFail.js');function a(e){return e&&'object'==typeof e&&'default'in e?e:{default:e}}var n=a(e);var o=a(r);exports.ApiService=class ApiService{createAxiosInstance(e){var{apiConfig:r,isBase:a=false,plugins:u={}}=e;var p=n.default.create(r);if(!a){var c=(null==u?void 0:u.request)||[];var l=(null==u?void 0:u.responseSuccess)||[];var v=(null==u?void 0:u.responseFail)||[];p.interceptors.request.use((e=>s.RequestInterceptor(e,[...c]))),p.interceptors.response.use((e=>t.ResponseInterceptorSuccess(e,[...l])),(e=>i.ResponseInterceptorFail(e,[...v]))),o.default(p,{retries:3,retryDelay:o.default.exponentialDelay})}return p}};
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
// @flow
|
|
2
|
+
import type { Axios, AxiosXHR, AxiosXHRConfig, AxiosError } from 'axios'
|
|
3
|
+
|
|
4
|
+
// flowlint-next-line unclear-type:off
|
|
5
|
+
export type AxiosConfig = AxiosXHRConfig<any> & { camelize?: boolean, withReferrer?: boolean, ... }
|
|
6
|
+
|
|
7
|
+
// flowlint-next-line unclear-type:off
|
|
8
|
+
export type AxiosErrorExtended = AxiosError<any> & {
|
|
9
|
+
// flowlint-next-line unclear-type:off
|
|
10
|
+
config: AxiosXHRConfig<any> & { _retry?: boolean }
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export interface AbstractApiRequestPlugin {
|
|
14
|
+
execute(config: AxiosConfig): Promise<AxiosConfig>;
|
|
15
|
+
isApplicable(config: AxiosConfig): boolean;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export interface AbstractApiResponseSuccessPlugin {
|
|
19
|
+
// flowlint-next-line unclear-type:off
|
|
20
|
+
execute(axios: AxiosXHR<any>): Promise<AxiosXHR<any>>;
|
|
21
|
+
// flowlint-next-line unclear-type:off
|
|
22
|
+
isApplicable(axios: AxiosXHR<any>): boolean;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export interface AbstractApiResponseFailPlugin {
|
|
26
|
+
// eslint-disable-next-line no-unused-vars
|
|
27
|
+
execute(error: AxiosErrorExtended): Promise<AxiosErrorExtended>;
|
|
28
|
+
// eslint-disable-next-line no-unused-vars
|
|
29
|
+
isApplicable(error: AxiosErrorExtended): boolean;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export type ApiConfig = {|
|
|
33
|
+
// flowlint-next-line unclear-type:off
|
|
34
|
+
apiConfig: $Shape<AxiosXHRConfig<any> & { crossDomain?: boolean }>,
|
|
35
|
+
isBase?: boolean,
|
|
36
|
+
plugins?: {
|
|
37
|
+
request?: AbstractApiRequestPlugin[],
|
|
38
|
+
responseSuccess?: AbstractApiResponseSuccessPlugin[],
|
|
39
|
+
responseFail?: AbstractApiResponseFailPlugin[]
|
|
40
|
+
},
|
|
41
|
+
|}
|
|
42
|
+
|
|
43
|
+
declare export class ApiService {
|
|
44
|
+
createAxiosInstance(params: ApiConfig): Axios
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// flowlint-next-line unclear-type:off
|
|
48
|
+
export type CaptchaRequestConfig = AxiosXHRConfig<any> & { camelize?: boolean }
|
package/api/index.mjs
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import e from'axios';import r from'axios-retry';import{RequestInterceptor as s}from'./interceptors/request.mjs';import{ResponseInterceptorSuccess as i}from'./interceptors/response.mjs';import{ResponseInterceptorFail as o}from'./interceptors/responseFail.mjs';class ApiService{createAxiosInstance(t){var{apiConfig:p,isBase:n=false,plugins:a={}}=t;var l=e.create(p);if(!n){var c=(null==a?void 0:a.request)||[];var m=(null==a?void 0:a.responseSuccess)||[];var u=(null==a?void 0:a.responseFail)||[];l.interceptors.request.use((e=>s(e,[...c]))),l.interceptors.response.use((e=>i(e,[...m])),(e=>o(e,[...u]))),r(l,{retries:3,retryDelay:r.exponentialDelay})}return l}}export{ApiService};
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
// @flow
|
|
2
|
+
import type { Axios, AxiosXHR, AxiosXHRConfig, AxiosError } from 'axios'
|
|
3
|
+
|
|
4
|
+
// flowlint-next-line unclear-type:off
|
|
5
|
+
export type AxiosConfig = AxiosXHRConfig<any> & { camelize?: boolean, withReferrer?: boolean, ... }
|
|
6
|
+
|
|
7
|
+
// flowlint-next-line unclear-type:off
|
|
8
|
+
export type AxiosErrorExtended = AxiosError<any> & {
|
|
9
|
+
// flowlint-next-line unclear-type:off
|
|
10
|
+
config: AxiosXHRConfig<any> & { _retry?: boolean }
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export interface AbstractApiRequestPlugin {
|
|
14
|
+
execute(config: AxiosConfig): Promise<AxiosConfig>;
|
|
15
|
+
isApplicable(config: AxiosConfig): boolean;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export interface AbstractApiResponseSuccessPlugin {
|
|
19
|
+
// flowlint-next-line unclear-type:off
|
|
20
|
+
execute(axios: AxiosXHR<any>): Promise<AxiosXHR<any>>;
|
|
21
|
+
// flowlint-next-line unclear-type:off
|
|
22
|
+
isApplicable(axios: AxiosXHR<any>): boolean;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export interface AbstractApiResponseFailPlugin {
|
|
26
|
+
// eslint-disable-next-line no-unused-vars
|
|
27
|
+
execute(error: AxiosErrorExtended): Promise<AxiosErrorExtended>;
|
|
28
|
+
// eslint-disable-next-line no-unused-vars
|
|
29
|
+
isApplicable(error: AxiosErrorExtended): boolean;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export type ApiConfig = {|
|
|
33
|
+
// flowlint-next-line unclear-type:off
|
|
34
|
+
apiConfig: $Shape<AxiosXHRConfig<any> & { crossDomain?: boolean }>,
|
|
35
|
+
isBase?: boolean,
|
|
36
|
+
plugins?: {
|
|
37
|
+
request?: AbstractApiRequestPlugin[],
|
|
38
|
+
responseSuccess?: AbstractApiResponseSuccessPlugin[],
|
|
39
|
+
responseFail?: AbstractApiResponseFailPlugin[]
|
|
40
|
+
},
|
|
41
|
+
|}
|
|
42
|
+
|
|
43
|
+
declare export class ApiService {
|
|
44
|
+
createAxiosInstance(params: ApiConfig): Axios
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// flowlint-next-line unclear-type:off
|
|
48
|
+
export type CaptchaRequestConfig = AxiosXHRConfig<any> & { camelize?: boolean }
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
'use strict';Object.defineProperty(exports,'__esModule',{value:true});var e=require('../../node_modules/@babel/runtime/helpers/esm/objectSpread2.js');var n=require('../../node_modules/@babel/runtime/helpers/esm/asyncToGenerator.js');function o(){return(o=n((function*(e,n){for(var o of n)o.isApplicable(e)&&(e=yield o.execute(e));return e}))).apply(this,arguments)}exports.RequestInterceptor=function(n,r){return n.headers=e({'Content-Type':'application/json'},n.headers),window&&window.location&&window.location.pathname&&window.location.origin&&(n.headers=e(e({},n.headers),{},{'X-Referer':window.location.origin+window.location.pathname})),r.length>0?function(e,n){return o.apply(this,arguments)}(n,r):n};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import e from'../../node_modules/@babel/runtime/helpers/esm/objectSpread2.mjs';import o from'../../node_modules/@babel/runtime/helpers/esm/asyncToGenerator.mjs';function n(){return(n=o((function*(e,o){for(var n of o)n.isApplicable(e)&&(e=yield n.execute(e));return e}))).apply(this,arguments)}function i(o,i){return o.headers=e({'Content-Type':'application/json'},o.headers),window&&window.location&&window.location.pathname&&window.location.origin&&(o.headers=e(e({},o.headers),{},{'X-Referer':window.location.origin+window.location.pathname})),i.length>0?function(e,o){return n.apply(this,arguments)}(o,i):o}export{i as RequestInterceptor};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
'use strict';Object.defineProperty(exports,'__esModule',{value:true});var e=require('../../node_modules/@babel/runtime/helpers/esm/asyncToGenerator.js');function r(){return(r=e((function*(e,r){for(var t of r)t.isApplicable(e)&&(e=yield t.execute(e));return e}))).apply(this,arguments)}exports.ResponseInterceptorSuccess=function(e,t){return t.length>0?function(e,t){return r.apply(this,arguments)}(e,t):e};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import e from'../../node_modules/@babel/runtime/helpers/esm/asyncToGenerator.mjs';function n(){return(n=e((function*(e,n){for(var r of n)r.isApplicable(e)&&(e=yield r.execute(e));return e}))).apply(this,arguments)}function r(e,r){return r.length>0?function(e,r){return n.apply(this,arguments)}(e,r):e}export{r as ResponseInterceptorSuccess};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
'use strict';Object.defineProperty(exports,'__esModule',{value:true});var e=require('../../node_modules/@babel/runtime/helpers/esm/objectSpread2.js');var t=[422,401];exports.ResponseInterceptorFail=function(r){var{config:s=null,response:a=null}=r;if(null===s||null===a)return Promise.reject(r);var u=s;t.includes(a.status)&&(u._retry=true);var o=e({errorText:r.toString(),headers:a.headers,status:a.status,statusText:a.statusText},'object'==typeof a.data?a.data:{data:a.data});return Promise.reject(o)};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import e from'../../node_modules/@babel/runtime/helpers/esm/objectSpread2.mjs';var t=[422,401];function r(r){var{config:a=null,response:s=null}=r;if(null===a||null===s)return Promise.reject(r);var u=a;t.includes(s.status)&&(u._retry=true);var o=e({errorText:r.toString(),headers:s.headers,status:s.status,statusText:s.statusText},'object'==typeof s.data?s.data:{data:s.data});return Promise.reject(o)}export{r as ResponseInterceptorFail};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
'use strict';Object.defineProperty(exports,'__esModule',{value:true}),exports.AbstractApiRequestPlugin=class AbstractApiRequestPlugin{};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
class AbstractApiRequestPlugin{}export{AbstractApiRequestPlugin};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
'use strict';Object.defineProperty(exports,'__esModule',{value:true}),exports.AbstractApiResponseFailPlugin=class AbstractApiResponseFailPlugin{};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
class AbstractApiResponseFailPlugin{}export{AbstractApiResponseFailPlugin};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
'use strict';Object.defineProperty(exports,'__esModule',{value:true}),exports.AbstractApiResponseSuccessPlugin=class AbstractApiResponseSuccessPlugin{};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
class AbstractApiResponseSuccessPlugin{}export{AbstractApiResponseSuccessPlugin};
|
package/index.d.ts
ADDED
package/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
'use strict';Object.defineProperty(exports,'__esModule',{value:true});var e=require('./api/index.js');var s=require('./recaptcha/index.js');var i=require('./api/plugins/AbstractApiRequestPlugin.js');var r=require('./api/plugins/AbstractApiResponseSuccessPlugin.js');var t=require('./api/plugins/AbstractApiResponseFailPlugin.js');var p=new e.ApiService;exports.RecaptchaService=s.RecaptchaService,exports.AbstractApiRequestPlugin=i.AbstractApiRequestPlugin,exports.AbstractApiResponseSuccessPlugin=r.AbstractApiResponseSuccessPlugin,exports.AbstractApiResponseFailPlugin=t.AbstractApiResponseFailPlugin,exports.ApiService=p;
|
package/index.js.flow
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
// @flow
|
|
2
|
+
|
|
3
|
+
import { ApiService } from './api'
|
|
4
|
+
|
|
5
|
+
const apiServiceInstance = new ApiService()
|
|
6
|
+
|
|
7
|
+
export { apiServiceInstance as ApiService }
|
|
8
|
+
export type {
|
|
9
|
+
ApiConfig,
|
|
10
|
+
AxiosConfig,
|
|
11
|
+
} from './api'
|
|
12
|
+
export {
|
|
13
|
+
AbstractApiRequestPlugin,
|
|
14
|
+
AbstractApiResponseSuccessPlugin,
|
|
15
|
+
AbstractApiResponseFailPlugin,
|
|
16
|
+
} from './api'
|
|
17
|
+
export type { RecaptchaService, RecaptchaConfig } from './recaptcha'
|
package/index.mjs
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{ApiService as s}from'./api/index.mjs';export{RecaptchaService}from'./recaptcha/index.mjs';export{AbstractApiRequestPlugin}from'./api/plugins/AbstractApiRequestPlugin.mjs';export{AbstractApiResponseSuccessPlugin}from'./api/plugins/AbstractApiResponseSuccessPlugin.mjs';export{AbstractApiResponseFailPlugin}from'./api/plugins/AbstractApiResponseFailPlugin.mjs';var e=new s;export{e as ApiService};
|
package/index.mjs.flow
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
// @flow
|
|
2
|
+
|
|
3
|
+
import { ApiService } from './api'
|
|
4
|
+
|
|
5
|
+
const apiServiceInstance = new ApiService()
|
|
6
|
+
|
|
7
|
+
export { apiServiceInstance as ApiService }
|
|
8
|
+
export type {
|
|
9
|
+
ApiConfig,
|
|
10
|
+
AxiosConfig,
|
|
11
|
+
} from './api'
|
|
12
|
+
export {
|
|
13
|
+
AbstractApiRequestPlugin,
|
|
14
|
+
AbstractApiResponseSuccessPlugin,
|
|
15
|
+
AbstractApiResponseFailPlugin,
|
|
16
|
+
} from './api'
|
|
17
|
+
export type { RecaptchaService, RecaptchaConfig } from './recaptcha'
|
package/package.json
ADDED
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@foxford/services",
|
|
3
|
+
"version": "1.0.0-beta-5bdc8181-20230605",
|
|
4
|
+
"description": "Foxford services",
|
|
5
|
+
"main": "index.js",
|
|
6
|
+
"module": "index.mjs",
|
|
7
|
+
"browser": "index.mjs",
|
|
8
|
+
"jsnext:main": "index.mjs",
|
|
9
|
+
"exports": {
|
|
10
|
+
".": {
|
|
11
|
+
"require": "./index.js",
|
|
12
|
+
"default": "./index.mjs"
|
|
13
|
+
},
|
|
14
|
+
"./index.mjs": "./index.mjs",
|
|
15
|
+
"./index.js": "./index.js",
|
|
16
|
+
"./package.json": "./package.json"
|
|
17
|
+
},
|
|
18
|
+
"typings": "index.d.ts",
|
|
19
|
+
"repository": {
|
|
20
|
+
"type": "git",
|
|
21
|
+
"url": "https://github.com/netology-group/stoege.git"
|
|
22
|
+
},
|
|
23
|
+
"homepage": "https://github.com/netology-group/stoege",
|
|
24
|
+
"bugs": "https://github.com/netology-group/stoege/issues",
|
|
25
|
+
"engines": {
|
|
26
|
+
"node": ">=14.x"
|
|
27
|
+
},
|
|
28
|
+
"publishConfig": {
|
|
29
|
+
"access": "public"
|
|
30
|
+
},
|
|
31
|
+
"author": "Olin Roman",
|
|
32
|
+
"maintainers": [
|
|
33
|
+
{
|
|
34
|
+
"name": "Olin Roman",
|
|
35
|
+
"email": "r.v.olin@foxford.ru"
|
|
36
|
+
}
|
|
37
|
+
],
|
|
38
|
+
"keywords": [
|
|
39
|
+
"foxford",
|
|
40
|
+
"services"
|
|
41
|
+
],
|
|
42
|
+
"license": "MIT",
|
|
43
|
+
"files": [
|
|
44
|
+
"README.md",
|
|
45
|
+
"api/index.d.ts",
|
|
46
|
+
"api/index.js",
|
|
47
|
+
"api/index.js.flow",
|
|
48
|
+
"api/index.mjs",
|
|
49
|
+
"api/index.mjs.flow",
|
|
50
|
+
"api/interceptors/request.js",
|
|
51
|
+
"api/interceptors/request.mjs",
|
|
52
|
+
"api/interceptors/response.js",
|
|
53
|
+
"api/interceptors/response.mjs",
|
|
54
|
+
"api/interceptors/responseFail.js",
|
|
55
|
+
"api/interceptors/responseFail.mjs",
|
|
56
|
+
"api/plugins/AbstractApiRequestPlugin.js",
|
|
57
|
+
"api/plugins/AbstractApiRequestPlugin.mjs",
|
|
58
|
+
"api/plugins/AbstractApiResponseFailPlugin.js",
|
|
59
|
+
"api/plugins/AbstractApiResponseFailPlugin.mjs",
|
|
60
|
+
"api/plugins/AbstractApiResponseSuccessPlugin.js",
|
|
61
|
+
"api/plugins/AbstractApiResponseSuccessPlugin.mjs",
|
|
62
|
+
"index.d.ts",
|
|
63
|
+
"index.js",
|
|
64
|
+
"index.js.flow",
|
|
65
|
+
"index.mjs",
|
|
66
|
+
"index.mjs.flow",
|
|
67
|
+
"node_modules/@babel/runtime/helpers/esm/asyncToGenerator.js",
|
|
68
|
+
"node_modules/@babel/runtime/helpers/esm/asyncToGenerator.mjs",
|
|
69
|
+
"node_modules/@babel/runtime/helpers/esm/defineProperty.js",
|
|
70
|
+
"node_modules/@babel/runtime/helpers/esm/defineProperty.mjs",
|
|
71
|
+
"node_modules/@babel/runtime/helpers/esm/objectSpread2.js",
|
|
72
|
+
"node_modules/@babel/runtime/helpers/esm/objectSpread2.mjs",
|
|
73
|
+
"node_modules/@babel/runtime/helpers/esm/toPrimitive.js",
|
|
74
|
+
"node_modules/@babel/runtime/helpers/esm/toPrimitive.mjs",
|
|
75
|
+
"node_modules/@babel/runtime/helpers/esm/toPropertyKey.js",
|
|
76
|
+
"node_modules/@babel/runtime/helpers/esm/toPropertyKey.mjs",
|
|
77
|
+
"node_modules/@babel/runtime/helpers/esm/typeof.js",
|
|
78
|
+
"node_modules/@babel/runtime/helpers/esm/typeof.mjs",
|
|
79
|
+
"packages.json",
|
|
80
|
+
"recaptcha/index.d.ts",
|
|
81
|
+
"recaptcha/index.js",
|
|
82
|
+
"recaptcha/index.js.flow",
|
|
83
|
+
"recaptcha/index.mjs",
|
|
84
|
+
"recaptcha/index.mjs.flow",
|
|
85
|
+
"utils/uuid.js",
|
|
86
|
+
"utils/uuid.mjs"
|
|
87
|
+
],
|
|
88
|
+
"scripts": {},
|
|
89
|
+
"peerDependencies": {}
|
|
90
|
+
}
|
|
91
|
+
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export type RecaptchaAnswer = string
|
|
2
|
+
|
|
3
|
+
export type RecaptchaConfig = {
|
|
4
|
+
locale?: string
|
|
5
|
+
sitekey?: string
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export interface RecaptchaInterface {
|
|
9
|
+
execute(): Promise<RecaptchaAnswer | void>
|
|
10
|
+
isEnabled(): boolean
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export class RecaptchaService implements RecaptchaInterface {
|
|
14
|
+
constructor(_params: RecaptchaConfig)
|
|
15
|
+
execute(): Promise<RecaptchaAnswer | void>
|
|
16
|
+
isEnabled(): boolean
|
|
17
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
'use strict';Object.defineProperty(exports,'__esModule',{value:true});var e=require('../node_modules/@babel/runtime/helpers/esm/objectSpread2.js');var a=require('../node_modules/@babel/runtime/helpers/esm/asyncToGenerator.js');var t=require('../utils/uuid.js');class CaptchaError extends Error{constructor(e,a){super(e),this.payload={},this.name='CaptchaError',this.message=e,a&&(this.payload=a)}}class RecaptchaService{constructor(e){var{sitekey:a,locale:t}=e;this._sitekey=null,this._locale='en',this._widgets=[],this._captcha=void 0,this._sitekey=null!=a?a:null,t&&(this._locale=t)}isEnabled(){return'string'==typeof this._sitekey&&''!==this._sitekey}__recaptchaReady(){this._captcha=window.grecaptcha}__destroyWidgetByUuid(e){if('string'==typeof e&&this._widgets.find((a=>a.uuid===e))){var a=this.__getGrecaptchaCallbackNames(e);window[a.resolve]&&delete window[a.resolve],window[a.reject]&&delete window[a.reject],window[a.expired]&&delete window[a.expired];var t=document.getElementById(e);t&&t.remove()}}__getGrecaptchaCallbackNames(e){return{expired:"".concat(RecaptchaService.EXPIRED_FUNC_NAME,"-").concat(e),reject:"".concat(RecaptchaService.REJECT_FUNC_NAME,"-").concat(e),resolve:"".concat(RecaptchaService.RESOLVE_FUNC_NAME,"-").concat(e)}}__appendScript(e){var t=this;return a((function*(){if(t._captcha)return Promise.resolve(t._captcha);if('string'!=typeof e||''===e)throw new TypeError('src script is not defined');var a=document.createElement('script');return a.src=e,document.body&&document.body.appendChild(a),new Promise(((e,t)=>{a.addEventListener('load',(()=>{e(true)})),a.addEventListener('error',(()=>{t()}))}))}))()}_loadScript(){var e=this;return a((function*(){if(e._captcha)return Promise.resolve(e._captcha);var t=function(){var t=a((function*(){return yield e.__appendScript("https://www.google.com/recaptcha/api.js?hl=".concat(e._locale,"&onload=__recaptchaReady__"))}));return function(){return t.apply(this,arguments)}}();return new Promise(((a,r)=>{window.__recaptchaReady__=()=>{e.__recaptchaReady(),e._captcha?a(e._captcha):r(new CaptchaError('Captcha is not available'))},t().catch((()=>r(new CaptchaError('Could not load recaptcha scripts'))))}))}))()}__renderRecaptcha(a,t){var r,c;var i=document.createElement('div');return i.style.display='none',i.id=a,document.body&&document.body.appendChild(i),console.debug("Render recaptcha widget",this._captcha),{id:null!==(r=null===(c=this._captcha)||void 0===c?void 0:c.render(a,e(e({},t),{},{sitekey:"6LcpP88UAAAAAIlNKh-Y5wgpV4dJlkDLEcDKUkdn",size:'invisible'})))&&void 0!==r?r:NaN,uuid:a}}__executeRecaptchaWidget(e,t){var r=this;return a((function*(){var a=r.__getGrecaptchaCallbackNames(t);return new Promise(((c,i)=>{var n;window[a.resolve]=()=>{var a;var i=null===(a=r._captcha)||void 0===a?void 0:a.getResponse(e);c({id:e,token:i,uuid:t})},window[a.reject]=()=>{i(new CaptchaError('recaptcha is rejected'))},window[a.expired]=()=>{i(new CaptchaError('recaptcha is expired'))};var o=null===(n=r._captcha)||void 0===n?void 0:n.execute(e);o?o.catch((e=>{e instanceof Error?i(new CaptchaError(e.message)):'string'==typeof e&&i(new CaptchaError(e))})):i(new CaptchaError('cannot call method execute from grecaptcha'))}))}))()}__createGoogleCaptchaTransaction(){var e=this;return a((function*(){var a=t.generateUUID();var r=e.__getGrecaptchaCallbackNames(a);window[r.resolve]=function(){return null},window[r.reject]=function(){return null},window[r.expired]=function(){return null};var{id:c}=e.__renderRecaptcha(a,{callback:r.resolve,'error-callback':r.reject,'expired-callback':r.expired});if(isNaN(c))throw e.__destroyWidgetByUuid(a),new CaptchaError('Recaptcha is not available');try{return yield e.__executeRecaptchaWidget(c,a)}catch(e){if(e instanceof CaptchaError)throw new CaptchaError('Cannot execute recaptcha with reason: '+e.message,{id:c,uuid:a});throw e}finally{e.__destroyWidgetByUuid(a)}}))()}execute(){var e=this;return a((function*(){if(false!==e.isEnabled()){try{if(yield e._loadScript(),!window.grecaptcha)throw new CaptchaError('grecaptcha is not available in window')}catch(e){if(e instanceof CaptchaError)throw new CaptchaError('grecaptcha is not available: '+e.message);throw e}var a=yield e.__createGoogleCaptchaTransaction();if(e._widgets.push(a),'string'==typeof a.token&&''!==a.token)return a.token}}))()}}RecaptchaService.RESOLVE_FUNC_NAME='recaptcha__GoogleRecaptchaResolved',RecaptchaService.REJECT_FUNC_NAME='recaptcha__GoogleRecaptchaRejected',RecaptchaService.EXPIRED_FUNC_NAME='recaptcha__GoogleRecaptchaExpired',exports.RecaptchaService=RecaptchaService;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
// @flow
|
|
2
|
+
export type RecaptchaAnswer = string
|
|
3
|
+
|
|
4
|
+
export type RecaptchaConfig = {|
|
|
5
|
+
locale?: string,
|
|
6
|
+
sitekey?: string,
|
|
7
|
+
|}
|
|
8
|
+
|
|
9
|
+
export interface RecaptchaInterface {
|
|
10
|
+
constructor(params: RecaptchaConfig): void;
|
|
11
|
+
execute(): Promise<RecaptchaAnswer | void>;
|
|
12
|
+
isEnabled(): boolean;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
declare export class RecaptchaService implements RecaptchaInterface {
|
|
16
|
+
constructor(params: RecaptchaConfig): void;
|
|
17
|
+
execute(): Promise<RecaptchaAnswer | void>;
|
|
18
|
+
isEnabled(): boolean;
|
|
19
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import e from'../node_modules/@babel/runtime/helpers/esm/objectSpread2.mjs';import a from'../node_modules/@babel/runtime/helpers/esm/asyncToGenerator.mjs';import{generateUUID as t}from'../utils/uuid.mjs';class CaptchaError extends Error{constructor(e,a){super(e),this.payload={},this.name='CaptchaError',this.message=e,a&&(this.payload=a)}}class RecaptchaService{constructor(e){var{sitekey:a,locale:t}=e;this._sitekey=null,this._locale='en',this._widgets=[],this._captcha=void 0,this._sitekey=null!=a?a:null,t&&(this._locale=t)}isEnabled(){return'string'==typeof this._sitekey&&''!==this._sitekey}__recaptchaReady(){this._captcha=window.grecaptcha}__destroyWidgetByUuid(e){if('string'==typeof e&&this._widgets.find((a=>a.uuid===e))){var a=this.__getGrecaptchaCallbackNames(e);window[a.resolve]&&delete window[a.resolve],window[a.reject]&&delete window[a.reject],window[a.expired]&&delete window[a.expired];var t=document.getElementById(e);t&&t.remove()}}__getGrecaptchaCallbackNames(e){return{expired:"".concat(RecaptchaService.EXPIRED_FUNC_NAME,"-").concat(e),reject:"".concat(RecaptchaService.REJECT_FUNC_NAME,"-").concat(e),resolve:"".concat(RecaptchaService.RESOLVE_FUNC_NAME,"-").concat(e)}}__appendScript(e){var t=this;return a((function*(){if(t._captcha)return Promise.resolve(t._captcha);if('string'!=typeof e||''===e)throw new TypeError('src script is not defined');var a=document.createElement('script');return a.src=e,document.body&&document.body.appendChild(a),new Promise(((e,t)=>{a.addEventListener('load',(()=>{e(true)})),a.addEventListener('error',(()=>{t()}))}))}))()}_loadScript(){var e=this;return a((function*(){if(e._captcha)return Promise.resolve(e._captcha);var t=function(){var t=a((function*(){return yield e.__appendScript("https://www.google.com/recaptcha/api.js?hl=".concat(e._locale,"&onload=__recaptchaReady__"))}));return function(){return t.apply(this,arguments)}}();return new Promise(((a,r)=>{window.__recaptchaReady__=()=>{e.__recaptchaReady(),e._captcha?a(e._captcha):r(new CaptchaError('Captcha is not available'))},t().catch((()=>r(new CaptchaError('Could not load recaptcha scripts'))))}))}))()}__renderRecaptcha(a,t){var r,c;var i=document.createElement('div');return i.style.display='none',i.id=a,document.body&&document.body.appendChild(i),console.debug("Render recaptcha widget",this._captcha),{id:null!==(r=null===(c=this._captcha)||void 0===c?void 0:c.render(a,e(e({},t),{},{sitekey:"6LcpP88UAAAAAIlNKh-Y5wgpV4dJlkDLEcDKUkdn",size:'invisible'})))&&void 0!==r?r:NaN,uuid:a}}__executeRecaptchaWidget(e,t){var r=this;return a((function*(){var a=r.__getGrecaptchaCallbackNames(t);return new Promise(((c,i)=>{var o;window[a.resolve]=()=>{var a;var i=null===(a=r._captcha)||void 0===a?void 0:a.getResponse(e);c({id:e,token:i,uuid:t})},window[a.reject]=()=>{i(new CaptchaError('recaptcha is rejected'))},window[a.expired]=()=>{i(new CaptchaError('recaptcha is expired'))};var n=null===(o=r._captcha)||void 0===o?void 0:o.execute(e);n?n.catch((e=>{e instanceof Error?i(new CaptchaError(e.message)):'string'==typeof e&&i(new CaptchaError(e))})):i(new CaptchaError('cannot call method execute from grecaptcha'))}))}))()}__createGoogleCaptchaTransaction(){var e=this;return a((function*(){var a=t();var r=e.__getGrecaptchaCallbackNames(a);window[r.resolve]=function(){return null},window[r.reject]=function(){return null},window[r.expired]=function(){return null};var{id:c}=e.__renderRecaptcha(a,{callback:r.resolve,'error-callback':r.reject,'expired-callback':r.expired});if(isNaN(c))throw e.__destroyWidgetByUuid(a),new CaptchaError('Recaptcha is not available');try{return yield e.__executeRecaptchaWidget(c,a)}catch(e){if(e instanceof CaptchaError)throw new CaptchaError('Cannot execute recaptcha with reason: '+e.message,{id:c,uuid:a});throw e}finally{e.__destroyWidgetByUuid(a)}}))()}execute(){var e=this;return a((function*(){if(false!==e.isEnabled()){try{if(yield e._loadScript(),!window.grecaptcha)throw new CaptchaError('grecaptcha is not available in window')}catch(e){if(e instanceof CaptchaError)throw new CaptchaError('grecaptcha is not available: '+e.message);throw e}var a=yield e.__createGoogleCaptchaTransaction();if(e._widgets.push(a),'string'==typeof a.token&&''!==a.token)return a.token}}))()}}RecaptchaService.RESOLVE_FUNC_NAME='recaptcha__GoogleRecaptchaResolved',RecaptchaService.REJECT_FUNC_NAME='recaptcha__GoogleRecaptchaRejected',RecaptchaService.EXPIRED_FUNC_NAME='recaptcha__GoogleRecaptchaExpired';export{RecaptchaService};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
// @flow
|
|
2
|
+
export type RecaptchaAnswer = string
|
|
3
|
+
|
|
4
|
+
export type RecaptchaConfig = {|
|
|
5
|
+
locale?: string,
|
|
6
|
+
sitekey?: string,
|
|
7
|
+
|}
|
|
8
|
+
|
|
9
|
+
export interface RecaptchaInterface {
|
|
10
|
+
constructor(params: RecaptchaConfig): void;
|
|
11
|
+
execute(): Promise<RecaptchaAnswer | void>;
|
|
12
|
+
isEnabled(): boolean;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
declare export class RecaptchaService implements RecaptchaInterface {
|
|
16
|
+
constructor(params: RecaptchaConfig): void;
|
|
17
|
+
execute(): Promise<RecaptchaAnswer | void>;
|
|
18
|
+
isEnabled(): boolean;
|
|
19
|
+
}
|
package/utils/uuid.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
'use strict';Object.defineProperty(exports,'__esModule',{value:true}),exports.generateUUID=function(){var e=(new Date).getTime();var r='undefined'!=typeof performance&&performance.now&&1e3*performance.now()||0;return'xxxx-xxxx-4xxx-yxxx'.replace(/[xy]/g,(function(t){var n=16*Math.random();return e>0?(n=(e+n)%16|0,e=Math.floor(e/16)):(n=(r+n)%16|0,r=Math.floor(r/16)),('x'===t?n:3&n|8).toString(16)}))};
|
package/utils/uuid.mjs
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
function e(){var e=(new Date).getTime();var r='undefined'!=typeof performance&&performance.now&&1e3*performance.now()||0;return'xxxx-xxxx-4xxx-yxxx'.replace(/[xy]/g,(function(x){var n=16*Math.random();return e>0?(n=(e+n)%16|0,e=Math.floor(e/16)):(n=(r+n)%16|0,r=Math.floor(r/16)),('x'===x?n:3&n|8).toString(16)}))}export{e as generateUUID};
|