@storecraft/sdk 1.0.15 → 1.0.17
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +9 -0
- package/index.js +28 -19
- package/package.json +1 -1
- package/src/ai.js +5 -5
- package/src/auth.js +56 -80
- package/src/checkout.js +7 -7
- package/src/collections.js +0 -7
- package/src/customers.js +0 -2
- package/src/discounts.js +1 -7
- package/src/email.js +67 -0
- package/src/images.js +0 -2
- package/src/notifications.js +3 -3
- package/src/orders.js +20 -3
- package/src/payments.js +49 -21
- package/src/posts.js +0 -1
- package/src/products.js +3 -8
- package/src/reference.js +46 -0
- package/src/search.js +2 -5
- package/src/shipping.js +0 -1
- package/src/statistics.js +19 -49
- package/src/storage.js +29 -38
- package/src/storefronts.js +23 -3
- package/src/tags.js +0 -1
- package/src/templates.js +0 -1
- package/src/utils.api.fetch.js +44 -51
- package/src/utils.functional.js +0 -6
- package/types.d.ts +17 -4
- package/src/settings.js +0 -19
package/src/discounts.js
CHANGED
@@ -1,8 +1,7 @@
|
|
1
1
|
/**
|
2
2
|
* @import {
|
3
3
|
* ApiQuery, DiscountType, DiscountTypeUpsert,
|
4
|
-
ProductType,
|
5
|
-
VariantType
|
4
|
+
* ProductType, VariantType
|
6
5
|
* } from '@storecraft/core/api'
|
7
6
|
*/
|
8
7
|
import { StorecraftSDK } from '../index.js'
|
@@ -20,7 +19,6 @@ import {
|
|
20
19
|
export default class Discounts extends collection_base {
|
21
20
|
|
22
21
|
/**
|
23
|
-
*
|
24
22
|
* @param {StorecraftSDK} sdk
|
25
23
|
*/
|
26
24
|
constructor(sdk) {
|
@@ -30,7 +28,6 @@ export default class Discounts extends collection_base {
|
|
30
28
|
/**
|
31
29
|
* @description Each discount has eligible products,
|
32
30
|
* you can query and filter these products by discount
|
33
|
-
*
|
34
31
|
* @param {string} id_or_handle discount `id` or `handle`
|
35
32
|
* @param {ApiQuery<ProductType | VariantType>} query query
|
36
33
|
* @return {Promise<(ProductType | VariantType)[]>} List of discounts
|
@@ -47,7 +44,6 @@ export default class Discounts extends collection_base {
|
|
47
44
|
/**
|
48
45
|
* @description Each discount has eligible products,
|
49
46
|
* you can count the query products by discount
|
50
|
-
*
|
51
47
|
* @param {string} id_or_handle discount `id` or `handle`
|
52
48
|
* @param {ApiQuery<ProductType | VariantType>} query query
|
53
49
|
* @return {Promise<number>} count
|
@@ -64,7 +60,6 @@ export default class Discounts extends collection_base {
|
|
64
60
|
* @description List all the tags of products in a collection, This is helpful
|
65
61
|
* for building a filter system in the frontend if you know in advance all
|
66
62
|
* the tags of the products in a collection
|
67
|
-
*
|
68
63
|
* @param {string} id_or_handle Discount `id` or `handle`
|
69
64
|
* @return {Promise<string[]>} List of tags
|
70
65
|
*/
|
@@ -76,7 +71,6 @@ export default class Discounts extends collection_base {
|
|
76
71
|
method: 'get'
|
77
72
|
}
|
78
73
|
);
|
79
|
-
|
80
74
|
return result
|
81
75
|
}
|
82
76
|
|
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) {
|
package/src/notifications.js
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
/**
|
2
|
-
* @import {
|
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/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 {
|
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(
|
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(
|
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
|
-
*
|
70
|
-
* using {@link get_from_collection_resource} or
|
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
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
|
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
|
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/reference.js
ADDED
@@ -0,0 +1,46 @@
|
|
1
|
+
/**
|
2
|
+
* @import { StorecraftConfig } from '@storecraft/core'
|
3
|
+
* @import { StorecraftAppPublicInfo } from '@storecraft/core/api'
|
4
|
+
*/
|
5
|
+
import { StorecraftSDK } from '../index.js'
|
6
|
+
import { fetchApiWithAuth } from './utils.api.fetch.js';
|
7
|
+
|
8
|
+
/**
|
9
|
+
* @description Reference
|
10
|
+
*/
|
11
|
+
export default class Reference {
|
12
|
+
|
13
|
+
/**
|
14
|
+
* @param {StorecraftSDK} sdk
|
15
|
+
*/
|
16
|
+
constructor(sdk) {
|
17
|
+
this.sdk = sdk;
|
18
|
+
}
|
19
|
+
|
20
|
+
/**
|
21
|
+
* @returns {Promise<StorecraftConfig>}
|
22
|
+
*/
|
23
|
+
settings = async () => {
|
24
|
+
/** @type {StorecraftConfig} */
|
25
|
+
const json = await fetchApiWithAuth(
|
26
|
+
this.sdk,
|
27
|
+
'reference/settings',
|
28
|
+
{ method: 'get' },
|
29
|
+
);
|
30
|
+
return json;
|
31
|
+
}
|
32
|
+
|
33
|
+
/**
|
34
|
+
* @returns {Promise<StorecraftAppPublicInfo>}
|
35
|
+
*/
|
36
|
+
info = async () => {
|
37
|
+
/** @type {StorecraftAppPublicInfo} */
|
38
|
+
const json = await fetchApiWithAuth(
|
39
|
+
this.sdk,
|
40
|
+
'reference/info',
|
41
|
+
{ method: 'get' },
|
42
|
+
);
|
43
|
+
return json;
|
44
|
+
}
|
45
|
+
|
46
|
+
}
|
package/src/search.js
CHANGED
@@ -6,22 +6,19 @@
|
|
6
6
|
|
7
7
|
import {
|
8
8
|
api_query_to_searchparams, object_to_search_params,
|
9
|
-
|
10
|
-
} from '@storecraft/core/api/utils.query.js';
|
9
|
+
} from '@storecraft/core/api/query.js';
|
11
10
|
import { StorecraftSDK } from '../index.js'
|
12
11
|
import { fetchApiWithAuth, url } from './utils.api.fetch.js';
|
12
|
+
import { string_array_to_string } from '@storecraft/core/api/query.utils.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/shipping.js
CHANGED
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 {
|
7
|
+
import {
|
8
|
+
api_query_to_searchparams
|
9
|
+
} from '@storecraft/core/api/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
|
-
*
|
66
|
-
* @param {string | number | Date} [to_day]
|
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(
|
75
|
-
|
76
|
-
|
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) => {
|