@storecraft/sdk 1.0.14 → 1.0.16

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/src/email.js ADDED
@@ -0,0 +1,67 @@
1
+ /**
2
+ * @import {
3
+ * MailResponse, SendMailParams, SendMailWithTemplateParams, templates_keys,
4
+ * templates_input_types
5
+ * } from '@storecraft/core/api'
6
+ */
7
+
8
+ import { StorecraftSDK } from '../index.js'
9
+ import { fetchApiWithAuth, url } from './utils.api.fetch.js';
10
+
11
+ /**
12
+ */
13
+ export default class Email {
14
+
15
+ /**
16
+ * @param {StorecraftSDK} sdk
17
+ */
18
+ constructor(sdk) {
19
+ this.sdk = sdk;
20
+ }
21
+
22
+ /**
23
+ * @description Send an email to multiple recipients
24
+ * @param {SendMailParams} params mail parameters
25
+ * @returns {Promise<MailResponse<any>>}
26
+ */
27
+ send = async (params) => {
28
+ const json = await fetchApiWithAuth(
29
+ this.sdk,
30
+ 'emails/send',
31
+ {
32
+ method: 'POST',
33
+ body: JSON.stringify(params),
34
+ headers: {
35
+ 'Content-Type': 'application/json',
36
+ },
37
+ },
38
+ );
39
+ return json;
40
+ }
41
+
42
+ /**
43
+ * @description Send an email to multiple recipients with a template.
44
+ * Each template has a `subject`, `html` and `text` body templates,
45
+ * that you can configure at the dashboard
46
+ * @template {templates_keys | string} [HANDLE=keyof templates_input_types]
47
+ * @param {SendMailWithTemplateParams<HANDLE>} params mail parameters
48
+ * @returns {Promise<MailResponse<any>>}
49
+ */
50
+ sendWithTemplate = async (params) => {
51
+ const json = await fetchApiWithAuth(
52
+ this.sdk,
53
+ 'emails/send-with-template',
54
+ {
55
+ method: 'POST',
56
+ body: JSON.stringify(params),
57
+ headers: {
58
+ 'Content-Type': 'application/json',
59
+ },
60
+ },
61
+ );
62
+ return json;
63
+ }
64
+
65
+ }
66
+
67
+
package/src/images.js CHANGED
@@ -6,13 +6,11 @@ import { collection_base } from './utils.api.fetch.js';
6
6
 
7
7
  /**
8
8
  * @description Base `images` **CRUD**
9
- *
10
9
  * @extends {collection_base<ImageTypeUpsert, ImageType>}
11
10
  */
12
11
  export default class Images extends collection_base {
13
12
 
14
13
  /**
15
- *
16
14
  * @param {StorecraftSDK} sdk
17
15
  */
18
16
  constructor(sdk) {
@@ -1,5 +1,7 @@
1
1
  /**
2
- * @import { NotificationTypeUpsert, NotificationType } from '@storecraft/core/api'
2
+ * @import {
3
+ * NotificationTypeUpsert, NotificationType
4
+ * } from '@storecraft/core/api'
3
5
  */
4
6
  import { StorecraftSDK } from '../index.js'
5
7
  import {
@@ -14,7 +16,6 @@ import {
14
16
  export default class Notifications extends collection_base {
15
17
 
16
18
  /**
17
- *
18
19
  * @param {StorecraftSDK} sdk
19
20
  */
20
21
  constructor(sdk) {
@@ -22,7 +23,6 @@ export default class Notifications extends collection_base {
22
23
  }
23
24
 
24
25
  /**
25
- *
26
26
  * @param {NotificationTypeUpsert[]} items
27
27
  */
28
28
  upsertBulk = items => {
package/src/orders.js CHANGED
@@ -1,8 +1,9 @@
1
1
  /**
2
- * @import { OrderDataUpsert, OrderData } from '@storecraft/core/api'
2
+ * @import { OrderDataUpsert, OrderData, ApiQuery } from '@storecraft/core/api'
3
3
  */
4
+ import { api_query_to_searchparams } from '@storecraft/core/api/utils.query.js';
4
5
  import { StorecraftSDK } from '../index.js'
5
- import { collection_base } from './utils.api.fetch.js';
6
+ import { collection_base, fetchApiWithAuth } from './utils.api.fetch.js';
6
7
 
7
8
  /**
8
9
  * @description Base `orders` **CRUD**
@@ -12,11 +13,27 @@ import { collection_base } from './utils.api.fetch.js';
12
13
  export default class Orders extends collection_base {
13
14
 
14
15
  /**
15
- *
16
16
  * @param {StorecraftSDK} sdk
17
17
  */
18
18
  constructor(sdk) {
19
19
  super(sdk, 'orders');
20
20
  }
21
21
 
22
+ /**
23
+ * @description List orders of current authenticated user
24
+ * @param {ApiQuery<OrderData>} [query]
25
+ * @returns {Promise<OrderData[]>}
26
+ */
27
+ list_my_orders(
28
+ query={}
29
+ ) {
30
+ const sq = api_query_to_searchparams(query);
31
+ return fetchApiWithAuth(
32
+ this.sdk,
33
+ `${this.base_name}/me?${sq.toString()}`,
34
+ {
35
+ method: 'get'
36
+ }
37
+ );
38
+ }
22
39
  }
package/src/payments.js CHANGED
@@ -1,5 +1,7 @@
1
1
  /**
2
- * @import { PaymentGatewayItemGet, PaymentGatewayStatus } from '@storecraft/core/api'
2
+ * @import {
3
+ * PaymentGatewayItemGet, PaymentGatewayStatus
4
+ * } from '@storecraft/core/api'
3
5
  */
4
6
  import { StorecraftSDK } from '../index.js'
5
7
  import {
@@ -16,7 +18,6 @@ export default class Payments {
16
18
  #sdk = undefined;
17
19
 
18
20
  /**
19
- *
20
21
  * @param {StorecraftSDK} sdk
21
22
  */
22
23
  constructor(sdk) {
@@ -24,34 +25,29 @@ export default class Payments {
24
25
  }
25
26
 
26
27
  /**
27
- *
28
28
  * @param {string} handle payment gateway `handle`
29
- *
30
- *
31
29
  * @returns {Promise<PaymentGatewayItemGet>}
32
30
  */
33
31
  get(handle) {
34
- return get_from_collection_resource(this.sdk, 'payments/gateways', handle);
32
+ return get_from_collection_resource(
33
+ this.sdk, 'payments/gateways', handle
34
+ );
35
35
  }
36
36
 
37
37
  /**
38
- *
39
- *
40
38
  * @returns {Promise<PaymentGatewayItemGet[]>}
41
39
  */
42
40
  list() {
43
- return list_from_collection_resource(this.sdk, 'payments/gateways');
41
+ return list_from_collection_resource(
42
+ this.sdk, 'payments/gateways'
43
+ );
44
44
  }
45
45
 
46
46
 
47
47
  /**
48
- *
49
48
  * Consult with the `payment` gateway about the payment
50
49
  * status of an `order`.
51
- *
52
- *
53
50
  * @param {string} order_id
54
- *
55
51
  * @returns {Promise<PaymentGatewayStatus>}
56
52
  */
57
53
  paymentStatusOfOrder(order_id) {
@@ -65,15 +61,12 @@ export default class Payments {
65
61
  }
66
62
 
67
63
  /**
68
- *
69
- * Invoke a `payment gateway` action on `order`. The list of available actions can be found
70
- * using {@link get_from_collection_resource} or {@link paymentStatusOfOrder}
71
- *
72
- *
64
+ * Invoke a `payment gateway` action on `order`.
65
+ * The list of available actions can be found
66
+ * using {@link get_from_collection_resource} or
67
+ * {@link paymentStatusOfOrder}
73
68
  * @param {string} action_handle The `action` handle at the gateway
74
69
  * @param {string} order_id the `id` of the `order`
75
- *
76
- *
77
70
  * @returns {Promise<PaymentGatewayStatus>}
78
71
  */
79
72
  invokeAction(action_handle, order_id) {
@@ -85,7 +78,42 @@ export default class Payments {
85
78
  }
86
79
  )
87
80
  }
88
-
81
+
82
+ /**
83
+ * Get an optional HTML Pay UI of the `payment gateway`
84
+ * @param {string} order_id the `id` of the `order`
85
+ * @returns {Promise<string>} `html` of the `payment gateway` UI
86
+ */
87
+ getBuyUI(order_id) {
88
+ return fetchApiWithAuth(
89
+ this.sdk,
90
+ `/payments/buy_ui/${order_id}`,
91
+ {
92
+ method: 'get'
93
+ }
94
+ )
95
+ }
96
+
97
+ /**
98
+ * invoke the webhook endpoint for async payment
99
+ * @param {string} gateway_handle The handle of the `payment gateway`
100
+ * @param {any} [body={}] Payload for the gateway webhook. This is specific to the
101
+ * `payment gateway` and the `webhook` endpoint.
102
+ * @returns {Promise<string>}
103
+ */
104
+ webhook(gateway_handle, body={}) {
105
+ return fetchApiWithAuth(
106
+ this.sdk,
107
+ `/payments/gateways/${gateway_handle}/webhook`,
108
+ {
109
+ method: 'post',
110
+ headers: {
111
+ 'Content-Type': 'application/json'
112
+ },
113
+ body: JSON.stringify(body)
114
+ }
115
+ )
116
+ }
89
117
 
90
118
  get sdk() {
91
119
  return this.#sdk;
package/src/posts.js CHANGED
@@ -12,7 +12,6 @@ import { collection_base } from './utils.api.fetch.js';
12
12
  export default class Posts extends collection_base {
13
13
 
14
14
  /**
15
- *
16
15
  * @param {StorecraftSDK} sdk
17
16
  */
18
17
  constructor(sdk) {
package/src/products.js CHANGED
@@ -14,7 +14,6 @@ import {
14
14
  export default class Products extends collection_base {
15
15
 
16
16
  /**
17
- *
18
17
  * @param {StorecraftSDK} sdk
19
18
  */
20
19
  constructor(sdk) {
@@ -26,7 +25,6 @@ export default class Products extends collection_base {
26
25
  * This is helpful for building a filter system in the frontend if
27
26
  * you know in advance all the tags of the products in a collection,
28
27
  * also see the collection confined version db_collections.list_collection_products_tags
29
- *
30
28
  * @return {Promise<string[]>} List of tags
31
29
  */
32
30
  list_used_tags = async () => {
@@ -42,15 +40,14 @@ export default class Products extends collection_base {
42
40
  }
43
41
 
44
42
  /**
45
- *
46
43
  * Change stock quantity of a `product` by a delta difference
47
44
  * number.
48
- *
49
45
  * @param {string} id_or_handle `id` ot `handle`
50
46
  * @param {number} howmuch a diff number by how much to update stock
47
+ * @return {Promise<boolean>}
51
48
  */
52
49
  changeStockOfBy = async (id_or_handle, howmuch) => {
53
- const response = await fetchOnlyApiResponseWithAuth(
50
+ const response = await fetchApiWithAuth(
54
51
  this.sdk,
55
52
  `products/${id_or_handle}?quantityBy=${howmuch}`,
56
53
  {
@@ -58,12 +55,11 @@ export default class Products extends collection_base {
58
55
  }
59
56
  );
60
57
 
61
- return response.ok;
58
+ return response;
62
59
  }
63
60
 
64
61
  /**
65
62
  * Add `products` to `collection`
66
- *
67
63
  * @param {ProductType[]} products
68
64
  * @param {CollectionType} collection
69
65
  */
@@ -78,7 +74,6 @@ export default class Products extends collection_base {
78
74
 
79
75
  /**
80
76
  * Remove `products` from `collection`
81
- *
82
77
  * @param {ProductType[]} products
83
78
  * @param {CollectionType} collection
84
79
  */
package/src/search.js CHANGED
@@ -13,15 +13,12 @@ import { fetchApiWithAuth, url } from './utils.api.fetch.js';
13
13
 
14
14
  /**
15
15
  * @description **Search** API (two options):
16
- *
17
16
  * - Quick Search across many resources
18
17
  * - Similarity search across `discount`, `products`, `collections`, `shipping`
19
- *
20
18
  */
21
19
  export default class Search {
22
20
 
23
21
  /**
24
- *
25
22
  * @param {StorecraftSDK} sdk
26
23
  */
27
24
  constructor(sdk) {
package/src/settings.js CHANGED
@@ -9,11 +9,10 @@ import { collection_base } from './utils.api.fetch.js';
9
9
  export default class Settings extends collection_base {
10
10
 
11
11
  /**
12
- *
13
12
  * @param {StorecraftSDK} sdk
14
13
  */
15
14
  constructor(sdk) {
16
- super(sdk, 'settings');
15
+ super(sdk, 'reference/settings');
17
16
  }
18
17
 
19
18
  }
package/src/shipping.js CHANGED
@@ -12,7 +12,6 @@ import { collection_base } from './utils.api.fetch.js';
12
12
  export default class Shipping extends collection_base {
13
13
 
14
14
  /**
15
- *
16
15
  * @param {StorecraftSDK} sdk
17
16
  */
18
17
  constructor(sdk) {
package/src/statistics.js CHANGED
@@ -4,7 +4,9 @@
4
4
  import { App } from '@storecraft/core';
5
5
  import { StorecraftSDK } from '../index.js'
6
6
  import { fetchApiWithAuth } from './utils.api.fetch.js';
7
- import { api_query_to_searchparams } from '@storecraft/core/api/utils.query.js';
7
+ import {
8
+ api_query_to_searchparams
9
+ } from '@storecraft/core/api/utils.query.js';
8
10
 
9
11
  /**
10
12
  * @description statistics endpoint
@@ -12,11 +14,8 @@ import { api_query_to_searchparams } from '@storecraft/core/api/utils.query.js';
12
14
  export default class Statistics {
13
15
  /** @type {StorecraftSDK} */
14
16
  #sdk;
15
- /** @type {Record<string, any>} */
16
- #cache = {};
17
17
 
18
18
  /**
19
- *
20
19
  * @param {StorecraftSDK} sdk
21
20
  */
22
21
  constructor(sdk) {
@@ -26,54 +25,30 @@ export default class Statistics {
26
25
  get sdk() {
27
26
  return this.#sdk;
28
27
  }
29
-
30
- /**
31
- * @param {string} key
32
- *
33
- * @returns {boolean}
34
- */
35
- isCacheValid = key => {
36
- return false;
37
- // return this.cache[key] &&
38
- // (Date.now()-this.cache[key].updatedAt)<HOUR
39
- }
40
-
41
- /**
42
- *
43
- * @param {string} key
44
- * @returns {OrdersStatisticsType}
45
- */
46
- fromCache = (key) => {
47
- if(this.isCacheValid(key))
48
- return this.#cache[key]
49
- return undefined
50
- }
51
-
52
- /**
53
- *
54
- * @param {string} key
55
- * @param {OrdersStatisticsType} value
56
- */
57
- putCache = (key, value) => {
58
- this.#cache[key] = value
59
- }
60
-
61
28
 
62
29
  /**
63
30
  * @description Load **Orders** `statistics`
64
- *
65
- * @param {string | number | Date} [from_day] `ISO` string | `UTC` | `timestamp` | `Date`
66
- * @param {string | number | Date} [to_day] `ISO` string | `UTC` | `timestamp` | `Date`
67
- *
31
+ * @param {string | number | Date} [from_day]
32
+ * `ISO` string | `UTC` | `timestamp` | `Date`
33
+ * @param {string | number | Date} [to_day]
34
+ * `ISO` string | `UTC` | `timestamp` | `Date`
68
35
  * @returns {Promise<OrdersStatisticsType>}
69
36
  */
70
37
  orders = async (from_day, to_day) => {
71
38
  const search = new URLSearchParams();
72
39
 
73
- if(from_day)
74
- search.set('fromDay', new Date(from_day).toISOString());
75
- if(to_day)
76
- search.set('toDay', new Date(to_day).toISOString());
40
+ if(from_day) {
41
+ search.set(
42
+ 'fromDay',
43
+ new Date(from_day).toISOString()
44
+ );
45
+ }
46
+ if(to_day) {
47
+ search.set(
48
+ 'toDay',
49
+ new Date(to_day).toISOString()
50
+ );
51
+ }
77
52
 
78
53
  return fetchApiWithAuth(
79
54
  this.sdk,
@@ -83,14 +58,9 @@ export default class Statistics {
83
58
 
84
59
  /**
85
60
  * @description Load **count** `statistics`
86
- *
87
61
  * @param {keyof App["db"]["resources"]} table
88
62
  * @param {ApiQuery} [query]
89
- *
90
- *
91
63
  * @returns {Promise<number>}
92
- *
93
- *
94
64
  * @throws
95
65
  */
96
66
  countOf = async (table, query) => {
package/src/storage.js CHANGED
@@ -1,19 +1,18 @@
1
1
  /**
2
- * @import { StorageFeatures, StorageSignedOperation } from '@storecraft/core/storage'
2
+ * @import {
3
+ * StorageFeatures, StorageSignedOperation
4
+ * } from '@storecraft/core/storage'
3
5
  */
4
6
 
5
7
  import { StorecraftSDK } from '../index.js'
6
8
  import { fetchOnlyApiResponseWithAuth } from './utils.api.fetch.js'
7
9
 
8
10
  /**
9
- *
10
11
  * @description `Storecraft` storage service.
11
- *
12
12
  * Supports:
13
13
  * - direct `downloads` / `uploads`
14
14
  * - presigned-urls for `download` / `upload` (If supported)
15
15
  * - `delete` files
16
- *
17
16
  */
18
17
  export default class Storage {
19
18
 
@@ -34,11 +33,8 @@ export default class Storage {
34
33
  }
35
34
 
36
35
  /**
37
- *
38
36
  * @description Retrieve the `features` of `storage`, which informs:
39
37
  * - Does `storage` supports `pre-signed` urls for `download` / `upload`
40
- *
41
- *
42
38
  * @returns {Promise<StorageFeatures>}
43
39
  */
44
40
  features = async () => {
@@ -75,12 +71,9 @@ export default class Storage {
75
71
 
76
72
  /**
77
73
  * @description Get a blob from `storage` driver with `presigned` urls
78
- *
79
74
  * @param {string} key file path key,
80
75
  * examples `image.png`, `collections/thumb.jpeg`
81
- *
82
76
  * @return {Promise<Blob>}
83
- *
84
77
  * @throws {error}
85
78
  */
86
79
  getBlobSigned = async (key) => {
@@ -104,7 +97,7 @@ export default class Storage {
104
97
  /** @type {StorageSignedOperation} */
105
98
  const presigned_req = await r.json();
106
99
 
107
- const presigned_res = await fetch(
100
+ const presigned_res = await this.sdk.fetcher(
108
101
  presigned_req.url,
109
102
  {
110
103
  method: presigned_req.method,
@@ -119,13 +112,11 @@ export default class Storage {
119
112
  }
120
113
 
121
114
  /**
122
- * @description Get a blob from `storage` driver, straight download. (Not recommended)
123
- *
115
+ * @description Get a blob from `storage` driver,
116
+ * straight download. (Not recommended)
124
117
  * @param {string} key file path key,
125
118
  * examples `image.png`, `collections/thumb.jpeg`
126
- *
127
119
  * @return {Promise<Blob>}
128
- *
129
120
  * @throws {error}
130
121
  */
131
122
  getBlobUnsigned = async (key) => {
@@ -137,10 +128,8 @@ export default class Storage {
137
128
  );
138
129
 
139
130
  const ctype = r.headers.get('Content-Type');
140
-
141
131
  if(!r.ok) {
142
132
  const error = await r.json();
143
-
144
133
  throw error;
145
134
  }
146
135
 
@@ -149,12 +138,9 @@ export default class Storage {
149
138
 
150
139
  /**
151
140
  * @description Get a blob from `storage` driver.
152
- *
153
141
  * @param {string} key file path key,
154
142
  * examples `image.png`, `collections/thumb.jpeg`
155
- *
156
143
  * @return {Promise<Blob>}
157
- *
158
144
  * @throws {error}
159
145
  */
160
146
  getBlob = async (key) => {
@@ -169,32 +155,36 @@ export default class Storage {
169
155
 
170
156
  /** @param {string} path */
171
157
  getText = (path) =>
172
- this.getBlob(path).then(blob => blob.text());
158
+ this.getBlob(path).then(blob => blob.text());
173
159
 
174
160
  /** @param {string} path */
175
161
  getJson = (path) =>
176
- this.getBlob(path).then(blob => blob.text().then(JSON.parse));
162
+ this.getBlob(path).then(
163
+ blob => blob.text().then(JSON.parse)
164
+ );
177
165
 
178
166
  /** @param {string} path */
179
167
  getImageObjectURL = (path) =>
180
- this.getBlob(path).then(blob => URL.createObjectURL(blob));
168
+ this.getBlob(path).then(
169
+ blob => URL.createObjectURL(blob)
170
+ );
181
171
 
182
172
  /**
183
173
  * @description get file source by inspecting the url:
184
- *
185
174
  * - If it starts with `storage://`, then use `backend`
186
175
  * storage service, to download and convert it to encoded
187
176
  * `object-url` for `<img/>`
188
- *
189
177
  * - Else. it is assumed to be a public `url`, and will
190
178
  * return the given url.
191
- *
192
179
  * @template {false | true} [IS_IMAGE=true]
193
180
  * @param {string} url
194
181
  * @param {IS_IMAGE} [isImage=true]
195
182
  * @returns {Promise<IS_IMAGE extends true ? string : any>}
196
183
  */
197
- getSource = async (url, isImage=(/** @type {IS_IMAGE} */ (true))) => {
184
+ getSource = async (
185
+ url,
186
+ isImage=(/** @type {IS_IMAGE} */ (true))
187
+ ) => {
198
188
  try {
199
189
 
200
190
  const is_storage = url.startsWith('storage://');
@@ -222,12 +212,13 @@ export default class Storage {
222
212
 
223
213
 
224
214
  /**
225
- * @description Put a blob into `storage` driver with `presigned` urls
226
- *
215
+ * @description Put a blob into `storage` driver
216
+ * with `presigned` urls if supported. this means the upload
217
+ * is offloaded from the backend to the client straight into
218
+ * other services that supports it such as s3.
227
219
  * @param {string} key file path key,
228
220
  * examples `image.png`, `collections/thumb.jpeg`
229
221
  * @param {string | Blob | Uint8Array | ArrayBuffer | File} data
230
- *
231
222
  */
232
223
  putBytesSigned = async (key, data) => {
233
224
 
@@ -248,7 +239,7 @@ export default class Storage {
248
239
  if(ctype === 'application/json') {
249
240
  /** @type {StorageSignedOperation} */
250
241
  const presigned_req = await r.json();
251
- const presigned_res = await fetch(
242
+ const presigned_res = await this.sdk.fetcher(
252
243
  presigned_req.url,
253
244
  {
254
245
  method: presigned_req.method,
@@ -264,12 +255,11 @@ export default class Storage {
264
255
  }
265
256
 
266
257
  /**
267
- * @description Put a blob into `storage` driver with direct `upload` (Not Recommended)
268
- *
258
+ * @description Put a blob into `storage` driver with
259
+ * direct `upload` (Not Recommended)
269
260
  * @param {string} key file path key,
270
261
  * examples `image.png`, `collections/thumb.jpeg`
271
262
  * @param {string | Blob | Uint8Array | ArrayBuffer | File} data
272
- *
273
263
  */
274
264
  putBytesUnsigned = async (key, data) => {
275
265
 
@@ -295,13 +285,10 @@ export default class Storage {
295
285
 
296
286
  /**
297
287
  * @description Put bytes into `storage` driver.
298
- *
299
288
  * @param {string} key file path key,
300
289
  * examples `image.png`, `collections/thumb.jpeg`
301
290
  * @param {string | Blob | Uint8Array | ArrayBuffer | File} data
302
- *
303
291
  * @return {Promise<boolean>}
304
- *
305
292
  * @throws {error}
306
293
  */
307
294
  putBytes = async (key, data) => {
@@ -316,7 +303,6 @@ export default class Storage {
316
303
 
317
304
  /**
318
305
  * @description Delete a `file` by key
319
- *
320
306
  * @param {string} key file path key,
321
307
  * examples `image.png`, `collections/thumb.jpeg`
322
308
  */
@@ -327,6 +313,11 @@ export default class Storage {
327
313
  { method: 'delete' }
328
314
  );
329
315
 
316
+ if(!r.ok) {
317
+ const error = await r.json();
318
+ throw error;
319
+ }
320
+
330
321
  return r.ok;
331
322
  }
332
323