@cloudcommerce/api 0.0.4 → 0.0.7

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.
@@ -1,8 +1,5 @@
1
- @cloudcommerce/api:build: cache hit, replaying output 95f3926a68635b20
1
+ @cloudcommerce/api:build: cache hit, replaying output 756432504a36199f
2
2
  @cloudcommerce/api:build: 
3
- @cloudcommerce/api:build: > @cloudcommerce/api@0.0.3 build /home/leo/code/ecomplus/cloud-commerce/packages/api
4
- @cloudcommerce/api:build: > zx scripts/build.mjs
3
+ @cloudcommerce/api:build: > @cloudcommerce/api@0.0.6 build /home/leo/code/ecomplus/cloud-commerce/packages/api
4
+ @cloudcommerce/api:build: > sh scripts/build.sh
5
5
  @cloudcommerce/api:build: 
6
- @cloudcommerce/api:build: $ rm -rf dist
7
- @cloudcommerce/api:build: $ tsc -p ../../tsconfig.json --outDir dist --declaration
8
- @cloudcommerce/api:build: $ cp -r src/types dist/
@@ -1,8 +1,17 @@
1
- @cloudcommerce/api:test: cache hit, replaying output b689b985522783d4
1
+ @cloudcommerce/api:test: cache hit, replaying output 184b4517428fafcb
2
2
  @cloudcommerce/api:test: 
3
- @cloudcommerce/api:test: > @cloudcommerce/api@0.0.3 test /home/leo/code/ecomplus/cloud-commerce/packages/api
4
- @cloudcommerce/api:test: > zx scripts/test.mjs
3
+ @cloudcommerce/api:test: > @cloudcommerce/api@0.0.6 test /home/leo/code/ecomplus/cloud-commerce/packages/api
4
+ @cloudcommerce/api:test: > tsc -p ../../tsconfig.test.json && vitest run
5
+ @cloudcommerce/api:test: 
6
+ @cloudcommerce/api:test: 
7
+ @cloudcommerce/api:test:  RUN v0.15.2 /home/leo/code/ecomplus/cloud-commerce/packages/api
8
+ @cloudcommerce/api:test: 
9
+ @cloudcommerce/api:test:  ✓ tests/index.test.ts > Read product and typecheck SKU
10
+ @cloudcommerce/api:test:  ✓ tests/index.test.ts > 404 with different Store ID from env
11
+ @cloudcommerce/api:test:  ✓ tests/index.test.ts > List categories and typecheck result
12
+ @cloudcommerce/api:test:  ✓ tests/index.test.ts > 401 trying to list API events
13
+ @cloudcommerce/api:test: 
14
+ @cloudcommerce/api:test: Test Files 1 passed (1)
15
+ @cloudcommerce/api:test:  Tests 4 passed (4)
16
+ @cloudcommerce/api:test:  Time 2.31s (in thread 735ms, 314.45%)
5
17
  @cloudcommerce/api:test: 
6
- @cloudcommerce/api:test: $ tsc -p ../../tsconfig.test.json
7
- @cloudcommerce/api:test: $ tsx tests/index.test.ts
8
- @cloudcommerce/api:test: ✓ Read product GFJ4714 and checked SKU type string
package/lib/index.d.ts ADDED
@@ -0,0 +1,183 @@
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
+ }
9
+ declare const def: {
10
+ middleware(config: Config): string;
11
+ };
12
+ declare const setMiddleware: (middleware: (config: Config) => string) => void;
13
+ declare const api: {
14
+ <T extends Config>(config: T, retries?: number): Promise<Response & {
15
+ config: Config;
16
+ data: ResponseBody<T>;
17
+ }>;
18
+ get: <E extends Endpoint, C extends AbstractedConfig>(endpoint: E, config?: C | undefined) => Promise<Response & {
19
+ config: Config;
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;
76
+ }>;
77
+ post: (endpoint: Endpoint, config?: AbstractedConfig) => Promise<Response & {
78
+ config: Config;
79
+ data: {
80
+ _id: string & {
81
+ length: 24;
82
+ };
83
+ };
84
+ }>;
85
+ put: (endpoint: Endpoint, config?: AbstractedConfig) => Promise<Response & {
86
+ config: Config;
87
+ data: null;
88
+ }>;
89
+ patch: (endpoint: Endpoint, config?: AbstractedConfig) => Promise<Response & {
90
+ config: Config;
91
+ data: null;
92
+ }>;
93
+ del: (endpoint: Endpoint, config?: AbstractedConfig) => Promise<Response & {
94
+ config: Config;
95
+ data: null;
96
+ }>;
97
+ delete: (endpoint: Endpoint, config?: AbstractedConfig) => Promise<Response & {
98
+ config: Config;
99
+ data: null;
100
+ }>;
101
+ };
102
+ declare type AbstractedConfig = Omit<Config, 'endpoint' | 'method'>;
103
+ declare const get: <E extends Endpoint, C extends AbstractedConfig>(endpoint: E, config?: C | undefined) => Promise<Response & {
104
+ config: Config;
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;
161
+ }>;
162
+ declare const post: (endpoint: Endpoint, config?: AbstractedConfig) => Promise<Response & {
163
+ config: Config;
164
+ data: {
165
+ _id: string & {
166
+ length: 24;
167
+ };
168
+ };
169
+ }>;
170
+ declare const put: (endpoint: Endpoint, config?: AbstractedConfig) => Promise<Response & {
171
+ config: Config;
172
+ data: null;
173
+ }>;
174
+ declare const patch: (endpoint: Endpoint, config?: AbstractedConfig) => Promise<Response & {
175
+ config: Config;
176
+ data: null;
177
+ }>;
178
+ declare const del: (endpoint: Endpoint, config?: AbstractedConfig) => Promise<Response & {
179
+ config: Config;
180
+ data: null;
181
+ }>;
182
+ export default api;
183
+ export { setMiddleware, get, post, put, patch, del, ApiError, };
package/lib/index.js ADDED
@@ -0,0 +1,115 @@
1
+ // @ts-ignore
2
+ const env = (typeof window === 'object' && window)
3
+ || (typeof process === 'object' && process && process.env)
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
+ }
14
+ const def = {
15
+ middleware(config) {
16
+ let url = config.baseUrl || env.API_BASE_URL || 'https://ecomplus.io/v2';
17
+ const storeId = config.storeId || env.ECOM_STORE_ID;
18
+ if (!storeId) {
19
+ throw new Error('`storeId` must be set in config or `ECOM_STORE_ID` env var');
20
+ }
21
+ url += `/:${storeId}`;
22
+ const lang = config.lang || env.ECOM_LANG;
23
+ if (lang) {
24
+ url += `,lang:${lang}`;
25
+ }
26
+ if (config.params) {
27
+ if (typeof config.params === 'string') {
28
+ url += `?${config.params}`;
29
+ } else {
30
+ // https://github.com/microsoft/TypeScript/issues/32951
31
+ url += `?${new URLSearchParams(config.params)}`;
32
+ }
33
+ }
34
+ return `${url}/${config.endpoint}`;
35
+ },
36
+ };
37
+ const setMiddleware = (middleware) => {
38
+ def.middleware = middleware;
39
+ };
40
+ const api = async (config, retries = 0) => {
41
+ const url = def.middleware(config);
42
+ const {
43
+ method, headers, timeout = 20000, maxRetries = 3,
44
+ } = config;
45
+ const abortController = new AbortController();
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
+ }
61
+ clearTimeout(timer);
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
+ }
79
+ }
80
+ throw new ApiError(config, response);
81
+ };
82
+ const get = (endpoint, config) => api({ ...config, endpoint });
83
+ const post = (endpoint, config) => api({
84
+ ...config,
85
+ method: 'post',
86
+ endpoint,
87
+ });
88
+ const put = (endpoint, config) => api({
89
+ ...config,
90
+ method: 'put',
91
+ endpoint,
92
+ });
93
+ const patch = (endpoint, config) => api({
94
+ ...config,
95
+ method: 'patch',
96
+ endpoint,
97
+ });
98
+ const del = (endpoint, config) => api({
99
+ ...config,
100
+ method: 'delete',
101
+ endpoint,
102
+ });
103
+ api.get = get;
104
+ api.post = post;
105
+ api.put = put;
106
+ api.patch = patch;
107
+ api.del = del;
108
+ api.delete = del;
109
+
110
+ export default api;
111
+
112
+ export {
113
+ setMiddleware, get, post, put, patch, del, ApiError,
114
+ };
115
+ // # sourceMappingURL=index.js.map
@@ -0,0 +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,QAAS,SAAQ,KAAK;IAK1B,YAAY,MAAc,EAAE,QAAmB,EAAE,GAAY,EAAE,YAAqB,KAAK;QACvF,KAAK,CAAC,QAAQ,EAAE,UAAU,IAAI,GAAG,IAAI,eAAe,CAAC,CAAC;QACtD,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;QACzB,IAAI,CAAC,UAAU,GAAG,QAAQ,EAAE,MAAM,CAAC;QACnC,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;IAC7B,CAAC;CACF;AAED,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,MAAM,aAAa,GAAG,CAAC,UAAiC,EAAE,EAAE;IAC1D,GAAG,CAAC,UAAU,GAAG,UAAU,CAAC;AAC9B,CAAC,CAAC;AAEF,MAAM,GAAG,GAAG,KAAK,EAAoB,MAAS,EAAE,OAAO,GAAG,CAAC,EAGxD,EAAE;IACH,MAAM,GAAG,GAAG,GAAG,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;IACnC,MAAM,EACJ,MAAM,EACN,OAAO,EACP,OAAO,GAAG,KAAK,EACf,UAAU,GAAG,CAAC,GACf,GAAG,MAAM,CAAC;IACX,MAAM,eAAe,GAAG,IAAI,eAAe,EAAE,CAAC;IAC9C,IAAI,SAAS,GAAG,KAAK,CAAC;IACtB,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE;QAC5B,eAAe,CAAC,KAAK,EAAE,CAAC;QACxB,SAAS,GAAG,IAAI,CAAC;IACnB,CAAC,EAAE,OAAO,CAAC,CAAC;IACZ,IAAI,QAA8B,CAAC;IACnC,IAAI;QACF,QAAQ,GAAG,MAAM,CAAC,MAAM,CAAC,KAAK,IAAI,KAAK,CAAC,CAAC,GAAG,EAAE;YAC5C,MAAM;YACN,OAAO;YACP,MAAM,EAAE,eAAe,CAAC,MAAM;SAC/B,CAAC,CAAC;KACJ;IAAC,OAAO,GAAQ,EAAE;QACjB,MAAM,IAAI,QAAQ,CAAC,MAAM,EAAE,QAAQ,EAAE,GAAG,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC;KAC9D;IACD,YAAY,CAAC,KAAK,CAAC,CAAC;IACpB,IAAI,QAAQ,EAAE;QACZ,IAAI,QAAQ,CAAC,EAAE,EAAE;YACf,OAAO;gBACL,GAAG,QAAQ;gBACX,MAAM;gBACN,IAAI,EAAE,MAAM,QAAQ,CAAC,IAAI,EAAE;aAC5B,CAAC;SACH;QACD,MAAM,EAAE,MAAM,EAAE,GAAG,QAAQ,CAAC;QAC5B,IAAI,UAAU,GAAG,OAAO,IAAI,CAAC,MAAM,KAAK,GAAG,IAAI,MAAM,IAAI,GAAG,CAAC,EAAE;YAC7D,MAAM,UAAU,GAAG,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC;YACvD,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;gBACrC,UAAU,CAAC,GAAG,EAAE;oBACd,GAAG,CAAC,MAAM,EAAE,OAAO,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;gBACvD,CAAC,EAAE,CAAC,UAAU,IAAI,QAAQ,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC;YACvD,CAAC,CAAC,CAAC;SACJ;KACF;IACD,MAAM,IAAI,QAAQ,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;AACvC,CAAC,CAAC;AAIF,MAAM,GAAG,GAAG,CACV,QAAW,EACX,MAAU,EAIT,EAAE,CAAC,GAAG,CAAC,EAAE,GAAG,MAAM,EAAE,QAAQ,EAAE,CAAC,CAAC;AAEnC,MAAM,IAAI,GAAG,CAAC,QAAkB,EAAE,MAAyB,EAAE,EAAE,CAAC,GAAG,CAAC;IAClE,GAAG,MAAM;IACT,MAAM,EAAE,MAAM;IACd,QAAQ;CACT,CAAC,CAAC;AAEH,MAAM,GAAG,GAAG,CAAC,QAAkB,EAAE,MAAyB,EAAE,EAAE,CAAC,GAAG,CAAC;IACjE,GAAG,MAAM;IACT,MAAM,EAAE,KAAK;IACb,QAAQ;CACT,CAAC,CAAC;AAEH,MAAM,KAAK,GAAG,CAAC,QAAkB,EAAE,MAAyB,EAAE,EAAE,CAAC,GAAG,CAAC;IACnE,GAAG,MAAM;IACT,MAAM,EAAE,OAAO;IACf,QAAQ;CACT,CAAC,CAAC;AAEH,MAAM,GAAG,GAAG,CAAC,QAAkB,EAAE,MAAyB,EAAE,EAAE,CAAC,GAAG,CAAC;IACjE,GAAG,MAAM;IACT,MAAM,EAAE,QAAQ;IAChB,QAAQ;CACT,CAAC,CAAC;AAEH,GAAG,CAAC,GAAG,GAAG,GAAG,CAAC;AACd,GAAG,CAAC,IAAI,GAAG,IAAI,CAAC;AAChB,GAAG,CAAC,GAAG,GAAG,GAAG,CAAC;AACd,GAAG,CAAC,KAAK,GAAG,KAAK,CAAC;AAClB,GAAG,CAAC,GAAG,GAAG,GAAG,CAAC;AACd,GAAG,CAAC,MAAM,GAAG,GAAG,CAAC;AAEjB,eAAe,GAAG,CAAC;AAEnB,OAAO,EACL,aAAa,EACb,GAAG,EACH,IAAI,EACJ,GAAG,EACH,KAAK,EACL,GAAG,EACH,QAAQ,GACT,CAAC"}
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
package/lib/types.d.ts ADDED
@@ -0,0 +1,77 @@
1
+ import type { Products } from './types/products';
2
+ import type { Categories } from './types/categories';
3
+ import type { Brands } from './types/brands';
4
+ import type { Collections } from './types/collections';
5
+ import type { Grids } from './types/grids';
6
+ import type { Carts } from './types/carts';
7
+ import type { Orders } from './types/orders';
8
+ import type { Customers } from './types/customers';
9
+ import type { Stores } from './types/stores';
10
+ import type { Applications } from './types/applications';
11
+ declare type Resource = 'products' | 'categories' | 'brands' | 'collections' | 'grids' | 'carts' | 'orders' | 'customers' | 'stores' | 'applications';
12
+ declare type ResourceId = string & {
13
+ length: 24;
14
+ };
15
+ declare type ResourceAndId = `${Resource}/${ResourceId}`;
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}`;
18
+ declare type Method = 'get' | 'post' | 'put' | 'patch' | 'delete';
19
+ declare type Config = {
20
+ baseUrl?: string;
21
+ storeId?: number;
22
+ lang?: string;
23
+ method?: Method;
24
+ endpoint: Endpoint;
25
+ params?: Record<string, string | number>;
26
+ headers?: Record<string, string>;
27
+ timeout?: number;
28
+ maxRetries?: number;
29
+ fetch?: typeof fetch;
30
+ };
31
+ declare type BaseListResultMeta = {
32
+ offset: number;
33
+ limit: number;
34
+ fields: Array<string>;
35
+ };
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' ? {
75
+ _id: ResourceId;
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;
77
+ export type { Products, Categories, Brands, Collections, Grids, Carts, Orders, Customers, Stores, Applications, Resource, ResourceAndId, Endpoint, Method, Config, ResponseBody, };
package/lib/types.js ADDED
@@ -0,0 +1,2 @@
1
+ export {};
2
+ // # sourceMappingURL=types.js.map
File without changes
package/package.json CHANGED
@@ -1,9 +1,9 @@
1
1
  {
2
2
  "name": "@cloudcommerce/api",
3
- "version": "0.0.4",
3
+ "version": "0.0.7",
4
4
  "description": "E-Com Plus Cloud Commerce APIs client/adapter",
5
- "main": "dist/index.js",
6
- "types": "dist/index.d.ts",
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": "zx scripts/build.mjs",
20
- "test": "zx scripts/test.mjs"
19
+ "build": "sh scripts/build.sh",
20
+ "test": "tsc -p ../../tsconfig.test.json && vitest run"
21
21
  }
22
22
  }
@@ -0,0 +1,6 @@
1
+ #!/bin/bash
2
+
3
+ rm -rf lib
4
+ tsc --outDir lib
5
+ cp -r src/types lib/
6
+ npx eslint --rule 'max-len: off' --ext .js lib --fix
package/src/index.ts CHANGED
@@ -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,76 +43,101 @@ 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 callApi = 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 { method, headers, timeout = 20000 } = config;
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
- signal: abortController.signal,
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.ok) {
52
- return {
53
- ...response,
54
- config,
55
- data: await response.json(),
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
- const error: any = new Error(response.statusText);
59
- error.config = config;
60
- error.response = response;
61
- throw error;
96
+ throw new ApiError(config, response);
62
97
  };
63
98
 
64
- const get = (endpoint: Endpoint, config: Exclude<Config, 'method'>) => callApi({
65
- ...config,
66
- method: 'get',
67
- endpoint,
68
- });
99
+ type AbstractedConfig = Omit<Config, 'endpoint' | 'method'>;
100
+
101
+ const get = <E extends Endpoint, C extends AbstractedConfig>(
102
+ endpoint: E,
103
+ config?: C,
104
+ ): Promise<Response & {
105
+ config: Config,
106
+ data: ResponseBody<{ endpoint: E }>,
107
+ }> => api({ ...config, endpoint });
69
108
 
70
- const post = (endpoint: Endpoint, config: Exclude<Config, 'method'>) => callApi({
109
+ const post = (endpoint: Endpoint, config?: AbstractedConfig) => api({
71
110
  ...config,
72
111
  method: 'post',
73
112
  endpoint,
74
113
  });
75
114
 
76
- const put = (endpoint: Endpoint, config: Exclude<Config, 'method'>) => callApi({
115
+ const put = (endpoint: Endpoint, config?: AbstractedConfig) => api({
77
116
  ...config,
78
117
  method: 'put',
79
118
  endpoint,
80
119
  });
81
120
 
82
- const patch = (endpoint: Endpoint, config: Exclude<Config, 'method'>) => callApi({
121
+ const patch = (endpoint: Endpoint, config?: AbstractedConfig) => api({
83
122
  ...config,
84
123
  method: 'patch',
85
124
  endpoint,
86
125
  });
87
126
 
88
- const del = (endpoint: Endpoint, config: Exclude<Config, 'method'>) => callApi({
127
+ const del = (endpoint: Endpoint, config?: AbstractedConfig) => api({
89
128
  ...config,
90
129
  method: 'delete',
91
130
  endpoint,
92
131
  });
93
132
 
94
- callApi.get = get;
95
- callApi.post = post;
96
- callApi.put = put;
97
- callApi.patch = patch;
98
- callApi.del = del;
99
- callApi.delete = del;
133
+ api.get = get;
134
+ api.post = post;
135
+ api.put = put;
136
+ api.patch = patch;
137
+ api.del = del;
138
+ api.delete = del;
100
139
 
101
- export default callApi;
140
+ export default api;
102
141
 
103
142
  export {
104
143
  setMiddleware,
@@ -107,4 +146,5 @@ export {
107
146
  put,
108
147
  patch,
109
148
  del,
149
+ ApiError,
110
150
  };
package/src/types.ts CHANGED
@@ -24,7 +24,22 @@ type ResourceId = string & { length: 24 };
24
24
 
25
25
  type ResourceAndId = `${Resource}/${ResourceId}`;
26
26
 
27
- type Endpoint = Resource | ResourceAndId | `${ResourceAndId}/${string}`;
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
 
@@ -32,27 +47,92 @@ type Config = {
32
47
  baseUrl?: string,
33
48
  storeId?: number,
34
49
  lang?: string,
35
- method: Method,
50
+ method?: Method,
36
51
  endpoint: Endpoint,
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>,
63
+ };
64
+
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,
40
117
  };
41
118
 
42
- type ResponseBody<T> =
43
- T extends Config & { method: 'post' } ? { _id: ResourceId } :
44
- T extends Config & { method: 'put' | 'patch' | 'delete' } ? null :
45
- T extends Config & { method: 'get', endpoint: `products/${ResourceId}` } ? Products :
46
- T extends Config & { method: 'get', endpoint: `categories/${ResourceId}` } ? Categories :
47
- T extends Config & { method: 'get', endpoint: `brands/${ResourceId}` } ? Brands :
48
- T extends Config & { method: 'get', endpoint: `collections/${ResourceId}` } ? Collections :
49
- T extends Config & { method: 'get', endpoint: `grids/${ResourceId}` } ? Grids :
50
- T extends Config & { method: 'get', endpoint: `carts/${ResourceId}` } ? Carts :
51
- T extends Config & { method: 'get', endpoint: `orders/${ResourceId}` } ? Orders :
52
- T extends Config & { method: 'get', endpoint: `customers/${ResourceId}` } ? Customers :
53
- T extends Config & { method: 'get', endpoint: `stores/${ResourceId}` } ? Stores :
54
- T extends Config & { method: 'get', endpoint: `applications/${ResourceId}` } ? Applications :
55
- any
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;
56
136
 
57
137
  export type {
58
138
  Products,
@@ -1,14 +1,54 @@
1
- /* eslint-disable no-console */
1
+ /* eslint-disable no-console, import/no-extraneous-dependencies */
2
+
3
+ import { test, expect } from 'vitest';
2
4
  import './fetch-polyfill';
3
- import callApi from '../src/index';
4
-
5
- callApi({
6
- storeId: 1056,
7
- method: 'get',
8
- endpoint: 'products/618041aa239b7206d3fc06de',
9
- }).then(({ data }) => {
10
- if (data.sku === 'string') {
5
+ import api, { ApiError } 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') {
11
14
  console.log('\\o/');
12
15
  }
13
- console.info(`✓ Read product ${data.sku} and checked SKU type string`);
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 (err: any) {
27
+ const error = err as ApiError;
28
+ expect(error.statusCode).toBe(404);
29
+ expect(error.response?.status).toBe(404);
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
+ }
14
54
  });
package/tsconfig.json ADDED
@@ -0,0 +1,6 @@
1
+ {
2
+ "extends": "../../tsconfig.json",
3
+ "compilerOptions": {
4
+ "declaration": true
5
+ }
6
+ }
package/dist/index.d.ts DELETED
@@ -1,65 +0,0 @@
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 callApi: {
7
- <T extends Config>(config: T): Promise<Response & {
8
- config: Config;
9
- data: ResponseBody<T>;
10
- }>;
11
- get: (endpoint: Endpoint, config: Exclude<Config, 'method'>) => Promise<Response & {
12
- config: Config;
13
- data: any;
14
- }>;
15
- post: (endpoint: Endpoint, config: Exclude<Config, 'method'>) => Promise<Response & {
16
- config: Config;
17
- data: {
18
- _id: string & {
19
- length: 24;
20
- };
21
- };
22
- }>;
23
- put: (endpoint: Endpoint, config: Exclude<Config, 'method'>) => Promise<Response & {
24
- config: Config;
25
- data: null;
26
- }>;
27
- patch: (endpoint: Endpoint, config: Exclude<Config, 'method'>) => Promise<Response & {
28
- config: Config;
29
- data: null;
30
- }>;
31
- del: (endpoint: Endpoint, config: Exclude<Config, 'method'>) => Promise<Response & {
32
- config: Config;
33
- data: null;
34
- }>;
35
- delete: (endpoint: Endpoint, config: Exclude<Config, 'method'>) => Promise<Response & {
36
- config: Config;
37
- data: null;
38
- }>;
39
- };
40
- declare const get: (endpoint: Endpoint, config: Exclude<Config, 'method'>) => Promise<Response & {
41
- config: Config;
42
- data: any;
43
- }>;
44
- declare const post: (endpoint: Endpoint, config: Exclude<Config, 'method'>) => Promise<Response & {
45
- config: Config;
46
- data: {
47
- _id: string & {
48
- length: 24;
49
- };
50
- };
51
- }>;
52
- declare const put: (endpoint: Endpoint, config: Exclude<Config, 'method'>) => Promise<Response & {
53
- config: Config;
54
- data: null;
55
- }>;
56
- declare const patch: (endpoint: Endpoint, config: Exclude<Config, 'method'>) => Promise<Response & {
57
- config: Config;
58
- data: null;
59
- }>;
60
- declare const del: (endpoint: Endpoint, config: Exclude<Config, 'method'>) => Promise<Response & {
61
- config: Config;
62
- data: null;
63
- }>;
64
- export default callApi;
65
- export { setMiddleware, get, post, put, patch, del, };
package/dist/index.js DELETED
@@ -1,89 +0,0 @@
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
- }
21
- else {
22
- // https://github.com/microsoft/TypeScript/issues/32951
23
- url += `?${new URLSearchParams(config.params)}`;
24
- }
25
- }
26
- return `${url}/${config.endpoint}`;
27
- },
28
- };
29
- // eslint-disable-next-line no-unused-vars
30
- const setMiddleware = (middleware) => {
31
- def.middleware = middleware;
32
- };
33
- const callApi = async (config) => {
34
- const url = def.middleware(config);
35
- const { method, headers, timeout = 20000 } = config;
36
- const abortController = new AbortController();
37
- const timer = setTimeout(() => abortController.abort(), timeout);
38
- const response = await fetch(url, {
39
- method,
40
- headers,
41
- signal: abortController.signal,
42
- });
43
- clearTimeout(timer);
44
- if (response.ok) {
45
- return {
46
- ...response,
47
- config,
48
- data: await response.json(),
49
- };
50
- }
51
- const error = new Error(response.statusText);
52
- error.config = config;
53
- error.response = response;
54
- throw error;
55
- };
56
- const get = (endpoint, config) => callApi({
57
- ...config,
58
- method: 'get',
59
- endpoint,
60
- });
61
- const post = (endpoint, config) => callApi({
62
- ...config,
63
- method: 'post',
64
- endpoint,
65
- });
66
- const put = (endpoint, config) => callApi({
67
- ...config,
68
- method: 'put',
69
- endpoint,
70
- });
71
- const patch = (endpoint, config) => callApi({
72
- ...config,
73
- method: 'patch',
74
- endpoint,
75
- });
76
- const del = (endpoint, config) => callApi({
77
- ...config,
78
- method: 'delete',
79
- endpoint,
80
- });
81
- callApi.get = get;
82
- callApi.post = post;
83
- callApi.put = put;
84
- callApi.patch = patch;
85
- callApi.del = del;
86
- callApi.delete = del;
87
- export default callApi;
88
- export { setMiddleware, get, post, put, patch, del, };
89
- //# sourceMappingURL=index.js.map
package/dist/index.js.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/types.d.ts DELETED
@@ -1,65 +0,0 @@
1
- import type { Products } from './types/products';
2
- import type { Categories } from './types/categories';
3
- import type { Brands } from './types/brands';
4
- import type { Collections } from './types/collections';
5
- import type { Grids } from './types/grids';
6
- import type { Carts } from './types/carts';
7
- import type { Orders } from './types/orders';
8
- import type { Customers } from './types/customers';
9
- import type { Stores } from './types/stores';
10
- import type { Applications } from './types/applications';
11
- declare type Resource = 'products' | 'categories' | 'brands' | 'collections' | 'grids' | 'carts' | 'orders' | 'customers' | 'stores' | 'applications';
12
- declare type ResourceId = string & {
13
- length: 24;
14
- };
15
- declare type ResourceAndId = `${Resource}/${ResourceId}`;
16
- declare type Endpoint = Resource | ResourceAndId | `${ResourceAndId}/${string}`;
17
- declare type Method = 'get' | 'post' | 'put' | 'patch' | 'delete';
18
- declare type Config = {
19
- baseUrl?: string;
20
- storeId?: number;
21
- lang?: string;
22
- method: Method;
23
- endpoint: Endpoint;
24
- params?: Record<string, string | number>;
25
- headers?: Record<string, string>;
26
- timeout?: number;
27
- };
28
- declare type ResponseBody<T> = T extends Config & {
29
- method: 'post';
30
- } ? {
31
- _id: ResourceId;
32
- } : T extends Config & {
33
- method: 'put' | 'patch' | 'delete';
34
- } ? null : T extends Config & {
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;
65
- export type { Products, Categories, Brands, Collections, Grids, Carts, Orders, Customers, Stores, Applications, Resource, ResourceAndId, Endpoint, Method, Config, ResponseBody, };
package/dist/types.js DELETED
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=types.js.map
package/scripts/build.mjs DELETED
@@ -1,5 +0,0 @@
1
- /* global $ */
2
-
3
- await $`rm -rf dist`;
4
- await $`tsc -p ../../tsconfig.json --outDir dist --declaration`;
5
- await $`cp -r src/types dist/`;
package/scripts/test.mjs DELETED
@@ -1,4 +0,0 @@
1
- /* global $ */
2
-
3
- await $`tsc -p ../../tsconfig.test.json`;
4
- await $`tsx tests/index.test.ts`;