@atomm-developer/generator-material-purchase 0.1.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/README.md +80 -0
- package/dist/README.md +424 -0
- package/dist/index.d.ts +81 -0
- package/dist/index.es.js +1925 -0
- package/dist/index.es.js.map +1 -0
- package/dist/index.umd.js +2 -0
- package/dist/index.umd.js.map +1 -0
- package/package.json +47 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.umd.js","sources":["../src/config.ts","../src/services/auth.ts","../src/services/api.ts","../node_modules/.pnpm/@xtool+shopify-sdk@2.0.7/node_modules/@xtool/shopify-sdk/dist/index.esm.js","../src/services/shopify.ts","../src/services/money.ts","../src/services/product.ts","../src/i18n/en.ts","../src/i18n/zh.ts","../src/i18n/index.ts","../src/ui/icons.ts","../src/ui/renderer.ts","../src/ui/styles.ts","../src/modal.ts","../src/index.ts"],"sourcesContent":["import type { StoreOption } from './types'\n\nexport const DEFAULT_API_BASE_URL = 'https://xcs-api.xtool.com'\n\nconst ICON_BASE = 'https://storage.atomm.com/xtool/aimake-static/static/xtool-shopify'\n\nexport const ShopifyStoreName = {\n MAKEBLOCK_XTOOL: 'makeblock-xtool',\n CA_XTOOL: 'ca-xtool',\n XTOOL_AUSTRALIA_STORE: 'xtool-australia-store',\n JP_XTOOL: 'jp-xtool',\n EU_XTOOL: 'eu-xtool',\n DE_XTOOL: 'de-xtool',\n FR_XTOOL: 'fr-xtool',\n UK_XTOOL: 'uk-xtool',\n} as const\n\nexport type ShopifyStoreNameType =\n (typeof ShopifyStoreName)[keyof typeof ShopifyStoreName]\n\nexport const PROD_STORE_OPTIONS: StoreOption[] = [\n {\n label: 'US',\n value: ShopifyStoreName.MAKEBLOCK_XTOOL,\n icon: `${ICON_BASE}/at_country_us.svg`,\n shopDomain: 'makeblock-xtool.myshopify.com',\n storeFrontAccessToken: '7bb184c4d18313c58d0ccd6bfa0f73a3',\n },\n {\n label: 'CA',\n value: ShopifyStoreName.CA_XTOOL,\n icon: `${ICON_BASE}/at_country_ca.svg`,\n shopDomain: 'ca-xtool.myshopify.com',\n storeFrontAccessToken: '7912e607574a3a6eaffaf501c75408e6',\n },\n {\n label: 'EU',\n value: ShopifyStoreName.EU_XTOOL,\n icon: `${ICON_BASE}/at_country_eu.svg`,\n shopDomain: 'eu-xtool.myshopify.com',\n storeFrontAccessToken: '0886b237162c21d11ba1ca30f6220c6f',\n },\n {\n label: 'UK',\n value: ShopifyStoreName.UK_XTOOL,\n icon: `${ICON_BASE}/at_country_uk.svg`,\n shopDomain: 'uk-xtool.myshopify.com',\n storeFrontAccessToken: 'adf825795f70225d0351ad387d538757',\n },\n {\n label: 'FR',\n value: ShopifyStoreName.FR_XTOOL,\n icon: `${ICON_BASE}/at_country_fr.svg`,\n shopDomain: 'fr-xtool.myshopify.com',\n storeFrontAccessToken: 'e397fc547281c76d1086776fa347d804',\n },\n {\n label: 'DE',\n value: ShopifyStoreName.DE_XTOOL,\n icon: `${ICON_BASE}/at_country_de.svg`,\n shopDomain: 'de-xtool.myshopify.com',\n storeFrontAccessToken: '87e1adaeba390a0b21e5ef6937792d2f',\n },\n {\n label: 'JP',\n value: ShopifyStoreName.JP_XTOOL,\n icon: `${ICON_BASE}/at_country_jp.svg`,\n shopDomain: 'jp-xtool.myshopify.com',\n storeFrontAccessToken: 'c9738498306280b6ae87bb999811d952',\n },\n {\n label: 'AU',\n value: ShopifyStoreName.XTOOL_AUSTRALIA_STORE,\n icon: `${ICON_BASE}/at_country_au.svg`,\n shopDomain: 'xtool-australia-store.myshopify.com',\n storeFrontAccessToken: 'fabb70f52384af557b4ac0392f86c2ed',\n },\n]\n\nconst COUNTRY_TO_SITE_LABEL_MAP: Record<string, string> = {\n store_us: ShopifyStoreName.MAKEBLOCK_XTOOL,\n store_ca: ShopifyStoreName.CA_XTOOL,\n store_eu: ShopifyStoreName.EU_XTOOL,\n store_uk: ShopifyStoreName.UK_XTOOL,\n store_fr: ShopifyStoreName.FR_XTOOL,\n store_de: ShopifyStoreName.DE_XTOOL,\n store_jp: ShopifyStoreName.JP_XTOOL,\n store_au: ShopifyStoreName.XTOOL_AUSTRALIA_STORE,\n}\n\nexport const STORE_LABEL_KEY_MAP: Record<string, string> = {\n [ShopifyStoreName.MAKEBLOCK_XTOOL]: 'store_us',\n [ShopifyStoreName.CA_XTOOL]: 'store_ca',\n [ShopifyStoreName.XTOOL_AUSTRALIA_STORE]: 'store_au',\n [ShopifyStoreName.EU_XTOOL]: 'store_eu',\n [ShopifyStoreName.DE_XTOOL]: 'store_de',\n [ShopifyStoreName.FR_XTOOL]: 'store_fr',\n [ShopifyStoreName.UK_XTOOL]: 'store_uk',\n [ShopifyStoreName.JP_XTOOL]: 'store_jp',\n}\n\nexport const COUNTRY_NAME_KEY_MAP: Record<string, string> = {\n [ShopifyStoreName.MAKEBLOCK_XTOOL]: 'country_usa',\n [ShopifyStoreName.CA_XTOOL]: 'country_canada',\n [ShopifyStoreName.XTOOL_AUSTRALIA_STORE]: 'country_australia',\n [ShopifyStoreName.EU_XTOOL]: 'country_eu',\n [ShopifyStoreName.DE_XTOOL]: 'country_germany',\n [ShopifyStoreName.FR_XTOOL]: 'country_france',\n [ShopifyStoreName.UK_XTOOL]: 'country_uk',\n [ShopifyStoreName.JP_XTOOL]: 'country_japan',\n}\n\nvoid COUNTRY_TO_SITE_LABEL_MAP\n\n/** 根据 IP 定位映射到 Shopify 站点 */\nexport function countryToSite(\n countryInfo?: { continent?: string; country?: string },\n): string {\n if (!countryInfo) return ShopifyStoreName.MAKEBLOCK_XTOOL\n switch (countryInfo.continent) {\n case 'EU':\n switch (countryInfo.country) {\n case 'GB':\n case 'GG':\n case 'IM':\n case 'JE':\n return ShopifyStoreName.UK_XTOOL\n case 'DE':\n case 'AT':\n return ShopifyStoreName.DE_XTOOL\n case 'FR':\n case 'LU':\n case 'MC':\n return ShopifyStoreName.FR_XTOOL\n default:\n return ShopifyStoreName.EU_XTOOL\n }\n case 'AS':\n return countryInfo.country === 'JP'\n ? ShopifyStoreName.JP_XTOOL\n : ShopifyStoreName.MAKEBLOCK_XTOOL\n case 'NA':\n return countryInfo.country === 'CA'\n ? ShopifyStoreName.CA_XTOOL\n : ShopifyStoreName.MAKEBLOCK_XTOOL\n case 'OC':\n return countryInfo.country === 'AU'\n ? ShopifyStoreName.XTOOL_AUSTRALIA_STORE\n : ShopifyStoreName.MAKEBLOCK_XTOOL\n default:\n return ShopifyStoreName.MAKEBLOCK_XTOOL\n }\n}\n\nexport const STORAGE_KEYS = {\n CURRENT_SHOP: 'xtool_current_shop_name',\n SHOP_INFO: 'xtool_shop_info',\n U_TOKEN: 'utoken',\n LANG: 'LANG_KEY',\n}\n","import { STORAGE_KEYS } from '../config'\n\n/** 读 cookie value */\nfunction getCookie(name: string): string {\n if (typeof document === 'undefined') return ''\n const reg = new RegExp(`(?:^|;\\\\s*)${name}=([^;]*)`)\n const match = document.cookie.match(reg)\n return match ? decodeURIComponent(match[1]!) : ''\n}\n\nexport function getUToken(): string {\n return getCookie(STORAGE_KEYS.U_TOKEN) || localStorage.getItem(STORAGE_KEYS.U_TOKEN) || ''\n}\n\nexport function getLang(): string {\n return localStorage.getItem(STORAGE_KEYS.LANG) || 'en'\n}\n","import type { ProductDataType } from '../types'\nimport { getLang, getUToken } from './auth'\n\ninterface RequestArgs {\n baseURL: string\n url: string\n method: 'GET' | 'POST'\n params?: Record<string, unknown>\n data?: unknown\n}\n\ninterface AtommResponse<T> {\n code: number\n msg?: string\n message?: string\n data: T\n}\n\nasync function atommRequest<T>({ baseURL, url, method, params, data }: RequestArgs): Promise<T> {\n let finalUrl = baseURL.replace(/\\/$/, '') + url\n if (params && method === 'GET') {\n const search = new URLSearchParams()\n Object.entries(params).forEach(([k, v]) => {\n if (v === undefined || v === null) return\n search.append(k, String(v))\n })\n const qs = search.toString()\n if (qs) finalUrl += (finalUrl.includes('?') ? '&' : '?') + qs\n }\n\n const res = await fetch(finalUrl, {\n method,\n headers: {\n 'content-type': 'application/json;charset=UTF-8',\n uToken: getUToken(),\n lang: getLang(),\n },\n body: method === 'POST' ? JSON.stringify(data ?? {}) : undefined,\n })\n\n if (!res.ok) {\n throw new Error(`HTTP ${res.status} ${res.statusText}`)\n }\n const body = (await res.json()) as AtommResponse<T>\n if (body.code === 0) return body.data\n throw new Error(body.msg || body.message || `Request failed with code ${body.code}`)\n}\n\nexport interface AccessoryPackParams {\n store: string\n generatorId: string\n accessoryType: string\n}\n\nexport function fetchAccessoryPack(\n baseURL: string,\n params: AccessoryPackParams,\n): Promise<ProductDataType[]> {\n return atommRequest<ProductDataType[]>({\n baseURL,\n url: '/community/v1/web/generator-accessory-pack',\n method: 'GET',\n params: params as unknown as Record<string, unknown>,\n })\n}\n\nexport function fetchIpLocation(\n baseURL: string,\n): Promise<{ continent: string; country: string }> {\n return atommRequest<{ continent: string; country: string }>({\n baseURL,\n url: '/community/v2/web/ip/location',\n method: 'GET',\n })\n}\n\nexport interface TrackProductContent {\n variantId: string | number\n productQuantity: number\n store?: string\n relatedObjectId?: number | string\n relatedObjectType?: string\n pageSource?: string\n}\n\nexport function fetchDistributionTrackId(\n baseURL: string,\n productContent: TrackProductContent[],\n): Promise<{ trackId: string }> {\n return atommRequest<{ trackId: string }>({\n baseURL,\n url: '/community/v1/web/distribution/order',\n method: 'POST',\n data: { productContent },\n })\n}\n","class f {\n constructor(t) {\n if (t.shopDomain && !t.shopDomain.match(/^[a-zA-Z0-9_-]+\\.myshopify\\.com$/))\n throw new Error(\"shopDomain 必须为 xxxx.myshopify.com 格式\");\n if (!t.storeFrontAccessToken)\n throw new Error(\"storeFrontAccessToken 必填\");\n this.config = {\n shopDomain: t.shopDomain,\n storeFrontAccessToken: t.storeFrontAccessToken,\n apiVersion: t.apiVersion || \"2025-07\",\n timeout: t.timeout || 3e4,\n cartStorageMode: t.cartStorageMode || \"memory\",\n cartStorageKey: t.cartStorageKey || \"xtool_shop_sdk_shopify_cart_id\"\n }, this.baseUrl = `https://${this.config.shopDomain}/api/${this.config.apiVersion}`;\n }\n /**\n * 发送 HTTP 请求\n */\n async request(t, e = {}) {\n const {\n method: o = \"GET\",\n headers: a = {},\n body: i,\n params: s\n } = e;\n let n = `${this.baseUrl}${t}`;\n if (s) {\n const r = new URLSearchParams(s).toString();\n n += `?${r}`;\n }\n const h = {\n \"Content-Type\": \"application/json\",\n \"X-Shopify-StoreFront-Access-Token\": this.config.storeFrontAccessToken,\n ...a\n }, c = {\n method: o,\n headers: h\n };\n i && (c.body = JSON.stringify(i));\n const d = new AbortController(), u = setTimeout(() => d.abort(), this.config.timeout);\n try {\n const r = await fetch(n, {\n ...c,\n signal: d.signal\n });\n clearTimeout(u);\n const p = {\n data: await r.json(),\n status: r.status,\n statusText: r.statusText,\n headers: this.parseHeaders(r.headers)\n };\n if (!r.ok)\n throw new Error(`API 请求失败: ${r.status} ${r.statusText}`);\n return p;\n } catch (r) {\n throw r instanceof Error ? r.name === \"AbortError\" ? new Error(\"请求超时\") : r : new Error(\"未知错误\");\n }\n }\n /**\n * 解析响应头\n */\n parseHeaders(t) {\n const e = {};\n return t.forEach((o, a) => {\n e[a] = o;\n }), e;\n }\n graphQlRequest(t, e = {}) {\n return this.request(\"/graphql.json\", {\n method: \"POST\",\n body: { query: t, variables: e }\n });\n }\n /**\n * 创建购物车\n * @param params 购物车参数\n * @returns 购物车信息,包含购物车 ID\n */\n async createCart(t) {\n const e = t.lines.map((s) => s.merchandiseId.startsWith(\"gid://shopify/ProductVariant/\") ? s : {\n ...s,\n merchandiseId: `gid://shopify/ProductVariant/${s.merchandiseId}`\n });\n return t.lines = e, (await this.graphQlRequest(`\n mutation cartCreate($input: CartInput) {\n cartCreate(input: $input) {\n cart {\n id\n checkoutUrl\n }\n userErrors {\n field\n message\n }\n warnings {\n code\n message\n target\n }\n }\n }\n `, { input: t })).data.data.cartCreate;\n }\n /**\n * 获取商品信息与Metafields\n * @param params 商品信息与Metafields参数\n * @returns 商品信息与Metafields\n */\n async getProductInfoWithMetafields(t) {\n const { productId: e, metafieldsIdentifiers: o } = t, a = `\n query Products($id: ID, $metafields_identifiers: [HasMetafieldsIdentifier!]!) {\n product(id: $id ) {\n title\n id\n handle\n tags\n productType\n totalInventory\n onlineStoreUrl\n handle\n isGiftCard\n description\n descriptionHtml\n selectedOrFirstAvailableVariant {\n id\n }\n featuredImage {\n url\n }\n metafields(identifiers: $metafields_identifiers){\n id\n namespace\n key\n value\n }\n variants(first: 20){\n nodes {\n id\n title\n }\n }\n }\n }\n `, i = {\n id: String(e).startsWith(\"gid://shopify/Product/\") ? e : `gid://shopify/Product/${e}`,\n metafields_identifiers: o\n };\n return (await this.graphQlRequest(a, i)).data.data.product;\n }\n /**\n * 获取店铺信息\n * @returns 店铺信息\n */\n async getShopInfo() {\n return (await this.graphQlRequest(`\n query Shop {\n shop {\n id\n name\n moneyFormat\n }\n }\n `)).data.data.shop;\n }\n /**\n * 自定义请求方法\n * 提供灵活的 HTTP 请求能力,可用于调用其他 Shopify API\n */\n async customRequest(t, e) {\n return this.request(t, e);\n }\n}\nexport {\n f as XtoolShopify\n};\n//# sourceMappingURL=index.esm.js.map\n","import { XtoolShopify } from '@xtool/shopify-sdk'\nimport { PROD_STORE_OPTIONS, STORAGE_KEYS } from '../config'\nimport type { StoreOption } from '../types'\n\nexport class ShopifyClient {\n currentShopName = ''\n private client: XtoolShopify | null = null\n initialized = false\n initializing = false\n\n get currentStore(): StoreOption | undefined {\n return PROD_STORE_OPTIONS.find((s) => s.value === this.currentShopName)\n }\n\n private initClientFor(shopName: string) {\n const store = PROD_STORE_OPTIONS.find((s) => s.value === shopName)\n if (!store) {\n console.warn(`[ShopifyClient] missing config for store: ${shopName}`)\n return\n }\n this.client = new XtoolShopify({\n shopDomain: store.shopDomain,\n storeFrontAccessToken: store.storeFrontAccessToken,\n })\n }\n\n async init(initialShopName: string) {\n if (this.initialized || this.initializing) return\n this.initializing = true\n try {\n this.currentShopName = initialShopName\n localStorage.setItem(STORAGE_KEYS.CURRENT_SHOP, this.currentShopName)\n this.initClientFor(this.currentShopName)\n await this.fetchAndSaveShopInfo()\n this.initialized = true\n } catch (e) {\n console.error('[ShopifyClient] init failed:', e)\n this.initialized = true\n } finally {\n this.initializing = false\n }\n }\n\n async fetchAndSaveShopInfo() {\n if (!this.client) return\n try {\n const info = await this.client.getShopInfo()\n localStorage.setItem(\n STORAGE_KEYS.SHOP_INFO,\n JSON.stringify({\n money_with_currency_format: info.moneyFormat,\n moneyFormat: info.moneyFormat,\n }),\n )\n } catch (e) {\n console.warn('[ShopifyClient] getShopInfo failed:', e)\n }\n }\n\n async changeShop(shopName: string) {\n this.currentShopName = shopName\n localStorage.setItem(STORAGE_KEYS.CURRENT_SHOP, shopName)\n this.initClientFor(shopName)\n await this.fetchAndSaveShopInfo()\n }\n\n async createCheckout(\n lines: { merchandiseId: string; quantity: number }[],\n options?: { trackId?: string },\n ) {\n if (!this.client) throw new Error('Shopify client not initialized')\n const attributes: Array<{ key: string; value: string }> = [\n { key: 'xtool_return_url', value: window.location.href },\n ]\n if (options?.trackId) {\n attributes.push({ key: 'atomm_track_id', value: options.trackId })\n }\n const result = await this.client.createCart({ lines, attributes })\n if (result.cart) return result.cart\n const errMsg = result.userErrors?.[0]?.message || 'Failed to create cart'\n throw new Error(errMsg)\n }\n}\n","import { STORAGE_KEYS } from '../config'\n\nexport function formatMoney(money: number | string): string {\n const moneyNumber = typeof money === 'string' ? parseFloat(money) : money\n if (isNaN(moneyNumber) || typeof moneyNumber !== 'number') return '$0.00'\n\n let shopInfo: { money_with_currency_format?: string; moneyFormat?: string } = {}\n try {\n const stored = localStorage.getItem(STORAGE_KEYS.SHOP_INFO)\n if (stored) shopInfo = JSON.parse(stored)\n } catch {\n /* noop */\n }\n\n const formatString =\n shopInfo.money_with_currency_format || shopInfo.moneyFormat || '${{amount}}'\n const placeholderRegex = /\\{\\{\\s*(\\w+)\\s*\\}\\}/\n\n function formatWithDelimiters(n: number, precision: number, thousands = ',', decimal = '.') {\n const parts = n.toFixed(precision).split('.')\n const dollars = parts[0]?.replace(/(\\d)(?=(\\d{3})+(?!\\d))/g, '$1' + thousands) || ''\n const cents = parts[1] ? decimal + parts[1] : ''\n return dollars + cents\n }\n\n const match = formatString.match(placeholderRegex)\n let value = ''\n if (match?.[1]) {\n switch (match[1]) {\n case 'amount':\n value = formatWithDelimiters(moneyNumber, 2)\n break\n case 'amount_no_decimals':\n value = formatWithDelimiters(moneyNumber, 0)\n break\n case 'amount_with_comma_separator':\n value = formatWithDelimiters(moneyNumber, 2, '.', ',')\n break\n case 'amount_no_decimals_with_comma_separator':\n value = formatWithDelimiters(moneyNumber, 0, '.', ',')\n break\n case 'amount_with_space_separator':\n value = formatWithDelimiters(moneyNumber, 2, ' ', ',')\n break\n case 'amount_with_apostrophe_separator':\n value = formatWithDelimiters(moneyNumber, 2, \"'\")\n break\n default:\n value = formatWithDelimiters(moneyNumber, 2)\n break\n }\n } else {\n value = formatWithDelimiters(moneyNumber, 2)\n }\n\n return formatString.replace(placeholderRegex, value)\n}\n","import type { ProductDataType, ProductVariantType } from '../types'\nimport { formatMoney } from './money'\n\nexport function assignUid(item: ProductDataType, index: number): string {\n const dvId = item.defaultVariant\n if (dvId != null) return `${item.id}_${String(dvId)}_${index}`\n const vid = item.variants?.[0]?.id\n if (vid != null) return `${item.id}_${vid}_${index}`\n return `${item.id}_${index}`\n}\n\nexport function isVariantPurchasable(v: ProductVariantType | null | undefined): boolean {\n if (!v) return false\n return v.availableForSale === true && v.outOfStock !== true\n}\n\nexport function refreshProductPrices(list: ProductDataType[]) {\n list.forEach((item) => {\n item.variants?.forEach((v) => {\n v.displayPrice = formatMoney(v.price || '0.00')\n v.displayCompareAtPrice = v.compareAtPrice ? formatMoney(v.compareAtPrice) : ''\n })\n })\n}\n\nexport function findVariantByOptions(\n product: ProductDataType,\n options: Record<string, string> | undefined,\n): ProductVariantType | null {\n if (!product.variants?.length) return null\n if (!options || Object.keys(options).length === 0) {\n if (product.defaultVariant) {\n const dv = product.variants.find((v) => v.id === product.defaultVariant)\n if (dv) return dv\n }\n return product.variants.find((v) => v.isBind) || product.variants[0] || null\n }\n const matched = product.variants.find((v) => {\n if (!v.option) return false\n for (const [k, val] of Object.entries(options)) {\n if (k === 'uid') continue\n if (val && val !== '' && v.option[k] !== val) return false\n }\n return true\n })\n if (matched) return matched\n if (product.defaultVariant) {\n const dv = product.variants.find((v) => v.id === product.defaultVariant)\n if (dv) return dv\n }\n return product.variants.find((v) => v.isBind) || product.variants[0] || null\n}\n\nexport function getOptionKeys(product: ProductDataType): string[] {\n const variants = product.variants\n if (!variants?.length) return []\n const isNonEmpty = (v: string | undefined) => !!v && v.trim() !== ''\n let keys: string[] = []\n if (product.options?.length) {\n keys = product.options.map((o) => o.key).filter(Boolean) as string[]\n } else if (variants[0]?.option) {\n keys = Object.keys(variants[0].option)\n }\n return keys.filter((k) => variants.some((v) => isNonEmpty(v.option?.[k])))\n}\n\nexport function getOptionValues(\n product: ProductDataType,\n keys: string[],\n index: number,\n selected: Record<string, string>,\n): string[] {\n const isNonEmpty = (v: string | undefined) => !!v && v.trim() !== ''\n const variants = product.variants || []\n const values = new Set<string>()\n variants.forEach((v) => {\n if (!v.option) return\n if (index > 0) {\n for (let i = 0; i < index; i++) {\n const prevKey = keys[i]!\n const prevVal = selected[prevKey]\n if (isNonEmpty(prevVal) && v.option[prevKey] !== prevVal) return\n }\n }\n const val = v.option[keys[index]!]\n if (isNonEmpty(val)) values.add(val!)\n })\n return Array.from(values).sort()\n}\n\nexport function getDefaultVariant(product: ProductDataType): ProductVariantType | null {\n const variants = product.variants\n if (!variants?.length) return null\n if (product.defaultVariant) {\n const found = variants.find((v) => v.id === product.defaultVariant)\n if (found) return found\n }\n return variants.find((v) => v.isBind) || variants[0] || null\n}\n\nexport function initSelectedOptionsForProduct(product: ProductDataType): Record<string, string> {\n const keys = getOptionKeys(product)\n const selected: Record<string, string> = {}\n if (!keys.length) return selected\n keys.forEach((k) => (selected[k] = ''))\n const target = getDefaultVariant(product)\n if (target?.option) {\n keys.forEach((k) => {\n const v = target.option![k]\n if (v && v.trim() !== '') selected[k] = v\n })\n } else {\n keys.forEach((k, i) => {\n const values = getOptionValues(product, keys, i, selected)\n if (values[0]) selected[k] = values[0]\n })\n }\n return selected\n}\n","export default {\n shopify_supplies_kit: 'Supplies Kit',\n close: 'Close',\n current_country_notice: 'Items will be shipped to {country}.',\n loading: 'Loading',\n no_items_in_cart: 'No items available.',\n sold_out: 'Sold out',\n total: 'Total',\n discount_notice: 'Discount codes can only be used in checkout.',\n buy_now: 'Buy now',\n failed_load_product_list: 'Failed to load product list.',\n checkout_failed: 'Failed to create checkout.',\n selected_items_out_of_stock: 'Selected items are sold out.',\n no_valid_products_selected: 'No valid products selected.',\n store_us: 'US',\n store_ca: 'CA',\n store_au: 'AU',\n store_eu: 'EU',\n store_de: 'DE',\n store_fr: 'FR',\n store_uk: 'UK',\n store_jp: 'JP',\n store_test: 'XT',\n country_usa: 'USA',\n country_canada: 'Canada',\n country_australia: 'Australia',\n country_eu: 'EU',\n country_germany: 'Germany',\n country_france: 'France',\n country_uk: 'UK',\n country_japan: 'Japan',\n} as Record<string, string>\n","export default {\n shopify_supplies_kit: '耗材包',\n close: '关闭',\n current_country_notice: '商品将发往{country}。',\n loading: '加载中',\n no_items_in_cart: '暂无可购买的商品。',\n sold_out: '售罄',\n total: '合计',\n discount_notice: '优惠码仅可在结算页使用。',\n buy_now: '立即购买',\n failed_load_product_list: '加载商品列表失败。',\n checkout_failed: '创建结算订单失败。',\n selected_items_out_of_stock: '所选商品已售罄。',\n no_valid_products_selected: '未选择有效商品。',\n store_us: '美国',\n store_ca: '加拿大',\n store_au: '澳大利亚',\n store_eu: '欧盟',\n store_de: '德国',\n store_fr: '法国',\n store_uk: '英国',\n store_jp: '日本',\n store_test: '测试',\n country_usa: '美国',\n country_canada: '加拿大',\n country_australia: '澳大利亚',\n country_eu: '欧洲',\n country_germany: '德国',\n country_france: '法国',\n country_uk: '英国',\n country_japan: '日本',\n} as Record<string, string>\n","import en from './en'\nimport zh from './zh'\nimport type { Locale } from '../types'\n\nexport class I18n {\n private locale: Locale = 'en'\n private dict: Record<string, Record<string, string>> = { en, zh }\n\n setLocale(locale: Locale) {\n this.locale = this.dict[locale] ? locale : 'en'\n }\n\n extend(messages: Partial<Record<Locale, Record<string, string>>> | undefined) {\n if (!messages) return\n Object.entries(messages).forEach(([loc, entries]) => {\n if (!entries) return\n this.dict[loc] = { ...(this.dict[loc] || {}), ...entries }\n })\n }\n\n t(key: string, params?: Record<string, string | number>): string {\n const table = this.dict[this.locale] || this.dict['en'] || {}\n let text = table[key] ?? this.dict['en']?.[key] ?? key\n if (params) {\n Object.entries(params).forEach(([k, v]) => {\n text = text.replace(new RegExp(`\\\\{\\\\s*${k}\\\\s*\\\\}`, 'g'), String(v))\n })\n }\n return text\n }\n}\n","/** 简单的 lucide 图标 SVG 字符串(24x24 viewBox,stroke=currentColor) */\n\nconst wrap = (path: string, size = 16) =>\n `<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"${size}\" height=\"${size}\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">${path}</svg>`\n\nexport const iconX = (size = 16) => wrap('<path d=\"M18 6 6 18\"/><path d=\"m6 6 12 12\"/>', size)\nexport const iconChevronDown = (size = 16) => wrap('<path d=\"m6 9 6 6 6-6\"/>', size)\nexport const iconChevronUp = (size = 16) => wrap('<path d=\"m18 15-6-6-6 6\"/>', size)\nexport const iconCheck = (size = 12) => wrap('<path d=\"M20 6 9 17l-5-5\"/>', size)\nexport const iconMinus = (size = 14) => wrap('<path d=\"M5 12h14\"/>', size)\nexport const iconPlus = (size = 14) =>\n wrap('<path d=\"M5 12h14\"/><path d=\"M12 5v14\"/>', size)\n","import {\n PROD_STORE_OPTIONS,\n STORE_LABEL_KEY_MAP,\n COUNTRY_NAME_KEY_MAP,\n} from '../config'\nimport { iconCheck, iconChevronDown, iconChevronUp, iconMinus, iconPlus, iconX } from './icons'\nimport { styles } from './styles'\nimport type { ProductDataType, ProductVariantType, StoreOption } from '../types'\nimport {\n findVariantByOptions,\n getOptionKeys,\n getOptionValues,\n initSelectedOptionsForProduct,\n isVariantPurchasable,\n} from '../services/product'\nimport { formatMoney } from '../services/money'\nimport { I18n } from '../i18n'\n\nexport interface RendererCallbacks {\n onClose: () => void\n onShopChange: (value: string) => void\n onCheckout: () => void\n}\n\nexport interface RendererState {\n productList: ProductDataType[]\n currentShopName: string\n loading: boolean\n checkoutLoading: boolean\n checkedUids: string[]\n productSelectedOptions: Record<string, Record<string, string>>\n shopMenuOpen: boolean\n openSelect: { uid: string; key: string } | null\n}\n\nexport class Renderer {\n private host: HTMLDivElement | null = null\n private shadow: ShadowRoot | null = null\n private overlay: HTMLDivElement | null = null\n private panel: HTMLDivElement | null = null\n private toastEl: HTMLDivElement | null = null\n private toastTimer: number | null = null\n private docClickHandler = (e: Event) => this.handleDocClick(e)\n\n constructor(\n private state: RendererState,\n private i18n: I18n,\n private callbacks: RendererCallbacks,\n private zIndex: number,\n ) {}\n\n mount() {\n if (this.host) return\n this.host = document.createElement('div')\n this.host.className = 'xpm-host'\n this.host.style.position = 'relative'\n this.host.style.zIndex = String(this.zIndex)\n this.shadow = this.host.attachShadow({ mode: 'open' })\n\n const styleEl = document.createElement('style')\n styleEl.textContent = styles\n this.shadow.appendChild(styleEl)\n\n this.overlay = document.createElement('div')\n this.overlay.className = 'xpm-overlay'\n this.overlay.addEventListener('click', () => this.callbacks.onClose())\n this.shadow.appendChild(this.overlay)\n\n this.panel = document.createElement('div')\n this.panel.className = 'xpm-panel'\n this.shadow.appendChild(this.panel)\n\n document.body.appendChild(this.host)\n this.shadow.addEventListener('click', this.docClickHandler)\n\n this.renderAll()\n // 下一帧切换 visible 用于动画\n requestAnimationFrame(() => {\n this.overlay?.classList.add('xpm-overlay--visible')\n this.panel?.classList.add('xpm-panel--visible')\n })\n }\n\n unmount() {\n if (!this.host) return\n this.shadow?.removeEventListener('click', this.docClickHandler)\n this.host.remove()\n this.host = null\n this.shadow = null\n this.overlay = null\n this.panel = null\n this.toastEl = null\n if (this.toastTimer) {\n clearTimeout(this.toastTimer)\n this.toastTimer = null\n }\n }\n\n /** 主动触发关闭动画,调用方负责在动画完成后 unmount */\n playClose(): Promise<void> {\n return new Promise((resolve) => {\n this.overlay?.classList.remove('xpm-overlay--visible')\n this.panel?.classList.remove('xpm-panel--visible')\n setTimeout(() => resolve(), 250)\n })\n }\n\n setState(patch: Partial<RendererState>) {\n Object.assign(this.state, patch)\n this.renderAll()\n }\n\n /** 不重渲,仅查 / 触发某些行为 */\n getState(): RendererState {\n return this.state\n }\n\n showToast(message: string) {\n if (!this.shadow) return\n if (!this.toastEl) {\n this.toastEl = document.createElement('div')\n this.toastEl.className = 'xpm-toast'\n this.shadow.appendChild(this.toastEl)\n }\n this.toastEl.textContent = message\n this.toastEl.classList.add('xpm-toast--visible')\n if (this.toastTimer) clearTimeout(this.toastTimer)\n this.toastTimer = window.setTimeout(() => {\n this.toastEl?.classList.remove('xpm-toast--visible')\n }, 2200)\n }\n\n private renderAll() {\n if (!this.panel) return\n this.panel.innerHTML = ''\n this.panel.appendChild(this.renderHeader())\n this.panel.appendChild(this.renderBanner())\n this.panel.appendChild(this.renderList())\n this.panel.appendChild(this.renderFooter())\n }\n\n private renderHeader(): HTMLElement {\n const header = document.createElement('header')\n header.className = 'xpm-header'\n\n const title = document.createElement('span')\n title.className = 'xpm-header__title'\n title.textContent = this.i18n.t('shopify_supplies_kit')\n\n const closeBtn = document.createElement('button')\n closeBtn.className = 'xpm-icon-btn'\n closeBtn.setAttribute('aria-label', this.i18n.t('close'))\n closeBtn.innerHTML = iconX(16)\n closeBtn.addEventListener('click', () => this.callbacks.onClose())\n\n header.appendChild(title)\n header.appendChild(closeBtn)\n return header\n }\n\n private renderBanner(): HTMLElement {\n const banner = document.createElement('div')\n banner.className = 'xpm-banner'\n\n const currentStore: StoreOption | undefined =\n PROD_STORE_OPTIONS.find((s) => s.value === this.state.currentShopName) ||\n PROD_STORE_OPTIONS[0]\n const countryKey = currentStore\n ? COUNTRY_NAME_KEY_MAP[currentStore.value] || 'country_usa'\n : 'country_usa'\n const countryName = this.i18n.t(countryKey)\n\n const bannerText = document.createElement('span')\n bannerText.className = 'xpm-banner__text'\n bannerText.textContent = this.i18n.t('current_country_notice', { country: countryName })\n\n const dropdown = document.createElement('div')\n dropdown.className = 'xpm-dropdown' + (this.state.shopMenuOpen ? ' xpm-dropdown--open' : '')\n dropdown.dataset.xpmStop = '1'\n\n const trigger = document.createElement('button')\n trigger.type = 'button'\n trigger.className = 'xpm-dropdown__trigger'\n trigger.addEventListener('click', (e) => {\n e.stopPropagation()\n this.setState({ shopMenuOpen: !this.state.shopMenuOpen, openSelect: null })\n })\n\n const triggerSelected = document.createElement('span')\n triggerSelected.className = 'xpm-dropdown__selected'\n if (currentStore?.icon) {\n const flag = document.createElement('img')\n flag.src = currentStore.icon\n flag.alt = ''\n flag.className = 'xpm-flag'\n triggerSelected.appendChild(flag)\n }\n const triggerLabel = document.createElement('span')\n const labelKey = currentStore ? STORE_LABEL_KEY_MAP[currentStore.value] : undefined\n triggerLabel.textContent = labelKey ? this.i18n.t(labelKey) : currentStore?.label || ''\n triggerSelected.appendChild(triggerLabel)\n trigger.appendChild(triggerSelected)\n\n const chevWrap = document.createElement('span')\n chevWrap.innerHTML = this.state.shopMenuOpen ? iconChevronUp(16) : iconChevronDown(16)\n trigger.appendChild(chevWrap)\n\n dropdown.appendChild(trigger)\n\n if (this.state.shopMenuOpen) {\n const menu = document.createElement('div')\n menu.className = 'xpm-dropdown__menu'\n PROD_STORE_OPTIONS.forEach((opt) => {\n const item = document.createElement('button')\n item.type = 'button'\n item.className = 'xpm-dropdown__item'\n if (opt.icon) {\n const ic = document.createElement('img')\n ic.src = opt.icon\n ic.alt = ''\n ic.className = 'xpm-dropdown__item-icon'\n item.appendChild(ic)\n }\n const labelText = document.createElement('span')\n const k = STORE_LABEL_KEY_MAP[opt.value]\n labelText.textContent = k ? this.i18n.t(k) : opt.label\n item.appendChild(labelText)\n item.addEventListener('click', (e) => {\n e.stopPropagation()\n this.setState({ shopMenuOpen: false })\n this.callbacks.onShopChange(opt.value)\n })\n menu.appendChild(item)\n })\n dropdown.appendChild(menu)\n }\n\n banner.appendChild(bannerText)\n banner.appendChild(dropdown)\n return banner\n }\n\n private renderList(): HTMLElement {\n const list = document.createElement('div')\n list.className = 'xpm-list'\n\n if (this.state.loading) {\n const ph = document.createElement('div')\n ph.className = 'xpm-placeholder'\n const sp = document.createElement('div')\n sp.className = 'xpm-spinner'\n const txt = document.createElement('span')\n txt.textContent = this.i18n.t('loading')\n ph.appendChild(sp)\n ph.appendChild(txt)\n list.appendChild(ph)\n return list\n }\n\n if (this.state.productList.length === 0) {\n const ph = document.createElement('div')\n ph.className = 'xpm-placeholder'\n ph.textContent = this.i18n.t('no_items_in_cart')\n list.appendChild(ph)\n return list\n }\n\n this.state.productList.forEach((p) => list.appendChild(this.renderCard(p)))\n return list\n }\n\n private renderCard(product: ProductDataType): HTMLElement {\n const keys = getOptionKeys(product)\n const hasOptions = keys.length > 0\n\n const selectedOpts =\n this.state.productSelectedOptions[product.uid] ||\n initSelectedOptionsForProduct(product)\n if (!this.state.productSelectedOptions[product.uid]) {\n this.state.productSelectedOptions[product.uid] = selectedOpts\n }\n\n const variant: ProductVariantType | null = findVariantByOptions(product, selectedOpts)\n const isSoldOut = variant?.outOfStock === true\n const isPurchasable = isVariantPurchasable(variant)\n const isChecked = isSoldOut || this.state.checkedUids.includes(product.uid)\n\n const row = document.createElement('div')\n row.className = 'xpm-row' + (hasOptions ? ' xpm-row--has-options' : '')\n\n // media\n const media = document.createElement('div')\n media.className = 'xpm-row__media'\n const thumb = document.createElement('div')\n thumb.className = 'xpm-row__thumb'\n const img = document.createElement('img')\n const imgSrc = (variant?.image && variant.image.trim() !== '' ? variant.image : product.image) || ''\n if (imgSrc) img.src = imgSrc\n img.alt = product.displayName || product.title || ''\n thumb.appendChild(img)\n if (isSoldOut) {\n const sold = document.createElement('div')\n sold.className = 'xpm-row__sold-out'\n sold.textContent = this.i18n.t('sold_out')\n thumb.appendChild(sold)\n }\n media.appendChild(thumb)\n\n const checkbox = document.createElement('label')\n checkbox.className =\n 'xpm-checkbox' +\n (isChecked ? ' xpm-checkbox--checked' : '') +\n (isSoldOut ? ' xpm-checkbox--disabled' : '')\n const input = document.createElement('input')\n input.type = 'checkbox'\n input.checked = isChecked\n input.disabled = isSoldOut\n input.addEventListener('change', (e) => {\n if (!isPurchasable) return\n const next = (e.target as HTMLInputElement).checked\n const set = new Set(this.state.checkedUids)\n if (next) set.add(product.uid)\n else set.delete(product.uid)\n this.setState({ checkedUids: Array.from(set) })\n })\n const box = document.createElement('span')\n box.className = 'xpm-checkbox__box'\n if (isChecked) box.innerHTML = iconCheck(12)\n checkbox.appendChild(input)\n checkbox.appendChild(box)\n media.appendChild(checkbox)\n\n row.appendChild(media)\n\n // info\n const info = document.createElement('div')\n info.className = 'xpm-row__info'\n\n const name = document.createElement('div')\n name.className = 'xpm-row__name'\n name.textContent = product.displayName || product.title || ''\n name.title = name.textContent\n info.appendChild(name)\n\n if (hasOptions) {\n const variants = document.createElement('div')\n variants.className = 'xpm-variants'\n keys.forEach((key, idx) => {\n variants.appendChild(this.renderSelect(product, key, idx, keys, selectedOpts))\n })\n info.appendChild(variants)\n }\n\n const meta = document.createElement('div')\n meta.className = 'xpm-row__meta' + (hasOptions ? ' xpm-row__meta--with-options' : '')\n\n const priceGroup = document.createElement('div')\n priceGroup.className = 'xpm-price-group'\n const price = parseFloat(String(variant?.price ?? '0')) || 0\n const compareAt = parseFloat(String(variant?.compareAtPrice ?? '0')) || 0\n if (compareAt > price && compareAt > 0) {\n const pct = Math.round(((compareAt - price) / compareAt) * 100)\n const discount = document.createElement('span')\n discount.className = 'xpm-price-group__discount'\n discount.textContent = `-${pct}%`\n priceGroup.appendChild(discount)\n }\n const current = document.createElement('span')\n current.className = 'xpm-price-group__current'\n current.textContent = variant?.displayPrice || formatMoney(variant?.price || '0.00')\n priceGroup.appendChild(current)\n if (variant?.compareAtPrice) {\n const cmp = document.createElement('span')\n cmp.className = 'xpm-price-group__compare'\n cmp.textContent = variant.displayCompareAtPrice || formatMoney(variant.compareAtPrice)\n priceGroup.appendChild(cmp)\n }\n meta.appendChild(priceGroup)\n\n const actions = document.createElement('div')\n actions.className = 'xpm-row__actions'\n const qty = document.createElement('div')\n qty.className = 'xpm-qty'\n const minusBtn = document.createElement('button')\n minusBtn.className = 'xpm-qty__btn'\n minusBtn.innerHTML = iconMinus(14)\n minusBtn.disabled = (product.quantity || 1) <= 1 || !isPurchasable\n minusBtn.addEventListener('click', () => this.changeQty(product, -1))\n const qtyVal = document.createElement('span')\n qtyVal.className = 'xpm-qty__value'\n qtyVal.textContent = String(product.quantity || 1)\n const plusBtn = document.createElement('button')\n plusBtn.className = 'xpm-qty__btn'\n plusBtn.innerHTML = iconPlus(14)\n plusBtn.disabled = !isPurchasable\n plusBtn.addEventListener('click', () => this.changeQty(product, 1))\n qty.appendChild(minusBtn)\n qty.appendChild(qtyVal)\n qty.appendChild(plusBtn)\n actions.appendChild(qty)\n meta.appendChild(actions)\n\n info.appendChild(meta)\n row.appendChild(info)\n return row\n }\n\n private renderSelect(\n product: ProductDataType,\n key: string,\n index: number,\n keys: string[],\n selected: Record<string, string>,\n ): HTMLElement {\n const open =\n this.state.openSelect?.uid === product.uid && this.state.openSelect?.key === key\n const wrap = document.createElement('div')\n wrap.className = 'xpm-select' + (open ? ' xpm-select--open' : '')\n wrap.dataset.xpmStop = '1'\n\n const trigger = document.createElement('button')\n trigger.type = 'button'\n trigger.className = 'xpm-select__trigger'\n const currentVal = selected[key] || ''\n if (!currentVal) trigger.classList.add('xpm-select__trigger--placeholder')\n const label = document.createElement('span')\n label.textContent = currentVal || ''\n trigger.appendChild(label)\n const chev = document.createElement('span')\n chev.innerHTML = open ? iconChevronUp(14) : iconChevronDown(14)\n trigger.appendChild(chev)\n trigger.addEventListener('click', (e) => {\n e.stopPropagation()\n this.setState({\n openSelect: open ? null : { uid: product.uid, key },\n shopMenuOpen: false,\n })\n })\n wrap.appendChild(trigger)\n\n if (open) {\n const values = getOptionValues(product, keys, index, selected)\n const menu = document.createElement('div')\n menu.className = 'xpm-select__menu'\n values.forEach((val) => {\n const opt = document.createElement('button')\n opt.type = 'button'\n opt.className =\n 'xpm-select__option' + (val === currentVal ? ' xpm-select__option--selected' : '')\n opt.textContent = val\n opt.addEventListener('click', (e) => {\n e.stopPropagation()\n this.handleVariantChange(product, keys, key, index, val)\n })\n menu.appendChild(opt)\n })\n wrap.appendChild(menu)\n }\n return wrap\n }\n\n private handleVariantChange(\n product: ProductDataType,\n keys: string[],\n key: string,\n index: number,\n value: string,\n ) {\n const next =\n { ...(this.state.productSelectedOptions[product.uid] || {}) } as Record<string, string>\n next[key] = value\n // 重置后续选项到第一个候选\n for (let i = index + 1; i < keys.length; i++) {\n const nk = keys[i]!\n next[nk] = ''\n const tempSelected = { ...next }\n const values = getOptionValues(product, keys, i, tempSelected)\n if (values[0]) next[nk] = values[0]\n }\n const nextOptions = {\n ...this.state.productSelectedOptions,\n [product.uid]: next,\n }\n\n // 选择变体后,若新变体可购买则保持/添加勾选,否则取消勾选\n const variant = findVariantByOptions(product, next)\n const nextChecked = new Set(this.state.checkedUids)\n if (isVariantPurchasable(variant)) {\n nextChecked.add(product.uid)\n } else {\n nextChecked.delete(product.uid)\n }\n\n this.setState({\n productSelectedOptions: nextOptions,\n checkedUids: Array.from(nextChecked),\n openSelect: null,\n })\n }\n\n private changeQty(product: ProductDataType, delta: number) {\n const next = (product.quantity || 1) + delta\n if (next < 1) return\n product.quantity = next\n this.setState({})\n }\n\n private renderFooter(): HTMLElement {\n const footer = document.createElement('footer')\n footer.className = 'xpm-footer'\n\n const inner = document.createElement('div')\n inner.className = 'xpm-footer__inner'\n\n let total = 0\n let hasPurchasable = false\n this.state.checkedUids.forEach((uid) => {\n const product = this.state.productList.find((p) => p.uid === uid)\n if (!product) return\n const options = this.state.productSelectedOptions[uid] || {}\n const variant = findVariantByOptions(product, options)\n if (!variant) return\n if (isVariantPurchasable(variant)) hasPurchasable = true\n if (variant.price) {\n total += (parseFloat(String(variant.price)) || 0) * (product.quantity || 1)\n }\n })\n\n const totalBlock = document.createElement('div')\n totalBlock.className = 'xpm-footer__total-block'\n const totalRow = document.createElement('div')\n totalRow.className = 'xpm-footer__total-row'\n const tl = document.createElement('span')\n tl.className = 'xpm-footer__total-label'\n tl.textContent = this.i18n.t('total')\n const tp = document.createElement('span')\n tp.className = 'xpm-footer__total-price'\n tp.textContent = formatMoney(total.toFixed(2))\n totalRow.appendChild(tl)\n totalRow.appendChild(tp)\n const warn = document.createElement('p')\n warn.className = 'xpm-footer__warning'\n warn.textContent = this.i18n.t('discount_notice')\n totalBlock.appendChild(totalRow)\n totalBlock.appendChild(warn)\n\n const buyBtn = document.createElement('button')\n buyBtn.className = 'xpm-buy-now'\n buyBtn.textContent = this.state.checkoutLoading\n ? this.i18n.t('loading')\n : this.i18n.t('buy_now')\n buyBtn.disabled = !hasPurchasable || this.state.checkoutLoading\n buyBtn.addEventListener('click', () => this.callbacks.onCheckout())\n\n inner.appendChild(totalBlock)\n inner.appendChild(buyBtn)\n footer.appendChild(inner)\n return footer\n }\n\n private handleDocClick(e: Event) {\n // 点击 select / dropdown 之外的区域时关掉它们\n const path = e.composedPath()\n const insideDropdown = path.some(\n (n) => (n as HTMLElement)?.dataset?.xpmStop === '1',\n )\n if (insideDropdown) return\n if (this.state.openSelect || this.state.shopMenuOpen) {\n this.setState({ openSelect: null, shopMenuOpen: false })\n }\n }\n}\n","/** 弹窗全部样式,BEM 命名前缀 xpm- (Xtool Purchase Modal) */\nexport const styles = `\n:host, .xpm-host {\n font-family: Inter, system-ui, -apple-system, \"Segoe UI\", Roboto, sans-serif;\n color: #2d3541;\n}\n*, *::before, *::after { box-sizing: border-box; }\n\n.xpm-overlay {\n position: fixed;\n inset: 0;\n background: rgba(0, 0, 0, 0.4);\n z-index: 0;\n opacity: 0;\n transition: opacity 0.2s ease;\n}\n.xpm-overlay--visible { opacity: 1; }\n\n.xpm-panel {\n position: fixed;\n top: 0;\n right: 0;\n width: 320px;\n height: 100vh;\n background: #fff;\n display: flex;\n flex-direction: column;\n box-shadow:\n 0 1.187px 2.373px rgba(0, 0, 0, 0.1),\n 0 23.733px 23.733px rgba(0, 0, 0, 0.1);\n transform: translateX(100%);\n transition: transform 0.25s ease;\n}\n.xpm-panel--visible { transform: translateX(0); }\n\n.xpm-header {\n height: 56px;\n padding: 12px;\n border-bottom: 1px solid #e7e9ed;\n display: flex;\n align-items: center;\n justify-content: space-between;\n flex-shrink: 0;\n background: #fff;\n}\n.xpm-header__title {\n color: #2d3541;\n font-size: 14px;\n font-weight: 600;\n line-height: 20px;\n}\n.xpm-icon-btn {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 24px;\n height: 24px;\n padding: 0;\n border: 0;\n border-radius: 4px;\n background: transparent;\n color: #2d3541;\n cursor: pointer;\n}\n.xpm-icon-btn:hover { background: #f0f0f5; }\n\n.xpm-banner {\n position: relative;\n display: flex;\n align-items: center;\n justify-content: space-between;\n height: 40px;\n padding: 8px 12px 0;\n flex-shrink: 0;\n background: #fff;\n}\n.xpm-banner__text {\n min-width: 0;\n color: #ff7c23;\n font-size: 10px;\n font-weight: 500;\n line-height: 14px;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n padding-right: 80px;\n}\n\n.xpm-dropdown {\n position: absolute;\n top: 8px;\n right: 12px;\n z-index: 30;\n display: flex;\n flex-direction: column;\n gap: 4px;\n width: 73px;\n flex-shrink: 0;\n}\n.xpm-dropdown__trigger {\n display: flex;\n align-items: center;\n gap: 4px;\n width: 73px;\n height: 32px;\n padding: 6px 4px 6px 8px;\n border: 1px solid transparent;\n background: #f0f0f5;\n border-radius: 4px;\n color: #070b10;\n cursor: pointer;\n transition: all 0.15s ease;\n}\n.xpm-dropdown--open .xpm-dropdown__trigger {\n border: 1px solid #070b10;\n background: #fff;\n}\n.xpm-dropdown__selected {\n flex: 1;\n min-width: 0;\n display: inline-flex;\n align-items: center;\n gap: 4px;\n color: #070b10;\n font-size: 12px;\n font-weight: 400;\n line-height: 16px;\n overflow: hidden;\n}\n.xpm-dropdown__selected span {\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n.xpm-dropdown__menu {\n display: flex;\n flex-direction: column;\n align-items: stretch;\n width: 73px;\n padding: 4px;\n overflow: hidden;\n border: 1px solid #f0f0f5;\n border-radius: 6px;\n background: #fff;\n box-shadow:\n 0 2px 8px rgba(0, 0, 0, 0.1),\n 0 16px 32px rgba(0, 0, 0, 0.1);\n}\n.xpm-dropdown__item {\n display: flex;\n align-items: center;\n gap: 8px;\n width: 100%;\n height: 32px;\n padding: 8px;\n border: 0;\n border-radius: 4px;\n background: transparent;\n color: #070b10;\n font-size: 12px;\n font-weight: 400;\n line-height: 16px;\n cursor: pointer;\n}\n.xpm-dropdown__item:hover { background: #f0f0f5; }\n.xpm-dropdown__item-icon {\n width: 16px;\n height: 16px;\n object-fit: contain;\n flex-shrink: 0;\n}\n.xpm-flag {\n width: 15px;\n height: 11px;\n object-fit: cover;\n flex-shrink: 0;\n}\n\n.xpm-list {\n flex: 1;\n min-height: 0;\n overflow-y: auto;\n background: #fff;\n}\n.xpm-list::-webkit-scrollbar { width: 4px; }\n.xpm-list::-webkit-scrollbar-thumb { background: #c5cad2; border-radius: 2px; }\n.xpm-list::-webkit-scrollbar-track { background: transparent; }\n\n.xpm-placeholder {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n gap: 8px;\n height: 100%;\n color: #848b96;\n font-size: 12px;\n}\n.xpm-spinner {\n width: 20px;\n height: 20px;\n border-radius: 50%;\n border: 2px solid #e7e9ed;\n border-top-color: #6e757f;\n animation: xpm-spin 0.8s linear infinite;\n}\n@keyframes xpm-spin { to { transform: rotate(1turn); } }\n\n.xpm-row {\n display: flex;\n gap: 12px;\n align-items: center;\n min-height: 110px;\n padding: 8px 12px;\n border-bottom: 1px solid rgba(83, 91, 136, 0.1);\n background: #fff;\n}\n.xpm-row--has-options {\n align-items: flex-start;\n min-height: 167px;\n padding: 12px;\n}\n.xpm-row--has-options .xpm-row__info {\n min-height: 142px;\n justify-content: flex-start;\n}\n.xpm-row--has-options .xpm-row__meta { margin-top: 0; }\n\n.xpm-row__media {\n position: relative;\n width: 88px;\n height: 88px;\n flex-shrink: 0;\n}\n.xpm-row__thumb {\n width: 88px;\n height: 88px;\n overflow: hidden;\n border: 1px solid rgba(0, 0, 0, 0.08);\n border-radius: 8px;\n background: #f6f6fa;\n}\n.xpm-row__thumb img {\n width: 100%;\n height: 100%;\n display: block;\n object-fit: cover;\n}\n.xpm-row__sold-out {\n position: absolute;\n left: 0;\n right: 0;\n bottom: 0;\n height: 24px;\n display: flex;\n align-items: center;\n justify-content: center;\n border-radius: 0 0 8px 8px;\n background: rgba(0, 0, 0, 0.8);\n color: #fff;\n font-size: 10px;\n font-weight: 400;\n line-height: 14px;\n}\n\n.xpm-checkbox {\n position: absolute;\n left: 4px;\n top: 4px;\n z-index: 2;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 16px;\n height: 16px;\n cursor: pointer;\n}\n.xpm-checkbox input {\n position: absolute;\n inset: 0;\n width: 100%;\n height: 100%;\n margin: 0;\n opacity: 0;\n cursor: pointer;\n}\n.xpm-checkbox__box {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 14px;\n height: 14px;\n border: 1px solid #d8dadf;\n border-radius: 2px;\n background: #fff;\n color: #fff;\n}\n.xpm-checkbox--checked .xpm-checkbox__box {\n border-color: #070b10;\n background: #070b10;\n}\n.xpm-checkbox--disabled,\n.xpm-checkbox--disabled input { cursor: not-allowed; }\n.xpm-checkbox--disabled .xpm-checkbox__box {\n border-color: #d8dadf;\n background: #d8dadf;\n}\n\n.xpm-row__info {\n flex: 1;\n min-width: 0;\n min-height: 80px;\n display: flex;\n flex-direction: column;\n justify-content: flex-start;\n gap: 8px;\n}\n.xpm-row__name {\n min-width: 100%;\n color: #070b10;\n font-size: 12px;\n font-weight: 600;\n line-height: 16px;\n display: -webkit-box;\n -webkit-line-clamp: 2;\n -webkit-box-orient: vertical;\n overflow: hidden;\n word-break: break-word;\n}\n\n.xpm-variants {\n display: flex;\n flex-direction: column;\n gap: 4px;\n width: 100%;\n}\n\n.xpm-select {\n position: relative;\n width: 100%;\n}\n.xpm-select__trigger {\n display: flex;\n align-items: center;\n justify-content: space-between;\n width: 100%;\n height: 28px;\n padding: 0 6px;\n border: 1px solid rgba(0, 0, 0, 0.1);\n border-radius: 4px;\n background: #fff;\n color: #2d3541;\n font-size: 12px;\n font-weight: 400;\n line-height: 16px;\n cursor: pointer;\n}\n.xpm-select__trigger--placeholder { color: #848b96; }\n.xpm-select--open .xpm-select__trigger { border-color: #070b10; }\n.xpm-select__menu {\n position: absolute;\n left: 0;\n right: 0;\n top: calc(100% + 4px);\n z-index: 40;\n max-height: 200px;\n overflow-y: auto;\n padding: 4px;\n border: 1px solid #f0f0f5;\n border-radius: 6px;\n background: #fff;\n box-shadow:\n 0 2px 8px rgba(0, 0, 0, 0.1),\n 0 16px 32px rgba(0, 0, 0, 0.1);\n}\n.xpm-select__option {\n display: flex;\n align-items: center;\n width: 100%;\n height: 28px;\n padding: 4px 8px;\n border: 0;\n border-radius: 4px;\n background: transparent;\n color: #2d3541;\n font-size: 12px;\n font-weight: 400;\n line-height: 16px;\n cursor: pointer;\n text-align: left;\n}\n.xpm-select__option:hover { background: #f0f0f5; }\n.xpm-select__option--selected { background: #f0f0f5; color: #070b10; font-weight: 500; }\n\n.xpm-row__meta {\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n.xpm-row__meta--with-options {\n flex-direction: row;\n align-items: center;\n justify-content: space-between;\n width: 100%;\n}\n\n.xpm-price-group {\n min-width: 0;\n display: flex;\n align-items: center;\n gap: 4px;\n white-space: nowrap;\n}\n.xpm-price-group__discount {\n flex-shrink: 0;\n color: #fa2730;\n font-size: 12px;\n font-weight: 600;\n line-height: 16px;\n}\n.xpm-price-group__current {\n min-width: 0;\n overflow: hidden;\n color: #070b10;\n font-size: 12px;\n font-weight: 600;\n line-height: 16px;\n text-overflow: ellipsis;\n}\n.xpm-price-group__compare {\n min-width: 0;\n overflow: hidden;\n color: #b3b9c2;\n font-size: 10px;\n font-weight: 400;\n line-height: 14px;\n text-decoration: line-through;\n text-overflow: ellipsis;\n}\n\n.xpm-row__actions {\n display: flex;\n align-items: center;\n justify-content: flex-end;\n min-height: 24px;\n}\n.xpm-qty {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n flex-shrink: 0;\n}\n.xpm-qty__btn {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 20px;\n height: 20px;\n padding: 0;\n border: 1px solid #d8dadf;\n border-radius: 2px;\n background: #fff;\n color: #070b10;\n cursor: pointer;\n}\n.xpm-qty__btn:hover:not(:disabled) { background: #f6f6fa; }\n.xpm-qty__btn:disabled { opacity: 0.4; cursor: not-allowed; }\n.xpm-qty__value {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 24px;\n height: 24px;\n color: #070b10;\n font-size: 12px;\n font-weight: 400;\n line-height: 16px;\n}\n\n.xpm-footer {\n flex-shrink: 0;\n height: 105px;\n padding: 8px 16px;\n border-top: 1px solid rgba(81, 97, 117, 0.1);\n background: #fff;\n}\n.xpm-footer__inner {\n display: flex;\n flex-direction: column;\n justify-content: center;\n gap: 8px;\n width: 100%;\n height: 100%;\n}\n.xpm-footer__total-block {\n display: flex;\n flex-direction: column;\n gap: 4px;\n align-items: flex-start;\n}\n.xpm-footer__total-row {\n display: flex;\n align-items: center;\n gap: 4px;\n color: #070b10;\n}\n.xpm-footer__total-label {\n font-size: 12px;\n font-weight: 600;\n line-height: 16px;\n}\n.xpm-footer__total-price {\n font-size: 16px;\n font-weight: 500;\n line-height: 22px;\n}\n.xpm-footer__warning {\n margin: 0;\n color: #ff7c23;\n font-size: 12px;\n font-weight: 500;\n line-height: 16px;\n}\n.xpm-buy-now {\n width: 100%;\n height: 32px;\n padding: 6px 12px;\n border: 0;\n border-radius: 6px;\n background: #ff0035;\n color: #fff;\n font-size: 12px;\n font-weight: 600;\n line-height: 16px;\n cursor: pointer;\n}\n.xpm-buy-now:hover:not(:disabled) { background: #e60030; }\n.xpm-buy-now:disabled { opacity: 0.6; cursor: not-allowed; }\n\n.xpm-toast {\n position: fixed;\n top: 24px;\n left: 50%;\n transform: translateX(-50%);\n z-index: 1000;\n padding: 8px 16px;\n border-radius: 6px;\n background: rgba(20, 20, 24, 0.92);\n color: #fff;\n font-size: 13px;\n line-height: 20px;\n box-shadow: 0 8px 24px rgba(0, 0, 0, 0.18);\n opacity: 0;\n transition: opacity 0.18s ease;\n pointer-events: none;\n}\n.xpm-toast--visible { opacity: 1; }\n`\n","import {\n DEFAULT_API_BASE_URL,\n PROD_STORE_OPTIONS,\n ShopifyStoreName,\n STORAGE_KEYS,\n countryToSite,\n} from './config'\nimport { fetchAccessoryPack, fetchDistributionTrackId, fetchIpLocation } from './services/api'\nimport { ShopifyClient } from './services/shopify'\nimport {\n assignUid,\n findVariantByOptions,\n isVariantPurchasable,\n refreshProductPrices,\n} from './services/product'\nimport { I18n } from './i18n'\nimport { Renderer, RendererState } from './ui/renderer'\nimport type {\n GeneratorMaterialPurchaseApi,\n ProductDataType,\n PurchaseModalInitOptions,\n} from './types'\n\nconst DEFAULT_Z_INDEX = 9999\n\nclass PurchaseModal implements GeneratorMaterialPurchaseApi {\n private options: PurchaseModalInitOptions | null = null\n private apiBaseUrl: string = DEFAULT_API_BASE_URL\n private i18n = new I18n()\n private shopify = new ShopifyClient()\n private renderer: Renderer | null = null\n private state: RendererState = this.createInitialState()\n private accessoryCache: ProductDataType[] | null = null\n\n private createInitialState(): RendererState {\n return {\n productList: [],\n currentShopName: '',\n loading: false,\n checkoutLoading: false,\n checkedUids: [],\n productSelectedOptions: {},\n shopMenuOpen: false,\n openSelect: null,\n }\n }\n\n init(options: PurchaseModalInitOptions): void {\n if (!options || !options.generatorId || !options.accessoryType) {\n throw new Error('[GeneratorMaterialPurchase] init requires generatorId and accessoryType')\n }\n this.options = options\n this.apiBaseUrl = options.apiBaseUrl || DEFAULT_API_BASE_URL\n this.i18n.setLocale(options.locale || 'en')\n this.i18n.extend(options.messages)\n }\n\n async open(): Promise<void> {\n if (!this.options) {\n throw new Error('[GeneratorMaterialPurchase] call init() before open()')\n }\n\n // 重新创建一份 state 以避免上次状态污染\n this.state = this.createInitialState()\n\n this.renderer = new Renderer(\n this.state,\n this.i18n,\n {\n onClose: () => this.close(),\n onShopChange: (v) => this.handleShopChange(v),\n onCheckout: () => this.handleCheckout(),\n },\n this.options.zIndex || DEFAULT_Z_INDEX,\n )\n this.renderer.mount()\n\n // 先用 loading 状态打开\n this.renderer.setState({ loading: true })\n\n try {\n // 选定初始 shop:localStorage 优先;否则 IP 探测\n const cached = localStorage.getItem(STORAGE_KEYS.CURRENT_SHOP) || ''\n let initialShop = cached\n if (!initialShop || !PROD_STORE_OPTIONS.find((s) => s.value === initialShop)) {\n try {\n const loc = await fetchIpLocation(this.apiBaseUrl)\n initialShop = countryToSite(loc)\n } catch {\n initialShop = ShopifyStoreName.MAKEBLOCK_XTOOL\n }\n }\n await this.shopify.init(initialShop)\n this.renderer.setState({ currentShopName: this.shopify.currentShopName })\n await this.loadProducts(false)\n } catch (e) {\n console.error('[GeneratorMaterialPurchase] open failed:', e)\n this.options.onError?.(e)\n this.renderer.setState({ loading: false })\n this.renderer.showToast(this.i18n.t('failed_load_product_list'))\n }\n }\n\n close(): void {\n if (!this.renderer) return\n const r = this.renderer\n this.renderer = null\n r.playClose().then(() => r.unmount())\n this.options?.onClose?.()\n }\n\n destroy(): void {\n if (this.renderer) {\n this.renderer.unmount()\n this.renderer = null\n }\n this.options = null\n this.shopify = new ShopifyClient()\n this.accessoryCache = null\n }\n\n private async handleShopChange(shopName: string) {\n if (!this.renderer || !this.options) return\n this.renderer.setState({\n loading: true,\n productList: [],\n checkedUids: [],\n productSelectedOptions: {},\n })\n try {\n await this.shopify.changeShop(shopName)\n this.renderer.setState({ currentShopName: this.shopify.currentShopName })\n await this.loadProducts(true)\n } catch (e) {\n console.error('[GeneratorMaterialPurchase] handleShopChange failed:', e)\n this.options.onError?.(e)\n this.renderer.setState({ loading: false })\n this.renderer.showToast(this.i18n.t('failed_load_product_list'))\n }\n }\n\n private async loadProducts(force: boolean) {\n if (!this.renderer || !this.options) return\n try {\n let raw: ProductDataType[]\n if (!force && this.accessoryCache?.length) {\n raw = this.accessoryCache\n } else {\n raw = await fetchAccessoryPack(this.apiBaseUrl, {\n store: this.shopify.currentShopName,\n generatorId: this.options.generatorId,\n accessoryType: this.options.accessoryType,\n })\n this.accessoryCache = raw\n }\n const list: ProductDataType[] = (raw || []).map((item, idx) => ({\n ...item,\n uid: item.uid ?? assignUid(item, idx),\n quantity: item.quantity || 1,\n }))\n refreshProductPrices(list)\n\n // 默认勾上所有可购买的\n const initialChecked: string[] = []\n list.forEach((p) => {\n const variant = findVariantByOptions(p, {})\n if (isVariantPurchasable(variant)) initialChecked.push(p.uid)\n })\n\n this.renderer.setState({\n productList: list,\n checkedUids: initialChecked,\n productSelectedOptions: {},\n loading: false,\n })\n } catch (e) {\n console.error('[GeneratorMaterialPurchase] loadProducts failed:', e)\n this.options.onError?.(e)\n this.renderer.setState({ loading: false })\n this.renderer.showToast(this.i18n.t('failed_load_product_list'))\n }\n }\n\n private async handleCheckout() {\n if (!this.renderer || !this.options) return\n if (this.state.checkedUids.length === 0) return\n const options = this.options\n this.renderer.setState({ checkoutLoading: true })\n\n try {\n let skippedOutOfStock = 0\n const lines = this.state.checkedUids\n .map((uid) => {\n const product = this.state.productList.find((p) => p.uid === uid)\n if (!product) return null\n const options = this.state.productSelectedOptions[uid] || {}\n const variant = findVariantByOptions(product, options)\n if (!variant?.id) return null\n if (!isVariantPurchasable(variant)) {\n skippedOutOfStock += 1\n return null\n }\n return {\n merchandiseId: String(variant.id),\n quantity: product.quantity || 1,\n }\n })\n .filter(Boolean) as { merchandiseId: string; quantity: number }[]\n\n if (lines.length === 0) {\n const key =\n skippedOutOfStock > 0 ? 'selected_items_out_of_stock' : 'no_valid_products_selected'\n this.renderer.showToast(this.i18n.t(key))\n return\n }\n\n let trackId: string | undefined\n try {\n const productContent = lines.map((l) => ({\n variantId: l.merchandiseId,\n productQuantity: l.quantity,\n store: this.shopify.currentShopName,\n relatedObjectId: 1,\n relatedObjectType: options.generatorId,\n pageSource: 'generator',\n }))\n const res = await fetchDistributionTrackId(this.apiBaseUrl, productContent)\n trackId = res?.trackId\n } catch (e) {\n console.warn('[GeneratorMaterialPurchase] fetchDistributionTrackId failed:', e)\n }\n\n const cart = await this.shopify.createCheckout(lines, { trackId })\n if (cart?.checkoutUrl) {\n if (options.onCheckoutSuccess) {\n options.onCheckoutSuccess(cart.checkoutUrl)\n } else {\n window.open(cart.checkoutUrl, '_blank')\n }\n }\n } catch (e) {\n console.error('[GeneratorMaterialPurchase] checkout failed:', e)\n options.onError?.(e)\n this.renderer?.showToast(this.i18n.t('checkout_failed'))\n } finally {\n this.renderer?.setState({ checkoutLoading: false })\n }\n }\n}\n\nexport const generatorMaterialPurchaseInstance = new PurchaseModal()\n","import { generatorMaterialPurchaseInstance } from './modal'\nimport type { GeneratorMaterialPurchaseApi, PurchaseModalInitOptions } from './types'\n\nconst api: GeneratorMaterialPurchaseApi = {\n init: (options) => generatorMaterialPurchaseInstance.init(options),\n open: () => generatorMaterialPurchaseInstance.open(),\n close: () => generatorMaterialPurchaseInstance.close(),\n destroy: () => generatorMaterialPurchaseInstance.destroy(),\n}\n\nif (typeof window !== 'undefined') {\n ;(window as unknown as { GeneratorMaterialPurchase: GeneratorMaterialPurchaseApi }).GeneratorMaterialPurchase =\n api\n}\n\nexport default api\nexport { api as GeneratorMaterialPurchase }\nexport type { GeneratorMaterialPurchaseApi, PurchaseModalInitOptions }\nexport * from './types'\n"],"names":["DEFAULT_API_BASE_URL","ICON_BASE","ShopifyStoreName","PROD_STORE_OPTIONS","label","value","icon","shopDomain","storeFrontAccessToken","STORE_LABEL_KEY_MAP","ShopifyStoreName_MAKEBLOCK_XTOOL","ShopifyStoreName_CA_XTOOL","ShopifyStoreName_XTOOL_AUSTRALIA_STORE","ShopifyStoreName_EU_XTOOL","ShopifyStoreName_DE_XTOOL","ShopifyStoreName_FR_XTOOL","ShopifyStoreName_UK_XTOOL","ShopifyStoreName_JP_XTOOL","COUNTRY_NAME_KEY_MAP","STORAGE_KEYS","getUToken","name","document","reg","RegExp","match","cookie","decodeURIComponent","getCookie","localStorage","getItem","async","atommRequest","baseURL","url","method","params","data","finalUrl","replace","search","URLSearchParams","Object","entries","forEach","k","v","append","String","qs","toString","includes","res","fetch","headers","uToken","lang","body","JSON","stringify","ok","Error","status","statusText","json","code","msg","message","f","constructor","t","this","config","apiVersion","timeout","cartStorageMode","cartStorageKey","baseUrl","request","e","o","a","i","s","n","c","d","AbortController","u","setTimeout","abort","r","signal","clearTimeout","p","parseHeaders","graphQlRequest","query","variables","createCart","lines","map","merchandiseId","startsWith","input","cartCreate","getProductInfoWithMetafields","productId","metafieldsIdentifiers","id","metafields_identifiers","product","getShopInfo","shop","customRequest","ShopifyClient","__publicField","currentStore","find","currentShopName","initClientFor","shopName","store","client","XtoolShopify","init","initialShopName","initialized","initializing","setItem","fetchAndSaveShopInfo","info","money_with_currency_format","moneyFormat","changeShop","createCheckout","options","attributes","key","window","location","href","trackId","push","result","cart","errMsg","_b","_a","userErrors","formatMoney","money","moneyNumber","parseFloat","isNaN","shopInfo","stored","parse","formatString","placeholderRegex","formatWithDelimiters","precision","thousands","decimal","parts","toFixed","split","assignUid","item","index","dvId","defaultVariant","vid","variants","isVariantPurchasable","availableForSale","outOfStock","findVariantByOptions","length","keys","dv","isBind","matched","option","val","getOptionKeys","filter","Boolean","some","trim","isNonEmpty","getOptionValues","selected","values","Set","prevKey","prevVal","add","Array","from","sort","en","shopify_supplies_kit","close","current_country_notice","loading","no_items_in_cart","sold_out","total","discount_notice","buy_now","failed_load_product_list","checkout_failed","selected_items_out_of_stock","no_valid_products_selected","store_us","store_ca","store_au","store_eu","store_de","store_fr","store_uk","store_jp","store_test","country_usa","country_canada","country_australia","country_eu","country_germany","country_france","country_uk","country_japan","zh","I18n","setLocale","locale","dict","extend","messages","loc","text","wrap","path","size","iconChevronDown","iconChevronUp","Renderer","state","i18n","callbacks","zIndex","handleDocClick","mount","host","createElement","className","style","position","shadow","attachShadow","mode","styleEl","textContent","appendChild","overlay","addEventListener","onClose","panel","docClickHandler","renderAll","requestAnimationFrame","classList","unmount","removeEventListener","remove","toastEl","toastTimer","playClose","Promise","resolve","setState","patch","assign","getState","showToast","innerHTML","renderHeader","renderBanner","renderList","renderFooter","header","title","closeBtn","setAttribute","iconX","banner","countryKey","countryName","bannerText","country","dropdown","shopMenuOpen","dataset","xpmStop","trigger","type","stopPropagation","openSelect","triggerSelected","flag","src","alt","triggerLabel","labelKey","chevWrap","menu","opt","ic","labelText","onShopChange","list","ph","sp","txt","productList","renderCard","hasOptions","selectedOpts","productSelectedOptions","uid","target","found","getDefaultVariant","initSelectedOptionsForProduct","variant","isSoldOut","isPurchasable","isChecked","checkedUids","row","media","thumb","img","imgSrc","image","displayName","sold","checkbox","checked","disabled","next","set","delete","box","iconCheck","idx","renderSelect","meta","priceGroup","price","compareAt","compareAtPrice","pct","Math","round","discount","current","displayPrice","cmp","displayCompareAtPrice","actions","qty","minusBtn","iconMinus","quantity","changeQty","qtyVal","plusBtn","iconPlus","open","currentVal","chev","handleVariantChange","nk","nextOptions","nextChecked","delta","footer","inner","hasPurchasable","totalBlock","totalRow","tl","tp","warn","buyBtn","checkoutLoading","onCheckout","composedPath","generatorMaterialPurchaseInstance","createInitialState","generatorId","accessoryType","apiBaseUrl","renderer","handleShopChange","handleCheckout","initialShop","countryInfo","continent","countryToSite","shopify","loadProducts","onError","call","then","destroy","accessoryCache","force","raw","refreshProductPrices","initialChecked","_c","skippedOutOfStock","productContent","l","variantId","productQuantity","relatedObjectId","relatedObjectType","pageSource","fetchDistributionTrackId","checkoutUrl","onCheckoutSuccess","api","GeneratorMaterialPurchase"],"mappings":"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","x_google_ignoreList":[3]}
|
package/package.json
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@atomm-developer/generator-material-purchase",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Atomm Generator 平台耗材购买弹窗 SDK,框架无关,支持 Vue / React / 原生 JS",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"atomm",
|
|
7
|
+
"generator",
|
|
8
|
+
"material",
|
|
9
|
+
"purchase",
|
|
10
|
+
"shopify"
|
|
11
|
+
],
|
|
12
|
+
"license": "MIT",
|
|
13
|
+
"type": "module",
|
|
14
|
+
"main": "./dist/index.umd.js",
|
|
15
|
+
"module": "./dist/index.es.js",
|
|
16
|
+
"types": "./dist/index.d.ts",
|
|
17
|
+
"exports": {
|
|
18
|
+
".": {
|
|
19
|
+
"types": "./dist/index.d.ts",
|
|
20
|
+
"import": "./dist/index.es.js",
|
|
21
|
+
"require": "./dist/index.umd.js"
|
|
22
|
+
}
|
|
23
|
+
},
|
|
24
|
+
"files": [
|
|
25
|
+
"dist",
|
|
26
|
+
"README.md"
|
|
27
|
+
],
|
|
28
|
+
"publishConfig": {
|
|
29
|
+
"registry": "https://registry.npmjs.org/",
|
|
30
|
+
"access": "public"
|
|
31
|
+
},
|
|
32
|
+
"scripts": {
|
|
33
|
+
"dev": "vite",
|
|
34
|
+
"build": "vite build && node scripts/copy-dist-readme.mjs",
|
|
35
|
+
"preview": "vite preview",
|
|
36
|
+
"type-check": "tsc --noEmit"
|
|
37
|
+
},
|
|
38
|
+
"dependencies": {
|
|
39
|
+
"@xtool/shopify-sdk": "^2.0.7"
|
|
40
|
+
},
|
|
41
|
+
"devDependencies": {
|
|
42
|
+
"terser": "^5.46.0",
|
|
43
|
+
"typescript": "~5.9.3",
|
|
44
|
+
"vite": "^6.2.4",
|
|
45
|
+
"vite-plugin-dts": "^4.5.4"
|
|
46
|
+
}
|
|
47
|
+
}
|