shop-client 3.9.2 → 3.11.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.
@@ -9,8 +9,8 @@ import {
9
9
  htmlToMarkdown,
10
10
  mergeWithLLM,
11
11
  pruneBreakdownForSignals
12
- } from "../chunk-VPPCOJC3.js";
13
- import "../chunk-2MF53V33.js";
12
+ } from "../chunk-GNIBTUEK.mjs";
13
+ import "../chunk-D5MTUWFO.mjs";
14
14
  export {
15
15
  classifyProduct,
16
16
  determineStoreType,
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  createCheckoutOperations
3
- } from "./chunk-RR6YTQWP.js";
3
+ } from "./chunk-W4SF6W2P.mjs";
4
4
  export {
5
5
  createCheckoutOperations
6
6
  };
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  rateLimitedFetch
3
- } from "./chunk-2MF53V33.js";
3
+ } from "./chunk-D5MTUWFO.mjs";
4
4
  import {
5
5
  formatPrice
6
- } from "./chunk-CN7L3BHG.js";
6
+ } from "./chunk-U3RQRBXZ.mjs";
7
7
 
8
8
  // src/collections.ts
9
9
  import { filter, isNonNullish } from "remeda";
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  rateLimitedFetch
3
- } from "./chunk-2MF53V33.js";
3
+ } from "./chunk-D5MTUWFO.mjs";
4
4
  import {
5
5
  formatPrice
6
- } from "./chunk-CN7L3BHG.js";
6
+ } from "./chunk-U3RQRBXZ.mjs";
7
7
 
8
8
  // src/products.ts
9
9
  import { filter, isNonNullish } from "remeda";
@@ -253,7 +253,7 @@ function createProductOperations(baseUrl, storeDomain, fetchProducts, productsDt
253
253
  return null;
254
254
  }
255
255
  const handle = baseProduct.handle;
256
- const { enrichProduct } = await import("./ai/enrich.js");
256
+ const { enrichProduct } = await import("./ai/enrich.mjs");
257
257
  const enriched = await enrichProduct(storeDomain, handle, {
258
258
  apiKey,
259
259
  useGfm: options == null ? void 0 : options.useGfm,
@@ -302,7 +302,7 @@ function createProductOperations(baseUrl, storeDomain, fetchProducts, productsDt
302
302
  productContent = lines.join("\n");
303
303
  } catch {
304
304
  }
305
- const { classifyProduct } = await import("./ai/enrich.js");
305
+ const { classifyProduct } = await import("./ai/enrich.mjs");
306
306
  const classification = await classifyProduct(productContent, {
307
307
  apiKey,
308
308
  model: options == null ? void 0 : options.model
@@ -328,7 +328,7 @@ function createProductOperations(baseUrl, storeDomain, fetchProducts, productsDt
328
328
  price: baseProduct.price,
329
329
  tags: baseProduct.tags
330
330
  };
331
- const { generateSEOContent: generateSEOContentLLM } = await import("./ai/enrich.js");
331
+ const { generateSEOContent: generateSEOContentLLM } = await import("./ai/enrich.mjs");
332
332
  const seo = await generateSEOContentLLM(payload, {
333
333
  apiKey,
334
334
  model: options == null ? void 0 : options.model
@@ -50,7 +50,7 @@ var RateLimiter = class {
50
50
  }
51
51
  }
52
52
  };
53
- var enabled = false;
53
+ var enabled = true;
54
54
  var defaultOptions = {
55
55
  maxRequestsPerInterval: 5,
56
56
  // 5 requests
@@ -149,25 +149,38 @@ function sleep(ms) {
149
149
  return new Promise((resolve) => setTimeout(resolve, ms));
150
150
  }
151
151
  async function rateLimitedFetch(input, init) {
152
- var _a, _b, _c, _d, _e, _f, _g;
152
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i;
153
+ const timeoutMs = Math.max(0, (_a = init == null ? void 0 : init.timeoutMs) != null ? _a : 0);
154
+ let controller;
155
+ let timer;
156
+ const hasSignal = !!(init == null ? void 0 : init.signal);
157
+ if (timeoutMs > 0 && !hasSignal) {
158
+ controller = new AbortController();
159
+ timer = setTimeout(() => controller == null ? void 0 : controller.abort(), timeoutMs);
160
+ }
161
+ const effInit = {
162
+ ...init,
163
+ signal: hasSignal ? init == null ? void 0 : init.signal : controller == null ? void 0 : controller.signal
164
+ };
153
165
  const klass = init == null ? void 0 : init.rateLimitClass;
154
166
  const byClass = klass ? classLimiters.get(klass) : void 0;
155
167
  const byHost = getHostLimiter(getHost(input));
156
- const eff = enabled ? (_a = byClass != null ? byClass : byHost) != null ? _a : limiter : void 0;
157
- const maxRetries = Math.max(0, (_c = (_b = init == null ? void 0 : init.retry) == null ? void 0 : _b.maxRetries) != null ? _c : 2);
158
- const baseDelayMs = Math.max(0, (_e = (_d = init == null ? void 0 : init.retry) == null ? void 0 : _d.baseDelayMs) != null ? _e : 200);
159
- const retryOnStatuses = (_g = (_f = init == null ? void 0 : init.retry) == null ? void 0 : _f.retryOnStatuses) != null ? _g : [429, 503];
168
+ const eff = enabled ? (_b = byClass != null ? byClass : byHost) != null ? _b : limiter : void 0;
169
+ const maxRetries = Math.max(0, (_d = (_c = init == null ? void 0 : init.retry) == null ? void 0 : _c.maxRetries) != null ? _d : 2);
170
+ const baseDelayMs = Math.max(0, (_f = (_e = init == null ? void 0 : init.retry) == null ? void 0 : _e.baseDelayMs) != null ? _f : 200);
171
+ const retryOnStatuses = (_h = (_g = init == null ? void 0 : init.retry) == null ? void 0 : _g.retryOnStatuses) != null ? _h : [429, 503];
160
172
  let attempt = 0;
161
173
  let lastError = null;
162
174
  let response = null;
163
175
  while (attempt <= maxRetries) {
164
176
  try {
165
177
  if (eff) {
166
- response = await eff.schedule(() => fetch(input, init));
178
+ response = await eff.schedule(() => fetch(input, effInit));
167
179
  } else {
168
- response = await fetch(input, init);
180
+ response = await fetch(input, effInit);
169
181
  }
170
182
  if (!response || response.ok || !retryOnStatuses.includes(response.status)) {
183
+ if (timer) clearTimeout(timer);
171
184
  return response;
172
185
  }
173
186
  } catch (err) {
@@ -175,10 +188,23 @@ async function rateLimitedFetch(input, init) {
175
188
  }
176
189
  attempt += 1;
177
190
  if (attempt > maxRetries) break;
178
- const jitter = Math.floor(Math.random() * 100);
179
- const delay = baseDelayMs * 2 ** (attempt - 1) + jitter;
191
+ let delay = baseDelayMs * 2 ** (attempt - 1) + Math.floor(Math.random() * 100);
192
+ const retryAfter = (_i = response == null ? void 0 : response.headers) == null ? void 0 : _i.get("retry-after");
193
+ if (retryAfter) {
194
+ const asNumber = Number(retryAfter);
195
+ if (!Number.isNaN(asNumber) && asNumber >= 0) {
196
+ delay = Math.max(delay, Math.floor(asNumber * 1e3));
197
+ } else {
198
+ const parsed = Date.parse(retryAfter);
199
+ if (!Number.isNaN(parsed)) {
200
+ const until = parsed - Date.now();
201
+ if (until > 0) delay = Math.max(delay, until);
202
+ }
203
+ }
204
+ }
180
205
  await sleep(delay);
181
206
  }
207
+ if (timer) clearTimeout(timer);
182
208
  if (response) return response;
183
209
  throw lastError != null ? lastError : new Error("rateLimitedFetch failed without response");
184
210
  }
@@ -1,19 +1,19 @@
1
1
  import {
2
2
  rateLimitedFetch
3
- } from "./chunk-2MF53V33.js";
3
+ } from "./chunk-D5MTUWFO.mjs";
4
4
  import {
5
5
  detectShopCountry
6
- } from "./chunk-QUDGES3A.js";
6
+ } from "./chunk-G7OCMGA6.mjs";
7
7
  import {
8
8
  extractDomainWithoutSuffix,
9
9
  generateStoreSlug,
10
10
  sanitizeDomain
11
- } from "./chunk-CN7L3BHG.js";
11
+ } from "./chunk-U3RQRBXZ.mjs";
12
12
 
13
13
  // src/client/get-info.ts
14
14
  import { unique } from "remeda";
15
- async function getInfoForStore(args) {
16
- var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m;
15
+ async function getInfoForStore(args, options) {
16
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p;
17
17
  const {
18
18
  baseUrl,
19
19
  storeDomain,
@@ -22,7 +22,8 @@ async function getInfoForStore(args) {
22
22
  validateLinksInBatches
23
23
  } = args;
24
24
  const response = await rateLimitedFetch(baseUrl, {
25
- rateLimitClass: "store:info"
25
+ rateLimitClass: "store:info",
26
+ timeoutMs: 7e3
26
27
  });
27
28
  if (!response.ok) {
28
29
  throw new Error(`HTTP error! status: ${response.status}`);
@@ -94,18 +95,22 @@ async function getInfoForStore(args) {
94
95
  )) {
95
96
  contactLinks.contactPage = (match == null ? void 0 : match[1]) || null;
96
97
  }
97
- const extractedProductLinks = ((_g = (_f = html.match(/href=["']([^"']*\/products\/[^"']+)["']/g)) == null ? void 0 : _f.map(
98
- (match) => {
99
- var _a2, _b2;
100
- return (_b2 = (_a2 = match == null ? void 0 : match.split("href=")[1]) == null ? void 0 : _a2.replace(/["']/g, "")) == null ? void 0 : _b2.split("/").at(-1);
101
- }
102
- )) == null ? void 0 : _g.filter(Boolean)) || [];
103
- const extractedCollectionLinks = ((_i = (_h = html.match(/href=["']([^"']*\/collections\/[^"']+)["']/g)) == null ? void 0 : _h.map(
104
- (match) => {
105
- var _a2, _b2;
106
- return (_b2 = (_a2 = match == null ? void 0 : match.split("href=")[1]) == null ? void 0 : _a2.replace(/["']/g, "")) == null ? void 0 : _b2.split("/").at(-1);
107
- }
108
- )) == null ? void 0 : _i.filter(Boolean)) || [];
98
+ const extractedProductLinks = unique(
99
+ ((_g = (_f = html.match(/href=["']([^"']*\/products\/[^"']+)["']/g)) == null ? void 0 : _f.map(
100
+ (match) => {
101
+ var _a2, _b2;
102
+ return (_b2 = (_a2 = match == null ? void 0 : match.split("href=")[1]) == null ? void 0 : _a2.replace(/["']/g, "")) == null ? void 0 : _b2.split("/").at(-1);
103
+ }
104
+ )) == null ? void 0 : _g.filter(Boolean)) || []
105
+ ).slice(0, 8);
106
+ const extractedCollectionLinks = unique(
107
+ ((_i = (_h = html.match(/href=["']([^"']*\/collections\/[^"']+)["']/g)) == null ? void 0 : _h.map(
108
+ (match) => {
109
+ var _a2, _b2;
110
+ return (_b2 = (_a2 = match == null ? void 0 : match.split("href=")[1]) == null ? void 0 : _a2.replace(/["']/g, "")) == null ? void 0 : _b2.split("/").at(-1);
111
+ }
112
+ )) == null ? void 0 : _i.filter(Boolean)) || []
113
+ ).slice(0, 8);
109
114
  const headerLinks = (_k = (_j = html.match(
110
115
  /<(header|nav|div|section)\b[^>]*\b(?:id|class)=["'][^"']*(?=.*shopify-section)(?=.*\b(header|navigation|nav|menu)\b)[^"']*["'][^>]*>[\s\S]*?<\/\1>/gi
111
116
  )) == null ? void 0 : _j.flatMap((header) => {
@@ -129,20 +134,37 @@ async function getInfoForStore(args) {
129
134
  })) != null ? _k : [];
130
135
  const slug = generateStoreSlug(baseUrl);
131
136
  const countryDetection = await detectShopCountry(html);
132
- const [homePageProductLinks, homePageCollectionLinks] = await Promise.all([
133
- validateLinksInBatches(
134
- extractedProductLinks.filter(
135
- (handle) => Boolean(handle)
137
+ const doValidate = (options == null ? void 0 : options.validateShowcase) === true;
138
+ let homePageProductLinks = [];
139
+ let homePageCollectionLinks = [];
140
+ if (doValidate) {
141
+ const batchSize = (_l = options == null ? void 0 : options.validationBatchSize) != null ? _l : 5;
142
+ const validated = await Promise.all([
143
+ validateLinksInBatches(
144
+ extractedProductLinks.filter(
145
+ (handle) => Boolean(handle)
146
+ ),
147
+ (handle) => validateProductExists(handle),
148
+ batchSize
136
149
  ),
137
- (handle) => validateProductExists(handle)
138
- ),
139
- validateLinksInBatches(
140
- extractedCollectionLinks.filter(
141
- (handle) => Boolean(handle)
142
- ),
143
- (handle) => validateCollectionExists(handle)
144
- )
145
- ]);
150
+ validateLinksInBatches(
151
+ extractedCollectionLinks.filter(
152
+ (handle) => Boolean(handle)
153
+ ),
154
+ (handle) => validateCollectionExists(handle),
155
+ batchSize
156
+ )
157
+ ]);
158
+ homePageProductLinks = (_m = validated[0]) != null ? _m : [];
159
+ homePageCollectionLinks = (_n = validated[1]) != null ? _n : [];
160
+ } else {
161
+ homePageProductLinks = extractedProductLinks.filter(
162
+ (handle) => Boolean(handle)
163
+ );
164
+ homePageCollectionLinks = extractedCollectionLinks.filter(
165
+ (handle) => Boolean(handle)
166
+ );
167
+ }
146
168
  const info = {
147
169
  name: name || slug,
148
170
  domain: sanitizeDomain(baseUrl),
@@ -157,14 +179,14 @@ async function getInfoForStore(args) {
157
179
  products: unique(homePageProductLinks != null ? homePageProductLinks : []),
158
180
  collections: unique(homePageCollectionLinks != null ? homePageCollectionLinks : [])
159
181
  },
160
- jsonLdData: ((_m = (_l = html.match(
182
+ jsonLdData: ((_p = (_o = html.match(
161
183
  /<script[^>]*type="application\/ld\+json"[^>]*>([^<]+)<\/script>/g
162
- )) == null ? void 0 : _l.map(
184
+ )) == null ? void 0 : _o.map(
163
185
  (match) => {
164
186
  var _a2;
165
187
  return ((_a2 = match == null ? void 0 : match.split(">")[1]) == null ? void 0 : _a2.replace(/<\/script/g, "")) || null;
166
188
  }
167
- )) == null ? void 0 : _m.map((json) => json ? JSON.parse(json) : null)) || [],
189
+ )) == null ? void 0 : _p.map((json) => json ? JSON.parse(json) : null)) || [],
168
190
  techProvider: {
169
191
  name: "shopify",
170
192
  walletId: shopifyWalletId,
@@ -33,6 +33,32 @@ var COUNTRY_CODES = {
33
33
  "+7": "RU"
34
34
  // Russia
35
35
  };
36
+ var CURRENCY_JSON_RE = /Shopify\.currency\s*=\s*(\{[^}]*\})/i;
37
+ var CURRENCY_ACTIVE_ASSIGN_RE = /Shopify\.currency\.active\s*=\s*['"]([A-Za-z]{3})['"]/i;
38
+ var SHOPIFY_COUNTRY_RE = /Shopify\.country\s*=\s*['"]([A-Za-z]{2})['"]/i;
39
+ var JSON_LD_RE = /<script[^>]*type=["']application\/ld\+json["'][^>]*>([\s\S]*?)<\/script>/gi;
40
+ var TEL_HREF_RE = /href=["']tel:([^"']+)["']/gi;
41
+ var COUNTRY_NAME_TO_ISO = {
42
+ india: "IN",
43
+ "united states": "US",
44
+ canada: "CA",
45
+ australia: "AU",
46
+ "united kingdom": "GB",
47
+ britain: "GB",
48
+ uk: "GB",
49
+ japan: "JP",
50
+ "south korea": "KR",
51
+ korea: "KR",
52
+ germany: "DE",
53
+ france: "FR",
54
+ italy: "IT",
55
+ spain: "ES",
56
+ brazil: "BR",
57
+ russia: "RU",
58
+ singapore: "SG",
59
+ indonesia: "ID",
60
+ pakistan: "PK"
61
+ };
36
62
  var CURRENCY_CODE_TO_COUNTRY = {
37
63
  INR: "IN",
38
64
  USD: "US",
@@ -51,11 +77,18 @@ function scoreCountry(countryScores, country, weight, reason) {
51
77
  countryScores[country].score += weight;
52
78
  countryScores[country].reasons.push(reason);
53
79
  }
80
+ function currentConfidence(countryScores) {
81
+ const sorted = Object.entries(countryScores).sort(
82
+ (a, b) => b[1].score - a[1].score
83
+ );
84
+ const best = sorted[0];
85
+ return best ? Math.min(1, best[1].score / 2) : 0;
86
+ }
54
87
  async function detectShopCountry(html) {
55
- var _a;
88
+ var _a, _b, _c;
56
89
  const countryScores = {};
57
90
  let detectedCurrencyCode;
58
- const currencyJsonMatch = html.match(/Shopify\.currency\s*=\s*(\{[^}]*\})/);
91
+ const currencyJsonMatch = html.match(CURRENCY_JSON_RE);
59
92
  if (currencyJsonMatch) {
60
93
  try {
61
94
  const raw = currencyJsonMatch[1];
@@ -71,9 +104,7 @@ async function detectShopCountry(html) {
71
104
  } catch (_error) {
72
105
  }
73
106
  } else {
74
- const currencyActiveAssignMatch = html.match(
75
- /Shopify\.currency\.active\s*=\s*['"]([A-Za-z]{3})['"]/i
76
- );
107
+ const currencyActiveAssignMatch = html.match(CURRENCY_ACTIVE_ASSIGN_RE);
77
108
  if (currencyActiveAssignMatch) {
78
109
  const captured = currencyActiveAssignMatch[1];
79
110
  const code = typeof captured === "string" ? captured.toUpperCase() : void 0;
@@ -86,9 +117,7 @@ async function detectShopCountry(html) {
86
117
  }
87
118
  }
88
119
  }
89
- const shopifyCountryMatch = html.match(
90
- /Shopify\.country\s*=\s*['"]([A-Za-z]{2})['"]/i
91
- );
120
+ const shopifyCountryMatch = html.match(SHOPIFY_COUNTRY_RE);
92
121
  if (shopifyCountryMatch) {
93
122
  const captured = shopifyCountryMatch[1];
94
123
  const iso = typeof captured === "string" ? captured.toUpperCase() : void 0;
@@ -96,10 +125,34 @@ async function detectShopCountry(html) {
96
125
  scoreCountry(countryScores, iso, 1, "Shopify.country");
97
126
  }
98
127
  }
128
+ if (currentConfidence(countryScores) >= 0.9) {
129
+ const sorted2 = Object.entries(countryScores).sort(
130
+ (a, b) => b[1].score - a[1].score
131
+ );
132
+ const best2 = sorted2[0];
133
+ return {
134
+ country: best2[0],
135
+ confidence: Math.min(1, best2[1].score / 2),
136
+ signals: best2[1].reasons,
137
+ currencyCode: detectedCurrencyCode
138
+ };
139
+ }
140
+ const telMatches = html.matchAll(TEL_HREF_RE);
141
+ for (const m of telMatches) {
142
+ const tel = (_a = m[1]) != null ? _a : "";
143
+ const prefix = (_b = tel.match(/^\+\d{1,3}/)) == null ? void 0 : _b[0];
144
+ if (prefix && COUNTRY_CODES[prefix])
145
+ scoreCountry(
146
+ countryScores,
147
+ COUNTRY_CODES[prefix],
148
+ 0.8,
149
+ `phone prefix ${prefix}`
150
+ );
151
+ }
99
152
  const phones = html.match(/\+\d{1,3}[\s\-()0-9]{5,}/g);
100
153
  if (phones) {
101
154
  for (const phone of phones) {
102
- const prefix = (_a = phone.match(/^\+\d{1,3}/)) == null ? void 0 : _a[0];
155
+ const prefix = (_c = phone.match(/^\+\d{1,3}/)) == null ? void 0 : _c[0];
103
156
  if (prefix && COUNTRY_CODES[prefix])
104
157
  scoreCountry(
105
158
  countryScores,
@@ -109,8 +162,7 @@ async function detectShopCountry(html) {
109
162
  );
110
163
  }
111
164
  }
112
- const jsonLdRegex = /<script[^>]+application\/ld\+json[^>]*>(.*?)<\/script>/g;
113
- let jsonLdMatch = jsonLdRegex.exec(html);
165
+ let jsonLdMatch = JSON_LD_RE.exec(html);
114
166
  while (jsonLdMatch !== null) {
115
167
  try {
116
168
  const json = jsonLdMatch[1];
@@ -141,34 +193,15 @@ async function detectShopCountry(html) {
141
193
  }
142
194
  } catch (_error) {
143
195
  }
144
- jsonLdMatch = jsonLdRegex.exec(html);
196
+ if (currentConfidence(countryScores) >= 0.9)
197
+ break;
198
+ jsonLdMatch = JSON_LD_RE.exec(html);
145
199
  }
146
200
  const footerMatch = html.match(/<footer[^>]*>(.*?)<\/footer>/i);
147
201
  if (footerMatch) {
148
202
  const footerTextGroup = footerMatch[1];
149
203
  const footerText = footerTextGroup ? footerTextGroup.toLowerCase() : "";
150
- const countryNameToISO = {
151
- india: "IN",
152
- "united states": "US",
153
- canada: "CA",
154
- australia: "AU",
155
- "united kingdom": "GB",
156
- britain: "GB",
157
- uk: "GB",
158
- japan: "JP",
159
- "south korea": "KR",
160
- korea: "KR",
161
- germany: "DE",
162
- france: "FR",
163
- italy: "IT",
164
- spain: "ES",
165
- brazil: "BR",
166
- russia: "RU",
167
- singapore: "SG",
168
- indonesia: "ID",
169
- pakistan: "PK"
170
- };
171
- for (const [countryName, isoCode] of Object.entries(countryNameToISO)) {
204
+ for (const [countryName, isoCode] of Object.entries(COUNTRY_NAME_TO_ISO)) {
172
205
  if (footerText.includes(countryName))
173
206
  scoreCountry(countryScores, isoCode, 0.4, "footer mention");
174
207
  }
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  rateLimitedFetch
3
- } from "./chunk-2MF53V33.js";
3
+ } from "./chunk-D5MTUWFO.mjs";
4
4
 
5
5
  // src/ai/enrich.ts
6
6
  import TurndownService from "turndown";
@@ -0,0 +1,8 @@
1
+ import {
2
+ createCollectionOperations
3
+ } from "./chunk-554O5ED6.mjs";
4
+ import "./chunk-D5MTUWFO.mjs";
5
+ import "./chunk-U3RQRBXZ.mjs";
6
+ export {
7
+ createCollectionOperations
8
+ };
package/dist/index.d.ts CHANGED
@@ -153,6 +153,8 @@ declare class ShopClient {
153
153
  */
154
154
  getInfo(options?: {
155
155
  force?: boolean;
156
+ validateShowcase?: boolean;
157
+ validationBatchSize?: number;
156
158
  }): Promise<StoreInfo>;
157
159
  /**
158
160
  * Manually clear the cached store info.
@@ -1,28 +1,28 @@
1
1
  import {
2
2
  createCheckoutOperations
3
- } from "./chunk-RR6YTQWP.js";
3
+ } from "./chunk-W4SF6W2P.mjs";
4
4
  import {
5
5
  createCollectionOperations
6
- } from "./chunk-MOBWPEY4.js";
6
+ } from "./chunk-554O5ED6.mjs";
7
7
  import {
8
8
  createProductOperations
9
- } from "./chunk-CXUCPK6X.js";
9
+ } from "./chunk-CNJRHWIK.mjs";
10
10
  import {
11
11
  createStoreOperations,
12
12
  getInfoForStore
13
- } from "./chunk-DJQEZNHG.js";
13
+ } from "./chunk-EUAKMCAX.mjs";
14
14
  import {
15
15
  classifyProduct,
16
16
  determineStoreType,
17
17
  generateSEOContent
18
- } from "./chunk-VPPCOJC3.js";
18
+ } from "./chunk-GNIBTUEK.mjs";
19
19
  import {
20
20
  configureRateLimit,
21
21
  rateLimitedFetch
22
- } from "./chunk-2MF53V33.js";
22
+ } from "./chunk-D5MTUWFO.mjs";
23
23
  import {
24
24
  detectShopCountry
25
- } from "./chunk-QUDGES3A.js";
25
+ } from "./chunk-G7OCMGA6.mjs";
26
26
  import {
27
27
  buildVariantOptionsMap,
28
28
  calculateDiscount,
@@ -32,7 +32,7 @@ import {
32
32
  normalizeKey,
33
33
  safeParseDate,
34
34
  sanitizeDomain
35
- } from "./chunk-CN7L3BHG.js";
35
+ } from "./chunk-U3RQRBXZ.mjs";
36
36
 
37
37
  // src/ai/determine-store-type.ts
38
38
  async function determineStoreTypeForStore(args) {
@@ -568,7 +568,8 @@ var ShopClient = class {
568
568
  const url = `${this.baseUrl}products/${handle}.js`;
569
569
  const response = await rateLimitedFetch(url, {
570
570
  method: "HEAD",
571
- rateLimitClass: "validate:product"
571
+ rateLimitClass: "validate:product",
572
+ timeoutMs: 5e3
572
573
  });
573
574
  const exists = response.ok;
574
575
  this.setCacheValue(cacheKey, exists);
@@ -590,7 +591,8 @@ var ShopClient = class {
590
591
  const url = `${this.baseUrl}collections/${handle}.json`;
591
592
  const response = await rateLimitedFetch(url, {
592
593
  method: "HEAD",
593
- rateLimitClass: "validate:collection"
594
+ rateLimitClass: "validate:collection",
595
+ timeoutMs: 5e3
594
596
  });
595
597
  const exists = response.ok;
596
598
  this.setCacheValue(cacheKey, exists);
@@ -685,13 +687,19 @@ var ShopClient = class {
685
687
  return await this.infoInFlight;
686
688
  }
687
689
  this.infoInFlight = (async () => {
688
- const { info, currencyCode } = await getInfoForStore({
689
- baseUrl: this.baseUrl,
690
- storeDomain: this.storeDomain,
691
- validateProductExists: (handle) => this.validateProductExists(handle),
692
- validateCollectionExists: (handle) => this.validateCollectionExists(handle),
693
- validateLinksInBatches: (items, validator, batchSize) => this.validateLinksInBatches(items, validator, batchSize)
694
- });
690
+ const { info, currencyCode } = await getInfoForStore(
691
+ {
692
+ baseUrl: this.baseUrl,
693
+ storeDomain: this.storeDomain,
694
+ validateProductExists: (handle) => this.validateProductExists(handle),
695
+ validateCollectionExists: (handle) => this.validateCollectionExists(handle),
696
+ validateLinksInBatches: (items, validator, batchSize) => this.validateLinksInBatches(items, validator, batchSize)
697
+ },
698
+ {
699
+ validateShowcase: (options == null ? void 0 : options.validateShowcase) === true,
700
+ validationBatchSize: options == null ? void 0 : options.validationBatchSize
701
+ }
702
+ );
695
703
  if (typeof currencyCode === "string") {
696
704
  this.storeCurrency = currencyCode;
697
705
  }
@@ -0,0 +1,8 @@
1
+ import {
2
+ createProductOperations
3
+ } from "./chunk-CNJRHWIK.mjs";
4
+ import "./chunk-D5MTUWFO.mjs";
5
+ import "./chunk-U3RQRBXZ.mjs";
6
+ export {
7
+ createProductOperations
8
+ };
package/dist/store.mjs ADDED
@@ -0,0 +1,9 @@
1
+ import {
2
+ createStoreOperations
3
+ } from "./chunk-EUAKMCAX.mjs";
4
+ import "./chunk-D5MTUWFO.mjs";
5
+ import "./chunk-G7OCMGA6.mjs";
6
+ import "./chunk-U3RQRBXZ.mjs";
7
+ export {
8
+ createStoreOperations
9
+ };
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  detectShopCountry
3
- } from "../chunk-QUDGES3A.js";
3
+ } from "../chunk-G7OCMGA6.mjs";
4
4
  export {
5
5
  detectShopCountry
6
6
  };
@@ -9,7 +9,7 @@ import {
9
9
  normalizeKey,
10
10
  safeParseDate,
11
11
  sanitizeDomain
12
- } from "../chunk-CN7L3BHG.js";
12
+ } from "../chunk-U3RQRBXZ.mjs";
13
13
  export {
14
14
  buildVariantKey,
15
15
  buildVariantOptionsMap,
@@ -10,6 +10,7 @@ type RateLimitedRequestInit = RequestInit & {
10
10
  baseDelayMs?: number;
11
11
  retryOnStatuses?: number[];
12
12
  };
13
+ timeoutMs?: number;
13
14
  };
14
15
  declare function configureRateLimit(options: Partial<RateLimitOptions & {
15
16
  enabled: boolean;
@@ -2,7 +2,7 @@ import {
2
2
  configureRateLimit,
3
3
  getRateLimitStatus,
4
4
  rateLimitedFetch
5
- } from "../chunk-2MF53V33.js";
5
+ } from "../chunk-D5MTUWFO.mjs";
6
6
  export {
7
7
  configureRateLimit,
8
8
  getRateLimitStatus,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "shop-client",
3
- "version": "3.9.2",
3
+ "version": "3.11.0",
4
4
  "type": "module",
5
5
  "main": "./dist/index.mjs",
6
6
  "module": "./dist/index.mjs",
@@ -1,8 +0,0 @@
1
- import {
2
- createCollectionOperations
3
- } from "./chunk-MOBWPEY4.js";
4
- import "./chunk-2MF53V33.js";
5
- import "./chunk-CN7L3BHG.js";
6
- export {
7
- createCollectionOperations
8
- };
package/dist/products.js DELETED
@@ -1,8 +0,0 @@
1
- import {
2
- createProductOperations
3
- } from "./chunk-CXUCPK6X.js";
4
- import "./chunk-2MF53V33.js";
5
- import "./chunk-CN7L3BHG.js";
6
- export {
7
- createProductOperations
8
- };
package/dist/store.js DELETED
@@ -1,9 +0,0 @@
1
- import {
2
- createStoreOperations
3
- } from "./chunk-DJQEZNHG.js";
4
- import "./chunk-2MF53V33.js";
5
- import "./chunk-QUDGES3A.js";
6
- import "./chunk-CN7L3BHG.js";
7
- export {
8
- createStoreOperations
9
- };
File without changes
File without changes