@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/src/storage.js CHANGED
@@ -1,19 +1,18 @@
1
1
  /**
2
- * @import { StorageFeatures, StorageSignedOperation } from '@storecraft/core/storage'
2
+ * @import {
3
+ * StorageFeatures, StorageSignedOperation
4
+ * } from '@storecraft/core/storage'
3
5
  */
4
6
 
5
7
  import { StorecraftSDK } from '../index.js'
6
8
  import { fetchOnlyApiResponseWithAuth } from './utils.api.fetch.js'
7
9
 
8
10
  /**
9
- *
10
11
  * @description `Storecraft` storage service.
11
- *
12
12
  * Supports:
13
13
  * - direct `downloads` / `uploads`
14
14
  * - presigned-urls for `download` / `upload` (If supported)
15
15
  * - `delete` files
16
- *
17
16
  */
18
17
  export default class Storage {
19
18
 
@@ -34,11 +33,8 @@ export default class Storage {
34
33
  }
35
34
 
36
35
  /**
37
- *
38
36
  * @description Retrieve the `features` of `storage`, which informs:
39
37
  * - Does `storage` supports `pre-signed` urls for `download` / `upload`
40
- *
41
- *
42
38
  * @returns {Promise<StorageFeatures>}
43
39
  */
44
40
  features = async () => {
@@ -75,12 +71,9 @@ export default class Storage {
75
71
 
76
72
  /**
77
73
  * @description Get a blob from `storage` driver with `presigned` urls
78
- *
79
74
  * @param {string} key file path key,
80
75
  * examples `image.png`, `collections/thumb.jpeg`
81
- *
82
76
  * @return {Promise<Blob>}
83
- *
84
77
  * @throws {error}
85
78
  */
86
79
  getBlobSigned = async (key) => {
@@ -104,7 +97,7 @@ export default class Storage {
104
97
  /** @type {StorageSignedOperation} */
105
98
  const presigned_req = await r.json();
106
99
 
107
- const presigned_res = await fetch(
100
+ const presigned_res = await this.sdk.fetcher(
108
101
  presigned_req.url,
109
102
  {
110
103
  method: presigned_req.method,
@@ -119,13 +112,11 @@ export default class Storage {
119
112
  }
120
113
 
121
114
  /**
122
- * @description Get a blob from `storage` driver, straight download. (Not recommended)
123
- *
115
+ * @description Get a blob from `storage` driver,
116
+ * straight download. (Not recommended)
124
117
  * @param {string} key file path key,
125
118
  * examples `image.png`, `collections/thumb.jpeg`
126
- *
127
119
  * @return {Promise<Blob>}
128
- *
129
120
  * @throws {error}
130
121
  */
131
122
  getBlobUnsigned = async (key) => {
@@ -137,10 +128,8 @@ export default class Storage {
137
128
  );
138
129
 
139
130
  const ctype = r.headers.get('Content-Type');
140
-
141
131
  if(!r.ok) {
142
132
  const error = await r.json();
143
-
144
133
  throw error;
145
134
  }
146
135
 
@@ -149,12 +138,9 @@ export default class Storage {
149
138
 
150
139
  /**
151
140
  * @description Get a blob from `storage` driver.
152
- *
153
141
  * @param {string} key file path key,
154
142
  * examples `image.png`, `collections/thumb.jpeg`
155
- *
156
143
  * @return {Promise<Blob>}
157
- *
158
144
  * @throws {error}
159
145
  */
160
146
  getBlob = async (key) => {
@@ -169,32 +155,36 @@ export default class Storage {
169
155
 
170
156
  /** @param {string} path */
171
157
  getText = (path) =>
172
- this.getBlob(path).then(blob => blob.text());
158
+ this.getBlob(path).then(blob => blob.text());
173
159
 
174
160
  /** @param {string} path */
175
161
  getJson = (path) =>
176
- this.getBlob(path).then(blob => blob.text().then(JSON.parse));
162
+ this.getBlob(path).then(
163
+ blob => blob.text().then(JSON.parse)
164
+ );
177
165
 
178
166
  /** @param {string} path */
179
167
  getImageObjectURL = (path) =>
180
- this.getBlob(path).then(blob => URL.createObjectURL(blob));
168
+ this.getBlob(path).then(
169
+ blob => URL.createObjectURL(blob)
170
+ );
181
171
 
182
172
  /**
183
173
  * @description get file source by inspecting the url:
184
- *
185
174
  * - If it starts with `storage://`, then use `backend`
186
175
  * storage service, to download and convert it to encoded
187
176
  * `object-url` for `<img/>`
188
- *
189
177
  * - Else. it is assumed to be a public `url`, and will
190
178
  * return the given url.
191
- *
192
179
  * @template {false | true} [IS_IMAGE=true]
193
180
  * @param {string} url
194
181
  * @param {IS_IMAGE} [isImage=true]
195
182
  * @returns {Promise<IS_IMAGE extends true ? string : any>}
196
183
  */
197
- getSource = async (url, isImage=(/** @type {IS_IMAGE} */ (true))) => {
184
+ getSource = async (
185
+ url,
186
+ isImage=(/** @type {IS_IMAGE} */ (true))
187
+ ) => {
198
188
  try {
199
189
 
200
190
  const is_storage = url.startsWith('storage://');
@@ -222,12 +212,13 @@ export default class Storage {
222
212
 
223
213
 
224
214
  /**
225
- * @description Put a blob into `storage` driver with `presigned` urls
226
- *
215
+ * @description Put a blob into `storage` driver
216
+ * with `presigned` urls if supported. this means the upload
217
+ * is offloaded from the backend to the client straight into
218
+ * other services that supports it such as s3.
227
219
  * @param {string} key file path key,
228
220
  * examples `image.png`, `collections/thumb.jpeg`
229
221
  * @param {string | Blob | Uint8Array | ArrayBuffer | File} data
230
- *
231
222
  */
232
223
  putBytesSigned = async (key, data) => {
233
224
 
@@ -248,7 +239,7 @@ export default class Storage {
248
239
  if(ctype === 'application/json') {
249
240
  /** @type {StorageSignedOperation} */
250
241
  const presigned_req = await r.json();
251
- const presigned_res = await fetch(
242
+ const presigned_res = await this.sdk.fetcher(
252
243
  presigned_req.url,
253
244
  {
254
245
  method: presigned_req.method,
@@ -264,12 +255,11 @@ export default class Storage {
264
255
  }
265
256
 
266
257
  /**
267
- * @description Put a blob into `storage` driver with direct `upload` (Not Recommended)
268
- *
258
+ * @description Put a blob into `storage` driver with
259
+ * direct `upload` (Not Recommended)
269
260
  * @param {string} key file path key,
270
261
  * examples `image.png`, `collections/thumb.jpeg`
271
262
  * @param {string | Blob | Uint8Array | ArrayBuffer | File} data
272
- *
273
263
  */
274
264
  putBytesUnsigned = async (key, data) => {
275
265
 
@@ -295,13 +285,10 @@ export default class Storage {
295
285
 
296
286
  /**
297
287
  * @description Put bytes into `storage` driver.
298
- *
299
288
  * @param {string} key file path key,
300
289
  * examples `image.png`, `collections/thumb.jpeg`
301
290
  * @param {string | Blob | Uint8Array | ArrayBuffer | File} data
302
- *
303
291
  * @return {Promise<boolean>}
304
- *
305
292
  * @throws {error}
306
293
  */
307
294
  putBytes = async (key, data) => {
@@ -316,7 +303,6 @@ export default class Storage {
316
303
 
317
304
  /**
318
305
  * @description Delete a `file` by key
319
- *
320
306
  * @param {string} key file path key,
321
307
  * examples `image.png`, `collections/thumb.jpeg`
322
308
  */
@@ -327,6 +313,11 @@ export default class Storage {
327
313
  { method: 'delete' }
328
314
  );
329
315
 
316
+ if(!r.ok) {
317
+ const error = await r.json();
318
+ throw error;
319
+ }
320
+
330
321
  return r.ok;
331
322
  }
332
323
 
@@ -13,7 +13,6 @@ import { collection_base, fetchApiWithAuth } from './utils.api.fetch.js';
13
13
  export default class Storefronts extends collection_base {
14
14
 
15
15
  /**
16
- *
17
16
  * @param {StorecraftSDK} sdk
18
17
  */
19
18
  constructor(sdk) {
@@ -24,11 +23,9 @@ export default class Storefronts extends collection_base {
24
23
  * @description Export a storefront into the `storage`. This is
25
24
  * beneficial for `collections`, that hardly change and therefore can be
26
25
  * efficiently stored in a cost-effective `storage` and **CDN** network.
27
- *
28
26
  * @param {HandleOrId} handle_or_id
29
27
  */
30
28
  publish = async (handle_or_id) => {
31
-
32
29
  const result = await fetchApiWithAuth(
33
30
  this.sdk,
34
31
  `storefronts/${handle_or_id}/export`,
@@ -36,6 +33,29 @@ export default class Storefronts extends collection_base {
36
33
  method: 'post'
37
34
  }
38
35
  );
36
+ return result
37
+ }
38
+
39
+ /**
40
+ * @description You can fetch the default auto-generated storefront.
41
+ * This will fetch all active
42
+ * - collections
43
+ * - discounts
44
+ * - shipping methods
45
+ * - posts (latest 5)
46
+ * - products(latest 10)
47
+ * that are linked to the storefront. Also, all the products
48
+ * tags aggregated so you can build a filter system in the frontend
49
+ * @returns {Promise<StorefrontType>}
50
+ */
51
+ get_default_auto_generated_storefront = async () => {
52
+ const result = await fetchApiWithAuth(
53
+ this.sdk,
54
+ `storefronts/auto-generated`,
55
+ {
56
+ method: 'get'
57
+ }
58
+ );
39
59
 
40
60
  return result
41
61
  }
package/src/tags.js CHANGED
@@ -12,7 +12,6 @@ import { collection_base } from './utils.api.fetch.js';
12
12
  export default class Tags extends collection_base {
13
13
 
14
14
  /**
15
- *
16
15
  * @param {StorecraftSDK} sdk
17
16
  */
18
17
  constructor(sdk) {
package/src/templates.js CHANGED
@@ -12,7 +12,6 @@ import { collection_base } from './utils.api.fetch.js';
12
12
  export default class Templates extends collection_base {
13
13
 
14
14
  /**
15
- *
16
15
  * @param {StorecraftSDK} sdk
17
16
  */
18
17
  constructor(sdk) {
@@ -5,11 +5,10 @@
5
5
  */
6
6
  import {
7
7
  api_query_to_searchparams
8
- } from '@storecraft/core/api/utils.query.js';
8
+ } from '@storecraft/core/api/query.js';
9
9
 
10
10
 
11
11
  /**
12
- *
13
12
  * @param {StorecraftSDKConfig} config
14
13
  * @param {string} path
15
14
  * @param {URLSearchParams} [query] url search params
@@ -34,12 +33,10 @@ export const url = (config, path, query) => {
34
33
  * - Prepends `backend` endpoint.
35
34
  * - Fetches with `authentication` middleware.
36
35
  * - Refreshed `auth` if needed.
37
- *
38
36
  * @param {StorecraftSDK} sdk
39
37
  * @param {string} path relative path in api
40
38
  * @param {RequestInit} [init] request `init` type
41
39
  * @param {URLSearchParams} [query] url search params
42
- *
43
40
  * @returns {Promise<Response>}
44
41
  */
45
42
  export const fetchOnlyApiResponseWithAuth = async (
@@ -48,11 +45,11 @@ export const fetchOnlyApiResponseWithAuth = async (
48
45
 
49
46
  const auth_token = await sdk.auth.working_auth_token();
50
47
  const auth_header_value = (
51
- sdk.auth.authStrategy==='apikey' ? 'Basic' : 'Bearer'
48
+ sdk.auth.currentAuthStrategy==='apikey' ? 'Basic' : 'Bearer'
52
49
  ) + ` ${auth_token}`;
53
50
 
54
51
 
55
- const response = await fetch(
52
+ const response = await sdk.fetcher(
56
53
  url(sdk.config, path, query),
57
54
  {
58
55
  ...init,
@@ -74,16 +71,14 @@ export const fetchOnlyApiResponseWithAuth = async (
74
71
  * - Refreshed `auth` if needed.
75
72
  * - Throws a `json` representation of the `error`,
76
73
  * if the request is `bad`
77
- *
74
+ * - returns the object according to the `content-type` header
75
+ * - json, text, html, blob
78
76
  * @template {any} [R=any]
79
- *
80
77
  * @param {StorecraftSDK} sdk
81
78
  * @param {string} path relative path in api
82
79
  * @param {RequestInit} [init] request `init` type
83
80
  * @param {URLSearchParams} [query] url search params
84
- *
85
81
  * @throws {error}
86
- *
87
82
  * @returns {Promise<R>}
88
83
  */
89
84
  export const fetchApiWithAuth = async (
@@ -98,15 +93,24 @@ export const fetchApiWithAuth = async (
98
93
 
99
94
  const isok = response.ok;
100
95
  let payload = undefined;
96
+ const ct = response?.headers?.get('content-type');
101
97
 
102
98
  try {
103
- payload = await response.json();
99
+ if(ct?.includes('application/json'))
100
+ payload = await response.json();
101
+ else if(ct?.includes('text/plain'))
102
+ payload = await response.text();
103
+ else if(ct?.includes('text/html'))
104
+ payload = await response.text();
105
+ else
106
+ payload = await response.blob();
104
107
  } catch(e) {
105
108
  console.log('fetchApiWithAuth.json()', e)
106
109
  }
107
110
 
108
- if(!isok)
111
+ if(!isok) {
109
112
  throw payload;
113
+ }
110
114
 
111
115
  return payload;
112
116
  }
@@ -114,16 +118,14 @@ export const fetchApiWithAuth = async (
114
118
 
115
119
  /**
116
120
  * @template {any} G Get type
117
- *
118
- *
119
121
  * @param {StorecraftSDK} sdk
120
122
  * @param {string} handle_or_id `handle` or `id`
121
123
  * @param {string} resource base path of resource
122
- *
123
- *
124
124
  * @returns {Promise<G>}
125
125
  */
126
- export async function get_from_collection_resource(sdk, resource, handle_or_id) {
126
+ export async function get_from_collection_resource(
127
+ sdk, resource, handle_or_id
128
+ ) {
127
129
  return fetchApiWithAuth(
128
130
  sdk,
129
131
  `${resource}/${handle_or_id}`,
@@ -135,18 +137,15 @@ export async function get_from_collection_resource(sdk, resource, handle_or_id)
135
137
 
136
138
 
137
139
  /**
138
- *
139
140
  * @template {any} U the upsert type
140
- *
141
- *
142
141
  * @param {StorecraftSDK} sdk
143
142
  * @param {string} resource base path of resource
144
143
  * @param {U} item Item to upsert
145
- *
146
- *
147
144
  * @returns {Promise<string>} id
148
145
  */
149
- export async function upsert_to_collection_resource(sdk, resource, item) {
146
+ export async function upsert_to_collection_resource(
147
+ sdk, resource, item
148
+ ) {
150
149
  return fetchApiWithAuth(
151
150
  sdk,
152
151
  `${resource}`,
@@ -176,19 +175,18 @@ export async function count_query_of_resource(sdk, resource, query) {
176
175
  {
177
176
  method: 'get',
178
177
  }
179
- ).then((result) => Number(result.count));
178
+ );
180
179
  }
181
180
 
182
181
  /**
183
- *
184
182
  * @param {StorecraftSDK} sdk
185
183
  * @param {string} resource base path of resource
186
184
  * @param {string} handle_or_id `handle` or `id`
187
- *
188
- *
189
185
  * @returns {Promise<boolean>}
190
186
  */
191
- export async function remove_from_collection_resource(sdk, resource, handle_or_id) {
187
+ export async function remove_from_collection_resource(
188
+ sdk, resource, handle_or_id
189
+ ) {
192
190
  return fetchApiWithAuth(
193
191
  sdk,
194
192
  `${resource}/${handle_or_id}`,
@@ -202,19 +200,15 @@ export async function remove_from_collection_resource(sdk, resource, handle_or_i
202
200
  /**
203
201
  * @description Invoke `api` endpoint that requires use of `query`
204
202
  * object. I named it `list` because it usually entails list op.
205
- *
206
- *
207
203
  * @template {any} G Get type
208
- *
209
- *
210
204
  * @param {StorecraftSDK} sdk
211
205
  * @param {string} resource base path of resource
212
206
  * @param {ApiQuery<G>} [query]
213
- *
214
- *
215
207
  * @returns {Promise<G[]>}
216
208
  */
217
- export async function list_from_collection_resource(sdk, resource, query={}) {
209
+ export async function list_from_collection_resource(
210
+ sdk, resource, query={}
211
+ ) {
218
212
  const sq = api_query_to_searchparams(query);
219
213
 
220
214
  // console.log('sq', sq.toString())
@@ -230,7 +224,6 @@ export async function list_from_collection_resource(sdk, resource, query={}) {
230
224
 
231
225
  /**
232
226
  * @description A simple resource base `class` with `CRUD` helpers
233
- *
234
227
  * @template {any} U upsert type
235
228
  * @template {any} G get type
236
229
  */
@@ -243,7 +236,6 @@ export class collection_base {
243
236
  #base_name = undefined;
244
237
 
245
238
  /**
246
- *
247
239
  * @param {StorecraftSDK} sdk storecraft sdk
248
240
  * @param {string} base_name base path of resource type
249
241
  */
@@ -254,36 +246,33 @@ export class collection_base {
254
246
 
255
247
 
256
248
  /**
257
- *
258
249
  * @param {string} handle_or_id `handle` or `id`
259
- *
260
- *
261
250
  * @returns {Promise<G>}
262
251
  */
263
252
  async get(handle_or_id) {
264
- return get_from_collection_resource(this.sdk, this.base_name, handle_or_id);
253
+ return get_from_collection_resource(
254
+ this.sdk, this.base_name, handle_or_id
255
+ );
265
256
  }
266
257
 
267
258
  /**
268
- *
269
259
  * @param {U} item Item to upsert
270
- *
271
- *
272
260
  * @returns {Promise<string>} id
273
261
  */
274
262
  async upsert(item) {
275
- return upsert_to_collection_resource(this.sdk, this.base_name, item);
263
+ return upsert_to_collection_resource(
264
+ this.sdk, this.base_name, item
265
+ );
276
266
  }
277
267
 
278
268
  /**
279
- *
280
269
  * @param {string} handle_or_id `handle` or `id`
281
- *
282
- *
283
270
  * @returns {Promise<boolean>}
284
271
  */
285
272
  async remove(handle_or_id) {
286
- return remove_from_collection_resource(this.sdk, this.base_name, handle_or_id);
273
+ return remove_from_collection_resource(
274
+ this.sdk, this.base_name, handle_or_id
275
+ );
287
276
  }
288
277
 
289
278
  /**
@@ -291,7 +280,9 @@ export class collection_base {
291
280
  * @returns {Promise<G[]>}
292
281
  */
293
282
  async list(query) {
294
- return list_from_collection_resource(this.sdk, this.base_name, query);
283
+ return list_from_collection_resource(
284
+ this.sdk, this.base_name, query
285
+ );
295
286
  }
296
287
 
297
288
  /**
@@ -299,7 +290,9 @@ export class collection_base {
299
290
  * @param {ApiQuery<G>} query Query object
300
291
  */
301
292
  async count_query(query) {
302
- return count_query_of_resource(this.sdk, this.base_name, query);
293
+ return count_query_of_resource(
294
+ this.sdk, this.base_name, query
295
+ );
303
296
  }
304
297
 
305
298
  get base_name() {
@@ -9,7 +9,6 @@ export const select_fields = (...fields) => {
9
9
  }
10
10
 
11
11
  /**
12
- *
13
12
  * @param {...any} fields
14
13
  */
15
14
  export const filter_fields = (...fields) => {
@@ -20,7 +19,6 @@ export const filter_fields = (...fields) => {
20
19
  }
21
20
 
22
21
  /**
23
- *
24
22
  * @param {object} o
25
23
  */
26
24
  export const select_unused_fields = o => Object.keys(o).reduce((p, c) => {
@@ -33,7 +31,6 @@ export const select_unused_fields = o => Object.keys(o).reduce((p, c) => {
33
31
  }, {});
34
32
 
35
33
  /**
36
- *
37
34
  * @param {any[]} items
38
35
  */
39
36
  export const filter_unused = items =>
@@ -55,7 +52,6 @@ export const delete_keys = (...keys) => {
55
52
 
56
53
 
57
54
  /**
58
- *
59
55
  * @param {string} text
60
56
  */
61
57
  export const text2tokens_unsafe = (text) => {
@@ -79,7 +75,6 @@ export const STOP_WORDS = [
79
75
  ]
80
76
 
81
77
  /**
82
- *
83
78
  * @param {string} text
84
79
  * @returns {string[] | undefined}
85
80
  */
@@ -101,7 +96,6 @@ export const text2tokens = (text) => {
101
96
 
102
97
 
103
98
  /**
104
- *
105
99
  * @param {any[]} arrA
106
100
  * @param {any[]} arrB
107
101
  * @returns
package/types.d.ts CHANGED
@@ -3,8 +3,8 @@ import type { ApiAuthResult, ApiKeyResult } from '@storecraft/core/api';
3
3
  export * from './index.js';
4
4
 
5
5
  /**
6
- * @description The `storecraft` **SDK**
7
- * `auth` config, represents either `apikey` or `jwt` authentication
6
+ * @description The `storecraft` **SDK** `auth` config,
7
+ * represents either `apikey` or `jwt` authentication
8
8
  */
9
9
  export type SdkConfigAuth = ApiAuthResult | ApiKeyResult;
10
10
 
@@ -13,9 +13,22 @@ export type SdkConfigAuth = ApiAuthResult | ApiKeyResult;
13
13
  */
14
14
  export type StorecraftSDKConfig = {
15
15
 
16
- /** Endpoint of `backend` */
16
+ /**
17
+ * @description Endpoint of `backend`
18
+ */
17
19
  endpoint?: string;
18
20
 
19
- /** `auth` info, may be either `apikey` or `jwt` results */
21
+ /**
22
+ * @description `auth` info, may be either `apikey` or `jwt` results.
23
+ * This will be setup automatically when performing `login` or
24
+ * `apikey` operations if
25
+ * - the {@link StorecraftSDKConfig.persist_auth} is set to `true`.
26
+ * - This us used by the sdk to re-authenticate the user when
27
+ * the token expires.
28
+ */
20
29
  auth?: SdkConfigAuth;
21
30
  }
31
+
32
+ export type Fetcher = (
33
+ input: RequestInfo, init?: RequestInit
34
+ ) => Promise<Response>
package/src/settings.js DELETED
@@ -1,19 +0,0 @@
1
- import { StorecraftSDK } from '../index.js'
2
- import { collection_base } from './utils.api.fetch.js';
3
-
4
- /**
5
- * @description Base `settings` **CRUD**
6
- *
7
- * @extends {collection_base<any, any>}
8
- */
9
- export default class Settings extends collection_base {
10
-
11
- /**
12
- *
13
- * @param {StorecraftSDK} sdk
14
- */
15
- constructor(sdk) {
16
- super(sdk, 'settings');
17
- }
18
-
19
- }