@storecraft/sdk 1.0.9 → 1.0.11

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 CHANGED
@@ -10,9 +10,40 @@ which means you can you it both at browser and at backend runtimes such (`node`
10
10
 
11
11
  It will allow you to fetch / mutate all of the resources at the `backend` in a
12
12
  convenient manner with `javascript`, such as:
13
- `products`, `collections`, `authentication`, `customers`, `orders`, `discounts`,
14
- `storage`, `storefronts`, `shipping`, `statistics`, `tags`, `posts`, `notifications`,
15
- `templates`, `extensions` and more :)
13
+
14
+ #### collections
15
+ `products`, `collections`, `auth_users`, `customers`, `orders`, `discounts`,
16
+ `storefronts`, `shipping`, `tags`, `posts`, `notifications`,
17
+ `templates`, `extensions`, `images`
18
+
19
+ #### Auth
20
+ Perform authentication such as `signin` / `signup` / `api-key`
21
+
22
+ #### Checkout
23
+ Perform checkout `create` / `complete`
24
+
25
+ #### Storage
26
+ Perform storage operations such as `put` / `get` / `delete`
27
+
28
+ #### Payments
29
+ Perform payments `status-check` / `invoke-action`
30
+
31
+ #### Statistics
32
+ - Query some basic statistics about `orders` in a time span
33
+ - Query count of items in collections
34
+
35
+ #### AI
36
+ Speak with a `storecraft` agent (Supports streaming :))
37
+
38
+ #### Semantic / Similarity Search
39
+ Search Storecraft with AI for similar `products`, `discounts`, `collections`, `shipping` based on a prompt.
40
+
41
+ #### Quick Search
42
+ List super lite search results with `id`, `handle`, `title` over most resources
43
+
44
+ <hr/>
45
+
46
+ Start by installing,
16
47
 
17
48
  Plus, everything is typed so you dont have to guess any parameter or queryable key
18
49
 
package/index.js CHANGED
@@ -1,3 +1,7 @@
1
+ /**
2
+ * @import { StorecraftSDKConfig } from './types.js'
3
+ * @import { App } from '@storecraft/core'
4
+ */
1
5
  import Auth from './src/auth.js'
2
6
  import Customers from './src/customers.js'
3
7
  import Tags from './src/tags.js'
@@ -16,24 +20,8 @@ import Payments from './src/payments.js'
16
20
  import Settings from './src/settings.js'
17
21
  import Notifications from './src/notifications.js'
18
22
  import Storage from './src/storage.js'
19
-
20
-
21
- /**
22
- * @typedef {import('@storecraft/core/api').ApiAuthResult |
23
- * import('@storecraft/core/api').ApiKeyResult
24
- * } SdkConfigAuth The `storecraft` **SDK** `auth` config, represents
25
- * either `apikey` or `jwt` authentication
26
- *
27
- */
28
-
29
-
30
- /**
31
- *
32
- * @typedef {object} StorecraftSDKConfig The `storecraft` **SDK** config
33
- * @property {string} [endpoint] Endpoint of `backend`
34
- * @property {SdkConfigAuth} [auth] `auth` info, may be either `apikey` or
35
- * `jwt` results
36
- */
23
+ import AI from './src/ai.js'
24
+ import Search from './src/search.js'
37
25
 
38
26
  /**
39
27
  * @description The official `storecraft` universal **SDK** for `javascript`
@@ -49,9 +37,10 @@ export class StorecraftSDK {
49
37
  constructor(config) {
50
38
  this.#_config = config;
51
39
 
40
+ this.ai = new AI(this);
41
+ this.search = new Search(this);
52
42
  this.auth = new Auth(this);
53
43
  this.storage = new Storage(this);
54
-
55
44
  this.customers = new Customers(this);
56
45
  this.tags = new Tags(this);
57
46
  this.templates = new Templates(this);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@storecraft/sdk",
3
- "version": "1.0.9",
3
+ "version": "1.0.11",
4
4
  "description": "Official storecraft Universal Javascript SDK",
5
5
  "license": "MIT",
6
6
  "author": "Tomer Shalev (https://github.com/store-craft)",
package/src/ai.js ADDED
@@ -0,0 +1,171 @@
1
+ /**
2
+ * @import {
3
+ * AgentRunParameters, AgentRunResponse
4
+ * } from '@storecraft/core/ai/agents/types.js'
5
+ * @import { content } from '@storecraft/core/ai/types.public.js'
6
+ */
7
+
8
+ import { HEADER_STORECRAFT_THREAD_ID } from '@storecraft/core/rest/con.ai.routes.js';
9
+ import { StorecraftSDK } from '../index.js'
10
+ import { url } from './utils.api.fetch.js';
11
+
12
+ /**
13
+ * @description **AI**
14
+ *
15
+ */
16
+ export default class AI {
17
+
18
+ /**
19
+ *
20
+ * @param {StorecraftSDK} sdk
21
+ */
22
+ constructor(sdk) {
23
+ this.sdk = sdk;
24
+ }
25
+
26
+ /**
27
+ * @description Speak with the main `storecraft` agent sync. It is
28
+ * recommended to use the streamed version {@link streamSpeak}
29
+ * @param {AgentRunParameters} params
30
+ * @returns {Promise<AgentRunResponse>}
31
+ */
32
+ speak = async (params) => {
33
+ const response = await fetch(
34
+ url(this.sdk.config, 'ai/agent/run'),
35
+ {
36
+ method: 'post',
37
+ body: JSON.stringify(params),
38
+ headers: {
39
+ 'Content-Type': 'application/json'
40
+ }
41
+ }
42
+ );
43
+
44
+ return response.json();
45
+ }
46
+
47
+ /**
48
+ * @description Stream Speak with the main `storecraft` agent via Server-Sent Events
49
+ * @param {AgentRunParameters} params
50
+ */
51
+ streamSpeak = async function(params) {
52
+ const response = await fetch(
53
+ url(this.sdk.config, 'ai/agent/stream'),
54
+ {
55
+ method: 'post',
56
+ body: JSON.stringify(params),
57
+ headers: {
58
+ 'Content-Type': 'application/json'
59
+ }
60
+ }
61
+ );
62
+
63
+ const threadId = response.headers.get(HEADER_STORECRAFT_THREAD_ID ?? 'X-Storecraft-Thread-Id');
64
+
65
+ if(!threadId) {
66
+ throw new Error(
67
+ `X-Storecraft-Thread-Id is missing, please tell the backend admin to
68
+ change the cors' Access-Control-Expose-Headers to accept the header`
69
+ )
70
+ }
71
+
72
+ return {
73
+ threadId,
74
+ generator: () => StreamSpeakGenerator(response.body)
75
+ }
76
+ }
77
+
78
+ }
79
+
80
+ const sleep = (ms=100) => {
81
+ return new Promise(
82
+ (resolve, reject) => {
83
+ setTimeout(
84
+ resolve, ms
85
+ )
86
+ }
87
+ )
88
+ }
89
+
90
+ /**
91
+ * @description Server Sent Events async generator
92
+ * @param {ReadableStream} stream web stream
93
+ */
94
+ const StreamSpeakGenerator = async function *(stream) {
95
+ for await (const sse of SSEGenerator(stream)) {
96
+ await sleep(50);
97
+ yield ( /** @type {content} */ (JSON.parse(sse.data)));
98
+ }
99
+ }
100
+
101
+ /**
102
+ * @description Server Sent Events async generator
103
+ * @param {ReadableStream} stream web stream
104
+ */
105
+ export const SSEGenerator = async function *(stream) {
106
+
107
+ let active_frame = [];
108
+ let residual_line = '';
109
+
110
+ const reader = stream.getReader();
111
+ let current = await reader.read();
112
+
113
+ while(!current.done) {
114
+
115
+ let text = (new TextDecoder()).decode(current.value);
116
+ // console.log('text \n\n', text)
117
+
118
+ if(residual_line) {
119
+ text = residual_line + text;
120
+ residual_line = '';
121
+ }
122
+
123
+ const lines = text.split(/\r\n|\n|\r/).map(l => l.trim());
124
+
125
+ for(const line of lines) {
126
+ if(line==='' && active_frame.length) {
127
+ // console.log('frame \n\n', active_frame)
128
+ // empty line means processing and dispatch
129
+ yield parse_frame(active_frame);
130
+ active_frame = [];
131
+ } else {
132
+ active_frame.push(line);
133
+ }
134
+ }
135
+
136
+ // if we got here and we have a line, then it
137
+ // was not finished (Otherwise, it would have been parsed and dispatched)
138
+ // I will need to prepend it to the next batch as it is incomplete
139
+ residual_line = active_frame.pop();
140
+
141
+ current = await reader.read();
142
+ }
143
+
144
+ }
145
+
146
+
147
+
148
+ /**
149
+ * @typedef {object} SSEFrame Server Sent Events frame
150
+ * @prop {string} [data]
151
+ * @prop {string} [event]
152
+ */
153
+
154
+ /**
155
+ *
156
+ * @param {string[]} lines
157
+ * @returns {SSEFrame}
158
+ */
159
+ const parse_frame = (lines) => {
160
+ return Object.fromEntries(
161
+ lines.map(
162
+ (l) => {
163
+ const delimiter = l.indexOf(':');
164
+ return [
165
+ l.slice(0, delimiter).trim(),
166
+ l.slice(delimiter + 1).trim(),
167
+ ]
168
+ }
169
+ )
170
+ );
171
+ }
package/src/auth.js CHANGED
@@ -3,6 +3,7 @@
3
3
  * ApiAuthChangePasswordType, ApiAuthResult, ApiAuthSigninType, ApiAuthSignupType,
4
4
  * ApiKeyResult, ApiQuery, AuthUserType, error
5
5
  * } from '@storecraft/core/api'
6
+ * @import { SdkConfigAuth } from '../types.js';
6
7
  */
7
8
 
8
9
  import { api_query_to_searchparams } from '@storecraft/core/api/utils.query.js';
@@ -12,10 +13,6 @@ import { assert } from './utils.functional.js';
12
13
 
13
14
 
14
15
  /**
15
- *
16
- * @typedef {import('../index.js').SdkConfigAuth} SdkConfigAuth
17
- *
18
- *
19
16
  * @typedef {object} SubscriberCallbackPayload
20
17
  * @prop {SdkConfigAuth} auth
21
18
  * @prop {boolean} isAuthenticated
@@ -72,7 +69,7 @@ export default class Auth {
72
69
  }
73
70
 
74
71
  /**
75
- * @param {import('../index.js').SdkConfigAuth} value
72
+ * @param {SdkConfigAuth} value
76
73
  */
77
74
  set currentAuth(value) {
78
75
  this.#sdk.config.auth = value;
package/src/checkout.js CHANGED
@@ -1,3 +1,6 @@
1
+ /**
2
+ * @import { CheckoutCreateType, OrderData, PricingData } from '@storecraft/core/api'
3
+ */
1
4
  import { StorecraftSDK } from '../index.js'
2
5
  import { fetchApiWithAuth } from './utils.api.fetch.js';
3
6
 
@@ -18,10 +21,10 @@ export default class Checkout {
18
21
  /**
19
22
  * @description Create a `checkout`
20
23
  *
21
- * @param {import('@storecraft/core/api').CheckoutCreateType} input
24
+ * @param {CheckoutCreateType} input
22
25
  * @param {string} gateway_handle
23
26
  *
24
- * @returns {Promise<Partial<import('@storecraft/core/api').OrderData>>}
27
+ * @returns {Promise<Partial<OrderData>>}
25
28
  */
26
29
  create = async (input, gateway_handle) => {
27
30
 
@@ -46,7 +49,7 @@ export default class Checkout {
46
49
  *
47
50
  * @param {string} order_id
48
51
  *
49
- * @returns {Promise<Partial<import('@storecraft/core/api').OrderData>>}
52
+ * @returns {Promise<Partial<OrderData>>}
50
53
  */
51
54
  complete = async (order_id) => {
52
55
 
@@ -62,11 +65,12 @@ export default class Checkout {
62
65
  }
63
66
 
64
67
  /**
65
- * @description calculate the pricing of an `order`. Using auto-discounts, coupons, shipping and line-items.
68
+ * @description calculate the pricing of an `order`. Using auto-discounts,
69
+ * coupons, shipping and line-items.
66
70
  *
67
- * @param {Partial<import('@storecraft/core/api').OrderData>} order
71
+ * @param {Partial<OrderData>} order
68
72
  *
69
- * @returns {Promise<Partial<import('@storecraft/core/api').PricingData>>}
73
+ * @returns {Promise<Partial<PricingData>>}
70
74
  */
71
75
  pricing = async (order) => {
72
76
 
@@ -1,3 +1,6 @@
1
+ /**
2
+ * @import { CollectionType, CollectionTypeUpsert } from '@storecraft/core/api'
3
+ */
1
4
  import { StorecraftSDK } from '../index.js'
2
5
  import { collection_base, fetchApiWithAuth } from './utils.api.fetch.js';
3
6
  import { filter_fields, filter_unused } from './utils.functional.js';
@@ -5,10 +8,7 @@ import { filter_fields, filter_unused } from './utils.functional.js';
5
8
  /**
6
9
  * @description Base `collections` **CRUD**
7
10
  *
8
- * @extends {collection_base<
9
- * import('@storecraft/core/api').CollectionTypeUpsert,
10
- * import('@storecraft/core/api').CollectionType>
11
- * }
11
+ * @extends {collection_base<CollectionTypeUpsert, CollectionType>}
12
12
  */
13
13
  export default class Collections extends collection_base {
14
14
 
package/src/customers.js CHANGED
@@ -1,13 +1,13 @@
1
+ /**
2
+ * @import { CustomerType, CustomerTypeUpsert } from '@storecraft/core/api'
3
+ */
1
4
  import { StorecraftSDK } from '../index.js'
2
5
  import { collection_base } from './utils.api.fetch.js';
3
6
 
4
7
  /**
5
8
  * @description Base `customers` **CRUD**
6
9
  *
7
- * @extends {collection_base<
8
- * import('@storecraft/core/api').CustomerTypeUpsert,
9
- * import('@storecraft/core/api').CustomerType>
10
- * }
10
+ * @extends {collection_base<CustomerTypeUpsert, CustomerType>}
11
11
  */
12
12
  export default class Customers extends collection_base {
13
13
 
package/src/discounts.js CHANGED
@@ -1,13 +1,13 @@
1
+ /**
2
+ * @import { DiscountType, DiscountTypeUpsert } from '@storecraft/core/api'
3
+ */
1
4
  import { StorecraftSDK } from '../index.js'
2
5
  import { collection_base } from './utils.api.fetch.js';
3
6
 
4
7
  /**
5
8
  * @description Base `discounts` **CRUD**
6
9
  *
7
- * @extends {collection_base<
8
- * import('@storecraft/core/api').DiscountTypeUpsert,
9
- * import('@storecraft/core/api').DiscountType>
10
- * }
10
+ * @extends {collection_base<DiscountTypeUpsert, DiscountType>}
11
11
  */
12
12
  export default class Discounts extends collection_base {
13
13
 
@@ -19,131 +19,4 @@ export default class Discounts extends collection_base {
19
19
  super(sdk, 'discounts');
20
20
  }
21
21
 
22
- // /**
23
- // *
24
- // * @param {DiscountData} discount_data
25
- // * @param {number} limit
26
- // */
27
- // publish = async (discount_data, limit=10000) => {
28
- // const coll_handle = `discount-${discount_data.code}`
29
- // const dd = {
30
- // ...discount_data,
31
- // _published: coll_handle
32
- // }
33
- // if(dd.info.details.meta.type==='order')
34
- // throw 'Exporting a discount collection is only available for \
35
- // Product discounts (you chose Order discount)'
36
-
37
- // // save current document, allow to fail
38
- // await this.set(
39
- // dd.code, dd
40
- // )
41
- // // await this.update(dd.code, { _published: coll_handle })
42
-
43
-
44
- // // first, remove all previous collection tag from previous products
45
- // try {
46
- // const products_to_remove =
47
- // await this.context.products.list([`col:${coll_handle}`], 10000)
48
- // // console.log('products_to_remove ', products_to_remove);
49
- // const batch_remove = writeBatch(this.context.firebase.db)
50
- // products_to_remove.forEach(it => {
51
- // const ref = doc(this.context.firebase.db, 'products', it[0])
52
- // batch_remove.update(ref, {
53
- // search : arrayRemove(`col:${coll_handle}`),
54
- // collections : arrayRemove(coll_handle),
55
- // [`discounts.${dd.code}`]: deleteField()
56
- // })
57
- // })
58
- // await batch_remove.commit()
59
-
60
- // } catch (e) {
61
- // console.log('Remove old: ' + String(e))
62
- // console.log(e)
63
- // }
64
-
65
- // try {
66
- // // filter in product filters
67
- // var product_filters = dd.info.filters.filter(f => f.meta.type==='product')
68
-
69
- // // then, make a server search that will filter out as much as possible
70
- // /**@type {Filter} */
71
- // var first_guided_filter = undefined
72
- // /**@type {string[]} */
73
- // var first_guided_search_terms = undefined
74
-
75
- // if(first_guided_filter = product_filters.find(f => f.meta.op==='p-in-handles')) {
76
- // first_guided_search_terms = first_guided_filter.value
77
- // }
78
- // else if(first_guided_filter = product_filters.find(f => f.meta.op==='p-in-tags')) {
79
- // first_guided_search_terms = first_guided_filter.value.map(t => `tag:${t}`)
80
- // }
81
- // else if(first_guided_filter = product_filters.find(f => f.meta.op==='p-in-collections')) {
82
- // first_guided_search_terms = first_guided_filter.value.map(c => `col:${c}`)
83
- // }
84
- // } catch (e) {
85
- // throw 'Filter preparing error: ' + String(e)
86
- // }
87
-
88
- // try {
89
- // // then, global filtering, this helps to reduce legal products for filtering
90
- // var products = await
91
- // this.context.products.list(first_guided_search_terms, limit)
92
-
93
- // // now local filtering (due to firebase limitations with filtering)
94
- // var filtered_products =
95
- // this.filterProductsWithFilters(products, product_filters)
96
-
97
- // // products = products.slice(0, 400)
98
- // } catch (e) {
99
- // throw 'Filtering error: ' + String(e)
100
- // }
101
-
102
- // try {
103
- // // add collection tag to each product with batch write
104
- // const batch = writeBatch(this.context.firebase.db)
105
- // filtered_products.forEach(it => {
106
- // const p = it[1]
107
- // const isActive = p?.active==true || (p.active===undefined)
108
- // if(!isActive)
109
- // return;
110
-
111
- // const ref = doc(this.context.firebase.db, 'products', it[0])
112
- // const dd_mod = {...dd}
113
- // delete dd_mod.search
114
- // delete dd_mod.order
115
- // batch.update(ref, {
116
- // collections : arrayUnion(coll_handle),
117
- // search : arrayUnion(`col:${coll_handle}`),
118
- // [`discounts.${dd_mod.code}`]: dd_mod
119
- // })
120
- // })
121
- // await batch.commit()
122
- // } catch (e) {
123
- // throw 'Products update failed: ' + String(e)
124
- // }
125
-
126
- // try {
127
- // // now, create a new collection
128
- // /**@type {import('./js-docs-types').CollectionData} */
129
- // const col_discount = {
130
- // desc : dd.desc,
131
- // handle : coll_handle,
132
- // title : dd.title,
133
- // media : dd.media,
134
- // tags : dd.tags,
135
- // attributes: dd.attributes,
136
- // createdAt: Date.now()
137
- // }
138
-
139
- // await this.context.collections.set(
140
- // col_discount.handle, col_discount
141
- // )
142
- // // await this.update(discount_data.code, { _published: coll_handle })
143
- // } catch (e) {
144
- // throw 'Collection creation failed: ' + String(e)
145
- // }
146
-
147
- // }
148
-
149
22
  }
package/src/images.js CHANGED
@@ -1,13 +1,13 @@
1
+ /**
2
+ * @import { ImageTypeUpsert, ImageType } from '@storecraft/core/api'
3
+ */
1
4
  import { StorecraftSDK } from '../index.js'
2
5
  import { collection_base } from './utils.api.fetch.js';
3
6
 
4
7
  /**
5
8
  * @description Base `images` **CRUD**
6
9
  *
7
- * @extends {collection_base<
8
- * import('@storecraft/core/api').ImageTypeUpsert,
9
- * import('@storecraft/core/api').ImageType>
10
- * }
10
+ * @extends {collection_base<ImageTypeUpsert, ImageType>}
11
11
  */
12
12
  export default class Images extends collection_base {
13
13
 
@@ -1,3 +1,6 @@
1
+ /**
2
+ * @import { NotificationTypeUpsert, NotificationType } from '@storecraft/core/api'
3
+ */
1
4
  import { StorecraftSDK } from '../index.js'
2
5
  import {
3
6
  collection_base, fetchApiWithAuth
@@ -6,10 +9,7 @@ import {
6
9
  /**
7
10
  * @description Base `notifications` **CRUD**
8
11
  *
9
- * @extends {collection_base<
10
- * import('@storecraft/core/api').NotificationTypeUpsert,
11
- * import('@storecraft/core/api').NotificationType>
12
- * }
12
+ * @extends {collection_base<NotificationTypeUpsert, NotificationType>}
13
13
  */
14
14
  export default class Notifications extends collection_base {
15
15
 
@@ -23,7 +23,7 @@ export default class Notifications extends collection_base {
23
23
 
24
24
  /**
25
25
  *
26
- * @param {import('@storecraft/core/api').NotificationTypeUpsert[]} items
26
+ * @param {NotificationTypeUpsert[]} items
27
27
  */
28
28
  upsertBulk = items => {
29
29
  return fetchApiWithAuth(
package/src/orders.js CHANGED
@@ -1,13 +1,13 @@
1
+ /**
2
+ * @import { OrderDataUpsert, OrderData } from '@storecraft/core/api'
3
+ */
1
4
  import { StorecraftSDK } from '../index.js'
2
5
  import { collection_base } from './utils.api.fetch.js';
3
6
 
4
7
  /**
5
8
  * @description Base `orders` **CRUD**
6
9
  *
7
- * @extends {collection_base<
8
- * import('@storecraft/core/api').OrderDataUpsert,
9
- * import('@storecraft/core/api').OrderData>
10
- * }
10
+ * @extends {collection_base<OrderDataUpsert, OrderData>}
11
11
  */
12
12
  export default class Orders extends collection_base {
13
13
 
package/src/payments.js CHANGED
@@ -1,6 +1,9 @@
1
+ /**
2
+ * @import { PaymentGatewayItemGet, PaymentGatewayStatus } from '@storecraft/core/api'
3
+ */
1
4
  import { StorecraftSDK } from '../index.js'
2
5
  import {
3
- fetchApiWithAuth, get, list
6
+ fetchApiWithAuth, get_from_collection_resource, list_from_collection_resource
4
7
  } from './utils.api.fetch.js';
5
8
 
6
9
  /**
@@ -8,7 +11,7 @@ import {
8
11
  */
9
12
  export default class Payments {
10
13
 
11
- /** @type {import('../index.js').StorecraftSDK} */
14
+ /** @type {StorecraftSDK} */
12
15
  #sdk = undefined;
13
16
 
14
17
  /**
@@ -24,19 +27,19 @@ export default class Payments {
24
27
  * @param {string} handle payment gateway `handle`
25
28
  *
26
29
  *
27
- * @returns {Promise<import('@storecraft/core/api').PaymentGatewayItemGet>}
30
+ * @returns {Promise<PaymentGatewayItemGet>}
28
31
  */
29
32
  get(handle) {
30
- return get(this.sdk, 'payments/gateways', handle);
33
+ return get_from_collection_resource(this.sdk, 'payments/gateways', handle);
31
34
  }
32
35
 
33
36
  /**
34
37
  *
35
38
  *
36
- * @returns {Promise<import('@storecraft/core/api').PaymentGatewayItemGet[]>}
39
+ * @returns {Promise<PaymentGatewayItemGet[]>}
37
40
  */
38
41
  list() {
39
- return list(this.sdk, 'payments/gateways');
42
+ return list_from_collection_resource(this.sdk, 'payments/gateways');
40
43
  }
41
44
 
42
45
 
@@ -48,7 +51,7 @@ export default class Payments {
48
51
  *
49
52
  * @param {string} order_id
50
53
  *
51
- * @returns {Promise<import('@storecraft/core/api').PaymentGatewayStatus>}
54
+ * @returns {Promise<PaymentGatewayStatus>}
52
55
  */
53
56
  paymentStatusOfOrder(order_id) {
54
57
  return fetchApiWithAuth(
@@ -62,14 +65,15 @@ export default class Payments {
62
65
 
63
66
  /**
64
67
  *
65
- * Invoke a `payment gateway` action on `order`
68
+ * Invoke a `payment gateway` action on `order`. The list of available actions can be found
69
+ * using {@link get_from_collection_resource} or {@link paymentStatusOfOrder}
66
70
  *
67
71
  *
68
72
  * @param {string} action_handle The `action` handle at the gateway
69
73
  * @param {string} order_id the `id` of the `order`
70
74
  *
71
75
  *
72
- * @returns {Promise<import('@storecraft/core/api').PaymentGatewayStatus>}
76
+ * @returns {Promise<PaymentGatewayStatus>}
73
77
  */
74
78
  invokeAction(action_handle, order_id) {
75
79
  return fetchApiWithAuth(
package/src/posts.js CHANGED
@@ -1,13 +1,13 @@
1
+ /**
2
+ * @import { PostTypeUpsert, PostType } from '@storecraft/core/api'
3
+ */
1
4
  import { StorecraftSDK } from '../index.js'
2
5
  import { collection_base } from './utils.api.fetch.js';
3
6
 
4
7
  /**
5
8
  * @description Base `posts` **CRUD**
6
9
  *
7
- * @extends {collection_base<
8
- * import('@storecraft/core/api').PostTypeUpsert,
9
- * import('@storecraft/core/api').PostType>
10
- * }
10
+ * @extends {collection_base<PostTypeUpsert, PostType>}
11
11
  */
12
12
  export default class Posts extends collection_base {
13
13
 
package/src/products.js CHANGED
@@ -1,3 +1,6 @@
1
+ /**
2
+ * @import { ProductTypeUpsert, ProductType, CollectionType } from '@storecraft/core/api'
3
+ */
1
4
  import { StorecraftSDK } from '../index.js'
2
5
  import {
3
6
  collection_base, fetchOnlyApiResponseWithAuth
@@ -6,10 +9,7 @@ import {
6
9
  /**
7
10
  * @description Base `products` **CRUD**
8
11
  *
9
- * @extends {collection_base<
10
- * import('@storecraft/core/api').ProductTypeUpsert,
11
- * import('@storecraft/core/api').ProductType>
12
- * }
12
+ * @extends {collection_base<ProductTypeUpsert, ProductType>}
13
13
  */
14
14
  export default class Products extends collection_base {
15
15
 
@@ -44,8 +44,8 @@ export default class Products extends collection_base {
44
44
  /**
45
45
  * Add `products` to `collection`
46
46
  *
47
- * @param {import('@storecraft/core/api').ProductType[]} products
48
- * @param {import('@storecraft/core/api').CollectionType} collection
47
+ * @param {ProductType[]} products
48
+ * @param {CollectionType} collection
49
49
  */
50
50
  batchAddProductsToCollection = async (products, collection) => {
51
51
  for (const pr of products) {
@@ -59,8 +59,8 @@ export default class Products extends collection_base {
59
59
  /**
60
60
  * Remove `products` from `collection`
61
61
  *
62
- * @param {import('@storecraft/core/api').ProductType[]} products
63
- * @param {import('@storecraft/core/api').CollectionType} collection
62
+ * @param {ProductType[]} products
63
+ * @param {CollectionType} collection
64
64
  */
65
65
  batchRemoveProductsFromCollection = async (products, collection) => {
66
66
  for (const pr of products) {
package/src/search.js ADDED
@@ -0,0 +1,84 @@
1
+ /**
2
+ * @import {
3
+ * AgentRunParameters, AgentRunResponse
4
+ * } from '@storecraft/core/ai/agents/types.js'
5
+ * @import {
6
+ * ApiQuery, QuickSearchResult, SimilaritySearchInput, SimilaritySearchResult
7
+ * } from '@storecraft/core/api'
8
+ */
9
+
10
+ import {
11
+ api_query_to_searchparams, object_to_search_params,
12
+ parse_query, string_array_to_string
13
+ } from '@storecraft/core/api/utils.query.js';
14
+ import { HEADER_STORECRAFT_THREAD_ID } from '@storecraft/core/rest/con.ai.routes.js';
15
+ import { StorecraftSDK } from '../index.js'
16
+ import { fetchApiWithAuth, url } from './utils.api.fetch.js';
17
+
18
+ /**
19
+ * @description **Search** API (two options):
20
+ *
21
+ * - Quick Search across many resources
22
+ * - Similarity search across `discount`, `products`, `collections`, `shipping`
23
+ *
24
+ */
25
+ export default class Search {
26
+
27
+ /**
28
+ *
29
+ * @param {StorecraftSDK} sdk
30
+ */
31
+ constructor(sdk) {
32
+ this.sdk = sdk;
33
+ }
34
+
35
+ /**
36
+ * @description List super lite search results with `id`, `handle`, `title`.
37
+ * Primarily used for quick and responsive lookup, this is cheap and cost-effective
38
+ * and works well in the dashboard. If an admin is hitting the endpoint, then he can
39
+ * even get results for orders, customer and auth_users. You can also use the expand in the
40
+ * query to efficiently control which resources are searched at the database
41
+ * @param {ApiQuery} params A regular {@link ApiQuery} object
42
+ * @returns {Promise<QuickSearchResult>}
43
+ */
44
+ quick = async (params) => {
45
+
46
+ /** @type {QuickSearchResult} */
47
+ const json = await fetchApiWithAuth(
48
+ this.sdk,
49
+ 'search',
50
+ { method: 'get' },
51
+ api_query_to_searchparams(params)
52
+ );
53
+
54
+ return json;
55
+ }
56
+
57
+
58
+ /**
59
+ * @description Search Storecraft with AI for similar
60
+ * `products`, `discounts`, `collections`, `shipping`
61
+ * based on a prompt
62
+ * @param {SimilaritySearchInput} params A {@link SimilaritySearchInput} object
63
+ * @returns {Promise<SimilaritySearchResult>}
64
+ */
65
+ similarity = async (params) => {
66
+
67
+ /** @type {SimilaritySearchResult} */
68
+ const json = await fetchApiWithAuth(
69
+ this.sdk,
70
+ 'similarity-search',
71
+ { method: 'get' },
72
+ object_to_search_params({
73
+ q: params.q,
74
+ namespaces: string_array_to_string(params.namespaces),
75
+ limit: params.limit ?? 5
76
+ })
77
+ );
78
+
79
+ return json;
80
+ }
81
+
82
+ }
83
+
84
+
package/src/shipping.js CHANGED
@@ -1,13 +1,13 @@
1
+ /**
2
+ * @import { ShippingMethodTypeUpsert, ShippingMethodType } from '@storecraft/core/api'
3
+ */
1
4
  import { StorecraftSDK } from '../index.js'
2
5
  import { collection_base } from './utils.api.fetch.js';
3
6
 
4
7
  /**
5
8
  * @description Base `shipping` **CRUD**
6
9
  *
7
- * @extends {collection_base<
8
- * import('@storecraft/core/api').ShippingMethodTypeUpsert,
9
- * import('@storecraft/core/api').ShippingMethodType>
10
- * }
10
+ * @extends {collection_base<ShippingMethodTypeUpsert, ShippingMethodType>}
11
11
  */
12
12
  export default class Shipping extends collection_base {
13
13
 
package/src/statistics.js CHANGED
@@ -1,3 +1,6 @@
1
+ /**
2
+ * @import { OrdersStatisticsType, ApiQuery } from '@storecraft/core/api'
3
+ */
1
4
  import { App } from '@storecraft/core';
2
5
  import { StorecraftSDK } from '../index.js'
3
6
  import { fetchApiWithAuth } from './utils.api.fetch.js';
@@ -38,7 +41,7 @@ export default class Statistics {
38
41
  /**
39
42
  *
40
43
  * @param {string} key
41
- * @returns {import('@storecraft/core/api').OrdersStatisticsType}
44
+ * @returns {OrdersStatisticsType}
42
45
  */
43
46
  fromCache = (key) => {
44
47
  if(this.isCacheValid(key))
@@ -49,7 +52,7 @@ export default class Statistics {
49
52
  /**
50
53
  *
51
54
  * @param {string} key
52
- * @param {import('@storecraft/core/api').OrdersStatisticsType} value
55
+ * @param {OrdersStatisticsType} value
53
56
  */
54
57
  putCache = (key, value) => {
55
58
  this.#cache[key] = value
@@ -62,7 +65,7 @@ export default class Statistics {
62
65
  * @param {string | number | Date} [from_day] `ISO` string | `UTC` | `timestamp` | `Date`
63
66
  * @param {string | number | Date} [to_day] `ISO` string | `UTC` | `timestamp` | `Date`
64
67
  *
65
- * @returns {Promise<import('@storecraft/core/api').OrdersStatisticsType>}
68
+ * @returns {Promise<OrdersStatisticsType>}
66
69
  */
67
70
  orders = async (from_day, to_day) => {
68
71
  const search = new URLSearchParams();
@@ -82,7 +85,7 @@ export default class Statistics {
82
85
  * @description Load **count** `statistics`
83
86
  *
84
87
  * @param {keyof App["db"]["resources"]} table
85
- * @param {import('@storecraft/core/api').ApiQuery} [query]
88
+ * @param {ApiQuery} [query]
86
89
  *
87
90
  *
88
91
  * @returns {Promise<number>}
package/src/storage.js CHANGED
@@ -1,3 +1,7 @@
1
+ /**
2
+ * @import { StorageFeatures, StorageSignedOperation } from '@storecraft/core/storage'
3
+ * @import { error } from '@storecraft/core/api'
4
+ */
1
5
 
2
6
  import { StorecraftSDK } from '../index.js'
3
7
  import { fetchOnlyApiResponseWithAuth } from './utils.api.fetch.js'
@@ -16,7 +20,7 @@ export default class Storage {
16
20
 
17
21
  /**
18
22
  * @type {{
19
- * features: import('@storecraft/core/storage').StorageFeatures
23
+ * features: StorageFeatures
20
24
  * }}
21
25
  */
22
26
  #cache = {
@@ -36,7 +40,7 @@ export default class Storage {
36
40
  * - Does `storage` supports `pre-signed` urls for `download` / `upload`
37
41
  *
38
42
  *
39
- * @returns {Promise<import('@storecraft/core/storage').StorageFeatures>}
43
+ * @returns {Promise<StorageFeatures>}
40
44
  */
41
45
  features = async () => {
42
46
  if(this.#cache.features)
@@ -78,7 +82,7 @@ export default class Storage {
78
82
  *
79
83
  * @return {Promise<Blob>}
80
84
  *
81
- * @throws {import('@storecraft/core/api').error}
85
+ * @throws {error}
82
86
  */
83
87
  getBlobSigned = async (key) => {
84
88
 
@@ -98,7 +102,7 @@ export default class Storage {
98
102
 
99
103
  // `presigned` url instructions
100
104
  if(ctype === 'application/json') {
101
- /** @type {import('@storecraft/core/storage').StorageSignedOperation} */
105
+ /** @type {StorageSignedOperation} */
102
106
  const presigned_req = await r.json();
103
107
 
104
108
  const presigned_res = await fetch(
@@ -123,7 +127,7 @@ export default class Storage {
123
127
  *
124
128
  * @return {Promise<Blob>}
125
129
  *
126
- * @throws {import('@storecraft/core/api').error}
130
+ * @throws {error}
127
131
  */
128
132
  getBlobUnsigned = async (key) => {
129
133
 
@@ -152,7 +156,7 @@ export default class Storage {
152
156
  *
153
157
  * @return {Promise<Blob>}
154
158
  *
155
- * @throws {import('@storecraft/core/api').error}
159
+ * @throws {error}
156
160
  */
157
161
  getBlob = async (key) => {
158
162
 
@@ -238,7 +242,7 @@ export default class Storage {
238
242
 
239
243
  // `presigned` url instructions
240
244
  if(ctype === 'application/json') {
241
- /** @type {import('@storecraft/core/storage').StorageSignedOperation} */
245
+ /** @type {StorageSignedOperation} */
242
246
  const presigned_req = await r.json();
243
247
  const presigned_res = await fetch(
244
248
  presigned_req.url,
@@ -294,7 +298,7 @@ export default class Storage {
294
298
  *
295
299
  * @return {Promise<boolean>}
296
300
  *
297
- * @throws {import('@storecraft/core/api').error}
301
+ * @throws {error}
298
302
  */
299
303
  putBytes = async (key, data) => {
300
304
 
@@ -1,13 +1,14 @@
1
+ /**
2
+ * @import { HandleOrId } from '@storecraft/core/database'
3
+ * @import { StorefrontType, StorefrontTypeUpsert } from '@storecraft/core/api'
4
+ */
1
5
  import { StorecraftSDK } from '../index.js'
2
6
  import { collection_base, fetchApiWithAuth } from './utils.api.fetch.js';
3
7
 
4
8
  /**
5
9
  * @description Base `storefronts` **CRUD**
6
10
  *
7
- * @extends {collection_base<
8
- * import('@storecraft/core/api').StorefrontTypeUpsert,
9
- * import('@storecraft/core/api').StorefrontType>
10
- * }
11
+ * @extends {collection_base<StorefrontTypeUpsert, StorefrontType>}
11
12
  */
12
13
  export default class Storefronts extends collection_base {
13
14
 
@@ -24,7 +25,7 @@ export default class Storefronts extends collection_base {
24
25
  * beneficial for `collections`, that hardly change and therefore can be
25
26
  * efficiently stored in a cost-effective `storage` and **CDN** network.
26
27
  *
27
- * @param {import('@storecraft/core/database').HandleOrId} handle_or_id
28
+ * @param {HandleOrId} handle_or_id
28
29
  */
29
30
  publish = async (handle_or_id) => {
30
31
 
package/src/tags.js CHANGED
@@ -1,13 +1,13 @@
1
+ /**
2
+ * @import { TagType, TagTypeUpsert } from '@storecraft/core/api'
3
+ */
1
4
  import { StorecraftSDK } from '../index.js'
2
5
  import { collection_base } from './utils.api.fetch.js';
3
6
 
4
7
  /**
5
8
  * @description Base `tags` **CRUD**
6
9
  *
7
- * @extends {collection_base<
8
- * import('@storecraft/core/api').TagTypeUpsert,
9
- * import('@storecraft/core/api').TagType>
10
- * }
10
+ * @extends {collection_base<TagTypeUpsert, TagType>}
11
11
  */
12
12
  export default class Tags extends collection_base {
13
13
 
package/src/templates.js CHANGED
@@ -1,13 +1,13 @@
1
+ /**
2
+ * @import { TemplateTypeUpsert, TemplateType } from '@storecraft/core/api'
3
+ */
1
4
  import { StorecraftSDK } from '../index.js'
2
5
  import { collection_base } from './utils.api.fetch.js';
3
6
 
4
7
  /**
5
8
  * @description Base `templates` **CRUD**
6
9
  *
7
- * @extends {collection_base<
8
- * import('@storecraft/core/api').TemplateTypeUpsert,
9
- * import('@storecraft/core/api').TemplateType>
10
- * }
10
+ * @extends {collection_base<TemplateTypeUpsert, TemplateType>}
11
11
  */
12
12
  export default class Templates extends collection_base {
13
13
 
@@ -1,4 +1,8 @@
1
-
1
+ /**
2
+ * @import { error, ApiQuery } from '@storecraft/core/api'
3
+ * @import { StorecraftSDK } from '../index.js'
4
+ * @import { StorecraftSDKConfig } from '../types.js'
5
+ */
2
6
  import {
3
7
  api_query_to_searchparams
4
8
  } from '@storecraft/core/api/utils.query.js';
@@ -7,15 +11,21 @@ import { assert } from './utils.functional.js';
7
11
 
8
12
  /**
9
13
  *
10
- * @param {import("../index.js").StorecraftSDKConfig} config
14
+ * @param {StorecraftSDKConfig} config
11
15
  * @param {string} path
16
+ * @param {URLSearchParams} [query] url search params
12
17
  */
13
- export const url = (config, path) => {
18
+ export const url = (config, path, query) => {
14
19
  let base = config?.endpoint?.trim();
15
20
 
16
21
  base = base?.endsWith('/') ? base.slice(0, -1) : base;
17
22
  path = path?.startsWith('/') ? path.slice(1) : path;
18
23
 
24
+ if(query?.size) {
25
+ path = path?.endsWith('/') ? path.slice(0, -1) : path;
26
+ path += '?' + query.toString();
27
+ }
28
+
19
29
  return base ? `${base}/api/${path}` : `/api/${path}`;
20
30
  }
21
31
 
@@ -26,13 +36,14 @@ export const url = (config, path) => {
26
36
  * - Fetches with `authentication` middleware.
27
37
  * - Refreshed `auth` if needed.
28
38
  *
29
- * @param {import('../index.js').StorecraftSDK} sdk
39
+ * @param {StorecraftSDK} sdk
30
40
  * @param {string} path relative path in api
31
41
  * @param {RequestInit} [init] request `init` type
42
+ * @param {URLSearchParams} [query] url search params
32
43
  *
33
44
  * @returns {Promise<Response>}
34
45
  */
35
- export const fetchOnlyApiResponseWithAuth = async (sdk, path, init={}) => {
46
+ export const fetchOnlyApiResponseWithAuth = async (sdk, path, init={}, query=undefined) => {
36
47
 
37
48
  const auth_token = await sdk.auth.working_auth_token();
38
49
  const auth_header_value = (
@@ -41,7 +52,7 @@ export const fetchOnlyApiResponseWithAuth = async (sdk, path, init={}) => {
41
52
 
42
53
 
43
54
  const response = await fetch(
44
- url(sdk.config, path),
55
+ url(sdk.config, path, query),
45
56
  {
46
57
  ...init,
47
58
  headers: {
@@ -71,19 +82,19 @@ export const fetchOnlyApiResponseWithAuth = async (sdk, path, init={}) => {
71
82
  *
72
83
  * @template {any} R
73
84
  *
74
- * @param {import('../index.js').StorecraftSDK} sdk
85
+ * @param {StorecraftSDK} sdk
75
86
  * @param {string} path relative path in api
76
87
  * @param {RequestInit} [init] request `init` type
88
+ * @param {URLSearchParams} [query] url search params
77
89
  *
78
- *
79
- * @throws {import('@storecraft/core/api').error}
90
+ * @throws {error}
80
91
  *
81
92
  * @returns {Promise<R>}
82
93
  */
83
- export const fetchApiWithAuth = async (sdk, path, init={}) => {
94
+ export const fetchApiWithAuth = async (sdk, path, init={}, query=undefined) => {
84
95
 
85
96
  const response = await fetchOnlyApiResponseWithAuth(
86
- sdk, path, init
97
+ sdk, path, init, query
87
98
  );
88
99
 
89
100
  // console.log('fetchApiWithAuth::response', response)
@@ -108,14 +119,14 @@ export const fetchApiWithAuth = async (sdk, path, init={}) => {
108
119
  * @template {any} G Get type
109
120
  *
110
121
  *
111
- * @param {import('../index.js').StorecraftSDK} sdk
122
+ * @param {StorecraftSDK} sdk
112
123
  * @param {string} handle_or_id `handle` or `id`
113
124
  * @param {string} resource base path of resource
114
125
  *
115
126
  *
116
127
  * @returns {Promise<G>}
117
128
  */
118
- export async function get(sdk, resource, handle_or_id) {
129
+ export async function get_from_collection_resource(sdk, resource, handle_or_id) {
119
130
  return fetchApiWithAuth(
120
131
  sdk,
121
132
  `${resource}/${handle_or_id}`,
@@ -131,14 +142,14 @@ export async function get(sdk, resource, handle_or_id) {
131
142
  * @template {any} U the upsert type
132
143
  *
133
144
  *
134
- * @param {import('../index.js').StorecraftSDK} sdk
145
+ * @param {StorecraftSDK} sdk
135
146
  * @param {string} resource base path of resource
136
147
  * @param {U} item Item to upsert
137
148
  *
138
149
  *
139
150
  * @returns {Promise<string>} id
140
151
  */
141
- export async function upsert(sdk, resource, item) {
152
+ export async function upsert_to_collection_resource(sdk, resource, item) {
142
153
  return fetchApiWithAuth(
143
154
  sdk,
144
155
  `${resource}`,
@@ -155,14 +166,14 @@ export async function upsert(sdk, resource, item) {
155
166
 
156
167
  /**
157
168
  *
158
- * @param {import('../index.js').StorecraftSDK} sdk
169
+ * @param {StorecraftSDK} sdk
159
170
  * @param {string} resource base path of resource
160
171
  * @param {string} handle_or_id `handle` or `id`
161
172
  *
162
173
  *
163
174
  * @returns {Promise<boolean>}
164
175
  */
165
- export async function remove(sdk, resource, handle_or_id) {
176
+ export async function remove_from_collection_resource(sdk, resource, handle_or_id) {
166
177
  return fetchApiWithAuth(
167
178
  sdk,
168
179
  `${resource}/${handle_or_id}`,
@@ -181,14 +192,14 @@ export async function remove(sdk, resource, handle_or_id) {
181
192
  * @template {any} G Get type
182
193
  *
183
194
  *
184
- * @param {import('../index.js').StorecraftSDK} sdk
195
+ * @param {StorecraftSDK} sdk
185
196
  * @param {string} resource base path of resource
186
- * @param {import('@storecraft/core/api').ApiQuery<G>} [query]
197
+ * @param {ApiQuery<G>} [query]
187
198
  *
188
199
  *
189
200
  * @returns {Promise<G[]>}
190
201
  */
191
- export async function list(sdk, resource, query={}) {
202
+ export async function list_from_collection_resource(sdk, resource, query={}) {
192
203
  const sq = api_query_to_searchparams(query);
193
204
 
194
205
  // console.log('sq', sq.toString())
@@ -210,7 +221,7 @@ export async function list(sdk, resource, query={}) {
210
221
  */
211
222
  export class collection_base {
212
223
 
213
- /** @type {import('../index.js').StorecraftSDK} */
224
+ /** @type {StorecraftSDK} */
214
225
  #sdk = undefined;
215
226
 
216
227
  /** @type {string} */
@@ -218,7 +229,7 @@ export class collection_base {
218
229
 
219
230
  /**
220
231
  *
221
- * @param {import('../index.js').StorecraftSDK} sdk storecraft sdk
232
+ * @param {StorecraftSDK} sdk storecraft sdk
222
233
  * @param {string} base_name base name of resource type
223
234
  */
224
235
  constructor(sdk, base_name) {
@@ -235,7 +246,7 @@ export class collection_base {
235
246
  * @returns {Promise<G>}
236
247
  */
237
248
  async get(handle_or_id) {
238
- return get(this.sdk, this.base_name, handle_or_id);
249
+ return get_from_collection_resource(this.sdk, this.base_name, handle_or_id);
239
250
  }
240
251
 
241
252
  /**
@@ -246,7 +257,7 @@ export class collection_base {
246
257
  * @returns {Promise<string>} id
247
258
  */
248
259
  async upsert(item) {
249
- return upsert(this.sdk, this.base_name, item);
260
+ return upsert_to_collection_resource(this.sdk, this.base_name, item);
250
261
  }
251
262
 
252
263
  /**
@@ -257,18 +268,18 @@ export class collection_base {
257
268
  * @returns {Promise<boolean>}
258
269
  */
259
270
  async remove(handle_or_id) {
260
- return remove(this.sdk, this.base_name, handle_or_id);
271
+ return remove_from_collection_resource(this.sdk, this.base_name, handle_or_id);
261
272
  }
262
273
 
263
274
  /**
264
275
  *
265
- * @param {import('@storecraft/core/api').ApiQuery<G>} query Query object
276
+ * @param {ApiQuery<G>} query Query object
266
277
  *
267
278
  *
268
279
  * @returns {Promise<G[]>}
269
280
  */
270
281
  async list(query) {
271
- return list(this.sdk, this.base_name, query);
282
+ return list_from_collection_resource(this.sdk, this.base_name, query);
272
283
  }
273
284
 
274
285
  get base_name() {
@@ -89,7 +89,9 @@ export const text2tokens = (text) => {
89
89
  // let tokens = text?.toString().toLowerCase().match(/[^\W_]+/g)
90
90
  let tokens = text?.toString().toLowerCase().match(/[\p{L}\d]+/gu)
91
91
 
92
+ // @ts-ignore
92
93
  tokens = tokens ?? []
94
+ // @ts-ignore
93
95
  tokens = tokens.filter(
94
96
  t => !STOP_WORDS.includes(t)
95
97
  )
package/types.d.ts CHANGED
@@ -1 +1,21 @@
1
- export * from './index.js';
1
+ import type { ApiAuthResult, ApiKeyResult } from '@storecraft/core/api';
2
+
3
+ export * from './index.js';
4
+
5
+ /**
6
+ * @description The `storecraft` **SDK**
7
+ * `auth` config, represents either `apikey` or `jwt` authentication
8
+ */
9
+ export type SdkConfigAuth = ApiAuthResult | ApiKeyResult;
10
+
11
+ /**
12
+ * @description The `storecraft` **SDK** config
13
+ */
14
+ export type StorecraftSDKConfig = {
15
+
16
+ /** Endpoint of `backend` */
17
+ endpoint?: string;
18
+
19
+ /** `auth` info, may be either `apikey` or `jwt` results */
20
+ auth?: SdkConfigAuth;
21
+ }