shop-client 3.8.2 → 3.9.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/LICENSE +1 -1
- package/README.md +158 -1
- package/dist/ai/enrich.d.ts +93 -0
- package/dist/ai/enrich.js +25 -0
- package/dist/checkout.js +5 -114
- package/dist/{chunk-2KBOKOAD.mjs → chunk-2MF53V33.js} +32 -13
- package/dist/{chunk-BWKBRM2Z.mjs → chunk-CN7L3BHG.js} +12 -1
- package/dist/chunk-CXUCPK6X.js +460 -0
- package/dist/{chunk-QCTICSBE.mjs → chunk-MOBWPEY4.js} +29 -7
- package/dist/chunk-ROH545KI.js +274 -0
- package/dist/{chunk-QL5OUZGP.mjs → chunk-RR6YTQWP.js} +0 -1
- package/dist/{chunk-O4BPIIQ6.mjs → chunk-V52MFQZE.js} +11 -281
- package/dist/{chunk-WTK5HUFI.mjs → chunk-VPPCOJC3.js} +13 -435
- package/dist/collections.d.ts +2 -1
- package/dist/collections.js +7 -539
- package/dist/index.d.ts +28 -87
- package/dist/index.js +109 -2597
- package/dist/products.d.ts +2 -1
- package/dist/products.js +7 -1205
- package/dist/store.d.ts +53 -1
- package/dist/store.js +8 -697
- package/dist/{store-CJVUz2Yb.d.ts → types-luPg5O08.d.ts} +1 -208
- package/dist/utils/detect-country.d.ts +32 -0
- package/dist/utils/detect-country.js +6 -0
- package/dist/utils/func.d.ts +61 -0
- package/dist/utils/func.js +24 -0
- package/dist/utils/rate-limit.d.ts +5 -0
- package/dist/utils/rate-limit.js +7 -200
- package/package.json +21 -10
- package/dist/checkout.d.mts +0 -31
- package/dist/checkout.js.map +0 -1
- package/dist/checkout.mjs +0 -7
- package/dist/checkout.mjs.map +0 -1
- package/dist/chunk-2KBOKOAD.mjs.map +0 -1
- package/dist/chunk-BWKBRM2Z.mjs.map +0 -1
- package/dist/chunk-O4BPIIQ6.mjs.map +0 -1
- package/dist/chunk-QCTICSBE.mjs.map +0 -1
- package/dist/chunk-QL5OUZGP.mjs.map +0 -1
- package/dist/chunk-WTK5HUFI.mjs.map +0 -1
- package/dist/collections.d.mts +0 -64
- package/dist/collections.js.map +0 -1
- package/dist/collections.mjs +0 -9
- package/dist/collections.mjs.map +0 -1
- package/dist/index.d.mts +0 -233
- package/dist/index.js.map +0 -1
- package/dist/index.mjs +0 -702
- package/dist/index.mjs.map +0 -1
- package/dist/products.d.mts +0 -63
- package/dist/products.js.map +0 -1
- package/dist/products.mjs +0 -9
- package/dist/products.mjs.map +0 -1
- package/dist/store-CJVUz2Yb.d.mts +0 -608
- package/dist/store.d.mts +0 -1
- package/dist/store.js.map +0 -1
- package/dist/store.mjs +0 -9
- package/dist/store.mjs.map +0 -1
- package/dist/utils/rate-limit.d.mts +0 -25
- package/dist/utils/rate-limit.js.map +0 -1
- package/dist/utils/rate-limit.mjs +0 -11
- package/dist/utils/rate-limit.mjs.map +0 -1
|
@@ -0,0 +1,274 @@
|
|
|
1
|
+
// src/utils/detect-country.ts
|
|
2
|
+
var COUNTRY_CODES = {
|
|
3
|
+
"+1": "US",
|
|
4
|
+
// United States (primary) / Canada also uses +1
|
|
5
|
+
"+44": "GB",
|
|
6
|
+
// United Kingdom
|
|
7
|
+
"+61": "AU",
|
|
8
|
+
// Australia
|
|
9
|
+
"+65": "SG",
|
|
10
|
+
// Singapore
|
|
11
|
+
"+91": "IN",
|
|
12
|
+
// India
|
|
13
|
+
"+81": "JP",
|
|
14
|
+
// Japan
|
|
15
|
+
"+49": "DE",
|
|
16
|
+
// Germany
|
|
17
|
+
"+33": "FR",
|
|
18
|
+
// France
|
|
19
|
+
"+971": "AE",
|
|
20
|
+
// United Arab Emirates
|
|
21
|
+
"+39": "IT",
|
|
22
|
+
// Italy
|
|
23
|
+
"+34": "ES",
|
|
24
|
+
// Spain
|
|
25
|
+
"+82": "KR",
|
|
26
|
+
// South Korea
|
|
27
|
+
"+55": "BR",
|
|
28
|
+
// Brazil
|
|
29
|
+
"+62": "ID",
|
|
30
|
+
// Indonesia
|
|
31
|
+
"+92": "PK",
|
|
32
|
+
// Pakistan
|
|
33
|
+
"+7": "RU"
|
|
34
|
+
// Russia
|
|
35
|
+
};
|
|
36
|
+
var CURRENCY_SYMBOLS = {
|
|
37
|
+
Rs: "IN",
|
|
38
|
+
// India
|
|
39
|
+
"\u20B9": "IN",
|
|
40
|
+
// India
|
|
41
|
+
$: "US",
|
|
42
|
+
// United States (primary, though many countries use $)
|
|
43
|
+
CA$: "CA",
|
|
44
|
+
// Canada
|
|
45
|
+
A$: "AU",
|
|
46
|
+
// Australia
|
|
47
|
+
"\xA3": "GB",
|
|
48
|
+
// United Kingdom
|
|
49
|
+
"\u20AC": "EU",
|
|
50
|
+
// European Union (not a country code, but commonly used)
|
|
51
|
+
AED: "AE",
|
|
52
|
+
// United Arab Emirates
|
|
53
|
+
"\u20A9": "KR",
|
|
54
|
+
// South Korea
|
|
55
|
+
"\xA5": "JP"
|
|
56
|
+
// Japan (primary, though China also uses ¥)
|
|
57
|
+
};
|
|
58
|
+
var CURRENCY_SYMBOL_TO_CODE = {
|
|
59
|
+
Rs: "INR",
|
|
60
|
+
"\u20B9": "INR",
|
|
61
|
+
$: "USD",
|
|
62
|
+
CA$: "CAD",
|
|
63
|
+
A$: "AUD",
|
|
64
|
+
"\xA3": "GBP",
|
|
65
|
+
"\u20AC": "EUR",
|
|
66
|
+
AED: "AED",
|
|
67
|
+
"\u20A9": "KRW",
|
|
68
|
+
"\xA5": "JPY"
|
|
69
|
+
};
|
|
70
|
+
var CURRENCY_CODE_TO_COUNTRY = {
|
|
71
|
+
INR: "IN",
|
|
72
|
+
USD: "US",
|
|
73
|
+
CAD: "CA",
|
|
74
|
+
AUD: "AU",
|
|
75
|
+
GBP: "GB",
|
|
76
|
+
EUR: "EU",
|
|
77
|
+
AED: "AE",
|
|
78
|
+
KRW: "KR",
|
|
79
|
+
JPY: "JP"
|
|
80
|
+
};
|
|
81
|
+
function scoreCountry(countryScores, country, weight, reason) {
|
|
82
|
+
if (!country) return;
|
|
83
|
+
if (!countryScores[country])
|
|
84
|
+
countryScores[country] = { score: 0, reasons: [] };
|
|
85
|
+
countryScores[country].score += weight;
|
|
86
|
+
countryScores[country].reasons.push(reason);
|
|
87
|
+
}
|
|
88
|
+
async function detectShopCountry(html) {
|
|
89
|
+
var _a, _b;
|
|
90
|
+
const countryScores = {};
|
|
91
|
+
let detectedCurrencyCode;
|
|
92
|
+
const shopifyFeaturesMatch = html.match(
|
|
93
|
+
/<script[^>]+id=["']shopify-features["'][^>]*>([\s\S]*?)<\/script>/
|
|
94
|
+
);
|
|
95
|
+
if (shopifyFeaturesMatch) {
|
|
96
|
+
try {
|
|
97
|
+
const json = shopifyFeaturesMatch[1];
|
|
98
|
+
if (!json) {
|
|
99
|
+
} else {
|
|
100
|
+
const data = JSON.parse(json);
|
|
101
|
+
if (data.country)
|
|
102
|
+
scoreCountry(
|
|
103
|
+
countryScores,
|
|
104
|
+
data.country,
|
|
105
|
+
1,
|
|
106
|
+
"shopify-features.country"
|
|
107
|
+
);
|
|
108
|
+
if ((_a = data.locale) == null ? void 0 : _a.includes("-")) {
|
|
109
|
+
const [, localeCountry] = data.locale.split("-");
|
|
110
|
+
if (localeCountry) {
|
|
111
|
+
scoreCountry(
|
|
112
|
+
countryScores,
|
|
113
|
+
localeCountry.toUpperCase(),
|
|
114
|
+
0.7,
|
|
115
|
+
"shopify-features.locale"
|
|
116
|
+
);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
if (data.moneyFormat) {
|
|
120
|
+
for (const symbol in CURRENCY_SYMBOLS) {
|
|
121
|
+
if (data.moneyFormat.includes(symbol)) {
|
|
122
|
+
const iso = CURRENCY_SYMBOLS[symbol];
|
|
123
|
+
if (typeof iso === "string") {
|
|
124
|
+
scoreCountry(countryScores, iso, 0.6, "moneyFormat symbol");
|
|
125
|
+
}
|
|
126
|
+
const code = CURRENCY_SYMBOL_TO_CODE[symbol];
|
|
127
|
+
if (!detectedCurrencyCode && typeof code === "string") {
|
|
128
|
+
detectedCurrencyCode = code;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
} catch (_error) {
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
const currencyJsonMatch = html.match(/Shopify\.currency\s*=\s*(\{[^}]*\})/);
|
|
138
|
+
if (currencyJsonMatch) {
|
|
139
|
+
try {
|
|
140
|
+
const raw = currencyJsonMatch[1];
|
|
141
|
+
const obj = JSON.parse(raw || "{}");
|
|
142
|
+
const activeCode = typeof (obj == null ? void 0 : obj.active) === "string" ? obj.active.toUpperCase() : void 0;
|
|
143
|
+
const iso = activeCode ? CURRENCY_CODE_TO_COUNTRY[activeCode] : void 0;
|
|
144
|
+
if (activeCode) {
|
|
145
|
+
detectedCurrencyCode = activeCode;
|
|
146
|
+
}
|
|
147
|
+
if (typeof iso === "string") {
|
|
148
|
+
scoreCountry(countryScores, iso, 0.8, "Shopify.currency.active");
|
|
149
|
+
}
|
|
150
|
+
} catch (_error) {
|
|
151
|
+
}
|
|
152
|
+
} else {
|
|
153
|
+
const currencyActiveAssignMatch = html.match(
|
|
154
|
+
/Shopify\.currency\.active\s*=\s*['"]([A-Za-z]{3})['"]/i
|
|
155
|
+
);
|
|
156
|
+
if (currencyActiveAssignMatch) {
|
|
157
|
+
const captured = currencyActiveAssignMatch[1];
|
|
158
|
+
const code = typeof captured === "string" ? captured.toUpperCase() : void 0;
|
|
159
|
+
const iso = code ? CURRENCY_CODE_TO_COUNTRY[code] : void 0;
|
|
160
|
+
if (code) {
|
|
161
|
+
detectedCurrencyCode = code;
|
|
162
|
+
}
|
|
163
|
+
if (typeof iso === "string") {
|
|
164
|
+
scoreCountry(countryScores, iso, 0.8, "Shopify.currency.active");
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
const shopifyCountryMatch = html.match(
|
|
169
|
+
/Shopify\.country\s*=\s*['"]([A-Za-z]{2})['"]/i
|
|
170
|
+
);
|
|
171
|
+
if (shopifyCountryMatch) {
|
|
172
|
+
const captured = shopifyCountryMatch[1];
|
|
173
|
+
const iso = typeof captured === "string" ? captured.toUpperCase() : void 0;
|
|
174
|
+
if (typeof iso === "string") {
|
|
175
|
+
scoreCountry(countryScores, iso, 1, "Shopify.country");
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
const phones = html.match(/\+\d{1,3}[\s\-()0-9]{5,}/g);
|
|
179
|
+
if (phones) {
|
|
180
|
+
for (const phone of phones) {
|
|
181
|
+
const prefix = (_b = phone.match(/^\+\d{1,3}/)) == null ? void 0 : _b[0];
|
|
182
|
+
if (prefix && COUNTRY_CODES[prefix])
|
|
183
|
+
scoreCountry(
|
|
184
|
+
countryScores,
|
|
185
|
+
COUNTRY_CODES[prefix],
|
|
186
|
+
0.8,
|
|
187
|
+
`phone prefix ${prefix}`
|
|
188
|
+
);
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
const jsonLdRegex = /<script[^>]+application\/ld\+json[^>]*>(.*?)<\/script>/g;
|
|
192
|
+
let jsonLdMatch = jsonLdRegex.exec(html);
|
|
193
|
+
while (jsonLdMatch !== null) {
|
|
194
|
+
try {
|
|
195
|
+
const json = jsonLdMatch[1];
|
|
196
|
+
if (!json) {
|
|
197
|
+
} else {
|
|
198
|
+
const raw = JSON.parse(json);
|
|
199
|
+
const collectAddressCountries = (node, results = []) => {
|
|
200
|
+
if (Array.isArray(node)) {
|
|
201
|
+
for (const item of node) collectAddressCountries(item, results);
|
|
202
|
+
return results;
|
|
203
|
+
}
|
|
204
|
+
if (node && typeof node === "object") {
|
|
205
|
+
const obj = node;
|
|
206
|
+
const address = obj.address;
|
|
207
|
+
if (address && typeof address === "object") {
|
|
208
|
+
const country = address.addressCountry;
|
|
209
|
+
if (typeof country === "string") results.push(country);
|
|
210
|
+
}
|
|
211
|
+
const graph = obj["@graph"];
|
|
212
|
+
if (graph) collectAddressCountries(graph, results);
|
|
213
|
+
}
|
|
214
|
+
return results;
|
|
215
|
+
};
|
|
216
|
+
const countries = collectAddressCountries(raw);
|
|
217
|
+
for (const country of countries) {
|
|
218
|
+
scoreCountry(countryScores, country, 1, "JSON-LD addressCountry");
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
} catch (_error) {
|
|
222
|
+
}
|
|
223
|
+
jsonLdMatch = jsonLdRegex.exec(html);
|
|
224
|
+
}
|
|
225
|
+
const footerMatch = html.match(/<footer[^>]*>(.*?)<\/footer>/i);
|
|
226
|
+
if (footerMatch) {
|
|
227
|
+
const footerTextGroup = footerMatch[1];
|
|
228
|
+
const footerText = footerTextGroup ? footerTextGroup.toLowerCase() : "";
|
|
229
|
+
const countryNameToISO = {
|
|
230
|
+
india: "IN",
|
|
231
|
+
"united states": "US",
|
|
232
|
+
canada: "CA",
|
|
233
|
+
australia: "AU",
|
|
234
|
+
"united kingdom": "GB",
|
|
235
|
+
britain: "GB",
|
|
236
|
+
uk: "GB",
|
|
237
|
+
japan: "JP",
|
|
238
|
+
"south korea": "KR",
|
|
239
|
+
korea: "KR",
|
|
240
|
+
germany: "DE",
|
|
241
|
+
france: "FR",
|
|
242
|
+
italy: "IT",
|
|
243
|
+
spain: "ES",
|
|
244
|
+
brazil: "BR",
|
|
245
|
+
russia: "RU",
|
|
246
|
+
singapore: "SG",
|
|
247
|
+
indonesia: "ID",
|
|
248
|
+
pakistan: "PK"
|
|
249
|
+
};
|
|
250
|
+
for (const [countryName, isoCode] of Object.entries(countryNameToISO)) {
|
|
251
|
+
if (footerText.includes(countryName))
|
|
252
|
+
scoreCountry(countryScores, isoCode, 0.4, "footer mention");
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
const sorted = Object.entries(countryScores).sort(
|
|
256
|
+
(a, b) => b[1].score - a[1].score
|
|
257
|
+
);
|
|
258
|
+
const best = sorted[0];
|
|
259
|
+
return best ? {
|
|
260
|
+
country: best[0],
|
|
261
|
+
confidence: Math.min(1, best[1].score / 2),
|
|
262
|
+
signals: best[1].reasons,
|
|
263
|
+
currencyCode: detectedCurrencyCode
|
|
264
|
+
} : {
|
|
265
|
+
country: "Unknown",
|
|
266
|
+
confidence: 0,
|
|
267
|
+
signals: [],
|
|
268
|
+
currencyCode: detectedCurrencyCode
|
|
269
|
+
};
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
export {
|
|
273
|
+
detectShopCountry
|
|
274
|
+
};
|
|
@@ -1,287 +1,17 @@
|
|
|
1
|
+
import {
|
|
2
|
+
rateLimitedFetch
|
|
3
|
+
} from "./chunk-2MF53V33.js";
|
|
4
|
+
import {
|
|
5
|
+
detectShopCountry
|
|
6
|
+
} from "./chunk-ROH545KI.js";
|
|
1
7
|
import {
|
|
2
8
|
extractDomainWithoutSuffix,
|
|
3
9
|
generateStoreSlug,
|
|
4
10
|
sanitizeDomain
|
|
5
|
-
} from "./chunk-
|
|
6
|
-
import {
|
|
7
|
-
rateLimitedFetch
|
|
8
|
-
} from "./chunk-2KBOKOAD.mjs";
|
|
11
|
+
} from "./chunk-CN7L3BHG.js";
|
|
9
12
|
|
|
10
13
|
// src/client/get-info.ts
|
|
11
14
|
import { unique } from "remeda";
|
|
12
|
-
|
|
13
|
-
// src/utils/detect-country.ts
|
|
14
|
-
var COUNTRY_CODES = {
|
|
15
|
-
"+1": "US",
|
|
16
|
-
// United States (primary) / Canada also uses +1
|
|
17
|
-
"+44": "GB",
|
|
18
|
-
// United Kingdom
|
|
19
|
-
"+61": "AU",
|
|
20
|
-
// Australia
|
|
21
|
-
"+65": "SG",
|
|
22
|
-
// Singapore
|
|
23
|
-
"+91": "IN",
|
|
24
|
-
// India
|
|
25
|
-
"+81": "JP",
|
|
26
|
-
// Japan
|
|
27
|
-
"+49": "DE",
|
|
28
|
-
// Germany
|
|
29
|
-
"+33": "FR",
|
|
30
|
-
// France
|
|
31
|
-
"+971": "AE",
|
|
32
|
-
// United Arab Emirates
|
|
33
|
-
"+39": "IT",
|
|
34
|
-
// Italy
|
|
35
|
-
"+34": "ES",
|
|
36
|
-
// Spain
|
|
37
|
-
"+82": "KR",
|
|
38
|
-
// South Korea
|
|
39
|
-
"+55": "BR",
|
|
40
|
-
// Brazil
|
|
41
|
-
"+62": "ID",
|
|
42
|
-
// Indonesia
|
|
43
|
-
"+92": "PK",
|
|
44
|
-
// Pakistan
|
|
45
|
-
"+7": "RU"
|
|
46
|
-
// Russia
|
|
47
|
-
};
|
|
48
|
-
var CURRENCY_SYMBOLS = {
|
|
49
|
-
Rs: "IN",
|
|
50
|
-
// India
|
|
51
|
-
"\u20B9": "IN",
|
|
52
|
-
// India
|
|
53
|
-
$: "US",
|
|
54
|
-
// United States (primary, though many countries use $)
|
|
55
|
-
CA$: "CA",
|
|
56
|
-
// Canada
|
|
57
|
-
A$: "AU",
|
|
58
|
-
// Australia
|
|
59
|
-
"\xA3": "GB",
|
|
60
|
-
// United Kingdom
|
|
61
|
-
"\u20AC": "EU",
|
|
62
|
-
// European Union (not a country code, but commonly used)
|
|
63
|
-
AED: "AE",
|
|
64
|
-
// United Arab Emirates
|
|
65
|
-
"\u20A9": "KR",
|
|
66
|
-
// South Korea
|
|
67
|
-
"\xA5": "JP"
|
|
68
|
-
// Japan (primary, though China also uses ¥)
|
|
69
|
-
};
|
|
70
|
-
var CURRENCY_SYMBOL_TO_CODE = {
|
|
71
|
-
Rs: "INR",
|
|
72
|
-
"\u20B9": "INR",
|
|
73
|
-
$: "USD",
|
|
74
|
-
CA$: "CAD",
|
|
75
|
-
A$: "AUD",
|
|
76
|
-
"\xA3": "GBP",
|
|
77
|
-
"\u20AC": "EUR",
|
|
78
|
-
AED: "AED",
|
|
79
|
-
"\u20A9": "KRW",
|
|
80
|
-
"\xA5": "JPY"
|
|
81
|
-
};
|
|
82
|
-
var CURRENCY_CODE_TO_COUNTRY = {
|
|
83
|
-
INR: "IN",
|
|
84
|
-
USD: "US",
|
|
85
|
-
CAD: "CA",
|
|
86
|
-
AUD: "AU",
|
|
87
|
-
GBP: "GB",
|
|
88
|
-
EUR: "EU",
|
|
89
|
-
AED: "AE",
|
|
90
|
-
KRW: "KR",
|
|
91
|
-
JPY: "JP"
|
|
92
|
-
};
|
|
93
|
-
function scoreCountry(countryScores, country, weight, reason) {
|
|
94
|
-
if (!country) return;
|
|
95
|
-
if (!countryScores[country])
|
|
96
|
-
countryScores[country] = { score: 0, reasons: [] };
|
|
97
|
-
countryScores[country].score += weight;
|
|
98
|
-
countryScores[country].reasons.push(reason);
|
|
99
|
-
}
|
|
100
|
-
async function detectShopifyCountry(html) {
|
|
101
|
-
var _a, _b;
|
|
102
|
-
const countryScores = {};
|
|
103
|
-
let detectedCurrencyCode;
|
|
104
|
-
const shopifyFeaturesMatch = html.match(
|
|
105
|
-
/<script[^>]+id=["']shopify-features["'][^>]*>([\s\S]*?)<\/script>/
|
|
106
|
-
);
|
|
107
|
-
if (shopifyFeaturesMatch) {
|
|
108
|
-
try {
|
|
109
|
-
const json = shopifyFeaturesMatch[1];
|
|
110
|
-
if (!json) {
|
|
111
|
-
} else {
|
|
112
|
-
const data = JSON.parse(json);
|
|
113
|
-
if (data.country)
|
|
114
|
-
scoreCountry(
|
|
115
|
-
countryScores,
|
|
116
|
-
data.country,
|
|
117
|
-
1,
|
|
118
|
-
"shopify-features.country"
|
|
119
|
-
);
|
|
120
|
-
if ((_a = data.locale) == null ? void 0 : _a.includes("-")) {
|
|
121
|
-
const [, localeCountry] = data.locale.split("-");
|
|
122
|
-
if (localeCountry) {
|
|
123
|
-
scoreCountry(
|
|
124
|
-
countryScores,
|
|
125
|
-
localeCountry.toUpperCase(),
|
|
126
|
-
0.7,
|
|
127
|
-
"shopify-features.locale"
|
|
128
|
-
);
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
if (data.moneyFormat) {
|
|
132
|
-
for (const symbol in CURRENCY_SYMBOLS) {
|
|
133
|
-
if (data.moneyFormat.includes(symbol)) {
|
|
134
|
-
const iso = CURRENCY_SYMBOLS[symbol];
|
|
135
|
-
if (typeof iso === "string") {
|
|
136
|
-
scoreCountry(countryScores, iso, 0.6, "moneyFormat symbol");
|
|
137
|
-
}
|
|
138
|
-
const code = CURRENCY_SYMBOL_TO_CODE[symbol];
|
|
139
|
-
if (!detectedCurrencyCode && typeof code === "string") {
|
|
140
|
-
detectedCurrencyCode = code;
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
}
|
|
145
|
-
}
|
|
146
|
-
} catch (_error) {
|
|
147
|
-
}
|
|
148
|
-
}
|
|
149
|
-
const currencyJsonMatch = html.match(/Shopify\.currency\s*=\s*(\{[^}]*\})/);
|
|
150
|
-
if (currencyJsonMatch) {
|
|
151
|
-
try {
|
|
152
|
-
const raw = currencyJsonMatch[1];
|
|
153
|
-
const obj = JSON.parse(raw || "{}");
|
|
154
|
-
const activeCode = typeof (obj == null ? void 0 : obj.active) === "string" ? obj.active.toUpperCase() : void 0;
|
|
155
|
-
const iso = activeCode ? CURRENCY_CODE_TO_COUNTRY[activeCode] : void 0;
|
|
156
|
-
if (activeCode) {
|
|
157
|
-
detectedCurrencyCode = activeCode;
|
|
158
|
-
}
|
|
159
|
-
if (typeof iso === "string") {
|
|
160
|
-
scoreCountry(countryScores, iso, 0.8, "Shopify.currency.active");
|
|
161
|
-
}
|
|
162
|
-
} catch (_error) {
|
|
163
|
-
}
|
|
164
|
-
} else {
|
|
165
|
-
const currencyActiveAssignMatch = html.match(
|
|
166
|
-
/Shopify\.currency\.active\s*=\s*['"]([A-Za-z]{3})['"]/i
|
|
167
|
-
);
|
|
168
|
-
if (currencyActiveAssignMatch) {
|
|
169
|
-
const captured = currencyActiveAssignMatch[1];
|
|
170
|
-
const code = typeof captured === "string" ? captured.toUpperCase() : void 0;
|
|
171
|
-
const iso = code ? CURRENCY_CODE_TO_COUNTRY[code] : void 0;
|
|
172
|
-
if (code) {
|
|
173
|
-
detectedCurrencyCode = code;
|
|
174
|
-
}
|
|
175
|
-
if (typeof iso === "string") {
|
|
176
|
-
scoreCountry(countryScores, iso, 0.8, "Shopify.currency.active");
|
|
177
|
-
}
|
|
178
|
-
}
|
|
179
|
-
}
|
|
180
|
-
const shopifyCountryMatch = html.match(
|
|
181
|
-
/Shopify\.country\s*=\s*['"]([A-Za-z]{2})['"]/i
|
|
182
|
-
);
|
|
183
|
-
if (shopifyCountryMatch) {
|
|
184
|
-
const captured = shopifyCountryMatch[1];
|
|
185
|
-
const iso = typeof captured === "string" ? captured.toUpperCase() : void 0;
|
|
186
|
-
if (typeof iso === "string") {
|
|
187
|
-
scoreCountry(countryScores, iso, 1, "Shopify.country");
|
|
188
|
-
}
|
|
189
|
-
}
|
|
190
|
-
const phones = html.match(/\+\d{1,3}[\s\-()0-9]{5,}/g);
|
|
191
|
-
if (phones) {
|
|
192
|
-
for (const phone of phones) {
|
|
193
|
-
const prefix = (_b = phone.match(/^\+\d{1,3}/)) == null ? void 0 : _b[0];
|
|
194
|
-
if (prefix && COUNTRY_CODES[prefix])
|
|
195
|
-
scoreCountry(
|
|
196
|
-
countryScores,
|
|
197
|
-
COUNTRY_CODES[prefix],
|
|
198
|
-
0.8,
|
|
199
|
-
`phone prefix ${prefix}`
|
|
200
|
-
);
|
|
201
|
-
}
|
|
202
|
-
}
|
|
203
|
-
const jsonLdRegex = /<script[^>]+application\/ld\+json[^>]*>(.*?)<\/script>/g;
|
|
204
|
-
let jsonLdMatch = jsonLdRegex.exec(html);
|
|
205
|
-
while (jsonLdMatch !== null) {
|
|
206
|
-
try {
|
|
207
|
-
const json = jsonLdMatch[1];
|
|
208
|
-
if (!json) {
|
|
209
|
-
} else {
|
|
210
|
-
const raw = JSON.parse(json);
|
|
211
|
-
const collectAddressCountries = (node, results = []) => {
|
|
212
|
-
if (Array.isArray(node)) {
|
|
213
|
-
for (const item of node) collectAddressCountries(item, results);
|
|
214
|
-
return results;
|
|
215
|
-
}
|
|
216
|
-
if (node && typeof node === "object") {
|
|
217
|
-
const obj = node;
|
|
218
|
-
const address = obj.address;
|
|
219
|
-
if (address && typeof address === "object") {
|
|
220
|
-
const country = address.addressCountry;
|
|
221
|
-
if (typeof country === "string") results.push(country);
|
|
222
|
-
}
|
|
223
|
-
const graph = obj["@graph"];
|
|
224
|
-
if (graph) collectAddressCountries(graph, results);
|
|
225
|
-
}
|
|
226
|
-
return results;
|
|
227
|
-
};
|
|
228
|
-
const countries = collectAddressCountries(raw);
|
|
229
|
-
for (const country of countries) {
|
|
230
|
-
scoreCountry(countryScores, country, 1, "JSON-LD addressCountry");
|
|
231
|
-
}
|
|
232
|
-
}
|
|
233
|
-
} catch (_error) {
|
|
234
|
-
}
|
|
235
|
-
jsonLdMatch = jsonLdRegex.exec(html);
|
|
236
|
-
}
|
|
237
|
-
const footerMatch = html.match(/<footer[^>]*>(.*?)<\/footer>/i);
|
|
238
|
-
if (footerMatch) {
|
|
239
|
-
const footerTextGroup = footerMatch[1];
|
|
240
|
-
const footerText = footerTextGroup ? footerTextGroup.toLowerCase() : "";
|
|
241
|
-
const countryNameToISO = {
|
|
242
|
-
india: "IN",
|
|
243
|
-
"united states": "US",
|
|
244
|
-
canada: "CA",
|
|
245
|
-
australia: "AU",
|
|
246
|
-
"united kingdom": "GB",
|
|
247
|
-
britain: "GB",
|
|
248
|
-
uk: "GB",
|
|
249
|
-
japan: "JP",
|
|
250
|
-
"south korea": "KR",
|
|
251
|
-
korea: "KR",
|
|
252
|
-
germany: "DE",
|
|
253
|
-
france: "FR",
|
|
254
|
-
italy: "IT",
|
|
255
|
-
spain: "ES",
|
|
256
|
-
brazil: "BR",
|
|
257
|
-
russia: "RU",
|
|
258
|
-
singapore: "SG",
|
|
259
|
-
indonesia: "ID",
|
|
260
|
-
pakistan: "PK"
|
|
261
|
-
};
|
|
262
|
-
for (const [countryName, isoCode] of Object.entries(countryNameToISO)) {
|
|
263
|
-
if (footerText.includes(countryName))
|
|
264
|
-
scoreCountry(countryScores, isoCode, 0.4, "footer mention");
|
|
265
|
-
}
|
|
266
|
-
}
|
|
267
|
-
const sorted = Object.entries(countryScores).sort(
|
|
268
|
-
(a, b) => b[1].score - a[1].score
|
|
269
|
-
);
|
|
270
|
-
const best = sorted[0];
|
|
271
|
-
return best ? {
|
|
272
|
-
country: best[0],
|
|
273
|
-
confidence: Math.min(1, best[1].score / 2),
|
|
274
|
-
signals: best[1].reasons,
|
|
275
|
-
currencyCode: detectedCurrencyCode
|
|
276
|
-
} : {
|
|
277
|
-
country: "Unknown",
|
|
278
|
-
confidence: 0,
|
|
279
|
-
signals: [],
|
|
280
|
-
currencyCode: detectedCurrencyCode
|
|
281
|
-
};
|
|
282
|
-
}
|
|
283
|
-
|
|
284
|
-
// src/client/get-info.ts
|
|
285
15
|
async function getInfoForStore(args) {
|
|
286
16
|
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m;
|
|
287
17
|
const {
|
|
@@ -291,7 +21,9 @@ async function getInfoForStore(args) {
|
|
|
291
21
|
validateCollectionExists,
|
|
292
22
|
validateLinksInBatches
|
|
293
23
|
} = args;
|
|
294
|
-
const response = await rateLimitedFetch(baseUrl
|
|
24
|
+
const response = await rateLimitedFetch(baseUrl, {
|
|
25
|
+
rateLimitClass: "store:info"
|
|
26
|
+
});
|
|
295
27
|
if (!response.ok) {
|
|
296
28
|
throw new Error(`HTTP error! status: ${response.status}`);
|
|
297
29
|
}
|
|
@@ -396,7 +128,7 @@ async function getInfoForStore(args) {
|
|
|
396
128
|
}).filter((item) => Boolean(item))) != null ? _b2 : [];
|
|
397
129
|
})) != null ? _k : [];
|
|
398
130
|
const slug = generateStoreSlug(baseUrl);
|
|
399
|
-
const countryDetection = await
|
|
131
|
+
const countryDetection = await detectShopCountry(html);
|
|
400
132
|
const [homePageProductLinks, homePageCollectionLinks] = await Promise.all([
|
|
401
133
|
validateLinksInBatches(
|
|
402
134
|
extractedProductLinks.filter(
|
|
@@ -496,8 +228,6 @@ function createStoreOperations(context) {
|
|
|
496
228
|
}
|
|
497
229
|
|
|
498
230
|
export {
|
|
499
|
-
detectShopifyCountry,
|
|
500
231
|
getInfoForStore,
|
|
501
232
|
createStoreOperations
|
|
502
233
|
};
|
|
503
|
-
//# sourceMappingURL=chunk-O4BPIIQ6.mjs.map
|