{"version":3,"sources":["../src/client/get-info.ts","../src/utils/detect-country.ts","../src/store.ts"],"sourcesContent":["import { unique } from \"remeda\";\nimport type { StoreInfo } from \"../store\";\nimport { detectShopifyCountry } from \"../utils/detect-country\";\nimport {\n  extractDomainWithoutSuffix,\n  generateStoreSlug,\n  sanitizeDomain,\n} from \"../utils/func\";\nimport { rateLimitedFetch } from \"../utils/rate-limit\";\n\ntype Args = {\n  baseUrl: string;\n  storeDomain: string;\n  validateProductExists: (handle: string) => Promise<boolean>;\n  validateCollectionExists: (handle: string) => Promise<boolean>;\n  validateLinksInBatches: <T>(\n    items: T[],\n    validator: (item: T) => Promise<boolean>,\n    batchSize?: number\n  ) => Promise<T[]>;\n};\n\n/**\n * Fetches comprehensive store information including metadata, social links, and showcase content.\n * Returns the structured StoreInfo and detected currency code (if available).\n */\nexport async function getInfoForStore(\n  args: Args\n): Promise<{ info: StoreInfo; currencyCode?: string }> {\n  const {\n    baseUrl,\n    storeDomain,\n    validateProductExists,\n    validateCollectionExists,\n    validateLinksInBatches,\n  } = args;\n\n  const response = await rateLimitedFetch(baseUrl);\n  if (!response.ok) {\n    throw new Error(`HTTP error! status: ${response.status}`);\n  }\n  const html = await response.text();\n\n  const getMetaTag = (name: string) => {\n    const regex = new RegExp(\n      `<meta[^>]*name=[\"']${name}[\"'][^>]*content=[\"'](.*?)[\"']`\n    );\n    const match = html.match(regex);\n    return match ? match[1] : null;\n  };\n\n  const getPropertyMetaTag = (property: string) => {\n    const regex = new RegExp(\n      `<meta[^>]*property=[\"']${property}[\"'][^>]*content=[\"'](.*?)[\"']`\n    );\n    const match = html.match(regex);\n    return match ? match[1] : null;\n  };\n\n  const name =\n    getMetaTag(\"og:site_name\") ?? extractDomainWithoutSuffix(baseUrl);\n  const title = getMetaTag(\"og:title\") ?? getMetaTag(\"twitter:title\");\n  const description =\n    getMetaTag(\"description\") || getPropertyMetaTag(\"og:description\");\n\n  const shopifyWalletId = getMetaTag(\"shopify-digital-wallet\")?.split(\"/\")[1];\n\n  const myShopifySubdomainMatch = html.match(/['\"](.*?\\.myshopify\\.com)['\"]/);\n  const myShopifySubdomain = myShopifySubdomainMatch\n    ? myShopifySubdomainMatch[1]\n    : null;\n\n  let logoUrl =\n    getPropertyMetaTag(\"og:image\") || getPropertyMetaTag(\"og:image:secure_url\");\n  if (!logoUrl) {\n    const logoMatch = html.match(\n      /<img[^>]+src=[\"']([^\"']+\\/cdn\\/shop\\/[^\"']+)[\"']/\n    );\n    const matchedUrl = logoMatch?.[1];\n    logoUrl = matchedUrl ? matchedUrl.replace(\"http://\", \"https://\") : null;\n  } else {\n    logoUrl = logoUrl.replace(\"http://\", \"https://\");\n  }\n\n  const socialLinks: Record<string, string> = {};\n  const socialRegex =\n    /<a[^>]+href=[\"']([^\"']*(?:facebook|twitter|instagram|pinterest|youtube|linkedin|tiktok|vimeo)\\.com[^\"']*)[\"']/g;\n  for (const match of html.matchAll(socialRegex)) {\n    const str = match[1];\n    if (!str) continue;\n    let href: string = str;\n    try {\n      if (href.startsWith(\"//\")) {\n        href = `https:${href}`;\n      } else if (href.startsWith(\"/\")) {\n        href = new URL(href, baseUrl).toString();\n      }\n      const parsed = new URL(href);\n      const domain = parsed.hostname.replace(\"www.\", \"\").split(\".\")[0];\n      if (domain) {\n        socialLinks[domain] = parsed.toString();\n      }\n    } catch {\n      // Skip invalid URLs without failing\n    }\n  }\n\n  const contactLinks = {\n    tel: null as string | null,\n    email: null as string | null,\n    contactPage: null as string | null,\n  };\n\n  for (const match of html.matchAll(/href=[\"']tel:([^\"']+)[\"']/g)) {\n    contactLinks.tel = match?.[1]?.trim() || null;\n  }\n  for (const match of html.matchAll(/href=[\"']mailto:([^\"']+)[\"']/g)) {\n    contactLinks.email = match?.[1]?.trim() || null;\n  }\n  for (const match of html.matchAll(\n    /href=[\"']([^\"']*(?:\\/contact|\\/pages\\/contact)[^\"']*)[\"']/g\n  )) {\n    contactLinks.contactPage = match?.[1] || null;\n  }\n\n  const extractedProductLinks =\n    html\n      .match(/href=[\"']([^\"']*\\/products\\/[^\"']+)[\"']/g)\n      ?.map((match) =>\n        match?.split(\"href=\")[1]?.replace(/[\"']/g, \"\")?.split(\"/\").at(-1)\n      )\n      ?.filter(Boolean) || [];\n\n  const extractedCollectionLinks =\n    html\n      .match(/href=[\"']([^\"']*\\/collections\\/[^\"']+)[\"']/g)\n      ?.map((match) =>\n        match?.split(\"href=\")[1]?.replace(/[\"']/g, \"\")?.split(\"/\").at(-1)\n      )\n      ?.filter(Boolean) || [];\n\n  const headerLinks =\n    html\n      .match(\n        /<(header|nav|div|section)\\b[^>]*\\b(?:id|class)=[\"'][^\"']*(?=.*shopify-section)(?=.*\\b(header|navigation|nav|menu)\\b)[^\"']*[\"'][^>]*>[\\s\\S]*?<\\/\\1>/gi\n      )\n      ?.flatMap((header) => {\n        const links = header\n          .match(/href=[\"']([^\"']+)[\"']/g)\n          ?.filter(\n            (link) =>\n              link.includes(\"/products/\") ||\n              link.includes(\"/collections/\") ||\n              link.includes(\"/pages/\")\n          );\n        return (\n          links\n            ?.map((link) => {\n              const href = link.match(/href=[\"']([^\"']+)[\"']/)?.[1];\n              if (\n                href &&\n                !href.startsWith(\"#\") &&\n                !href.startsWith(\"javascript:\")\n              ) {\n                try {\n                  const url = new URL(href, storeDomain);\n                  return url.pathname.replace(/^\\/|\\/$/g, \"\");\n                } catch {\n                  return href.replace(/^\\/|\\/$/g, \"\");\n                }\n              }\n              return null;\n            })\n            .filter((item): item is string => Boolean(item)) ?? []\n        );\n      }) ?? [];\n\n  const slug = generateStoreSlug(baseUrl);\n\n  const countryDetection = await detectShopifyCountry(html);\n\n  const [homePageProductLinks, homePageCollectionLinks] = await Promise.all([\n    validateLinksInBatches(\n      extractedProductLinks.filter((handle): handle is string =>\n        Boolean(handle)\n      ),\n      (handle) => validateProductExists(handle)\n    ),\n    validateLinksInBatches(\n      extractedCollectionLinks.filter((handle): handle is string =>\n        Boolean(handle)\n      ),\n      (handle) => validateCollectionExists(handle)\n    ),\n  ]);\n\n  const info: StoreInfo = {\n    name: name || slug,\n    domain: sanitizeDomain(baseUrl),\n    slug,\n    title: title || null,\n    description: description || null,\n    logoUrl: logoUrl,\n    socialLinks,\n    contactLinks,\n    headerLinks,\n    showcase: {\n      products: unique(homePageProductLinks ?? []),\n      collections: unique(homePageCollectionLinks ?? []),\n    },\n    jsonLdData:\n      html\n        .match(\n          /<script[^>]*type=\"application\\/ld\\+json\"[^>]*>([^<]+)<\\/script>/g\n        )\n        ?.map(\n          (match) => match?.split(\">\")[1]?.replace(/<\\/script/g, \"\") || null\n        )\n        ?.map((json) => (json ? JSON.parse(json) : null)) || [],\n    techProvider: {\n      name: \"shopify\",\n      walletId: shopifyWalletId,\n      subDomain: myShopifySubdomain ?? null,\n    },\n    country: countryDetection.country,\n  };\n\n  const currencyCode = (countryDetection as any)?.currencyCode;\n  return { info, currencyCode };\n}\n","import type {\n  CountryDetectionResult,\n  CountryScores,\n  ShopifyFeaturesData,\n} from \"../types\";\n\nconst COUNTRY_CODES: Record<string, string> = {\n  \"+1\": \"US\", // United States (primary) / Canada also uses +1\n  \"+44\": \"GB\", // United Kingdom\n  \"+61\": \"AU\", // Australia\n  \"+65\": \"SG\", // Singapore\n  \"+91\": \"IN\", // India\n  \"+81\": \"JP\", // Japan\n  \"+49\": \"DE\", // Germany\n  \"+33\": \"FR\", // France\n  \"+971\": \"AE\", // United Arab Emirates\n  \"+39\": \"IT\", // Italy\n  \"+34\": \"ES\", // Spain\n  \"+82\": \"KR\", // South Korea\n  \"+55\": \"BR\", // Brazil\n  \"+62\": \"ID\", // Indonesia\n  \"+92\": \"PK\", // Pakistan\n  \"+7\": \"RU\", // Russia\n};\n\nconst CURRENCY_SYMBOLS: Record<string, string> = {\n  Rs: \"IN\", // India\n  \"₹\": \"IN\", // India\n  $: \"US\", // United States (primary, though many countries use $)\n  CA$: \"CA\", // Canada\n  A$: \"AU\", // Australia\n  \"£\": \"GB\", // United Kingdom\n  \"€\": \"EU\", // European Union (not a country code, but commonly used)\n  AED: \"AE\", // United Arab Emirates\n  \"₩\": \"KR\", // South Korea\n  \"¥\": \"JP\", // Japan (primary, though China also uses ¥)\n};\n\n// Map currency symbols commonly found in Shopify money formats to ISO currency codes\nconst CURRENCY_SYMBOL_TO_CODE: Record<string, string> = {\n  Rs: \"INR\",\n  \"₹\": \"INR\",\n  $: \"USD\",\n  CA$: \"CAD\",\n  A$: \"AUD\",\n  \"£\": \"GBP\",\n  \"€\": \"EUR\",\n  AED: \"AED\",\n  \"₩\": \"KRW\",\n  \"¥\": \"JPY\",\n};\n\n// Map Shopify currency codes to likely ISO country codes\n// Note: Some codes (e.g., USD, EUR) are used by multiple countries; we treat them as signals.\nconst CURRENCY_CODE_TO_COUNTRY: Record<string, string> = {\n  INR: \"IN\",\n  USD: \"US\",\n  CAD: \"CA\",\n  AUD: \"AU\",\n  GBP: \"GB\",\n  EUR: \"EU\",\n  AED: \"AE\",\n  KRW: \"KR\",\n  JPY: \"JP\",\n};\n\nfunction scoreCountry(\n  countryScores: CountryScores,\n  country: string,\n  weight: number,\n  reason: string\n): void {\n  if (!country) return;\n  if (!countryScores[country])\n    countryScores[country] = { score: 0, reasons: [] };\n  countryScores[country].score += weight;\n  countryScores[country].reasons.push(reason);\n}\n\n/**\n * Detects the country of a Shopify store by analyzing various signals in the HTML content.\n *\n * This function examines multiple data sources within the HTML to determine the store's country:\n * - Shopify features JSON data (country, locale, money format)\n * - Phone number prefixes in contact information\n * - JSON-LD structured data with address information\n * - Footer mentions of country names\n * - Currency symbols in money formatting\n *\n * @param html - The HTML content of the Shopify store's homepage\n * @returns Promise resolving to country detection results containing:\n * - `country` - The detected country ISO 3166-1 alpha-2 code (e.g., \"US\", \"GB\") or \"Unknown\" if no reliable detection\n * - `confidence` - Confidence score between 0 and 1 (higher = more confident)\n * - `signals` - Array of detection signals that contributed to the result\n *\n * @example\n * ```typescript\n * const response = await fetch('https://exampleshop.com');\n * const html = await response.text();\n * const result = await detectShopifyCountry(html);\n *\n * console.log(result.country); // \"US\" (ISO code for United States)\n * console.log(result.confidence); // 0.85\n * console.log(result.signals); // [\"shopify-features.country\", \"phone prefix +1\"]\n * ```\n */\nexport async function detectShopifyCountry(\n  html: string\n): Promise<CountryDetectionResult> {\n  const countryScores: CountryScores = {};\n  let detectedCurrencyCode: string | undefined;\n\n  // 1️⃣ Extract Shopify features JSON\n  const shopifyFeaturesMatch = html.match(\n    /<script[^>]+id=[\"']shopify-features[\"'][^>]*>([\\s\\S]*?)<\\/script>/\n  );\n  if (shopifyFeaturesMatch) {\n    try {\n      const json = shopifyFeaturesMatch[1];\n      if (!json) {\n        // no content in capture group; skip\n      } else {\n        const data: ShopifyFeaturesData = JSON.parse(json);\n        if (data.country)\n          scoreCountry(\n            countryScores,\n            data.country,\n            1,\n            \"shopify-features.country\"\n          );\n        if (data.locale?.includes(\"-\")) {\n          const [, localeCountry] = data.locale.split(\"-\");\n          if (localeCountry) {\n            scoreCountry(\n              countryScores,\n              localeCountry.toUpperCase(),\n              0.7,\n              \"shopify-features.locale\"\n            );\n          }\n        }\n        if (data.moneyFormat) {\n          for (const symbol in CURRENCY_SYMBOLS) {\n            if (data.moneyFormat.includes(symbol)) {\n              const iso =\n                CURRENCY_SYMBOLS[symbol as keyof typeof CURRENCY_SYMBOLS];\n              if (typeof iso === \"string\") {\n                scoreCountry(countryScores, iso, 0.6, \"moneyFormat symbol\");\n              }\n              // Also capture currency code if symbol is recognized\n              const code =\n                CURRENCY_SYMBOL_TO_CODE[\n                  symbol as keyof typeof CURRENCY_SYMBOL_TO_CODE\n                ];\n              if (!detectedCurrencyCode && typeof code === \"string\") {\n                detectedCurrencyCode = code;\n              }\n            }\n          }\n        }\n      }\n    } catch (_error) {\n      // Silently handle JSON parsing errors\n    }\n  }\n\n  // 1️⃣ b) Detect Shopify.currency active code (common across many Shopify themes)\n  // Example: Shopify.currency = {\"active\":\"INR\",\"rate\":\"1.0\"};\n  // Fallback pattern: Shopify.currency.active = 'INR';\n  const currencyJsonMatch = html.match(/Shopify\\.currency\\s*=\\s*(\\{[^}]*\\})/);\n  if (currencyJsonMatch) {\n    try {\n      const raw = currencyJsonMatch[1];\n      const obj = JSON.parse(raw || \"{}\") as any;\n      const activeCode =\n        typeof obj?.active === \"string\" ? obj.active.toUpperCase() : undefined;\n      const iso = activeCode ? CURRENCY_CODE_TO_COUNTRY[activeCode] : undefined;\n      if (activeCode) {\n        detectedCurrencyCode = activeCode;\n      }\n      if (typeof iso === \"string\") {\n        // Treat as a strong signal\n        scoreCountry(countryScores, iso, 0.8, \"Shopify.currency.active\");\n      }\n    } catch (_error) {\n      // ignore malformed objects\n    }\n  } else {\n    const currencyActiveAssignMatch = html.match(\n      /Shopify\\.currency\\.active\\s*=\\s*['\"]([A-Za-z]{3})['\"]/i\n    );\n    if (currencyActiveAssignMatch) {\n      const captured = currencyActiveAssignMatch[1];\n      const code =\n        typeof captured === \"string\" ? captured.toUpperCase() : undefined;\n      const iso = code ? CURRENCY_CODE_TO_COUNTRY[code] : undefined;\n      if (code) {\n        detectedCurrencyCode = code;\n      }\n      if (typeof iso === \"string\") {\n        scoreCountry(countryScores, iso, 0.8, \"Shopify.currency.active\");\n      }\n    }\n  }\n\n  // 1️⃣ c) Detect explicit Shopify.country assignment\n  // Example: Shopify.country = \"IN\";\n  const shopifyCountryMatch = html.match(\n    /Shopify\\.country\\s*=\\s*['\"]([A-Za-z]{2})['\"]/i\n  );\n  if (shopifyCountryMatch) {\n    const captured = shopifyCountryMatch[1];\n    const iso =\n      typeof captured === \"string\" ? captured.toUpperCase() : undefined;\n    if (typeof iso === \"string\") {\n      // Treat as strongest signal\n      scoreCountry(countryScores, iso, 1, \"Shopify.country\");\n    }\n  }\n\n  // 2️⃣ Extract phone numbers\n  const phones = html.match(/\\+\\d{1,3}[\\s\\-()0-9]{5,}/g);\n  if (phones) {\n    for (const phone of phones) {\n      const prefix = phone.match(/^\\+\\d{1,3}/)?.[0];\n      if (prefix && COUNTRY_CODES[prefix])\n        scoreCountry(\n          countryScores,\n          COUNTRY_CODES[prefix],\n          0.8,\n          `phone prefix ${prefix}`\n        );\n    }\n  }\n\n  // 3️⃣ Extract JSON-LD addressCountry fields\n  const jsonLdRegex = /<script[^>]+application\\/ld\\+json[^>]*>(.*?)<\\/script>/g;\n  let jsonLdMatch: RegExpExecArray | null = jsonLdRegex.exec(html);\n  while (jsonLdMatch !== null) {\n    try {\n      const json = jsonLdMatch[1];\n      if (!json) {\n        // skip empty capture\n      } else {\n        const raw = JSON.parse(json) as unknown;\n\n        const collectAddressCountries = (\n          node: unknown,\n          results: string[] = []\n        ): string[] => {\n          if (Array.isArray(node)) {\n            for (const item of node) collectAddressCountries(item, results);\n            return results;\n          }\n          if (node && typeof node === \"object\") {\n            const obj = node as Record<string, unknown>;\n            const address = obj.address;\n            if (address && typeof address === \"object\") {\n              const country = (address as Record<string, unknown>)\n                .addressCountry;\n              if (typeof country === \"string\") results.push(country);\n            }\n            // Support nested graphs\n            const graph = obj[\"@graph\"];\n            if (graph) collectAddressCountries(graph, results);\n          }\n          return results;\n        };\n\n        const countries = collectAddressCountries(raw);\n        for (const country of countries) {\n          scoreCountry(countryScores, country, 1, \"JSON-LD addressCountry\");\n        }\n      }\n    } catch (_error) {\n      // Silently handle JSON parsing errors\n    }\n    // advance to next match\n    jsonLdMatch = jsonLdRegex.exec(html);\n  }\n\n  // 4️⃣ Footer country mentions - now using ISO codes\n  const footerMatch = html.match(/<footer[^>]*>(.*?)<\\/footer>/i);\n  if (footerMatch) {\n    const footerTextGroup = footerMatch[1];\n    const footerText = footerTextGroup ? footerTextGroup.toLowerCase() : \"\";\n    // Create a mapping of country names to ISO codes for footer detection\n    const countryNameToISO: Record<string, string> = {\n      india: \"IN\",\n      \"united states\": \"US\",\n      canada: \"CA\",\n      australia: \"AU\",\n      \"united kingdom\": \"GB\",\n      britain: \"GB\",\n      uk: \"GB\",\n      japan: \"JP\",\n      \"south korea\": \"KR\",\n      korea: \"KR\",\n      germany: \"DE\",\n      france: \"FR\",\n      italy: \"IT\",\n      spain: \"ES\",\n      brazil: \"BR\",\n      russia: \"RU\",\n      singapore: \"SG\",\n      indonesia: \"ID\",\n      pakistan: \"PK\",\n    };\n\n    for (const [countryName, isoCode] of Object.entries(countryNameToISO)) {\n      if (footerText.includes(countryName))\n        scoreCountry(countryScores, isoCode, 0.4, \"footer mention\");\n    }\n  }\n\n  // Pick best guess\n  const sorted = Object.entries(countryScores).sort(\n    (a, b) => b[1].score - a[1].score\n  );\n  const best = sorted[0];\n\n  return best\n    ? {\n        country: best[0],\n        confidence: Math.min(1, best[1].score / 2),\n        signals: best[1].reasons,\n        currencyCode: detectedCurrencyCode,\n      }\n    : {\n        country: \"Unknown\",\n        confidence: 0,\n        signals: [],\n        currencyCode: detectedCurrencyCode,\n      };\n}\n","import { getInfoForStore } from \"./client/get-info\";\nimport type { CountryDetectionResult, JsonLdEntry } from \"./types\";\n\n/**\n * Store operations interface for managing store-related functionality.\n * Provides methods to fetch comprehensive store information and metadata.\n */\nexport interface StoreOperations {\n  info(): Promise<StoreInfo>;\n}\n\n/**\n * Comprehensive store information structure returned by the info method.\n * Contains all metadata, branding, social links, and showcase content for a Shopify store.\n */\nexport interface StoreInfo {\n  name: string;\n  domain: string;\n  slug: string;\n  title: string | null;\n  description: string | null;\n  logoUrl: string | null;\n  socialLinks: Record<string, string>;\n  contactLinks: {\n    tel: string | null;\n    email: string | null;\n    contactPage: string | null;\n  };\n  headerLinks: string[];\n  showcase: {\n    products: string[];\n    collections: string[];\n  };\n  jsonLdData: JsonLdEntry[] | undefined;\n  techProvider: {\n    name: string;\n    walletId: string | undefined;\n    subDomain: string | null;\n  };\n  country: CountryDetectionResult[\"country\"];\n}\n\n/**\n * Creates store operations for a ShopClient instance.\n * @param context - ShopClient context containing necessary methods and properties for store operations\n */\nexport function createStoreOperations(context: {\n  baseUrl: string;\n  storeDomain: string;\n  validateProductExists: (handle: string) => Promise<boolean>;\n  validateCollectionExists: (handle: string) => Promise<boolean>;\n  validateLinksInBatches: <T>(\n    items: T[],\n    validator: (item: T) => Promise<boolean>,\n    batchSize?: number\n  ) => Promise<T[]>;\n  handleFetchError: (error: unknown, context: string, url: string) => never;\n}): StoreOperations {\n  return {\n    /**\n     * Fetches comprehensive store information including metadata, social links, and showcase content.\n     *\n     * @returns {Promise<StoreInfo>} Store information object containing:\n     * - `name` - Store name from meta tags or domain\n     * - `domain` - Store domain URL\n     * - `slug` - Generated store slug\n     * - `title` - Store title from meta tags\n     * - `description` - Store description from meta tags\n     * - `logoUrl` - Store logo URL from Open Graph or CDN\n     * - `socialLinks` - Object with social media links (facebook, twitter, instagram, etc.)\n     * - `contactLinks` - Object with contact information (tel, email, contactPage)\n     * - `headerLinks` - Array of navigation links from header\n     * - `showcase` - Object with featured products and collections from homepage\n     * - `jsonLdData` - Structured data from JSON-LD scripts\n     * - `techProvider` - Shopify-specific information (walletId, subDomain)\n     * - `country` - Country detection results with ISO 3166-1 alpha-2 codes (e.g., \"US\", \"GB\")\n     *\n     * @throws {Error} When the store URL is unreachable or returns an error\n     *\n     * @example\n     * ```typescript\n     * const shop = new ShopClient('https://exampleshop.com');\n     * const storeInfo = await shop.getInfo();\n     *\n     * console.log(storeInfo.name); // \"Example Store\"\n     * console.log(storeInfo.socialLinks.instagram); // \"https://instagram.com/example\"\n     * console.log(storeInfo.showcase.products); // [\"product-handle-1\", \"product-handle-2\"]\n     * console.log(storeInfo.country); // \"US\"\n     * ```\n     */\n    info: async (): Promise<StoreInfo> => {\n      try {\n        // Delegate to shared client parser to avoid redundancy\n        const { info } = await getInfoForStore({\n          baseUrl: context.baseUrl,\n          storeDomain: context.storeDomain,\n          validateProductExists: context.validateProductExists,\n          validateCollectionExists: context.validateCollectionExists,\n          validateLinksInBatches: context.validateLinksInBatches,\n        });\n        return info;\n        /* const response = await rateLimitedFetch(context.baseUrl);\n        if (!response.ok) {\n          throw new Error(`HTTP error! status: ${response.status}`);\n        }\n        const html = await response.text();\n\n        const getMetaTag = (name: string) => {\n          const regex = new RegExp(\n            `<meta[^>]*name=[\"']${name}[\"'][^>]*content=[\"'](.*?)[\"']`\n          );\n          const match = html.match(regex);\n          return match ? match[1] : null;\n        };\n\n        const getPropertyMetaTag = (property: string) => {\n          const regex = new RegExp(\n            `<meta[^>]*property=[\"']${property}[\"'][^>]*content=[\"'](.*?)[\"']`\n          );\n          const match = html.match(regex);\n          return match ? match[1] : null;\n        };\n\n        const name =\n          getMetaTag(\"og:site_name\") ??\n          extractDomainWithoutSuffix(context.baseUrl);\n        const title = getMetaTag(\"og:title\") ?? getMetaTag(\"twitter:title\");\n\n        const description =\n          getMetaTag(\"description\") || getPropertyMetaTag(\"og:description\");\n\n        const shopifyWalletId = getMetaTag(\"shopify-digital-wallet\")?.split(\n          \"/\"\n        )[1];\n\n        const myShopifySubdomainMatch = html.match(\n          /['\"](.*?\\.myshopify\\.com)['\"]/\n        );\n        const myShopifySubdomain = myShopifySubdomainMatch\n          ? myShopifySubdomainMatch[1]\n          : null;\n\n        let logoUrl =\n          getPropertyMetaTag(\"og:image\") ||\n          getPropertyMetaTag(\"og:image:secure_url\");\n        if (!logoUrl) {\n          const logoMatch = html.match(\n            /<img[^>]+src=[\"']([^\"']+\\/cdn\\/shop\\/[^\"']+)[\"']/\n          );\n          const group = logoMatch?.[1];\n          logoUrl = group ? group.replace(\"http://\", \"https://\") : null;\n        } else {\n          logoUrl = logoUrl.replace(\"http://\", \"https://\");\n        }\n\n        const socialLinks: Record<string, string> = {};\n        const socialRegex =\n          /<a[^>]+href=[\"']([^\"']*(?:facebook|twitter|instagram|pinterest|youtube|linkedin|tiktok|vimeo)\\.com[^\"']*)[\"']/g;\n        for (const match of html.matchAll(socialRegex)) {\n          const hrefGroup = match[1];\n          if (!hrefGroup) continue;\n          let href: string = hrefGroup;\n          try {\n            if (href.startsWith(\"//\")) {\n              href = `https:${href}`;\n            } else if (href.startsWith(\"/\")) {\n              href = new URL(href, context.baseUrl).toString();\n            }\n            const parsed = new URL(href);\n            const domain = parsed.hostname.replace(\"www.\", \"\").split(\".\")[0];\n            if (domain) {\n              socialLinks[domain] = parsed.toString();\n            }\n          } catch {\n            // Skip invalid URL entries silently\n          }\n        }\n\n        const contactLinks = {\n          tel: null as string | null,\n          email: null as string | null,\n          contactPage: null as string | null,\n        };\n\n        // Extract contact details using focused regexes to avoid parser pitfalls\n        for (const match of html.matchAll(/href=[\"']tel:([^\"']+)[\"']/g)) {\n          const group = match[1];\n          if (group) contactLinks.tel = group.trim();\n        }\n        for (const match of html.matchAll(/href=[\"']mailto:([^\"']+)[\"']/g)) {\n          const group = match[1];\n          if (group) contactLinks.email = group.trim();\n        }\n        for (const match of html.matchAll(\n          /href=[\"']([^\"']*(?:\\/contact|\\/pages\\/contact)[^\"']*)[\"']/g\n        )) {\n          const group = match[1];\n          if (group) contactLinks.contactPage = group;\n        }\n\n        const extractedProductLinks =\n          html\n            .match(/href=[\"']([^\"']*\\/products\\/[^\"']+)[\"']/g)\n            ?.map((match) => {\n              const afterHref = match.split(\"href=\")[1];\n              if (!afterHref) return null;\n              const last = afterHref.replace(/[\\'\"]/g, \"\").split(\"/\").at(-1);\n              return last ?? null;\n            })\n            ?.filter((x): x is string => Boolean(x)) || [];\n\n        const extractedCollectionLinks =\n          html\n            .match(/href=[\"']([^\"']*\\/collections\\/[^\"']+)[\"']/g)\n            ?.map((match) => {\n              const afterHref = match.split(\"href=\")[1];\n              if (!afterHref) return null;\n              const last = afterHref.replace(/[\\'\"]/g, \"\").split(\"/\").at(-1);\n              return last ?? null;\n            })\n            ?.filter((x): x is string => Boolean(x)) || [];\n\n        // Validate links in batches for better performance\n        const [homePageProductLinks, homePageCollectionLinks] =\n          await Promise.all([\n            context.validateLinksInBatches(\n              extractedProductLinks.filter((handle): handle is string =>\n                Boolean(handle)\n              ),\n              (handle) => context.validateProductExists(handle)\n            ),\n            context.validateLinksInBatches(\n              extractedCollectionLinks.filter((handle): handle is string =>\n                Boolean(handle)\n              ),\n              (handle) => context.validateCollectionExists(handle)\n            ),\n          ]);\n\n        const jsonLd = html\n          .match(\n            /<script[^>]*type=\"application\\/ld\\+json\"[^>]*>([^<]+)<\\/script>/g\n          )\n          ?.map((match) => {\n            const afterGt = match.split(\">\")[1];\n            return afterGt ? afterGt.replace(/<\\/script/g, \"\") : \"\";\n          });\n        const jsonLdData: JsonLdEntry[] | undefined = jsonLd?.map(\n          (json) => JSON.parse(json) as JsonLdEntry\n        );\n\n        const headerLinks =\n          html\n            .match(\n              /<(header|nav|div|section)\\b[^>]*\\b(?:id|class)=[\"'][^\"']*(?=.*shopify-section)(?=.*\\b(header|navigation|nav|menu)\\b)[^\"']*[\"'][^>]*>[\\s\\S]*?<\\/\\1>/gi\n            )\n            ?.flatMap((header) => {\n              const links = header\n                .match(/href=[\"']([^\"']+)[\"']/g)\n                ?.filter(\n                  (link) =>\n                    link.includes(\"/products/\") ||\n                    link.includes(\"/collections/\") ||\n                    link.includes(\"/pages/\")\n                );\n              return (\n                links\n                  ?.map((link) => {\n                    const href = link.match(/href=[\"']([^\"']+)[\"']/)?.[1];\n                    if (\n                      href &&\n                      !href.startsWith(\"#\") &&\n                      !href.startsWith(\"javascript:\")\n                    ) {\n                      try {\n                        const url = new URL(href, context.storeDomain);\n                        return url.pathname.replace(/^\\/|\\/$/g, \"\");\n                      } catch {\n                        return href.replace(/^\\/|\\/$/g, \"\");\n                      }\n                    }\n                    return null;\n                  })\n                  .filter((item): item is string => Boolean(item)) ?? []\n              );\n            }) ?? [];\n\n        const slug = generateStoreSlug(context.baseUrl);\n\n        // Detect country information\n        const countryDetection = await detectShopifyCountry(html);\n\n        return {\n          name: name || slug,\n          domain: context.baseUrl,\n          slug,\n          title: title ?? null,\n          description: description ?? null,\n          logoUrl,\n          socialLinks,\n          contactLinks,\n          headerLinks,\n          showcase: {\n            products: unique(homePageProductLinks ?? []),\n            collections: unique(homePageCollectionLinks ?? []),\n          },\n          jsonLdData,\n          techProvider: {\n            name: \"shopify\",\n            walletId: shopifyWalletId,\n            subDomain: myShopifySubdomain ?? null,\n          },\n          country: countryDetection?.country || \"\",\n        };\n        */\n      } catch (error) {\n        context.handleFetchError(error, \"fetching store info\", context.baseUrl);\n      }\n    },\n  };\n}\n"],"mappings":"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","names":["name","_a","_b"]}