@storecraft/sdk 0.1.0 → 1.0.2

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
@@ -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/v-api').ApiAuthResult |
23
- * import('@storecraft/core/v-api').ApiKeyResult
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` admin **SDK** for `javascript`
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
  /**
@@ -1,10 +1,6 @@
1
1
  {
2
- "compileOnSave": false,
3
2
  "compilerOptions": {
4
- "noEmit": true,
5
- "allowJs": true,
6
3
  "checkJs": true,
7
- "resolveJsonModule": true,
8
4
  "target": "ESNext",
9
5
  "module": "NodeNext",
10
6
  "moduleResolution": "NodeNext",
@@ -21,7 +17,8 @@
21
17
  },
22
18
  "include": [
23
19
  "*",
24
- "**/*"
20
+ "**/*",
21
+ "src/*.js",
25
22
  ],
26
23
  "exclude": [
27
24
  "**/*.json"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@storecraft/sdk",
3
- "version": "0.1.0",
3
+ "version": "1.0.2",
4
4
  "description": "Official storecraft Universal Javascript SDK",
5
5
  "license": "MIT",
6
6
  "author": "Tomer Shalev (https://github.com/store-craft)",
@@ -18,7 +18,8 @@
18
18
  ],
19
19
  "scripts": {
20
20
  "sdk:test": "echo \"Error: no test specified\" && exit 1",
21
- "sdk:publish": "npm publish --access public"
21
+ "test": "npm run sdk:test",
22
+ "prepublishOnly": "npm version patch --force"
22
23
  },
23
24
  "type": "module",
24
25
  "types": "./types.d.ts",
package/src/auth.js CHANGED
@@ -1,4 +1,4 @@
1
- import { api_query_to_searchparams } from '@storecraft/core/v-api/utils.query.js';
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/v-api').ApiAuthResult} */
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/v-api').ApiAuthResult} user
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/v-api').ApiAuthResult>}
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/v-api').ApiAuthSigninType} */
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
- assert(res.ok, 'auth/error');
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/v-api').ApiAuthResult} */
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/v-api').ApiAuthSignupType} */
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/v-api').ApiAuthResult} */
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/v-api').ApiKeyResult} */
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/v-api').AuthUserType} */
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/v-api').ApiQuery} query
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/v-api').AuthUserType[]} */
438
+ /** @type {import('@storecraft/core/api').AuthUserType[]} */
371
439
  const items = await fetchApiWithAuth(
372
440
  this.#sdk,
373
441
  '/auth/apikeys',
@@ -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
+ }
@@ -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/v-api').CollectionTypeUpsert,
10
- * import('@storecraft/core/v-api').CollectionType>
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
- try {
33
- // fetch collection
34
- var [exists, id, collection] = await this.get(collection_handle)
35
- } catch (e) {
36
- throw 'Collection read error: ' + String(e)
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
- var [url, ref] = await this.context.storage.uploadBytes(
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
- try {
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/v-api').CustomerTypeUpsert,
9
- * import('@storecraft/core/v-api').CustomerType>
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 {