@storecraft/sdk 0.1.0 → 1.0.1
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 +8 -0
- package/index.js +5 -5
- package/{tsconfig.json → jsconfig.json} +0 -4
- package/package.json +1 -1
- package/src/auth.js +87 -19
- package/src/checkout.js +88 -0
- package/src/collections.js +14 -69
- package/src/customers.js +3 -3
- package/src/discounts.js +125 -125
- package/src/images.js +3 -3
- package/src/notifications.js +4 -60
- package/src/orders.js +3 -28
- package/src/payments.js +5 -5
- package/src/posts.js +3 -3
- package/src/products.js +7 -7
- package/src/settings.js +1 -1
- package/src/shipping.js +3 -3
- package/src/statistics.js +10 -7
- package/src/storage.js +18 -18
- package/src/storefronts.js +16 -87
- package/src/tags.js +3 -3
- package/src/templates.js +3 -3
- package/src/utils.api.fetch.js +7 -6
- package/types.d.ts +1 -1
- package/src/bots.js +0 -113
package/README.md
CHANGED
@@ -1,5 +1,10 @@
|
|
1
1
|
# **Storecraft** Official Universal `Javascript` **SDK**
|
2
2
|
|
3
|
+
<div style="text-align:center">
|
4
|
+
<img src='https://storecraft.app/storecraft-color.svg'
|
5
|
+
width='90%' />
|
6
|
+
</div><hr/><br/>
|
7
|
+
|
3
8
|
This is the official `storecraft` universal javascript `SDK` which is `fetch` based,
|
4
9
|
which means you can you it both at browser and at backend runtimes such (`node` / `bun` / `deno`)
|
5
10
|
|
@@ -9,6 +14,9 @@ convenient manner with `javascript`, such as:
|
|
9
14
|
`storage`, `storefronts`, `shipping`, `statistics`, `tags`, `posts`, `notifications`,
|
10
15
|
`templates`, `extensions` and more :)
|
11
16
|
|
17
|
+
```bash
|
18
|
+
npm i @storecraft/sdk
|
19
|
+
```
|
12
20
|
|
13
21
|
## Authentication
|
14
22
|
|
package/index.js
CHANGED
@@ -11,16 +11,16 @@ import StoreFronts from './src/storefronts.js'
|
|
11
11
|
import Statistics from './src/statistics.js'
|
12
12
|
import Images from './src/images.js'
|
13
13
|
import Posts from './src/posts.js'
|
14
|
+
import Checkout from './src/checkout.js'
|
14
15
|
import Payments from './src/payments.js'
|
15
16
|
import Settings from './src/settings.js'
|
16
17
|
import Notifications from './src/notifications.js'
|
17
|
-
import Bots from './src/bots.js'
|
18
18
|
import Storage from './src/storage.js'
|
19
19
|
|
20
20
|
|
21
21
|
/**
|
22
|
-
* @typedef {import('@storecraft/core/
|
23
|
-
* import('@storecraft/core/
|
22
|
+
* @typedef {import('@storecraft/core/api').ApiAuthResult |
|
23
|
+
* import('@storecraft/core/api').ApiKeyResult
|
24
24
|
* } SdkConfigAuth The `storecraft` **SDK** `auth` config, represents
|
25
25
|
* either `apikey` or `jwt` authentication
|
26
26
|
*
|
@@ -36,7 +36,7 @@ import Storage from './src/storage.js'
|
|
36
36
|
*/
|
37
37
|
|
38
38
|
/**
|
39
|
-
* The official `storecraft`
|
39
|
+
* @description The official `storecraft` universal **SDK** for `javascript`
|
40
40
|
*/
|
41
41
|
export class StorecraftSDK {
|
42
42
|
|
@@ -65,9 +65,9 @@ export class StorecraftSDK {
|
|
65
65
|
this.images = new Images(this);
|
66
66
|
this.posts = new Posts(this);
|
67
67
|
this.payments = new Payments(this);
|
68
|
+
this.checkout = new Checkout(this);
|
68
69
|
this.settings = new Settings(this);
|
69
70
|
this.notifications = new Notifications(this);
|
70
|
-
this.bots = new Bots(this);
|
71
71
|
}
|
72
72
|
|
73
73
|
/**
|
package/package.json
CHANGED
package/src/auth.js
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
import { api_query_to_searchparams } from '@storecraft/core/
|
1
|
+
import { api_query_to_searchparams } from '@storecraft/core/api/utils.query.js';
|
2
2
|
import { StorecraftSDK } from '../index.js';
|
3
3
|
import { fetchApiWithAuth, url } from './utils.api.fetch.js';
|
4
4
|
import { assert } from './utils.functional.js';
|
@@ -21,7 +21,7 @@ import { assert } from './utils.functional.js';
|
|
21
21
|
|
22
22
|
|
23
23
|
/**
|
24
|
-
* `Storecraft` authentication module:
|
24
|
+
* @description `Storecraft` authentication module:
|
25
25
|
* - Supports `subscribtion` to `auth` events
|
26
26
|
*
|
27
27
|
*/
|
@@ -43,7 +43,7 @@ export default class Auth {
|
|
43
43
|
|
44
44
|
/**
|
45
45
|
*
|
46
|
-
* Get the current `auth` config, which is one of:
|
46
|
+
* @description Get the current `auth` config, which is one of:
|
47
47
|
*
|
48
48
|
* 1. `JWT` with `access_token`, `refresh_token`, `claims`
|
49
49
|
* 2. `Api Key` with a single value, which can be used as is in:
|
@@ -77,7 +77,7 @@ export default class Auth {
|
|
77
77
|
|
78
78
|
/**
|
79
79
|
*
|
80
|
-
* Get a working token, by the following strategy:
|
80
|
+
* @description Get a working token, by the following strategy:
|
81
81
|
*
|
82
82
|
* - If you are in `JWT` strategy:
|
83
83
|
* - If the current `access_token` will expire soon or is already expired
|
@@ -106,7 +106,7 @@ export default class Auth {
|
|
106
106
|
|
107
107
|
/**
|
108
108
|
*
|
109
|
-
* Perform re-authentication for `JWT` auth, which means:
|
109
|
+
* @description Perform re-authentication for `JWT` auth, which means:
|
110
110
|
*
|
111
111
|
* - use the `refresh_token` to gain a new `access_token`
|
112
112
|
*
|
@@ -136,7 +136,7 @@ export default class Auth {
|
|
136
136
|
}
|
137
137
|
);
|
138
138
|
|
139
|
-
/** @type {import('@storecraft/core/
|
139
|
+
/** @type {import('@storecraft/core/api').ApiAuthResult} */
|
140
140
|
let payload = undefined;
|
141
141
|
|
142
142
|
if(auth_res.ok) {
|
@@ -203,7 +203,7 @@ export default class Auth {
|
|
203
203
|
|
204
204
|
/**
|
205
205
|
*
|
206
|
-
* @param {import('@storecraft/core/
|
206
|
+
* @param {import('@storecraft/core/api').ApiAuthResult} user
|
207
207
|
*/
|
208
208
|
#_update_and_notify_subscribers = (user) => {
|
209
209
|
this.currentAuth = user
|
@@ -217,12 +217,12 @@ export default class Auth {
|
|
217
217
|
* @param {string} password
|
218
218
|
*
|
219
219
|
*
|
220
|
-
* @returns {Promise<import('@storecraft/core/
|
220
|
+
* @returns {Promise<import('@storecraft/core/api').ApiAuthResult>}
|
221
221
|
*/
|
222
222
|
signin = async (email, password) => {
|
223
223
|
// console.log('ep ', email, password)
|
224
224
|
|
225
|
-
/** @type {import('@storecraft/core/
|
225
|
+
/** @type {import('@storecraft/core/api').ApiAuthSigninType} */
|
226
226
|
const info = {
|
227
227
|
email, password
|
228
228
|
}
|
@@ -238,9 +238,26 @@ export default class Auth {
|
|
238
238
|
}
|
239
239
|
);
|
240
240
|
|
241
|
-
|
241
|
+
if(!res.ok) {
|
242
|
+
/** @type {import('@storecraft/core/api').error} */
|
243
|
+
let error_payload = {
|
244
|
+
messages: [
|
245
|
+
{
|
246
|
+
message: 'auth/error'
|
247
|
+
}
|
248
|
+
]
|
249
|
+
};
|
250
|
+
|
251
|
+
try {
|
252
|
+
error_payload = await res.json();
|
253
|
+
} catch (e) {
|
254
|
+
}
|
255
|
+
|
256
|
+
throw error_payload;
|
257
|
+
}
|
258
|
+
// assert(res.ok, 'auth/error2');
|
242
259
|
|
243
|
-
/** @type {import('@storecraft/core/
|
260
|
+
/** @type {import('@storecraft/core/api').ApiAuthResult} */
|
244
261
|
const payload = await res.json();
|
245
262
|
|
246
263
|
// console.log('auth_result', payload)
|
@@ -257,11 +274,14 @@ export default class Auth {
|
|
257
274
|
*
|
258
275
|
* @param {string} email
|
259
276
|
* @param {string} password
|
277
|
+
* @param {string} [firstname]
|
278
|
+
* @param {string} [lastname]
|
260
279
|
*/
|
261
|
-
signup = async (email, password) => {
|
262
|
-
/** @type {import('@storecraft/core/
|
280
|
+
signup = async (email, password, firstname, lastname) => {
|
281
|
+
/** @type {import('@storecraft/core/api').ApiAuthSignupType} */
|
263
282
|
const info = {
|
264
|
-
email, password
|
283
|
+
email, password,
|
284
|
+
firstname, lastname
|
265
285
|
}
|
266
286
|
|
267
287
|
const res = await fetch(
|
@@ -277,7 +297,7 @@ export default class Auth {
|
|
277
297
|
|
278
298
|
assert(res.ok, 'auth/error');
|
279
299
|
|
280
|
-
/** @type {import('@storecraft/core/
|
300
|
+
/** @type {import('@storecraft/core/api').ApiAuthResult} */
|
281
301
|
const payload = await res.json();
|
282
302
|
|
283
303
|
this.#_update_and_notify_subscribers(
|
@@ -288,6 +308,54 @@ export default class Auth {
|
|
288
308
|
}
|
289
309
|
|
290
310
|
|
311
|
+
/**
|
312
|
+
*
|
313
|
+
* @param {import('@storecraft/core/api').ApiAuthChangePasswordType} params
|
314
|
+
*/
|
315
|
+
|
316
|
+
changePassword = async (params) => {
|
317
|
+
|
318
|
+
const res = await fetch(
|
319
|
+
url(this.#sdk.config, `/auth/change-password`),
|
320
|
+
{
|
321
|
+
method: 'post',
|
322
|
+
body: JSON.stringify(params),
|
323
|
+
headers: {
|
324
|
+
'Content-Type' : 'application/json'
|
325
|
+
}
|
326
|
+
}
|
327
|
+
);
|
328
|
+
|
329
|
+
if(!res.ok) {
|
330
|
+
/** @type {import('@storecraft/core/api').error} */
|
331
|
+
let error_payload = {
|
332
|
+
messages: [
|
333
|
+
{
|
334
|
+
message: 'auth/error'
|
335
|
+
}
|
336
|
+
]
|
337
|
+
};
|
338
|
+
|
339
|
+
try {
|
340
|
+
error_payload = await res.json();
|
341
|
+
} catch (e) {
|
342
|
+
}
|
343
|
+
|
344
|
+
throw error_payload;
|
345
|
+
}
|
346
|
+
|
347
|
+
/** @type {import('@storecraft/core/api').ApiAuthResult} */
|
348
|
+
const payload = await res.json();
|
349
|
+
|
350
|
+
this.#_update_and_notify_subscribers(
|
351
|
+
payload
|
352
|
+
);
|
353
|
+
|
354
|
+
return payload;
|
355
|
+
}
|
356
|
+
|
357
|
+
|
358
|
+
|
291
359
|
signout = async () => {
|
292
360
|
console.log('signout');
|
293
361
|
|
@@ -299,7 +367,7 @@ export default class Auth {
|
|
299
367
|
|
300
368
|
|
301
369
|
create_api_key = async () => {
|
302
|
-
/** @type {import('@storecraft/core/
|
370
|
+
/** @type {import('@storecraft/core/api').ApiKeyResult} */
|
303
371
|
const item = await fetchApiWithAuth(
|
304
372
|
this.#sdk,
|
305
373
|
'/auth/apikeys',
|
@@ -318,7 +386,7 @@ export default class Auth {
|
|
318
386
|
* @param {string} email_or_id
|
319
387
|
*/
|
320
388
|
get_auth_user = async (email_or_id) => {
|
321
|
-
/** @type {import('@storecraft/core/
|
389
|
+
/** @type {import('@storecraft/core/api').AuthUserType} */
|
322
390
|
const item = await fetchApiWithAuth(
|
323
391
|
this.#sdk,
|
324
392
|
`/auth/users/${email_or_id}`,
|
@@ -349,7 +417,7 @@ export default class Auth {
|
|
349
417
|
/**
|
350
418
|
*
|
351
419
|
*
|
352
|
-
* @param {import('@storecraft/core/
|
420
|
+
* @param {import('@storecraft/core/api').ApiQuery} query
|
353
421
|
*
|
354
422
|
*/
|
355
423
|
list_auth_users = async (query) => {
|
@@ -367,7 +435,7 @@ export default class Auth {
|
|
367
435
|
|
368
436
|
list_api_keys_auth_users = async () => {
|
369
437
|
|
370
|
-
/** @type {import('@storecraft/core/
|
438
|
+
/** @type {import('@storecraft/core/api').AuthUserType[]} */
|
371
439
|
const items = await fetchApiWithAuth(
|
372
440
|
this.#sdk,
|
373
441
|
'/auth/apikeys',
|
package/src/checkout.js
ADDED
@@ -0,0 +1,88 @@
|
|
1
|
+
import { StorecraftSDK } from '../index.js'
|
2
|
+
import { fetchApiWithAuth } from './utils.api.fetch.js';
|
3
|
+
|
4
|
+
/**
|
5
|
+
* @description Base `checkout` **api**
|
6
|
+
*
|
7
|
+
*/
|
8
|
+
export default class Checkout {
|
9
|
+
|
10
|
+
/**
|
11
|
+
*
|
12
|
+
* @param {StorecraftSDK} sdk
|
13
|
+
*/
|
14
|
+
constructor(sdk) {
|
15
|
+
this.sdk = sdk;
|
16
|
+
}
|
17
|
+
|
18
|
+
/**
|
19
|
+
* @description Create a `checkout`
|
20
|
+
*
|
21
|
+
* @param {import('@storecraft/core/api').CheckoutCreateType} input
|
22
|
+
* @param {string} gateway_handle
|
23
|
+
*
|
24
|
+
* @returns {Promise<Partial<import('@storecraft/core/api').OrderData>>}
|
25
|
+
*/
|
26
|
+
create = async (input, gateway_handle) => {
|
27
|
+
|
28
|
+
console.log('input', input)
|
29
|
+
const result = await fetchApiWithAuth(
|
30
|
+
this.sdk,
|
31
|
+
`checkout/create?gateway=${gateway_handle}`,
|
32
|
+
{
|
33
|
+
method: 'post',
|
34
|
+
body: JSON.stringify(input),
|
35
|
+
headers: {
|
36
|
+
'Content-Type': 'application/json'
|
37
|
+
}
|
38
|
+
}
|
39
|
+
);
|
40
|
+
|
41
|
+
return result
|
42
|
+
}
|
43
|
+
|
44
|
+
/**
|
45
|
+
* @description Complete a `checkout`
|
46
|
+
*
|
47
|
+
* @param {string} order_id
|
48
|
+
*
|
49
|
+
* @returns {Promise<Partial<import('@storecraft/core/api').OrderData>>}
|
50
|
+
*/
|
51
|
+
complete = async (order_id) => {
|
52
|
+
|
53
|
+
const result = await fetchApiWithAuth(
|
54
|
+
this.sdk,
|
55
|
+
`checkout/${order_id}/complete`,
|
56
|
+
{
|
57
|
+
method: 'post',
|
58
|
+
}
|
59
|
+
);
|
60
|
+
|
61
|
+
return result
|
62
|
+
}
|
63
|
+
|
64
|
+
/**
|
65
|
+
* @description calculate the pricing of an `order`. Using auto-discounts, coupons, shipping and line-items.
|
66
|
+
*
|
67
|
+
* @param {Partial<import('@storecraft/core/api').OrderData>} order
|
68
|
+
*
|
69
|
+
* @returns {Promise<Partial<import('@storecraft/core/api').PricingData>>}
|
70
|
+
*/
|
71
|
+
pricing = async (order) => {
|
72
|
+
|
73
|
+
const result = await fetchApiWithAuth(
|
74
|
+
this.sdk,
|
75
|
+
`checkout/pricing`,
|
76
|
+
{
|
77
|
+
method: 'post',
|
78
|
+
body: JSON.stringify(order),
|
79
|
+
headers: {
|
80
|
+
'Content-Type': 'application/json'
|
81
|
+
}
|
82
|
+
}
|
83
|
+
);
|
84
|
+
|
85
|
+
return result
|
86
|
+
}
|
87
|
+
|
88
|
+
}
|
package/src/collections.js
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
import { StorecraftSDK } from '../index.js'
|
2
|
-
import { collection_base } from './utils.api.fetch.js';
|
2
|
+
import { collection_base, fetchApiWithAuth } from './utils.api.fetch.js';
|
3
3
|
import { filter_fields, filter_unused } from './utils.functional.js';
|
4
4
|
|
5
5
|
/**
|
6
|
-
* Base `collections` **CRUD**
|
6
|
+
* @description Base `collections` **CRUD**
|
7
7
|
*
|
8
8
|
* @extends {collection_base<
|
9
|
-
* import('@storecraft/core/
|
10
|
-
* import('@storecraft/core/
|
9
|
+
* import('@storecraft/core/api').CollectionTypeUpsert,
|
10
|
+
* import('@storecraft/core/api').CollectionType>
|
11
11
|
* }
|
12
12
|
*/
|
13
13
|
export default class Collections extends collection_base {
|
@@ -21,79 +21,24 @@ export default class Collections extends collection_base {
|
|
21
21
|
}
|
22
22
|
|
23
23
|
/**
|
24
|
+
* @description Export a collection of `products` into the `storage`. This is
|
25
|
+
* beneficial for `collections`, that hardly change and therefore can be
|
26
|
+
* efficiently stored in a cost-effective `storage` and **CDN** network.
|
24
27
|
*
|
25
28
|
* @param {string} collection_handle
|
26
29
|
* @param {number} limit
|
27
30
|
*/
|
28
31
|
publish = async (collection_handle, limit=1000) => {
|
29
|
-
throw new Error('Implement me !!!')
|
30
|
-
// extra filtering for validation
|
31
32
|
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
}
|
38
|
-
|
39
|
-
// get all products in collection
|
40
|
-
try {
|
41
|
-
var pick_data = items => items.map(item => item[1])
|
42
|
-
/** @param {ProductData[]} items */
|
43
|
-
var filter_hard_on_collection = items => items.filter(
|
44
|
-
item => (
|
45
|
-
item.collections &&
|
46
|
-
item.collections.indexOf(collection_handle)>=0 &&
|
47
|
-
item.qty>0 &&
|
48
|
-
(item.active || item.active===undefined) &&
|
49
|
-
(!item.parent_handle)
|
50
|
-
)
|
51
|
-
)
|
52
|
-
const filter_fields_in = filter_fields(
|
53
|
-
'title', 'handle', 'media', 'desc', 'price', 'attributes',
|
54
|
-
'video', 'tags', 'updatedAt', 'compareAtPrice', 'discounts',
|
55
|
-
'parent_handle', 'variants_options', 'variants_products'
|
56
|
-
)
|
57
|
-
var products = await this.context.products.list(
|
58
|
-
[`col:${collection_handle}`], limit
|
59
|
-
)
|
60
|
-
// console.log('products', products)
|
61
|
-
products = pick_data(products)
|
62
|
-
products = filter_hard_on_collection(products)
|
63
|
-
products = filter_fields_in(products)
|
64
|
-
products = filter_unused(products)
|
65
|
-
} catch (e) {
|
66
|
-
throw 'products read error: ' + String(e)
|
67
|
-
}
|
68
|
-
|
69
|
-
try {
|
70
|
-
// upload collection export
|
71
|
-
const metadata = {
|
72
|
-
contentType: 'application/json',
|
73
|
-
contentEncoding: 'gzip',
|
74
|
-
cacheControl: `max-age=${60*60*1}, must-revalidate`
|
75
|
-
// cacheControl: `private, max-age=${60*60*1}`
|
76
|
-
// cacheControl: `max-age=${60*60*5}, must-revalidate`
|
33
|
+
const result = await fetchApiWithAuth(
|
34
|
+
this.sdk,
|
35
|
+
`collections/${collection_handle}/export`,
|
36
|
+
{
|
37
|
+
method: 'post'
|
77
38
|
}
|
78
|
-
|
79
|
-
`collections/${collection_handle}.json`,
|
80
|
-
pako.gzip(
|
81
|
-
JSON.stringify({
|
82
|
-
...collection,
|
83
|
-
products
|
84
|
-
})
|
85
|
-
),
|
86
|
-
metadata
|
87
|
-
)
|
88
|
-
} catch(e) {
|
89
|
-
throw 'Collection upload error: ' + String(e)
|
90
|
-
}
|
39
|
+
);
|
91
40
|
|
92
|
-
|
93
|
-
await this.update(collection_handle, { _published: url })
|
94
|
-
} catch (e) {
|
95
|
-
throw 'Collection update error: ' + String(e)
|
96
|
-
}
|
41
|
+
return result
|
97
42
|
}
|
98
43
|
|
99
44
|
// /**
|
package/src/customers.js
CHANGED
@@ -2,11 +2,11 @@ import { StorecraftSDK } from '../index.js'
|
|
2
2
|
import { collection_base } from './utils.api.fetch.js';
|
3
3
|
|
4
4
|
/**
|
5
|
-
* Base `customers` **CRUD**
|
5
|
+
* @description Base `customers` **CRUD**
|
6
6
|
*
|
7
7
|
* @extends {collection_base<
|
8
|
-
* import('@storecraft/core/
|
9
|
-
* import('@storecraft/core/
|
8
|
+
* import('@storecraft/core/api').CustomerTypeUpsert,
|
9
|
+
* import('@storecraft/core/api').CustomerType>
|
10
10
|
* }
|
11
11
|
*/
|
12
12
|
export default class Customers extends collection_base {
|