cloudcommerce 0.0.3 → 0.0.6
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/CHANGELOG.md +28 -0
- package/package.json +5 -2
- package/packages/api/lib/index.d.ts +134 -0
- package/packages/api/lib/index.js +100 -0
- package/packages/api/lib/index.js.map +1 -0
- package/packages/api/{dist → lib}/types/applications.d.ts +0 -0
- package/packages/api/{dist → lib}/types/authentications.d.ts +0 -0
- package/packages/api/{dist → lib}/types/brands.d.ts +0 -0
- package/packages/api/{dist → lib}/types/carts.d.ts +0 -0
- package/packages/api/{dist → lib}/types/categories.d.ts +0 -0
- package/packages/api/{dist → lib}/types/collections.d.ts +0 -0
- package/packages/api/{dist → lib}/types/customers.d.ts +0 -0
- package/packages/api/{dist → lib}/types/grids.d.ts +0 -0
- package/packages/api/{dist → lib}/types/orders.d.ts +0 -0
- package/packages/api/{dist → lib}/types/products.d.ts +0 -0
- package/packages/api/{dist → lib}/types/stores.d.ts +0 -0
- package/packages/api/{dist → lib}/types.d.ts +7 -32
- package/packages/api/lib/types.js +2 -0
- package/packages/api/{dist → lib}/types.js.map +0 -0
- package/packages/api/package.json +5 -5
- package/packages/api/scripts/build.sh +6 -0
- package/packages/api/src/index.ts +45 -28
- package/packages/api/src/types.ts +14 -11
- package/packages/api/tests/fetch-polyfill.js +21 -0
- package/packages/api/tests/index.test.ts +30 -0
- package/packages/api/tsconfig.json +6 -0
- package/packages/apps/discounts/package.json +1 -1
- package/packages/storefront/package.json +3 -2
- package/tsconfig.json +2 -1
- package/tsconfig.test.json +11 -0
- package/turbo.json +6 -1
- package/vite.config.ts +12 -0
- package/packages/api/dist/index.d.ts +0 -65
- package/packages/api/dist/index.js +0 -91
- package/packages/api/dist/index.js.map +0 -1
- package/packages/api/dist/types/procedures.d.ts +0 -139
- package/packages/api/dist/types/triggers.d.ts +0 -79
- package/packages/api/dist/types.js +0 -2
- package/packages/api/scripts/build.mjs +0 -5
- package/packages/api/src/types/procedures.d.ts +0 -139
- package/packages/api/src/types/triggers.d.ts +0 -79
- package/packages/api/tests/types.test.ts +0 -13
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,34 @@
|
|
|
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.6](https://github.com/ecomplus/cloud-commerce/compare/v0.0.5...v0.0.6) (2022-06-16)
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
### Features
|
|
9
|
+
|
|
10
|
+
* **api:** New config option `maxRetries` (default 3) to retry on 429 and 5xx errors ([35c5287](https://github.com/ecomplus/cloud-commerce/commit/35c5287545a79bd15596f96e88bdb7d98c056183))
|
|
11
|
+
|
|
12
|
+
### [0.0.5](https://github.com/ecomplus/cloud-commerce/compare/v0.0.4...v0.0.5) (2022-06-16)
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
### Features
|
|
16
|
+
|
|
17
|
+
* **api:** Error object (not 2xx) includes `statusCode` property (as Fastify errors) ([a9681f2](https://github.com/ecomplus/cloud-commerce/commit/a9681f23ceb9b007f90e95351ca133fdac865f1b))
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
### Bug Fixes
|
|
21
|
+
|
|
22
|
+
* **api:** Config object is optional on abstracted method functions ([2eebbe7](https://github.com/ecomplus/cloud-commerce/commit/2eebbe771971b5ac87b85f6068a36d7e1f647aba))
|
|
23
|
+
* **api:** Resolve with resource type on read without method (get is default) ([52b1a9b](https://github.com/ecomplus/cloud-commerce/commit/52b1a9b7cb48210b155ac620eaa6b3c8d95d681e))
|
|
24
|
+
|
|
25
|
+
### [0.0.4](https://github.com/ecomplus/cloud-commerce/compare/v0.0.3...v0.0.4) (2022-06-15)
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
### Bug Fixes
|
|
29
|
+
|
|
30
|
+
* **api:** Fix adding `:storeId` to default API base URL ([d424760](https://github.com/ecomplus/cloud-commerce/commit/d4247602168078acc0b05f5d1bbf5980f636bd71))
|
|
31
|
+
* **api:** No `procedures` and `triggers` resources on Store API v2 (remove from default types) ([66281d4](https://github.com/ecomplus/cloud-commerce/commit/66281d41f25a707fabda2233d2404724ba6b53f4))
|
|
32
|
+
|
|
5
33
|
### [0.0.3](https://github.com/ecomplus/cloud-commerce/compare/v0.0.2...v0.0.3) (2022-06-14)
|
|
6
34
|
|
|
7
35
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cloudcommerce",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.6",
|
|
4
4
|
"description": "Open fair-code headless commerce platform: API-first, microservices based, event driven and cloud native",
|
|
5
5
|
"main": "src/index.js",
|
|
6
6
|
"author": "E-Com Club Softwares para E-commerce <ti@e-com.club>",
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
"postinstall": "husky install",
|
|
14
14
|
"build": "turbo run build",
|
|
15
15
|
"test": "turbo run test",
|
|
16
|
-
"release": "pnpm build && standard-version --commit-all",
|
|
16
|
+
"release": "pnpm build && pnpm test && standard-version --commit-all",
|
|
17
17
|
"postpublish": "zx scripts/release.mjs --publish"
|
|
18
18
|
},
|
|
19
19
|
"standard-version": {
|
|
@@ -34,9 +34,12 @@
|
|
|
34
34
|
"eslint-plugin-import": "^2.26.0",
|
|
35
35
|
"eslint-plugin-vue": "^9.1.1",
|
|
36
36
|
"husky": "^8.0.1",
|
|
37
|
+
"node-fetch": "^3.2.6",
|
|
37
38
|
"standard-version": "^9.5.0",
|
|
38
39
|
"turbo": "^1.2.16",
|
|
39
40
|
"typescript": "^4.7.3",
|
|
41
|
+
"vite": "^2.9.12",
|
|
42
|
+
"vitest": "^0.15.1",
|
|
40
43
|
"zx": "^6.2.5"
|
|
41
44
|
}
|
|
42
45
|
}
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
import type { Endpoint, Config, ResponseBody } from './types';
|
|
2
|
+
declare const def: {
|
|
3
|
+
middleware(config: Config): string;
|
|
4
|
+
};
|
|
5
|
+
declare const setMiddleware: (middleware: (config: Config) => string) => void;
|
|
6
|
+
declare const api: {
|
|
7
|
+
<T extends Config>(config: T, retries?: number): Promise<Response & {
|
|
8
|
+
config: Config;
|
|
9
|
+
data: ResponseBody<T>;
|
|
10
|
+
}>;
|
|
11
|
+
get: <E extends Endpoint, C extends AbstractedConfig>(endpoint: E, config?: C | undefined) => Promise<Response & {
|
|
12
|
+
config: Config;
|
|
13
|
+
data: {
|
|
14
|
+
endpoint: E;
|
|
15
|
+
} extends infer T_1 ? T_1 extends {
|
|
16
|
+
endpoint: E;
|
|
17
|
+
} ? T_1 extends Config & {
|
|
18
|
+
method?: "get" | undefined;
|
|
19
|
+
endpoint: `products/${string}`;
|
|
20
|
+
} ? import("./types").Products : T_1 extends Config & {
|
|
21
|
+
method?: "get" | undefined;
|
|
22
|
+
endpoint: `categories/${string}`;
|
|
23
|
+
} ? import("./types").Categories : T_1 extends Config & {
|
|
24
|
+
method?: "get" | undefined;
|
|
25
|
+
endpoint: `brands/${string}`;
|
|
26
|
+
} ? import("./types").Brands : T_1 extends Config & {
|
|
27
|
+
method?: "get" | undefined;
|
|
28
|
+
endpoint: `collections/${string}`;
|
|
29
|
+
} ? import("./types").Collections : T_1 extends Config & {
|
|
30
|
+
method?: "get" | undefined;
|
|
31
|
+
endpoint: `grids/${string}`;
|
|
32
|
+
} ? import("./types").Grids : T_1 extends Config & {
|
|
33
|
+
method?: "get" | undefined;
|
|
34
|
+
endpoint: `carts/${string}`;
|
|
35
|
+
} ? import("./types").Carts : T_1 extends Config & {
|
|
36
|
+
method?: "get" | undefined;
|
|
37
|
+
endpoint: `orders/${string}`;
|
|
38
|
+
} ? import("./types").Orders : T_1 extends Config & {
|
|
39
|
+
method?: "get" | undefined;
|
|
40
|
+
endpoint: `customers/${string}`;
|
|
41
|
+
} ? import("./types").Customers : T_1 extends Config & {
|
|
42
|
+
method?: "get" | undefined;
|
|
43
|
+
endpoint: `stores/${string}`;
|
|
44
|
+
} ? import("./types").Stores : T_1 extends Config & {
|
|
45
|
+
method?: "get" | undefined;
|
|
46
|
+
endpoint: `applications/${string}`;
|
|
47
|
+
} ? import("./types").Applications : any : never : never;
|
|
48
|
+
}>;
|
|
49
|
+
post: (endpoint: Endpoint, config?: AbstractedConfig) => Promise<Response & {
|
|
50
|
+
config: Config;
|
|
51
|
+
data: {
|
|
52
|
+
_id: string & {
|
|
53
|
+
length: 24;
|
|
54
|
+
};
|
|
55
|
+
};
|
|
56
|
+
}>;
|
|
57
|
+
put: (endpoint: Endpoint, config?: AbstractedConfig) => Promise<Response & {
|
|
58
|
+
config: Config;
|
|
59
|
+
data: null;
|
|
60
|
+
}>;
|
|
61
|
+
patch: (endpoint: Endpoint, config?: AbstractedConfig) => Promise<Response & {
|
|
62
|
+
config: Config;
|
|
63
|
+
data: null;
|
|
64
|
+
}>;
|
|
65
|
+
del: (endpoint: Endpoint, config?: AbstractedConfig) => Promise<Response & {
|
|
66
|
+
config: Config;
|
|
67
|
+
data: null;
|
|
68
|
+
}>;
|
|
69
|
+
delete: (endpoint: Endpoint, config?: AbstractedConfig) => Promise<Response & {
|
|
70
|
+
config: Config;
|
|
71
|
+
data: null;
|
|
72
|
+
}>;
|
|
73
|
+
};
|
|
74
|
+
declare type AbstractedConfig = Omit<Config, 'endpoint' | 'method'>;
|
|
75
|
+
declare const get: <E extends Endpoint, C extends AbstractedConfig>(endpoint: E, config?: C | undefined) => Promise<Response & {
|
|
76
|
+
config: Config;
|
|
77
|
+
data: {
|
|
78
|
+
endpoint: E;
|
|
79
|
+
} extends infer T_1 ? T_1 extends {
|
|
80
|
+
endpoint: E;
|
|
81
|
+
} ? T_1 extends Config & {
|
|
82
|
+
method?: "get" | undefined;
|
|
83
|
+
endpoint: `products/${string}`;
|
|
84
|
+
} ? import("./types").Products : T_1 extends Config & {
|
|
85
|
+
method?: "get" | undefined;
|
|
86
|
+
endpoint: `categories/${string}`;
|
|
87
|
+
} ? import("./types").Categories : T_1 extends Config & {
|
|
88
|
+
method?: "get" | undefined;
|
|
89
|
+
endpoint: `brands/${string}`;
|
|
90
|
+
} ? import("./types").Brands : T_1 extends Config & {
|
|
91
|
+
method?: "get" | undefined;
|
|
92
|
+
endpoint: `collections/${string}`;
|
|
93
|
+
} ? import("./types").Collections : T_1 extends Config & {
|
|
94
|
+
method?: "get" | undefined;
|
|
95
|
+
endpoint: `grids/${string}`;
|
|
96
|
+
} ? import("./types").Grids : T_1 extends Config & {
|
|
97
|
+
method?: "get" | undefined;
|
|
98
|
+
endpoint: `carts/${string}`;
|
|
99
|
+
} ? import("./types").Carts : T_1 extends Config & {
|
|
100
|
+
method?: "get" | undefined;
|
|
101
|
+
endpoint: `orders/${string}`;
|
|
102
|
+
} ? import("./types").Orders : T_1 extends Config & {
|
|
103
|
+
method?: "get" | undefined;
|
|
104
|
+
endpoint: `customers/${string}`;
|
|
105
|
+
} ? import("./types").Customers : T_1 extends Config & {
|
|
106
|
+
method?: "get" | undefined;
|
|
107
|
+
endpoint: `stores/${string}`;
|
|
108
|
+
} ? import("./types").Stores : T_1 extends Config & {
|
|
109
|
+
method?: "get" | undefined;
|
|
110
|
+
endpoint: `applications/${string}`;
|
|
111
|
+
} ? import("./types").Applications : any : never : never;
|
|
112
|
+
}>;
|
|
113
|
+
declare const post: (endpoint: Endpoint, config?: AbstractedConfig) => Promise<Response & {
|
|
114
|
+
config: Config;
|
|
115
|
+
data: {
|
|
116
|
+
_id: string & {
|
|
117
|
+
length: 24;
|
|
118
|
+
};
|
|
119
|
+
};
|
|
120
|
+
}>;
|
|
121
|
+
declare const put: (endpoint: Endpoint, config?: AbstractedConfig) => Promise<Response & {
|
|
122
|
+
config: Config;
|
|
123
|
+
data: null;
|
|
124
|
+
}>;
|
|
125
|
+
declare const patch: (endpoint: Endpoint, config?: AbstractedConfig) => Promise<Response & {
|
|
126
|
+
config: Config;
|
|
127
|
+
data: null;
|
|
128
|
+
}>;
|
|
129
|
+
declare const del: (endpoint: Endpoint, config?: AbstractedConfig) => Promise<Response & {
|
|
130
|
+
config: Config;
|
|
131
|
+
data: null;
|
|
132
|
+
}>;
|
|
133
|
+
export default api;
|
|
134
|
+
export { setMiddleware, get, post, put, patch, del, };
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
// @ts-ignore
|
|
2
|
+
const env = (typeof window === 'object' && window)
|
|
3
|
+
|| (typeof process === 'object' && process && process.env)
|
|
4
|
+
|| {};
|
|
5
|
+
const def = {
|
|
6
|
+
middleware(config) {
|
|
7
|
+
let url = config.baseUrl || env.API_BASE_URL || 'https://ecomplus.io/v2';
|
|
8
|
+
const storeId = config.storeId || env.ECOM_STORE_ID;
|
|
9
|
+
if (!storeId) {
|
|
10
|
+
throw new Error('`storeId` must be set in config or `ECOM_STORE_ID` env var');
|
|
11
|
+
}
|
|
12
|
+
url += `/:${storeId}`;
|
|
13
|
+
const lang = config.lang || env.ECOM_LANG;
|
|
14
|
+
if (lang) {
|
|
15
|
+
url += `,lang:${lang}`;
|
|
16
|
+
}
|
|
17
|
+
if (config.params) {
|
|
18
|
+
if (typeof config.params === 'string') {
|
|
19
|
+
url += `?${config.params}`;
|
|
20
|
+
} else {
|
|
21
|
+
// https://github.com/microsoft/TypeScript/issues/32951
|
|
22
|
+
url += `?${new URLSearchParams(config.params)}`;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
return `${url}/${config.endpoint}`;
|
|
26
|
+
},
|
|
27
|
+
};
|
|
28
|
+
// eslint-disable-next-line no-unused-vars
|
|
29
|
+
const setMiddleware = (middleware) => {
|
|
30
|
+
def.middleware = middleware;
|
|
31
|
+
};
|
|
32
|
+
const api = async (config, retries = 0) => {
|
|
33
|
+
const url = def.middleware(config);
|
|
34
|
+
const {
|
|
35
|
+
method, headers, timeout = 20000, maxRetries = 3,
|
|
36
|
+
} = config;
|
|
37
|
+
const abortController = new AbortController();
|
|
38
|
+
const timer = setTimeout(() => abortController.abort(), timeout);
|
|
39
|
+
const response = await fetch(url, {
|
|
40
|
+
method,
|
|
41
|
+
headers,
|
|
42
|
+
signal: abortController.signal,
|
|
43
|
+
});
|
|
44
|
+
clearTimeout(timer);
|
|
45
|
+
if (response.ok) {
|
|
46
|
+
return {
|
|
47
|
+
...response,
|
|
48
|
+
config,
|
|
49
|
+
data: await response.json(),
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
const { status } = response;
|
|
53
|
+
if (maxRetries < retries && (status === 429 || status >= 500)) {
|
|
54
|
+
const retryAfter = response.headers.get('retry-after');
|
|
55
|
+
return new Promise((resolve, reject) => {
|
|
56
|
+
setTimeout(() => {
|
|
57
|
+
api(config, retries + 1).then(resolve).catch(reject);
|
|
58
|
+
}, (retryAfter && parseInt(retryAfter, 10)) || 5000);
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
const error = new Error(response.statusText);
|
|
62
|
+
error.config = config;
|
|
63
|
+
error.response = response;
|
|
64
|
+
error.statusCode = status;
|
|
65
|
+
throw error;
|
|
66
|
+
};
|
|
67
|
+
const get = (endpoint, config) => api({ ...config, endpoint });
|
|
68
|
+
const post = (endpoint, config) => api({
|
|
69
|
+
...config,
|
|
70
|
+
method: 'post',
|
|
71
|
+
endpoint,
|
|
72
|
+
});
|
|
73
|
+
const put = (endpoint, config) => api({
|
|
74
|
+
...config,
|
|
75
|
+
method: 'put',
|
|
76
|
+
endpoint,
|
|
77
|
+
});
|
|
78
|
+
const patch = (endpoint, config) => api({
|
|
79
|
+
...config,
|
|
80
|
+
method: 'patch',
|
|
81
|
+
endpoint,
|
|
82
|
+
});
|
|
83
|
+
const del = (endpoint, config) => api({
|
|
84
|
+
...config,
|
|
85
|
+
method: 'delete',
|
|
86
|
+
endpoint,
|
|
87
|
+
});
|
|
88
|
+
api.get = get;
|
|
89
|
+
api.post = post;
|
|
90
|
+
api.put = put;
|
|
91
|
+
api.patch = patch;
|
|
92
|
+
api.del = del;
|
|
93
|
+
api.delete = del;
|
|
94
|
+
|
|
95
|
+
export default api;
|
|
96
|
+
|
|
97
|
+
export {
|
|
98
|
+
setMiddleware, get, post, put, patch, del,
|
|
99
|
+
};
|
|
100
|
+
// # sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
@@ -19,11 +19,16 @@ declare type Config = {
|
|
|
19
19
|
baseUrl?: string;
|
|
20
20
|
storeId?: number;
|
|
21
21
|
lang?: string;
|
|
22
|
-
method
|
|
22
|
+
method?: Method;
|
|
23
23
|
endpoint: Endpoint;
|
|
24
24
|
params?: Record<string, string | number>;
|
|
25
25
|
headers?: Record<string, string>;
|
|
26
26
|
timeout?: number;
|
|
27
|
+
maxRetries?: number;
|
|
28
|
+
};
|
|
29
|
+
declare type ReadConfig<endpoint> = Config & {
|
|
30
|
+
method?: 'get';
|
|
31
|
+
endpoint: endpoint;
|
|
27
32
|
};
|
|
28
33
|
declare type ResponseBody<T> = T extends Config & {
|
|
29
34
|
method: 'post';
|
|
@@ -31,35 +36,5 @@ declare type ResponseBody<T> = T extends Config & {
|
|
|
31
36
|
_id: ResourceId;
|
|
32
37
|
} : T extends Config & {
|
|
33
38
|
method: 'put' | 'patch' | 'delete';
|
|
34
|
-
} ? null : T extends
|
|
35
|
-
method: 'get';
|
|
36
|
-
endpoint: `products/${ResourceId}`;
|
|
37
|
-
} ? Products : T extends Config & {
|
|
38
|
-
method: 'get';
|
|
39
|
-
endpoint: `categories/${ResourceId}`;
|
|
40
|
-
} ? Categories : T extends Config & {
|
|
41
|
-
method: 'get';
|
|
42
|
-
endpoint: `brands/${ResourceId}`;
|
|
43
|
-
} ? Brands : T extends Config & {
|
|
44
|
-
method: 'get';
|
|
45
|
-
endpoint: `collections/${ResourceId}`;
|
|
46
|
-
} ? Collections : T extends Config & {
|
|
47
|
-
method: 'get';
|
|
48
|
-
endpoint: `grids/${ResourceId}`;
|
|
49
|
-
} ? Grids : T extends Config & {
|
|
50
|
-
method: 'get';
|
|
51
|
-
endpoint: `carts/${ResourceId}`;
|
|
52
|
-
} ? Carts : T extends Config & {
|
|
53
|
-
method: 'get';
|
|
54
|
-
endpoint: `orders/${ResourceId}`;
|
|
55
|
-
} ? Orders : T extends Config & {
|
|
56
|
-
method: 'get';
|
|
57
|
-
endpoint: `customers/${ResourceId}`;
|
|
58
|
-
} ? Customers : T extends Config & {
|
|
59
|
-
method: 'get';
|
|
60
|
-
endpoint: `stores/${ResourceId}`;
|
|
61
|
-
} ? Stores : T extends Config & {
|
|
62
|
-
method: 'get';
|
|
63
|
-
endpoint: `applications/${ResourceId}`;
|
|
64
|
-
} ? Applications : any;
|
|
39
|
+
} ? 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;
|
|
65
40
|
export type { Products, Categories, Brands, Collections, Grids, Carts, Orders, Customers, Stores, Applications, Resource, ResourceAndId, Endpoint, Method, Config, ResponseBody, };
|
|
File without changes
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cloudcommerce/api",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.6",
|
|
4
4
|
"description": "E-Com Plus Cloud Commerce APIs client/adapter",
|
|
5
|
-
"main": "
|
|
6
|
-
"types": "
|
|
5
|
+
"main": "lib/index.js",
|
|
6
|
+
"types": "lib/index.d.ts",
|
|
7
7
|
"repository": {
|
|
8
8
|
"type": "git",
|
|
9
9
|
"url": "git+https://github.com/ecomplus/cloud-commerce.git",
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
},
|
|
17
17
|
"homepage": "https://github.com/ecomplus/cloud-commerce/tree/main/packages/api#readme",
|
|
18
18
|
"scripts": {
|
|
19
|
-
"build": "
|
|
20
|
-
"test": "tsc
|
|
19
|
+
"build": "sh scripts/build.sh",
|
|
20
|
+
"test": "tsc -p ../../tsconfig.test.json && vitest run"
|
|
21
21
|
}
|
|
22
22
|
}
|
|
@@ -8,16 +8,14 @@ const env: { [key: string]: string } = (typeof window === 'object' && window)
|
|
|
8
8
|
const def = {
|
|
9
9
|
middleware(config: Config) {
|
|
10
10
|
let url = config.baseUrl || env.API_BASE_URL || 'https://ecomplus.io/v2';
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
url += `,lang:${lang}`;
|
|
20
|
-
}
|
|
11
|
+
const storeId = config.storeId || env.ECOM_STORE_ID;
|
|
12
|
+
if (!storeId) {
|
|
13
|
+
throw new Error('`storeId` must be set in config or `ECOM_STORE_ID` env var');
|
|
14
|
+
}
|
|
15
|
+
url += `/:${storeId}`;
|
|
16
|
+
const lang = config.lang || env.ECOM_LANG;
|
|
17
|
+
if (lang) {
|
|
18
|
+
url += `,lang:${lang}`;
|
|
21
19
|
}
|
|
22
20
|
if (config.params) {
|
|
23
21
|
if (typeof config.params === 'string') {
|
|
@@ -36,12 +34,17 @@ const setMiddleware = (middleware: typeof def.middleware) => {
|
|
|
36
34
|
def.middleware = middleware;
|
|
37
35
|
};
|
|
38
36
|
|
|
39
|
-
const
|
|
37
|
+
const api = async <T extends Config>(config: T, retries = 0): Promise<Response & {
|
|
40
38
|
config: Config,
|
|
41
39
|
data: ResponseBody<T>,
|
|
42
40
|
}> => {
|
|
43
41
|
const url = def.middleware(config);
|
|
44
|
-
const {
|
|
42
|
+
const {
|
|
43
|
+
method,
|
|
44
|
+
headers,
|
|
45
|
+
timeout = 20000,
|
|
46
|
+
maxRetries = 3,
|
|
47
|
+
} = config;
|
|
45
48
|
const abortController = new AbortController();
|
|
46
49
|
const timer = setTimeout(() => abortController.abort(), timeout);
|
|
47
50
|
const response = await fetch(url, {
|
|
@@ -57,50 +60,64 @@ const callApi = async <T extends Config>(config: T): Promise<Response & {
|
|
|
57
60
|
data: await response.json(),
|
|
58
61
|
};
|
|
59
62
|
}
|
|
63
|
+
const { status } = response;
|
|
64
|
+
if (maxRetries < retries && (status === 429 || status >= 500)) {
|
|
65
|
+
const retryAfter = response.headers.get('retry-after');
|
|
66
|
+
return new Promise((resolve, reject) => {
|
|
67
|
+
setTimeout(() => {
|
|
68
|
+
api(config, retries + 1).then(resolve).catch(reject);
|
|
69
|
+
}, (retryAfter && parseInt(retryAfter, 10)) || 5000);
|
|
70
|
+
});
|
|
71
|
+
}
|
|
60
72
|
const error: any = new Error(response.statusText);
|
|
61
73
|
error.config = config;
|
|
62
74
|
error.response = response;
|
|
75
|
+
error.statusCode = status;
|
|
63
76
|
throw error;
|
|
64
77
|
};
|
|
65
78
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
endpoint,
|
|
70
|
-
|
|
79
|
+
type AbstractedConfig = Omit<Config, 'endpoint' | 'method'>;
|
|
80
|
+
|
|
81
|
+
const get = <E extends Endpoint, C extends AbstractedConfig>(
|
|
82
|
+
endpoint: E,
|
|
83
|
+
config?: C,
|
|
84
|
+
): Promise<Response & {
|
|
85
|
+
config: Config,
|
|
86
|
+
data: ResponseBody<{ endpoint: E }>,
|
|
87
|
+
}> => api({ ...config, endpoint });
|
|
71
88
|
|
|
72
|
-
const post = (endpoint: Endpoint, config
|
|
89
|
+
const post = (endpoint: Endpoint, config?: AbstractedConfig) => api({
|
|
73
90
|
...config,
|
|
74
91
|
method: 'post',
|
|
75
92
|
endpoint,
|
|
76
93
|
});
|
|
77
94
|
|
|
78
|
-
const put = (endpoint: Endpoint, config
|
|
95
|
+
const put = (endpoint: Endpoint, config?: AbstractedConfig) => api({
|
|
79
96
|
...config,
|
|
80
97
|
method: 'put',
|
|
81
98
|
endpoint,
|
|
82
99
|
});
|
|
83
100
|
|
|
84
|
-
const patch = (endpoint: Endpoint, config
|
|
101
|
+
const patch = (endpoint: Endpoint, config?: AbstractedConfig) => api({
|
|
85
102
|
...config,
|
|
86
103
|
method: 'patch',
|
|
87
104
|
endpoint,
|
|
88
105
|
});
|
|
89
106
|
|
|
90
|
-
const del = (endpoint: Endpoint, config
|
|
107
|
+
const del = (endpoint: Endpoint, config?: AbstractedConfig) => api({
|
|
91
108
|
...config,
|
|
92
109
|
method: 'delete',
|
|
93
110
|
endpoint,
|
|
94
111
|
});
|
|
95
112
|
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
113
|
+
api.get = get;
|
|
114
|
+
api.post = post;
|
|
115
|
+
api.put = put;
|
|
116
|
+
api.patch = patch;
|
|
117
|
+
api.del = del;
|
|
118
|
+
api.delete = del;
|
|
102
119
|
|
|
103
|
-
export default
|
|
120
|
+
export default api;
|
|
104
121
|
|
|
105
122
|
export {
|
|
106
123
|
setMiddleware,
|
|
@@ -32,26 +32,29 @@ type Config = {
|
|
|
32
32
|
baseUrl?: string,
|
|
33
33
|
storeId?: number,
|
|
34
34
|
lang?: string,
|
|
35
|
-
method
|
|
35
|
+
method?: Method,
|
|
36
36
|
endpoint: Endpoint,
|
|
37
37
|
params?: Record<string, string | number>,
|
|
38
38
|
headers?: Record<string, string>,
|
|
39
39
|
timeout?: number,
|
|
40
|
+
maxRetries?: number,
|
|
40
41
|
};
|
|
41
42
|
|
|
43
|
+
type ReadConfig<endpoint> = Config & { method?: 'get', endpoint: endpoint };
|
|
44
|
+
|
|
42
45
|
type ResponseBody<T> =
|
|
43
46
|
T extends Config & { method: 'post' } ? { _id: ResourceId } :
|
|
44
47
|
T extends Config & { method: 'put' | 'patch' | 'delete' } ? null :
|
|
45
|
-
T extends
|
|
46
|
-
T extends
|
|
47
|
-
T extends
|
|
48
|
-
T extends
|
|
49
|
-
T extends
|
|
50
|
-
T extends
|
|
51
|
-
T extends
|
|
52
|
-
T extends
|
|
53
|
-
T extends
|
|
54
|
-
T extends
|
|
48
|
+
T extends ReadConfig<`products/${ResourceId}`> ? Products :
|
|
49
|
+
T extends ReadConfig<`categories/${ResourceId}`> ? Categories :
|
|
50
|
+
T extends ReadConfig<`brands/${ResourceId}`> ? Brands :
|
|
51
|
+
T extends ReadConfig<`collections/${ResourceId}`> ? Collections :
|
|
52
|
+
T extends ReadConfig<`grids/${ResourceId}`> ? Grids :
|
|
53
|
+
T extends ReadConfig<`carts/${ResourceId}`> ? Carts :
|
|
54
|
+
T extends ReadConfig<`orders/${ResourceId}`> ? Orders :
|
|
55
|
+
T extends ReadConfig<`customers/${ResourceId}`> ? Customers :
|
|
56
|
+
T extends ReadConfig<`stores/${ResourceId}`> ? Stores :
|
|
57
|
+
T extends ReadConfig<`applications/${ResourceId}`> ? Applications :
|
|
55
58
|
any
|
|
56
59
|
|
|
57
60
|
export type {
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/* eslint-disable import/no-extraneous-dependencies, no-unused-vars */
|
|
2
|
+
|
|
3
|
+
import fetch, {
|
|
4
|
+
Blob,
|
|
5
|
+
blobFrom,
|
|
6
|
+
blobFromSync,
|
|
7
|
+
File,
|
|
8
|
+
fileFrom,
|
|
9
|
+
fileFromSync,
|
|
10
|
+
FormData,
|
|
11
|
+
Headers,
|
|
12
|
+
Request,
|
|
13
|
+
Response,
|
|
14
|
+
} from 'node-fetch';
|
|
15
|
+
|
|
16
|
+
if (!globalThis.fetch) {
|
|
17
|
+
globalThis.fetch = fetch;
|
|
18
|
+
globalThis.Headers = Headers;
|
|
19
|
+
globalThis.Request = Request;
|
|
20
|
+
globalThis.Response = Response;
|
|
21
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/* eslint-disable no-console, import/no-extraneous-dependencies */
|
|
2
|
+
|
|
3
|
+
import { test, expect } from 'vitest';
|
|
4
|
+
import './fetch-polyfill';
|
|
5
|
+
import api from '../src/index';
|
|
6
|
+
|
|
7
|
+
const productId = '618041aa239b7206d3fc06de';
|
|
8
|
+
test('Read product and typecheck SKU', async () => {
|
|
9
|
+
const { data } = await api({
|
|
10
|
+
storeId: 1056,
|
|
11
|
+
endpoint: `products/${productId}`,
|
|
12
|
+
});
|
|
13
|
+
if (data.sku === '123') {
|
|
14
|
+
console.log('\\o/');
|
|
15
|
+
}
|
|
16
|
+
expect(data.sku).toBeTypeOf('string');
|
|
17
|
+
expect(data._id).toBe(productId);
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
test('404 with different Store ID from env', async () => {
|
|
21
|
+
process.env.ECOM_STORE_ID = '1011';
|
|
22
|
+
try {
|
|
23
|
+
const { data } = await api.get(`products/${productId}`);
|
|
24
|
+
console.log(data);
|
|
25
|
+
throw new Error('Should have thrown not found');
|
|
26
|
+
} catch (error: any) {
|
|
27
|
+
expect(error.statusCode).toBe(404);
|
|
28
|
+
expect(error.response?.status).toBe(404);
|
|
29
|
+
}
|
|
30
|
+
});
|