@spree/sdk 0.6.9 → 0.7.0

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/dist/index.cjs CHANGED
@@ -1,158 +1,8 @@
1
1
  'use strict';
2
2
 
3
- // src/request.ts
4
- var SpreeError = class extends Error {
5
- code;
6
- status;
7
- details;
8
- constructor(response, status) {
9
- super(response.error.message);
10
- this.name = "SpreeError";
11
- this.code = response.error.code;
12
- this.status = status;
13
- this.details = response.error.details;
14
- }
15
- };
16
- function calculateDelay(attempt, config) {
17
- const exponentialDelay = config.baseDelay * Math.pow(2, attempt);
18
- const jitter = Math.random() * config.baseDelay;
19
- return Math.min(exponentialDelay + jitter, config.maxDelay);
20
- }
21
- function sleep(ms) {
22
- return new Promise((resolve) => setTimeout(resolve, ms));
23
- }
24
- function generateIdempotencyKey() {
25
- return `spree-sdk-retry-${crypto.randomUUID()}`;
26
- }
27
- function shouldRetryOnStatus(method, status, config, hasIdempotencyKey) {
28
- const isIdempotent = method === "GET" || method === "HEAD" || hasIdempotencyKey;
29
- if (isIdempotent) {
30
- return config.retryOnStatus.includes(status);
31
- }
32
- return status === 429;
33
- }
34
- function shouldRetryOnNetworkError(method, config, hasIdempotencyKey) {
35
- if (!config.retryOnNetworkError) return false;
36
- return method === "GET" || method === "HEAD" || hasIdempotencyKey;
37
- }
38
- function createRequestFn(config, basePath, auth, defaults) {
39
- return async function request(method, path, options = {}) {
40
- const { token, orderToken, idempotencyKey, headers = {}, body, params } = options;
41
- const locale = options.locale ?? defaults?.locale;
42
- const currency = options.currency ?? defaults?.currency;
43
- const country = options.country ?? defaults?.country;
44
- const url = new URL(`${config.baseUrl}${basePath}${path}`);
45
- if (params) {
46
- Object.entries(params).forEach(([key, value]) => {
47
- if (value !== void 0) {
48
- if (Array.isArray(value)) {
49
- value.forEach((v) => url.searchParams.append(key, String(v)));
50
- } else {
51
- url.searchParams.set(key, String(value));
52
- }
53
- }
54
- });
55
- }
56
- const requestHeaders = {
57
- "Content-Type": "application/json",
58
- ...headers
59
- };
60
- if (auth.headerName && auth.headerValue) {
61
- requestHeaders[auth.headerName] = auth.headerValue;
62
- }
63
- if (token) {
64
- requestHeaders["Authorization"] = `Bearer ${token}`;
65
- }
66
- if (orderToken) {
67
- requestHeaders["x-spree-order-token"] = orderToken;
68
- }
69
- if (locale) {
70
- requestHeaders["x-spree-locale"] = locale;
71
- }
72
- if (currency) {
73
- requestHeaders["x-spree-currency"] = currency;
74
- }
75
- if (country) {
76
- requestHeaders["x-spree-country"] = country;
77
- }
78
- const isMutating = method !== "GET" && method !== "HEAD";
79
- const effectiveIdempotencyKey = idempotencyKey ?? (isMutating && config.retryConfig ? generateIdempotencyKey() : void 0);
80
- if (effectiveIdempotencyKey) {
81
- requestHeaders["Idempotency-Key"] = effectiveIdempotencyKey;
82
- }
83
- const hasIdempotencyKey = !!effectiveIdempotencyKey;
84
- const maxAttempts = config.retryConfig ? config.retryConfig.maxRetries + 1 : 1;
85
- for (let attempt = 0; attempt < maxAttempts; attempt++) {
86
- try {
87
- const response = await config.fetchFn(url.toString(), {
88
- method,
89
- headers: requestHeaders,
90
- body: body ? JSON.stringify(body) : void 0
91
- });
92
- if (!response.ok) {
93
- const isLastAttempt = attempt >= maxAttempts - 1;
94
- if (!isLastAttempt && config.retryConfig && shouldRetryOnStatus(method, response.status, config.retryConfig, hasIdempotencyKey)) {
95
- const retryAfter = response.headers.get("Retry-After");
96
- const delay = retryAfter ? Math.min(parseInt(retryAfter, 10) * 1e3, config.retryConfig.maxDelay) : calculateDelay(attempt, config.retryConfig);
97
- await sleep(delay);
98
- continue;
99
- }
100
- const errorBody = await response.json();
101
- throw new SpreeError(errorBody, response.status);
102
- }
103
- if (response.status === 204) {
104
- return void 0;
105
- }
106
- return response.json();
107
- } catch (error) {
108
- if (error instanceof SpreeError) {
109
- throw error;
110
- }
111
- const isLastAttempt = attempt >= maxAttempts - 1;
112
- if (!isLastAttempt && config.retryConfig && shouldRetryOnNetworkError(method, config.retryConfig, hasIdempotencyKey)) {
113
- const delay = calculateDelay(attempt, config.retryConfig);
114
- await sleep(delay);
115
- continue;
116
- }
117
- throw error;
118
- }
119
- }
120
- throw new Error("Unexpected end of retry loop");
121
- };
122
- }
3
+ var sdkCore = require('@spree/sdk-core');
123
4
 
124
- // src/params.ts
125
- var PASSTHROUGH_KEYS = /* @__PURE__ */ new Set(["page", "limit", "expand", "sort", "fields"]);
126
- function transformListParams(params) {
127
- const result = {};
128
- for (const [key, value] of Object.entries(params)) {
129
- if (value === void 0) continue;
130
- if (PASSTHROUGH_KEYS.has(key)) {
131
- result[key] = Array.isArray(value) ? value.join(",") : value;
132
- continue;
133
- }
134
- if (key.startsWith("q[")) {
135
- result[key] = value;
136
- continue;
137
- }
138
- if (Array.isArray(value)) {
139
- const base = key.endsWith("[]") ? key.slice(0, -2) : key;
140
- result[`q[${base}][]`] = value;
141
- } else {
142
- result[`q[${key}]`] = value;
143
- }
144
- }
145
- return result;
146
- }
147
-
148
- // src/store-client.ts
149
- function getParams(params) {
150
- if (!params) return void 0;
151
- const result = {};
152
- if (params.expand?.length) result.expand = params.expand.join(",");
153
- if (params.fields?.length) result.fields = params.fields.join(",");
154
- return Object.keys(result).length > 0 ? result : void 0;
155
- }
5
+ // src/client.ts
156
6
  var StoreClient = class {
157
7
  request;
158
8
  constructor(request) {
@@ -184,14 +34,14 @@ var StoreClient = class {
184
34
  */
185
35
  list: (params, options) => this.request("GET", "/products", {
186
36
  ...options,
187
- params: transformListParams({ ...params })
37
+ params: sdkCore.transformListParams({ ...params })
188
38
  }),
189
39
  /**
190
40
  * Get a product by ID or slug
191
41
  */
192
42
  get: (idOrSlug, params, options) => this.request("GET", `/products/${idOrSlug}`, {
193
43
  ...options,
194
- params: getParams(params)
44
+ params: sdkCore.getParams(params)
195
45
  }),
196
46
  /**
197
47
  * Get available filters for products
@@ -211,14 +61,14 @@ var StoreClient = class {
211
61
  */
212
62
  list: (params, options) => this.request("GET", "/taxonomies", {
213
63
  ...options,
214
- params: transformListParams({ ...params })
64
+ params: sdkCore.transformListParams({ ...params })
215
65
  }),
216
66
  /**
217
67
  * Get a taxonomy by ID
218
68
  */
219
69
  get: (id, params, options) => this.request("GET", `/taxonomies/${id}`, {
220
70
  ...options,
221
- params: getParams(params)
71
+ params: sdkCore.getParams(params)
222
72
  })
223
73
  };
224
74
  taxons = {
@@ -227,14 +77,14 @@ var StoreClient = class {
227
77
  */
228
78
  list: (params, options) => this.request("GET", "/taxons", {
229
79
  ...options,
230
- params: transformListParams({ ...params })
80
+ params: sdkCore.transformListParams({ ...params })
231
81
  }),
232
82
  /**
233
83
  * Get a taxon by ID or permalink
234
84
  */
235
85
  get: (idOrPermalink, params, options) => this.request("GET", `/taxons/${idOrPermalink}`, {
236
86
  ...options,
237
- params: getParams(params)
87
+ params: sdkCore.getParams(params)
238
88
  }),
239
89
  /**
240
90
  * Nested resource: Products in a taxon
@@ -249,7 +99,7 @@ var StoreClient = class {
249
99
  `/taxons/${taxonId}/products`,
250
100
  {
251
101
  ...options,
252
- params: transformListParams({ ...params })
102
+ params: sdkCore.transformListParams({ ...params })
253
103
  }
254
104
  )
255
105
  }
@@ -270,7 +120,7 @@ var StoreClient = class {
270
120
  */
271
121
  get: (iso, params, options) => this.request("GET", `/countries/${iso}`, {
272
122
  ...options,
273
- params: getParams(params)
123
+ params: sdkCore.getParams(params)
274
124
  })
275
125
  };
276
126
  currencies = {
@@ -327,7 +177,7 @@ var StoreClient = class {
327
177
  get: (marketId, iso, params, options) => this.request(
328
178
  "GET",
329
179
  `/markets/${marketId}/countries/${iso}`,
330
- { ...options, params: getParams(params) }
180
+ { ...options, params: sdkCore.getParams(params) }
331
181
  )
332
182
  }
333
183
  };
@@ -364,7 +214,7 @@ var StoreClient = class {
364
214
  */
365
215
  get: (idOrNumber, params, options) => this.request("GET", `/orders/${idOrNumber}`, {
366
216
  ...options,
367
- params: getParams(params)
217
+ params: sdkCore.getParams(params)
368
218
  }),
369
219
  /**
370
220
  * Update an order
@@ -582,7 +432,7 @@ var StoreClient = class {
582
432
  list: (params, options) => this.request(
583
433
  "GET",
584
434
  "/customer/addresses",
585
- { ...options, params: transformListParams({ ...params }) }
435
+ { ...options, params: sdkCore.transformListParams({ ...params }) }
586
436
  ),
587
437
  /**
588
438
  * Get an address by ID
@@ -624,7 +474,7 @@ var StoreClient = class {
624
474
  list: (params, options) => this.request(
625
475
  "GET",
626
476
  "/customer/credit_cards",
627
- { ...options, params: transformListParams({ ...params }) }
477
+ { ...options, params: sdkCore.transformListParams({ ...params }) }
628
478
  ),
629
479
  /**
630
480
  * Get a credit card by ID
@@ -646,7 +496,7 @@ var StoreClient = class {
646
496
  list: (params, options) => this.request(
647
497
  "GET",
648
498
  "/customer/gift_cards",
649
- { ...options, params: transformListParams({ ...params }) }
499
+ { ...options, params: sdkCore.transformListParams({ ...params }) }
650
500
  ),
651
501
  /**
652
502
  * Get a gift card by ID
@@ -662,7 +512,7 @@ var StoreClient = class {
662
512
  */
663
513
  list: (params, options) => this.request("GET", "/customer/orders", {
664
514
  ...options,
665
- params: transformListParams({ ...params })
515
+ params: sdkCore.transformListParams({ ...params })
666
516
  })
667
517
  },
668
518
  /**
@@ -702,14 +552,14 @@ var StoreClient = class {
702
552
  */
703
553
  list: (params, options) => this.request("GET", "/wishlists", {
704
554
  ...options,
705
- params: transformListParams({ ...params })
555
+ params: sdkCore.transformListParams({ ...params })
706
556
  }),
707
557
  /**
708
558
  * Get a wishlist by ID
709
559
  */
710
560
  get: (id, params, options) => this.request("GET", `/wishlists/${id}`, {
711
561
  ...options,
712
- params: getParams(params)
562
+ params: sdkCore.getParams(params)
713
563
  }),
714
564
  /**
715
565
  * Create a wishlist
@@ -760,86 +610,42 @@ var StoreClient = class {
760
610
  };
761
611
  };
762
612
 
763
- // src/admin-client.ts
764
- var AdminClient = class {
765
- /** @internal */
766
- request;
767
- constructor(request) {
768
- this.request = request;
769
- void this.request;
770
- }
771
- };
772
-
773
613
  // src/client.ts
774
- var SpreeClient = class {
775
- /** Store API — customer-facing endpoints (products, cart, checkout, account) */
776
- store;
777
- /** Admin API — administrative endpoints (manage orders, products, settings) */
778
- admin;
779
- _defaults;
780
- constructor(config) {
781
- if (!config.publishableKey && !config.secretKey) {
782
- throw new Error("SpreeClient requires at least one of publishableKey or secretKey");
783
- }
784
- const baseUrl = config.baseUrl.replace(/\/$/, "");
785
- const fetchFn = config.fetch || fetch.bind(globalThis);
786
- this._defaults = {
787
- locale: config.locale,
788
- currency: config.currency,
789
- country: config.country
790
- };
791
- let retryConfig;
792
- if (config.retry === false) {
793
- retryConfig = false;
794
- } else {
795
- retryConfig = {
796
- maxRetries: config.retry?.maxRetries ?? 2,
797
- retryOnStatus: config.retry?.retryOnStatus ?? [429, 500, 502, 503, 504],
798
- baseDelay: config.retry?.baseDelay ?? 300,
799
- maxDelay: config.retry?.maxDelay ?? 1e4,
800
- retryOnNetworkError: config.retry?.retryOnNetworkError ?? true
801
- };
802
- }
803
- const requestConfig = { baseUrl, fetchFn, retryConfig };
804
- const storeRequestFn = createRequestFn(
805
- requestConfig,
806
- "/api/v3/store",
807
- config.publishableKey ? { headerName: "x-spree-api-key", headerValue: config.publishableKey } : { headerName: "", headerValue: "" },
808
- this._defaults
809
- );
810
- const adminRequestFn = createRequestFn(
811
- requestConfig,
812
- "/api/v3/admin",
813
- {
814
- headerName: "Authorization",
815
- headerValue: config.secretKey ? `Bearer ${config.secretKey}` : ""
816
- },
817
- this._defaults
818
- );
819
- this.store = new StoreClient(storeRequestFn);
820
- this.admin = new AdminClient(adminRequestFn);
821
- }
822
- /** Set default locale for all subsequent requests */
823
- setLocale(locale) {
824
- this._defaults.locale = locale;
825
- }
826
- /** Set default currency for all subsequent requests */
827
- setCurrency(currency) {
828
- this._defaults.currency = currency;
829
- }
830
- /** Set default country for all subsequent requests */
831
- setCountry(country) {
832
- this._defaults.country = country;
833
- }
834
- };
835
- function createSpreeClient(config) {
836
- return new SpreeClient(config);
614
+ function createClient(config) {
615
+ const baseUrl = config.baseUrl.replace(/\/$/, "");
616
+ const fetchFn = config.fetch || fetch.bind(globalThis);
617
+ const defaults = {
618
+ locale: config.locale,
619
+ currency: config.currency,
620
+ country: config.country
621
+ };
622
+ const retryConfig = sdkCore.resolveRetryConfig(config.retry);
623
+ const requestConfig = { baseUrl, fetchFn, retryConfig };
624
+ const requestFn = sdkCore.createRequestFn(
625
+ requestConfig,
626
+ "/api/v3/store",
627
+ { headerName: "x-spree-api-key", headerValue: config.publishableKey },
628
+ defaults
629
+ );
630
+ const storeClient = new StoreClient(requestFn);
631
+ const client = Object.create(storeClient);
632
+ client.setLocale = (locale) => {
633
+ defaults.locale = locale;
634
+ };
635
+ client.setCurrency = (currency) => {
636
+ defaults.currency = currency;
637
+ };
638
+ client.setCountry = (country) => {
639
+ defaults.country = country;
640
+ };
641
+ return client;
837
642
  }
838
643
 
839
- exports.AdminClient = AdminClient;
840
- exports.SpreeClient = SpreeClient;
841
- exports.SpreeError = SpreeError;
644
+ Object.defineProperty(exports, "SpreeError", {
645
+ enumerable: true,
646
+ get: function () { return sdkCore.SpreeError; }
647
+ });
842
648
  exports.StoreClient = StoreClient;
843
- exports.createSpreeClient = createSpreeClient;
649
+ exports.createClient = createClient;
844
650
  //# sourceMappingURL=index.cjs.map
845
651
  //# sourceMappingURL=index.cjs.map