cloudcommerce 0.0.5 → 0.0.8
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/.eslintrc.cjs +2 -1
- package/CHANGELOG.md +29 -0
- package/package.json +9 -8
- package/packages/api/lib/index.d.ts +121 -72
- package/packages/api/lib/index.js +47 -21
- package/packages/api/lib/index.js.map +1 -1
- package/packages/api/lib/types.d.ts +48 -10
- package/packages/api/package.json +2 -1
- package/packages/api/src/index.ts +54 -19
- package/packages/api/src/types.ts +94 -16
- package/packages/api/tests/index.test.ts +26 -2
- package/packages/apps/discounts/package.json +2 -1
- package/packages/storefront/package.json +2 -1
package/.eslintrc.cjs
CHANGED
|
@@ -26,6 +26,8 @@ module.exports = {
|
|
|
26
26
|
'no-param-reassign': 'warn',
|
|
27
27
|
'no-underscore-dangle': 'off',
|
|
28
28
|
'no-continue': 'off',
|
|
29
|
+
'lines-between-class-members': 'off',
|
|
30
|
+
'arrow-body-style': 'off',
|
|
29
31
|
'import/extensions': [
|
|
30
32
|
'error',
|
|
31
33
|
'ignorePackages',
|
|
@@ -42,7 +44,6 @@ module.exports = {
|
|
|
42
44
|
{ blankLine: 'never', prev: 'directive', next: 'directive' },
|
|
43
45
|
{ blankLine: 'never', prev: 'import', next: 'import' },
|
|
44
46
|
],
|
|
45
|
-
'arrow-body-style': 'off',
|
|
46
47
|
'import/order': [
|
|
47
48
|
'error',
|
|
48
49
|
{ groups: ['type', 'builtin', 'external', 'parent', 'sibling', 'index'] },
|
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,35 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
|
|
4
4
|
|
|
5
|
+
### [0.0.8](https://github.com/ecomplus/cloud-commerce/compare/v0.0.7...v0.0.8) (2022-06-21)
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
### Bug Fixes
|
|
9
|
+
|
|
10
|
+
* Explictly set packages `"type": "module"` ([dcaffce](https://github.com/ecomplus/cloud-commerce/commit/dcaffcecf78d30cd480f1cf2794eb61afaeba5bf))
|
|
11
|
+
|
|
12
|
+
### [0.0.7](https://github.com/ecomplus/cloud-commerce/compare/v0.0.6...v0.0.7) (2022-06-21)
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
### Features
|
|
16
|
+
|
|
17
|
+
* **api:** Add `fetch` option to config ([9ca0f68](https://github.com/ecomplus/cloud-commerce/commit/9ca0f681b003132574a6f147d406c8dddab93261))
|
|
18
|
+
* **api:** Add events, slug, search and auth endpoints to type ([9d4f712](https://github.com/ecomplus/cloud-commerce/commit/9d4f71217e73e22b941cfea855416a86e7bbc9a2))
|
|
19
|
+
* **api:** New (exported) `ApiError` class ([8e88494](https://github.com/ecomplus/cloud-commerce/commit/8e884944505caf3861aef4bce440f7fd0ed937a4))
|
|
20
|
+
* **api:** Type definiftion for list requests (`/${resource}`) ([21d71ff](https://github.com/ecomplus/cloud-commerce/commit/21d71ff56ac1220d16324f1018a9804b7f5cf3c3))
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
### Bug Fixes
|
|
24
|
+
|
|
25
|
+
* **api:** Event `timestamp` retrieved as date iso string (not object) ([aa18cc7](https://github.com/ecomplus/cloud-commerce/commit/aa18cc7e8cf0d8fb3345da7e48ddc15f4bb2209e))
|
|
26
|
+
|
|
27
|
+
### [0.0.6](https://github.com/ecomplus/cloud-commerce/compare/v0.0.5...v0.0.6) (2022-06-16)
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
### Features
|
|
31
|
+
|
|
32
|
+
* **api:** New config option `maxRetries` (default 3) to retry on 429 and 5xx errors ([35c5287](https://github.com/ecomplus/cloud-commerce/commit/35c5287545a79bd15596f96e88bdb7d98c056183))
|
|
33
|
+
|
|
5
34
|
### [0.0.5](https://github.com/ecomplus/cloud-commerce/compare/v0.0.4...v0.0.5) (2022-06-16)
|
|
6
35
|
|
|
7
36
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cloudcommerce",
|
|
3
|
-
"
|
|
3
|
+
"type": "module",
|
|
4
|
+
"version": "0.0.8",
|
|
4
5
|
"description": "Open fair-code headless commerce platform: API-first, microservices based, event driven and cloud native",
|
|
5
6
|
"main": "src/index.js",
|
|
6
7
|
"author": "E-Com Club Softwares para E-commerce <ti@e-com.club>",
|
|
@@ -25,11 +26,11 @@
|
|
|
25
26
|
"@commitlint/cli": "^17.0.2",
|
|
26
27
|
"@commitlint/config-conventional": "^17.0.2",
|
|
27
28
|
"@commitlint/rules": "^17.0.0",
|
|
28
|
-
"@types/node": "^17.0.
|
|
29
|
-
"@typescript-eslint/eslint-plugin": "^5.
|
|
30
|
-
"@typescript-eslint/parser": "^5.
|
|
31
|
-
"esbuild": "^0.14.
|
|
32
|
-
"eslint": "^8.
|
|
29
|
+
"@types/node": "^17.0.45",
|
|
30
|
+
"@typescript-eslint/eslint-plugin": "^5.29.0",
|
|
31
|
+
"@typescript-eslint/parser": "^5.29.0",
|
|
32
|
+
"esbuild": "^0.14.47",
|
|
33
|
+
"eslint": "^8.18.0",
|
|
33
34
|
"eslint-config-airbnb-base": "^15.0.0",
|
|
34
35
|
"eslint-plugin-import": "^2.26.0",
|
|
35
36
|
"eslint-plugin-vue": "^9.1.1",
|
|
@@ -37,9 +38,9 @@
|
|
|
37
38
|
"node-fetch": "^3.2.6",
|
|
38
39
|
"standard-version": "^9.5.0",
|
|
39
40
|
"turbo": "^1.2.16",
|
|
40
|
-
"typescript": "^4.7.
|
|
41
|
+
"typescript": "^4.7.4",
|
|
41
42
|
"vite": "^2.9.12",
|
|
42
|
-
"vitest": "^0.15.
|
|
43
|
+
"vitest": "^0.15.2",
|
|
43
44
|
"zx": "^6.2.5"
|
|
44
45
|
}
|
|
45
46
|
}
|
|
@@ -1,50 +1,78 @@
|
|
|
1
1
|
import type { Endpoint, Config, ResponseBody } from './types';
|
|
2
|
+
declare class ApiError extends Error {
|
|
3
|
+
config: Config;
|
|
4
|
+
response?: Response;
|
|
5
|
+
statusCode?: number;
|
|
6
|
+
isTimeout: boolean;
|
|
7
|
+
constructor(config: Config, response?: Response, msg?: string, isTimeout?: boolean);
|
|
8
|
+
}
|
|
2
9
|
declare const def: {
|
|
3
10
|
middleware(config: Config): string;
|
|
4
11
|
};
|
|
5
12
|
declare const setMiddleware: (middleware: (config: Config) => string) => void;
|
|
6
13
|
declare const api: {
|
|
7
|
-
<T extends Config>(config: T): Promise<Response & {
|
|
14
|
+
<T extends Config>(config: T, retries?: number): Promise<Response & {
|
|
8
15
|
config: Config;
|
|
9
16
|
data: ResponseBody<T>;
|
|
10
17
|
}>;
|
|
11
18
|
get: <E extends Endpoint, C extends AbstractedConfig>(endpoint: E, config?: C | undefined) => Promise<Response & {
|
|
12
19
|
config: Config;
|
|
13
|
-
data: {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
20
|
+
data: E extends `products/${string}` ? import("./types").Products : E extends `categories/${string}` ? import("./types").Categories : E extends `brands/${string}` ? import("./types").Brands : E extends `collections/${string}` ? import("./types").Collections : E extends `grids/${string}` ? import("./types").Grids : E extends `carts/${string}` ? import("./types").Carts : E extends `orders/${string}` ? import("./types").Orders : E extends `customers/${string}` ? import("./types").Customers : E extends `stores/${string}` ? import("./types").Stores : E extends `applications/${string}` ? import("./types").Applications : E extends import("./types").Resource ? {
|
|
21
|
+
result: E extends infer T_1 ? T_1 extends E ? T_1 extends "products" ? import("./types").Products[] : T_1 extends "categories" ? import("./types").Categories[] : T_1 extends "brands" ? import("./types").Brands[] : T_1 extends "collections" ? import("./types").Collections[] : T_1 extends "grids" ? import("./types").Grids[] : T_1 extends "carts" ? import("./types").Carts[] : T_1 extends "orders" ? import("./types").Orders[] : T_1 extends "customers" ? import("./types").Customers[] : T_1 extends "stores" ? import("./types").Stores[] : T_1 extends "applications" ? import("./types").Applications[] : never : never : never;
|
|
22
|
+
meta: {
|
|
23
|
+
offset: number;
|
|
24
|
+
limit: number;
|
|
25
|
+
fields: string[];
|
|
26
|
+
} & {
|
|
27
|
+
count?: number | undefined;
|
|
28
|
+
sort: {
|
|
29
|
+
field: string;
|
|
30
|
+
order: 1 | -1;
|
|
31
|
+
}[];
|
|
32
|
+
query: {
|
|
33
|
+
[key: string]: any;
|
|
34
|
+
};
|
|
35
|
+
};
|
|
36
|
+
} : E extends "events/products" | "events/categories" | "events/brands" | "events/collections" | "events/grids" | "events/carts" | "events/orders" | "events/customers" | "events/stores" | "events/applications" | `events/products/${string}` | `events/categories/${string}` | `events/brands/${string}` | `events/collections/${string}` | `events/grids/${string}` | `events/carts/${string}` | `events/orders/${string}` | `events/customers/${string}` | `events/stores/${string}` | `events/applications/${string}` | "events/me" ? {
|
|
37
|
+
result: ({
|
|
38
|
+
timestamp: string;
|
|
39
|
+
store_id?: number | undefined;
|
|
40
|
+
resource?: string | undefined;
|
|
41
|
+
authentication_id?: (string & {
|
|
42
|
+
length: 24;
|
|
43
|
+
}) | null | undefined;
|
|
44
|
+
resource_id?: (string & {
|
|
45
|
+
length: 24;
|
|
46
|
+
}) | undefined;
|
|
47
|
+
action: string;
|
|
48
|
+
modified_fields: string[];
|
|
49
|
+
method?: number | undefined;
|
|
50
|
+
endpoint?: string | undefined;
|
|
51
|
+
body?: any;
|
|
52
|
+
ip?: string | undefined;
|
|
53
|
+
} & (E extends infer T_2 ? T_2 extends E ? T_2 extends "events/products" | "events/categories" | "events/brands" | "events/collections" | "events/grids" | "events/carts" | "events/orders" | "events/customers" | "events/stores" | "events/applications" ? {
|
|
54
|
+
resource_id: string & {
|
|
55
|
+
length: 24;
|
|
56
|
+
};
|
|
57
|
+
authentication_id: (string & {
|
|
58
|
+
length: 24;
|
|
59
|
+
}) | null;
|
|
60
|
+
} : T_2 extends `events/products/${string}` | `events/categories/${string}` | `events/brands/${string}` | `events/collections/${string}` | `events/grids/${string}` | `events/carts/${string}` | `events/orders/${string}` | `events/customers/${string}` | `events/stores/${string}` | `events/applications/${string}` ? {
|
|
61
|
+
authentication_id: (string & {
|
|
62
|
+
length: 24;
|
|
63
|
+
}) | null;
|
|
64
|
+
} : T_2 extends "events/me" ? {
|
|
65
|
+
resource: import("./types").Resource;
|
|
66
|
+
resource_id: string & {
|
|
67
|
+
length: 24;
|
|
68
|
+
};
|
|
69
|
+
} : never : never : never))[];
|
|
70
|
+
meta: {
|
|
71
|
+
offset: number;
|
|
72
|
+
limit: number;
|
|
73
|
+
fields: string[];
|
|
74
|
+
};
|
|
75
|
+
} : any;
|
|
48
76
|
}>;
|
|
49
77
|
post: (endpoint: Endpoint, config?: AbstractedConfig) => Promise<Response & {
|
|
50
78
|
config: Config;
|
|
@@ -74,41 +102,62 @@ declare const api: {
|
|
|
74
102
|
declare type AbstractedConfig = Omit<Config, 'endpoint' | 'method'>;
|
|
75
103
|
declare const get: <E extends Endpoint, C extends AbstractedConfig>(endpoint: E, config?: C | undefined) => Promise<Response & {
|
|
76
104
|
config: Config;
|
|
77
|
-
data: {
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
105
|
+
data: E extends `products/${string}` ? import("./types").Products : E extends `categories/${string}` ? import("./types").Categories : E extends `brands/${string}` ? import("./types").Brands : E extends `collections/${string}` ? import("./types").Collections : E extends `grids/${string}` ? import("./types").Grids : E extends `carts/${string}` ? import("./types").Carts : E extends `orders/${string}` ? import("./types").Orders : E extends `customers/${string}` ? import("./types").Customers : E extends `stores/${string}` ? import("./types").Stores : E extends `applications/${string}` ? import("./types").Applications : E extends import("./types").Resource ? {
|
|
106
|
+
result: E extends infer T_1 ? T_1 extends E ? T_1 extends "products" ? import("./types").Products[] : T_1 extends "categories" ? import("./types").Categories[] : T_1 extends "brands" ? import("./types").Brands[] : T_1 extends "collections" ? import("./types").Collections[] : T_1 extends "grids" ? import("./types").Grids[] : T_1 extends "carts" ? import("./types").Carts[] : T_1 extends "orders" ? import("./types").Orders[] : T_1 extends "customers" ? import("./types").Customers[] : T_1 extends "stores" ? import("./types").Stores[] : T_1 extends "applications" ? import("./types").Applications[] : never : never : never;
|
|
107
|
+
meta: {
|
|
108
|
+
offset: number;
|
|
109
|
+
limit: number;
|
|
110
|
+
fields: string[];
|
|
111
|
+
} & {
|
|
112
|
+
count?: number | undefined;
|
|
113
|
+
sort: {
|
|
114
|
+
field: string;
|
|
115
|
+
order: 1 | -1;
|
|
116
|
+
}[];
|
|
117
|
+
query: {
|
|
118
|
+
[key: string]: any;
|
|
119
|
+
};
|
|
120
|
+
};
|
|
121
|
+
} : E extends "events/products" | "events/categories" | "events/brands" | "events/collections" | "events/grids" | "events/carts" | "events/orders" | "events/customers" | "events/stores" | "events/applications" | `events/products/${string}` | `events/categories/${string}` | `events/brands/${string}` | `events/collections/${string}` | `events/grids/${string}` | `events/carts/${string}` | `events/orders/${string}` | `events/customers/${string}` | `events/stores/${string}` | `events/applications/${string}` | "events/me" ? {
|
|
122
|
+
result: ({
|
|
123
|
+
timestamp: string;
|
|
124
|
+
store_id?: number | undefined;
|
|
125
|
+
resource?: string | undefined;
|
|
126
|
+
authentication_id?: (string & {
|
|
127
|
+
length: 24;
|
|
128
|
+
}) | null | undefined;
|
|
129
|
+
resource_id?: (string & {
|
|
130
|
+
length: 24;
|
|
131
|
+
}) | undefined;
|
|
132
|
+
action: string;
|
|
133
|
+
modified_fields: string[];
|
|
134
|
+
method?: number | undefined;
|
|
135
|
+
endpoint?: string | undefined;
|
|
136
|
+
body?: any;
|
|
137
|
+
ip?: string | undefined;
|
|
138
|
+
} & (E extends infer T_2 ? T_2 extends E ? T_2 extends "events/products" | "events/categories" | "events/brands" | "events/collections" | "events/grids" | "events/carts" | "events/orders" | "events/customers" | "events/stores" | "events/applications" ? {
|
|
139
|
+
resource_id: string & {
|
|
140
|
+
length: 24;
|
|
141
|
+
};
|
|
142
|
+
authentication_id: (string & {
|
|
143
|
+
length: 24;
|
|
144
|
+
}) | null;
|
|
145
|
+
} : T_2 extends `events/products/${string}` | `events/categories/${string}` | `events/brands/${string}` | `events/collections/${string}` | `events/grids/${string}` | `events/carts/${string}` | `events/orders/${string}` | `events/customers/${string}` | `events/stores/${string}` | `events/applications/${string}` ? {
|
|
146
|
+
authentication_id: (string & {
|
|
147
|
+
length: 24;
|
|
148
|
+
}) | null;
|
|
149
|
+
} : T_2 extends "events/me" ? {
|
|
150
|
+
resource: import("./types").Resource;
|
|
151
|
+
resource_id: string & {
|
|
152
|
+
length: 24;
|
|
153
|
+
};
|
|
154
|
+
} : never : never : never))[];
|
|
155
|
+
meta: {
|
|
156
|
+
offset: number;
|
|
157
|
+
limit: number;
|
|
158
|
+
fields: string[];
|
|
159
|
+
};
|
|
160
|
+
} : any;
|
|
112
161
|
}>;
|
|
113
162
|
declare const post: (endpoint: Endpoint, config?: AbstractedConfig) => Promise<Response & {
|
|
114
163
|
config: Config;
|
|
@@ -131,4 +180,4 @@ declare const del: (endpoint: Endpoint, config?: AbstractedConfig) => Promise<Re
|
|
|
131
180
|
data: null;
|
|
132
181
|
}>;
|
|
133
182
|
export default api;
|
|
134
|
-
export { setMiddleware, get, post, put, patch, del, };
|
|
183
|
+
export { setMiddleware, get, post, put, patch, del, ApiError, };
|
|
@@ -2,6 +2,15 @@
|
|
|
2
2
|
const env = (typeof window === 'object' && window)
|
|
3
3
|
|| (typeof process === 'object' && process && process.env)
|
|
4
4
|
|| {};
|
|
5
|
+
class ApiError extends Error {
|
|
6
|
+
constructor(config, response, msg, isTimeout = false) {
|
|
7
|
+
super(response?.statusText || msg || 'Request error');
|
|
8
|
+
this.config = config;
|
|
9
|
+
this.response = response;
|
|
10
|
+
this.statusCode = response?.status;
|
|
11
|
+
this.isTimeout = isTimeout;
|
|
12
|
+
}
|
|
13
|
+
}
|
|
5
14
|
const def = {
|
|
6
15
|
middleware(config) {
|
|
7
16
|
let url = config.baseUrl || env.API_BASE_URL || 'https://ecomplus.io/v2';
|
|
@@ -25,33 +34,50 @@ const def = {
|
|
|
25
34
|
return `${url}/${config.endpoint}`;
|
|
26
35
|
},
|
|
27
36
|
};
|
|
28
|
-
// eslint-disable-next-line no-unused-vars
|
|
29
37
|
const setMiddleware = (middleware) => {
|
|
30
38
|
def.middleware = middleware;
|
|
31
39
|
};
|
|
32
|
-
const api = async (config) => {
|
|
40
|
+
const api = async (config, retries = 0) => {
|
|
33
41
|
const url = def.middleware(config);
|
|
34
|
-
const {
|
|
42
|
+
const {
|
|
43
|
+
method, headers, timeout = 20000, maxRetries = 3,
|
|
44
|
+
} = config;
|
|
35
45
|
const abortController = new AbortController();
|
|
36
|
-
|
|
37
|
-
const
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
46
|
+
let isTimeout = false;
|
|
47
|
+
const timer = setTimeout(() => {
|
|
48
|
+
abortController.abort();
|
|
49
|
+
isTimeout = true;
|
|
50
|
+
}, timeout);
|
|
51
|
+
let response;
|
|
52
|
+
try {
|
|
53
|
+
response = await (config.fetch || fetch)(url, {
|
|
54
|
+
method,
|
|
55
|
+
headers,
|
|
56
|
+
signal: abortController.signal,
|
|
57
|
+
});
|
|
58
|
+
} catch (err) {
|
|
59
|
+
throw new ApiError(config, response, err.message, isTimeout);
|
|
60
|
+
}
|
|
42
61
|
clearTimeout(timer);
|
|
43
|
-
if (response
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
62
|
+
if (response) {
|
|
63
|
+
if (response.ok) {
|
|
64
|
+
return {
|
|
65
|
+
...response,
|
|
66
|
+
config,
|
|
67
|
+
data: await response.json(),
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
const { status } = response;
|
|
71
|
+
if (maxRetries < retries && (status === 429 || status >= 500)) {
|
|
72
|
+
const retryAfter = response.headers.get('retry-after');
|
|
73
|
+
return new Promise((resolve, reject) => {
|
|
74
|
+
setTimeout(() => {
|
|
75
|
+
api(config, retries + 1).then(resolve).catch(reject);
|
|
76
|
+
}, (retryAfter && parseInt(retryAfter, 10)) || 5000);
|
|
77
|
+
});
|
|
78
|
+
}
|
|
49
79
|
}
|
|
50
|
-
|
|
51
|
-
error.config = config;
|
|
52
|
-
error.response = response;
|
|
53
|
-
error.statusCode = response.status;
|
|
54
|
-
throw error;
|
|
80
|
+
throw new ApiError(config, response);
|
|
55
81
|
};
|
|
56
82
|
const get = (endpoint, config) => api({ ...config, endpoint });
|
|
57
83
|
const post = (endpoint, config) => api({
|
|
@@ -84,6 +110,6 @@ api.delete = del;
|
|
|
84
110
|
export default api;
|
|
85
111
|
|
|
86
112
|
export {
|
|
87
|
-
setMiddleware, get, post, put, patch, del,
|
|
113
|
+
setMiddleware, get, post, put, patch, del, ApiError,
|
|
88
114
|
};
|
|
89
115
|
// # sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,aAAa;AACb,MAAM,GAAG,GAA8B,CAAC,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,CAAC;OACxE,CAAC,OAAO,OAAO,KAAK,QAAQ,IAAI,OAAO,IAAI,OAAO,CAAC,GAAG,CAAC;OACvD,EAAE,CAAC;AAER,MAAM,GAAG,GAAG;IACV,UAAU,CAAC,MAAc;QACvB,IAAI,GAAG,GAAG,MAAM,CAAC,OAAO,IAAI,GAAG,CAAC,YAAY,IAAI,wBAAwB,CAAC;QACzE,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,IAAI,GAAG,CAAC,aAAa,CAAC;QACpD,IAAI,CAAC,OAAO,EAAE;YACZ,MAAM,IAAI,KAAK,CAAC,4DAA4D,CAAC,CAAC;SAC/E;QACD,GAAG,IAAI,KAAK,OAAO,EAAE,CAAC;QACtB,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,IAAI,GAAG,CAAC,SAAS,CAAC;QAC1C,IAAI,IAAI,EAAE;YACR,GAAG,IAAI,SAAS,IAAI,EAAE,CAAC;SACxB;QACD,IAAI,MAAM,CAAC,MAAM,EAAE;YACjB,IAAI,OAAO,MAAM,CAAC,MAAM,KAAK,QAAQ,EAAE;gBACrC,GAAG,IAAI,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;aAC5B;iBAAM;gBACL,uDAAuD;gBACvD,GAAG,IAAI,IAAI,IAAI,eAAe,CAAC,MAAM,CAAC,MAAgC,CAAC,EAAE,CAAC;aAC3E;SACF;QACD,OAAO,GAAG,GAAG,IAAI,MAAM,CAAC,QAAQ,EAAE,CAAC;IACrC,CAAC;CACF,CAAC;AAEF,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -13,7 +13,8 @@ declare type ResourceId = string & {
|
|
|
13
13
|
length: 24;
|
|
14
14
|
};
|
|
15
15
|
declare type ResourceAndId = `${Resource}/${ResourceId}`;
|
|
16
|
-
declare type
|
|
16
|
+
declare type EventsEndpoint = `events/${Resource}` | `events/${ResourceAndId}` | 'events/me';
|
|
17
|
+
declare type Endpoint = Resource | ResourceAndId | `${ResourceAndId}/${string}` | `slugs/${string}` | 'search/v1' | EventsEndpoint | 'login' | 'authenticate' | 'ask-auth-callback' | 'check-username' | `$aggregate/${Exclude<Resource, 'stores' | 'applications'>}` | `schemas/${Resource}`;
|
|
17
18
|
declare type Method = 'get' | 'post' | 'put' | 'patch' | 'delete';
|
|
18
19
|
declare type Config = {
|
|
19
20
|
baseUrl?: string;
|
|
@@ -24,16 +25,53 @@ declare type Config = {
|
|
|
24
25
|
params?: Record<string, string | number>;
|
|
25
26
|
headers?: Record<string, string>;
|
|
26
27
|
timeout?: number;
|
|
28
|
+
maxRetries?: number;
|
|
29
|
+
fetch?: typeof fetch;
|
|
27
30
|
};
|
|
28
|
-
declare type
|
|
29
|
-
|
|
30
|
-
|
|
31
|
+
declare type BaseListResultMeta = {
|
|
32
|
+
offset: number;
|
|
33
|
+
limit: number;
|
|
34
|
+
fields: Array<string>;
|
|
31
35
|
};
|
|
32
|
-
declare type
|
|
33
|
-
|
|
34
|
-
|
|
36
|
+
declare type ResourceListResult<TResource extends Resource> = {
|
|
37
|
+
result: TResource extends 'products' ? Products[] : TResource extends 'categories' ? Categories[] : TResource extends 'brands' ? Brands[] : TResource extends 'collections' ? Collections[] : TResource extends 'grids' ? Grids[] : TResource extends 'carts' ? Carts[] : TResource extends 'orders' ? Orders[] : TResource extends 'customers' ? Customers[] : TResource extends 'stores' ? Stores[] : TResource extends 'applications' ? Applications[] : never;
|
|
38
|
+
meta: BaseListResultMeta & {
|
|
39
|
+
count?: number;
|
|
40
|
+
sort: Array<{
|
|
41
|
+
field: string;
|
|
42
|
+
order: 1 | -1;
|
|
43
|
+
}>;
|
|
44
|
+
query: {
|
|
45
|
+
[key: string]: any;
|
|
46
|
+
};
|
|
47
|
+
};
|
|
48
|
+
};
|
|
49
|
+
declare type EventFieldsByEndpoint<TEndpoint extends EventsEndpoint> = TEndpoint extends `events/${Resource}` ? {
|
|
50
|
+
resource_id: ResourceId;
|
|
51
|
+
authentication_id: ResourceId | null;
|
|
52
|
+
} : TEndpoint extends `events/${ResourceAndId}` ? {
|
|
53
|
+
authentication_id: ResourceId | null;
|
|
54
|
+
} : TEndpoint extends 'events/me' ? {
|
|
55
|
+
resource: Resource;
|
|
56
|
+
resource_id: ResourceId;
|
|
57
|
+
} : never;
|
|
58
|
+
declare type EventsResult<TEndpoint extends EventsEndpoint> = {
|
|
59
|
+
result: Array<{
|
|
60
|
+
timestamp: string;
|
|
61
|
+
store_id?: number;
|
|
62
|
+
resource?: string;
|
|
63
|
+
authentication_id?: ResourceId | null;
|
|
64
|
+
resource_id?: ResourceId;
|
|
65
|
+
action: string;
|
|
66
|
+
modified_fields: string[];
|
|
67
|
+
method?: number | undefined;
|
|
68
|
+
endpoint?: string;
|
|
69
|
+
body?: any;
|
|
70
|
+
ip?: string;
|
|
71
|
+
} & EventFieldsByEndpoint<TEndpoint>>;
|
|
72
|
+
meta: BaseListResultMeta;
|
|
73
|
+
};
|
|
74
|
+
declare type ResponseBody<TConfig extends Config> = TConfig['method'] extends 'post' ? {
|
|
35
75
|
_id: ResourceId;
|
|
36
|
-
} :
|
|
37
|
-
method: 'put' | 'patch' | 'delete';
|
|
38
|
-
} ? null : T extends ReadConfig<`products/${ResourceId}`> ? Products : T extends ReadConfig<`categories/${ResourceId}`> ? Categories : T extends ReadConfig<`brands/${ResourceId}`> ? Brands : T extends ReadConfig<`collections/${ResourceId}`> ? Collections : T extends ReadConfig<`grids/${ResourceId}`> ? Grids : T extends ReadConfig<`carts/${ResourceId}`> ? Carts : T extends ReadConfig<`orders/${ResourceId}`> ? Orders : T extends ReadConfig<`customers/${ResourceId}`> ? Customers : T extends ReadConfig<`stores/${ResourceId}`> ? Stores : T extends ReadConfig<`applications/${ResourceId}`> ? Applications : any;
|
|
76
|
+
} : TConfig['method'] extends 'put' | 'patch' | 'delete' ? null : TConfig['endpoint'] extends `products/${ResourceId}` ? Products : TConfig['endpoint'] extends `categories/${ResourceId}` ? Categories : TConfig['endpoint'] extends `brands/${ResourceId}` ? Brands : TConfig['endpoint'] extends `collections/${ResourceId}` ? Collections : TConfig['endpoint'] extends `grids/${ResourceId}` ? Grids : TConfig['endpoint'] extends `carts/${ResourceId}` ? Carts : TConfig['endpoint'] extends `orders/${ResourceId}` ? Orders : TConfig['endpoint'] extends `customers/${ResourceId}` ? Customers : TConfig['endpoint'] extends `stores/${ResourceId}` ? Stores : TConfig['endpoint'] extends `applications/${ResourceId}` ? Applications : TConfig['endpoint'] extends Resource ? ResourceListResult<TConfig['endpoint']> : TConfig['endpoint'] extends EventsEndpoint ? EventsResult<TConfig['endpoint']> : any;
|
|
39
77
|
export type { Products, Categories, Brands, Collections, Grids, Carts, Orders, Customers, Stores, Applications, Resource, ResourceAndId, Endpoint, Method, Config, ResponseBody, };
|
|
@@ -5,6 +5,20 @@ const env: { [key: string]: string } = (typeof window === 'object' && window)
|
|
|
5
5
|
|| (typeof process === 'object' && process && process.env)
|
|
6
6
|
|| {};
|
|
7
7
|
|
|
8
|
+
class ApiError extends Error {
|
|
9
|
+
config: Config;
|
|
10
|
+
response?: Response;
|
|
11
|
+
statusCode?: number;
|
|
12
|
+
isTimeout: boolean;
|
|
13
|
+
constructor(config: Config, response?: Response, msg?: string, isTimeout: boolean = false) {
|
|
14
|
+
super(response?.statusText || msg || 'Request error');
|
|
15
|
+
this.config = config;
|
|
16
|
+
this.response = response;
|
|
17
|
+
this.statusCode = response?.status;
|
|
18
|
+
this.isTimeout = isTimeout;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
8
22
|
const def = {
|
|
9
23
|
middleware(config: Config) {
|
|
10
24
|
let url = config.baseUrl || env.API_BASE_URL || 'https://ecomplus.io/v2';
|
|
@@ -29,37 +43,57 @@ const def = {
|
|
|
29
43
|
},
|
|
30
44
|
};
|
|
31
45
|
|
|
32
|
-
// eslint-disable-next-line no-unused-vars
|
|
33
46
|
const setMiddleware = (middleware: typeof def.middleware) => {
|
|
34
47
|
def.middleware = middleware;
|
|
35
48
|
};
|
|
36
49
|
|
|
37
|
-
const api = async <T extends Config>(config: T): Promise<Response & {
|
|
50
|
+
const api = async <T extends Config>(config: T, retries = 0): Promise<Response & {
|
|
38
51
|
config: Config,
|
|
39
52
|
data: ResponseBody<T>,
|
|
40
53
|
}> => {
|
|
41
54
|
const url = def.middleware(config);
|
|
42
|
-
const {
|
|
43
|
-
const abortController = new AbortController();
|
|
44
|
-
const timer = setTimeout(() => abortController.abort(), timeout);
|
|
45
|
-
const response = await fetch(url, {
|
|
55
|
+
const {
|
|
46
56
|
method,
|
|
47
57
|
headers,
|
|
48
|
-
|
|
49
|
-
|
|
58
|
+
timeout = 20000,
|
|
59
|
+
maxRetries = 3,
|
|
60
|
+
} = config;
|
|
61
|
+
const abortController = new AbortController();
|
|
62
|
+
let isTimeout = false;
|
|
63
|
+
const timer = setTimeout(() => {
|
|
64
|
+
abortController.abort();
|
|
65
|
+
isTimeout = true;
|
|
66
|
+
}, timeout);
|
|
67
|
+
let response: Response | undefined;
|
|
68
|
+
try {
|
|
69
|
+
response = await (config.fetch || fetch)(url, {
|
|
70
|
+
method,
|
|
71
|
+
headers,
|
|
72
|
+
signal: abortController.signal,
|
|
73
|
+
});
|
|
74
|
+
} catch (err: any) {
|
|
75
|
+
throw new ApiError(config, response, err.message, isTimeout);
|
|
76
|
+
}
|
|
50
77
|
clearTimeout(timer);
|
|
51
|
-
if (response
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
78
|
+
if (response) {
|
|
79
|
+
if (response.ok) {
|
|
80
|
+
return {
|
|
81
|
+
...response,
|
|
82
|
+
config,
|
|
83
|
+
data: await response.json(),
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
const { status } = response;
|
|
87
|
+
if (maxRetries < retries && (status === 429 || status >= 500)) {
|
|
88
|
+
const retryAfter = response.headers.get('retry-after');
|
|
89
|
+
return new Promise((resolve, reject) => {
|
|
90
|
+
setTimeout(() => {
|
|
91
|
+
api(config, retries + 1).then(resolve).catch(reject);
|
|
92
|
+
}, (retryAfter && parseInt(retryAfter, 10)) || 5000);
|
|
93
|
+
});
|
|
94
|
+
}
|
|
57
95
|
}
|
|
58
|
-
|
|
59
|
-
error.config = config;
|
|
60
|
-
error.response = response;
|
|
61
|
-
error.statusCode = response.status;
|
|
62
|
-
throw error;
|
|
96
|
+
throw new ApiError(config, response);
|
|
63
97
|
};
|
|
64
98
|
|
|
65
99
|
type AbstractedConfig = Omit<Config, 'endpoint' | 'method'>;
|
|
@@ -112,4 +146,5 @@ export {
|
|
|
112
146
|
put,
|
|
113
147
|
patch,
|
|
114
148
|
del,
|
|
149
|
+
ApiError,
|
|
115
150
|
};
|
|
@@ -24,7 +24,22 @@ type ResourceId = string & { length: 24 };
|
|
|
24
24
|
|
|
25
25
|
type ResourceAndId = `${Resource}/${ResourceId}`;
|
|
26
26
|
|
|
27
|
-
type
|
|
27
|
+
type EventsEndpoint = `events/${Resource}`
|
|
28
|
+
| `events/${ResourceAndId}`
|
|
29
|
+
| 'events/me';
|
|
30
|
+
|
|
31
|
+
type Endpoint = Resource
|
|
32
|
+
| ResourceAndId
|
|
33
|
+
| `${ResourceAndId}/${string}`
|
|
34
|
+
| `slugs/${string}`
|
|
35
|
+
| 'search/v1'
|
|
36
|
+
| EventsEndpoint
|
|
37
|
+
| 'login'
|
|
38
|
+
| 'authenticate'
|
|
39
|
+
| 'ask-auth-callback'
|
|
40
|
+
| 'check-username'
|
|
41
|
+
| `$aggregate/${Exclude<Resource, 'stores' | 'applications'>}`
|
|
42
|
+
| `schemas/${Resource}`;
|
|
28
43
|
|
|
29
44
|
type Method = 'get' | 'post' | 'put' | 'patch' | 'delete';
|
|
30
45
|
|
|
@@ -37,24 +52,87 @@ type Config = {
|
|
|
37
52
|
params?: Record<string, string | number>,
|
|
38
53
|
headers?: Record<string, string>,
|
|
39
54
|
timeout?: number,
|
|
55
|
+
maxRetries?: number,
|
|
56
|
+
fetch?: typeof fetch,
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
type BaseListResultMeta = {
|
|
60
|
+
offset: number,
|
|
61
|
+
limit: number,
|
|
62
|
+
fields: Array<string>,
|
|
40
63
|
};
|
|
41
64
|
|
|
42
|
-
type
|
|
65
|
+
type ResourceListResult<TResource extends Resource> = {
|
|
66
|
+
result:
|
|
67
|
+
TResource extends 'products' ? Products[] :
|
|
68
|
+
TResource extends 'categories' ? Categories[] :
|
|
69
|
+
TResource extends 'brands' ? Brands[] :
|
|
70
|
+
TResource extends 'collections' ? Collections[] :
|
|
71
|
+
TResource extends 'grids' ? Grids[] :
|
|
72
|
+
TResource extends 'carts' ? Carts[] :
|
|
73
|
+
TResource extends 'orders' ? Orders[] :
|
|
74
|
+
TResource extends 'customers' ? Customers[] :
|
|
75
|
+
TResource extends 'stores' ? Stores[] :
|
|
76
|
+
TResource extends 'applications' ? Applications[] :
|
|
77
|
+
never,
|
|
78
|
+
meta: BaseListResultMeta & {
|
|
79
|
+
count?: number,
|
|
80
|
+
sort: Array<{
|
|
81
|
+
field: string,
|
|
82
|
+
order: 1 | -1,
|
|
83
|
+
}>,
|
|
84
|
+
query: { [key: string]: any },
|
|
85
|
+
},
|
|
86
|
+
};
|
|
87
|
+
|
|
88
|
+
type EventFieldsByEndpoint<TEndpoint extends EventsEndpoint> =
|
|
89
|
+
TEndpoint extends `events/${Resource}` ? {
|
|
90
|
+
resource_id: ResourceId,
|
|
91
|
+
authentication_id: ResourceId | null,
|
|
92
|
+
} :
|
|
93
|
+
TEndpoint extends `events/${ResourceAndId}` ? {
|
|
94
|
+
authentication_id: ResourceId | null,
|
|
95
|
+
} :
|
|
96
|
+
TEndpoint extends 'events/me' ? {
|
|
97
|
+
resource: Resource,
|
|
98
|
+
resource_id: ResourceId,
|
|
99
|
+
} :
|
|
100
|
+
never;
|
|
101
|
+
|
|
102
|
+
type EventsResult<TEndpoint extends EventsEndpoint> = {
|
|
103
|
+
result: Array<{
|
|
104
|
+
timestamp: string,
|
|
105
|
+
store_id?: number,
|
|
106
|
+
resource?: string,
|
|
107
|
+
authentication_id?: ResourceId | null,
|
|
108
|
+
resource_id?: ResourceId,
|
|
109
|
+
action: string,
|
|
110
|
+
modified_fields: string[],
|
|
111
|
+
method?: number | undefined,
|
|
112
|
+
endpoint?: string,
|
|
113
|
+
body?: any,
|
|
114
|
+
ip?: string,
|
|
115
|
+
} & EventFieldsByEndpoint<TEndpoint>>,
|
|
116
|
+
meta: BaseListResultMeta,
|
|
117
|
+
};
|
|
43
118
|
|
|
44
|
-
type ResponseBody<
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
119
|
+
type ResponseBody<TConfig extends Config> =
|
|
120
|
+
TConfig['method'] extends 'post' ? { _id: ResourceId } :
|
|
121
|
+
TConfig['method'] extends 'put' | 'patch' | 'delete' ? null :
|
|
122
|
+
// method?: 'get'
|
|
123
|
+
TConfig['endpoint'] extends `products/${ResourceId}` ? Products :
|
|
124
|
+
TConfig['endpoint'] extends `categories/${ResourceId}` ? Categories :
|
|
125
|
+
TConfig['endpoint'] extends `brands/${ResourceId}` ? Brands :
|
|
126
|
+
TConfig['endpoint'] extends `collections/${ResourceId}` ? Collections :
|
|
127
|
+
TConfig['endpoint'] extends `grids/${ResourceId}` ? Grids :
|
|
128
|
+
TConfig['endpoint'] extends `carts/${ResourceId}` ? Carts :
|
|
129
|
+
TConfig['endpoint'] extends `orders/${ResourceId}` ? Orders :
|
|
130
|
+
TConfig['endpoint'] extends `customers/${ResourceId}` ? Customers :
|
|
131
|
+
TConfig['endpoint'] extends `stores/${ResourceId}` ? Stores :
|
|
132
|
+
TConfig['endpoint'] extends `applications/${ResourceId}` ? Applications :
|
|
133
|
+
TConfig['endpoint'] extends Resource ? ResourceListResult<TConfig['endpoint']> :
|
|
134
|
+
TConfig['endpoint'] extends EventsEndpoint ? EventsResult<TConfig['endpoint']> :
|
|
135
|
+
any;
|
|
58
136
|
|
|
59
137
|
export type {
|
|
60
138
|
Products,
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
import { test, expect } from 'vitest';
|
|
4
4
|
import './fetch-polyfill';
|
|
5
|
-
import api from '../src/index';
|
|
5
|
+
import api, { ApiError } from '../src/index';
|
|
6
6
|
|
|
7
7
|
const productId = '618041aa239b7206d3fc06de';
|
|
8
8
|
test('Read product and typecheck SKU', async () => {
|
|
@@ -23,8 +23,32 @@ test('404 with different Store ID from env', async () => {
|
|
|
23
23
|
const { data } = await api.get(`products/${productId}`);
|
|
24
24
|
console.log(data);
|
|
25
25
|
throw new Error('Should have thrown not found');
|
|
26
|
-
} catch (
|
|
26
|
+
} catch (err: any) {
|
|
27
|
+
const error = err as ApiError;
|
|
27
28
|
expect(error.statusCode).toBe(404);
|
|
28
29
|
expect(error.response?.status).toBe(404);
|
|
29
30
|
}
|
|
30
31
|
});
|
|
32
|
+
|
|
33
|
+
test('List categories and typecheck result', async () => {
|
|
34
|
+
const { data } = await api.get('categories');
|
|
35
|
+
if (data.result === []) {
|
|
36
|
+
console.log('Any category found');
|
|
37
|
+
}
|
|
38
|
+
expect(Array.isArray(data.result)).toBe(true);
|
|
39
|
+
expect(data.meta).toBeTypeOf('object');
|
|
40
|
+
expect(data.meta.offset).toBeTypeOf('number');
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
test('401 trying to list API events', async () => {
|
|
44
|
+
try {
|
|
45
|
+
const { data } = await api.get('events/orders');
|
|
46
|
+
console.log(data);
|
|
47
|
+
console.log(data.result[0].modified_fields);
|
|
48
|
+
throw new Error('Should have thrown unauthorized');
|
|
49
|
+
} catch (err: any) {
|
|
50
|
+
const error = err as ApiError;
|
|
51
|
+
expect(error.statusCode).toBe(401);
|
|
52
|
+
expect(error.response?.status).toBe(401);
|
|
53
|
+
}
|
|
54
|
+
});
|