@occluze/tether 0.6.8 → 0.7.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +28 -28
- package/dist/esm/astro.js +2 -2
- package/dist/esm/chunks/account-CXMA5RPZ.js +1 -0
- package/dist/esm/chunks/account-pages-IZO7FEOZ.js +1 -0
- package/dist/esm/chunks/analytics-PG5FPRDN.js +1 -0
- package/dist/esm/chunks/chunk-4HD4J5JC.js +1 -0
- package/dist/esm/chunks/chunk-6TFMLT4A.js +4 -0
- package/dist/esm/chunks/chunk-BBVUVPMO.js +1 -0
- package/dist/esm/chunks/chunk-E5YO6274.js +1 -0
- package/dist/esm/chunks/chunk-EW5SYO6L.js +1 -0
- package/dist/esm/chunks/chunk-HJY2JSNB.js +1 -0
- package/dist/esm/chunks/chunk-MQYB6BH4.js +1 -0
- package/dist/esm/chunks/chunk-N3V45JPS.js +1 -0
- package/dist/esm/chunks/chunk-RPMBCAGS.js +1 -0
- package/dist/esm/chunks/chunk-VFNHIGCS.js +1 -0
- package/dist/esm/chunks/chunk-WT7RGGJU.js +1 -0
- package/dist/esm/chunks/chunk-YN6LEBEN.js +1 -0
- package/dist/esm/chunks/chunk-Z6HS3H7K.js +1 -0
- package/dist/esm/chunks/diagnose-XCEBQKBO.js +14 -0
- package/dist/esm/chunks/extras-4HU3VSBQ.js +1 -0
- package/dist/esm/chunks/markets-ui-M4IQ62CT.js +1 -0
- package/dist/esm/chunks/search-A5DS2IOS.js +1 -0
- package/dist/esm/index.js +1 -1
- package/dist/esm/server.js +2 -2
- package/dist/presets/barba.esm.js +19 -23
- package/dist/tether.account-pages.js +332 -367
- package/dist/tether.account-pages.min.js +1 -1
- package/dist/tether.account.js +253 -492
- package/dist/tether.account.min.js +1 -1
- package/dist/tether.analytics.js +82 -89
- package/dist/tether.analytics.min.js +1 -1
- package/dist/tether.diagnose.js +52 -34
- package/dist/tether.diagnose.min.js +2 -2
- package/dist/tether.extras.js +42 -37
- package/dist/tether.extras.min.js +1 -1
- package/dist/tether.js +1361 -935
- package/dist/tether.markets.js +89 -91
- package/dist/tether.markets.min.js +1 -1
- package/dist/tether.min.js +0 -0
- package/dist/tether.min.js.map +4 -4
- package/dist/tether.search.js +60 -69
- package/dist/tether.search.min.js +1 -1
- package/dist/types/server/src/shared/account-orders.d.ts +44 -0
- package/dist/types/server/src/shared/account-routes.d.ts +153 -0
- package/dist/types/server/src/shared/api-versions.d.ts +13 -0
- package/dist/types/server/src/shared/cart-id.d.ts +2 -0
- package/dist/types/server/src/shared/error-message.d.ts +2 -0
- package/dist/types/server/src/shared/json.d.ts +25 -0
- package/dist/types/server/src/shared/market-codes.d.ts +16 -0
- package/dist/types/src/account/addresses-view.d.ts +5 -0
- package/dist/types/src/account/answers.d.ts +40 -0
- package/dist/types/src/account/markup.d.ts +19 -0
- package/dist/types/src/account/operations.d.ts +41 -0
- package/dist/types/src/account/order-lines.d.ts +13 -0
- package/dist/types/src/account/order-list.d.ts +12 -0
- package/dist/types/src/account/order-page.d.ts +6 -0
- package/dist/types/src/account/page-answers.d.ts +182 -0
- package/dist/types/src/account/page-events.d.ts +2 -0
- package/dist/types/src/account/server-client.d.ts +60 -0
- package/dist/types/src/account/subscriptions-view.d.ts +2 -0
- package/dist/types/src/account-api.d.ts +18 -0
- package/dist/types/src/account-marks.d.ts +15 -0
- package/dist/types/src/account-pages.d.ts +8 -0
- package/dist/types/src/account.d.ts +64 -0
- package/dist/types/src/amounts.d.ts +12 -0
- package/dist/types/src/analytics-shopify.d.ts +41 -0
- package/dist/types/src/analytics.d.ts +2 -0
- package/dist/types/src/api-version.d.ts +28 -0
- package/dist/types/src/astro.d.ts +42 -0
- package/dist/types/src/cart/cart-shape.d.ts +43 -0
- package/dist/types/src/cart/checkout.d.ts +16 -0
- package/dist/types/src/cart/drawer.d.ts +18 -0
- package/dist/types/src/cart/mutations.d.ts +85 -0
- package/dist/types/src/cart/render.d.ts +17 -0
- package/dist/types/src/cart/store.d.ts +185 -0
- package/dist/types/src/cart.d.ts +106 -0
- package/dist/types/src/client.d.ts +134 -0
- package/dist/types/src/collection.d.ts +25 -0
- package/dist/types/src/config-sections.d.ts +40 -0
- package/dist/types/src/config.d.ts +190 -0
- package/dist/types/src/controls/cart-controls.d.ts +2 -0
- package/dist/types/src/controls/discount.d.ts +2 -0
- package/dist/types/src/controls/extras.d.ts +5 -0
- package/dist/types/src/controls/navigation.d.ts +12 -0
- package/dist/types/src/diagnose-markup.d.ts +19 -0
- package/dist/types/src/diagnose.d.ts +60 -0
- package/dist/types/src/dom.d.ts +75 -0
- package/dist/types/src/extras.d.ts +21 -0
- package/dist/types/src/fragments.d.ts +158 -0
- package/dist/types/src/globals.d.ts +15 -0
- package/dist/types/src/images.d.ts +20 -0
- package/dist/types/src/index.d.ts +167 -0
- package/dist/types/src/initial.d.ts +56 -0
- package/dist/types/src/lazy.d.ts +28 -0
- package/dist/types/src/loader.d.ts +84 -0
- package/dist/types/src/market-codes.d.ts +6 -0
- package/dist/types/src/markets-ui.d.ts +32 -0
- package/dist/types/src/markets.d.ts +72 -0
- package/dist/types/src/markup.d.ts +131 -0
- package/dist/types/src/mounting.d.ts +46 -0
- package/dist/types/src/page-market.d.ts +27 -0
- package/dist/types/src/presets/barba.d.ts +56 -0
- package/dist/types/src/product-events.d.ts +2 -0
- package/dist/types/src/product-render.d.ts +17 -0
- package/dist/types/src/product-shape.d.ts +90 -0
- package/dist/types/src/product-state.d.ts +110 -0
- package/dist/types/src/product.d.ts +66 -0
- package/dist/types/src/repeaters.d.ts +16 -0
- package/dist/types/src/search.d.ts +33 -0
- package/dist/types/src/selling-plans.d.ts +64 -0
- package/dist/types/src/server.d.ts +88 -0
- package/dist/types/src/shopify-values.d.ts +46 -0
- package/dist/types/src/status.d.ts +33 -0
- package/dist/types/src/storage.d.ts +12 -0
- package/dist/types/src/store-html.d.ts +39 -0
- package/dist/types/src/storefront/catalog.d.ts +38 -0
- package/dist/types/src/storefront/json-ld.d.ts +20 -0
- package/dist/types/src/variant-render.d.ts +14 -0
- package/package.json +24 -24
- package/dist/esm/chunks/account-C3NP6HFB.js +0 -1
- package/dist/esm/chunks/account-pages-WLK374FO.js +0 -1
- package/dist/esm/chunks/analytics-G3SAWMNL.js +0 -1
- package/dist/esm/chunks/chunk-27PJJZGC.js +0 -1
- package/dist/esm/chunks/chunk-2FSXS55U.js +0 -1
- package/dist/esm/chunks/chunk-FCSWQDVV.js +0 -1
- package/dist/esm/chunks/chunk-FOMSMIAM.js +0 -1
- package/dist/esm/chunks/chunk-GZJTCLLW.js +0 -1
- package/dist/esm/chunks/chunk-HEQILZVR.js +0 -1
- package/dist/esm/chunks/chunk-JOOEXYF3.js +0 -4
- package/dist/esm/chunks/chunk-MPTQYLSM.js +0 -1
- package/dist/esm/chunks/chunk-NEHZ37TU.js +0 -3
- package/dist/esm/chunks/chunk-V74KGEJF.js +0 -1
- package/dist/esm/chunks/chunk-VT4CDUJJ.js +0 -1
- package/dist/esm/chunks/chunk-YJLWX2HK.js +0 -1
- package/dist/esm/chunks/diagnose-6VVGZNTY.js +0 -14
- package/dist/esm/chunks/extras-GJVRDFM3.js +0 -1
- package/dist/esm/chunks/markets-ui-UNB4PTA7.js +0 -1
- package/dist/esm/chunks/search-OU75RNQL.js +0 -1
- package/src/account/addresses-view.js +0 -92
- package/src/account/browser-session.js +0 -359
- package/src/account/markup.js +0 -48
- package/src/account/operations.js +0 -180
- package/src/account/order-lines.js +0 -96
- package/src/account/order-list.js +0 -91
- package/src/account/order-page.js +0 -192
- package/src/account/page-events.js +0 -288
- package/src/account/server-client.js +0 -172
- package/src/account/shared.js +0 -111
- package/src/account/shopify-auth.js +0 -150
- package/src/account/subscriptions-view.js +0 -158
- package/src/account-api.js +0 -118
- package/src/account-links.js +0 -35
- package/src/account-pages.js +0 -89
- package/src/account.js +0 -342
- package/src/amounts.js +0 -36
- package/src/analytics-shopify.js +0 -241
- package/src/analytics.js +0 -352
- package/src/api-version.js +0 -85
- package/src/astro.js +0 -266
- package/src/cart/checkout.js +0 -97
- package/src/cart/drawer.js +0 -138
- package/src/cart/mutations.js +0 -234
- package/src/cart/render.js +0 -294
- package/src/cart/store.js +0 -326
- package/src/cart.js +0 -391
- package/src/client.js +0 -267
- package/src/collection.js +0 -183
- package/src/config.js +0 -349
- package/src/controls/cart-controls.js +0 -155
- package/src/controls/discount.js +0 -96
- package/src/controls/extras.js +0 -63
- package/src/controls/navigation.js +0 -83
- package/src/diagnose-markup.js +0 -333
- package/src/diagnose.js +0 -295
- package/src/dom.js +0 -287
- package/src/extras.js +0 -145
- package/src/fragments.js +0 -237
- package/src/images.js +0 -104
- package/src/index.js +0 -353
- package/src/initial.js +0 -87
- package/src/lazy-iife.js +0 -116
- package/src/lazy.js +0 -39
- package/src/loader.js +0 -337
- package/src/market-codes.js +0 -35
- package/src/markets-ui.js +0 -204
- package/src/markets.js +0 -334
- package/src/markup.js +0 -64
- package/src/mounting.js +0 -277
- package/src/page-market.js +0 -116
- package/src/parts/account-pages.js +0 -6
- package/src/parts/account.js +0 -6
- package/src/parts/analytics.js +0 -6
- package/src/parts/diagnose.js +0 -6
- package/src/parts/extras.js +0 -6
- package/src/parts/markets.js +0 -6
- package/src/parts/search.js +0 -6
- package/src/presets/barba.js +0 -190
- package/src/product-events.js +0 -130
- package/src/product-render.js +0 -257
- package/src/product-state.js +0 -318
- package/src/product.js +0 -344
- package/src/repeaters.js +0 -173
- package/src/search.js +0 -323
- package/src/selling-plans.js +0 -154
- package/src/server.js +0 -215
- package/src/shopify-values.js +0 -89
- package/src/status.js +0 -126
- package/src/store-html.js +0 -0
- package/src/storefront/catalog.js +0 -199
- package/src/storefront/json-ld.js +0 -167
- package/src/variant-render.js +0 -165
- package/types/astro.d.ts +0 -28
- package/types/barba.d.ts +0 -16
- package/types/index.d.ts +0 -577
- package/types/server.d.ts +0 -182
package/types/index.d.ts
DELETED
|
@@ -1,577 +0,0 @@
|
|
|
1
|
-
// Type definitions for @occluze/tether
|
|
2
|
-
// Shopify Storefront API objects are typed loosely (`ShopifyProduct` etc.): Tether passes them
|
|
3
|
-
// through as Shopify returns them. See https://shopify.dev/docs/api/storefront for the full shape.
|
|
4
|
-
|
|
5
|
-
export interface Money {
|
|
6
|
-
amount: string;
|
|
7
|
-
currencyCode: string;
|
|
8
|
-
}
|
|
9
|
-
export interface ShopifyImage {
|
|
10
|
-
url: string;
|
|
11
|
-
altText?: string | null;
|
|
12
|
-
width?: number;
|
|
13
|
-
height?: number;
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
export interface ShopifySellingPlan {
|
|
17
|
-
id: string;
|
|
18
|
-
name: string;
|
|
19
|
-
description?: string | null;
|
|
20
|
-
recurringDeliveries?: boolean;
|
|
21
|
-
options: { name: string; value: string }[];
|
|
22
|
-
priceAdjustments: unknown[];
|
|
23
|
-
/** Added by Tether: the plan's group. */
|
|
24
|
-
group?: { name: string; [k: string]: unknown };
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
export interface ShopifyVariant {
|
|
28
|
-
id: string;
|
|
29
|
-
title: string;
|
|
30
|
-
availableForSale: boolean;
|
|
31
|
-
currentlyNotInStock?: boolean;
|
|
32
|
-
quantityAvailable?: number | null;
|
|
33
|
-
sku?: string | null;
|
|
34
|
-
barcode?: string | null;
|
|
35
|
-
selectedOptions: { name: string; value: string }[];
|
|
36
|
-
image?: ShopifyImage | null;
|
|
37
|
-
price: Money;
|
|
38
|
-
compareAtPrice?: Money | null;
|
|
39
|
-
unitPrice?: Money | null;
|
|
40
|
-
sellingPlanAllocations?: { nodes: unknown[] };
|
|
41
|
-
[k: string]: unknown;
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
export interface ShopifyProduct {
|
|
45
|
-
id: string;
|
|
46
|
-
handle: string;
|
|
47
|
-
title: string;
|
|
48
|
-
description: string;
|
|
49
|
-
descriptionHtml: string;
|
|
50
|
-
productType?: string;
|
|
51
|
-
vendor?: string;
|
|
52
|
-
tags: string[];
|
|
53
|
-
availableForSale: boolean;
|
|
54
|
-
requiresSellingPlan?: boolean;
|
|
55
|
-
featuredImage?: ShopifyImage | null;
|
|
56
|
-
images: { nodes: ShopifyImage[] };
|
|
57
|
-
priceRange: { minVariantPrice: Money; maxVariantPrice: Money };
|
|
58
|
-
options: { name: string; optionValues: { name: string; swatch?: unknown }[] }[];
|
|
59
|
-
variants: { nodes: ShopifyVariant[] };
|
|
60
|
-
sellingPlanGroups?: { nodes: unknown[] };
|
|
61
|
-
metafields?: ({ namespace: string; key: string; type: string; value: string; reference?: unknown } | null)[];
|
|
62
|
-
seo?: { title?: string | null; description?: string | null };
|
|
63
|
-
onlineStoreUrl?: string | null;
|
|
64
|
-
[k: string]: unknown;
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
export interface ShopifyCartLine {
|
|
68
|
-
id: string;
|
|
69
|
-
quantity: number;
|
|
70
|
-
merchandise: ShopifyVariant & { product: Pick<ShopifyProduct, 'id' | 'handle' | 'title'> & Record<string, unknown> };
|
|
71
|
-
sellingPlanAllocation?: { sellingPlan: { id: string; name: string } } | null;
|
|
72
|
-
attributes?: { key: string; value: string }[];
|
|
73
|
-
cost: {
|
|
74
|
-
totalAmount: Money;
|
|
75
|
-
subtotalAmount: Money;
|
|
76
|
-
amountPerQuantity: Money;
|
|
77
|
-
compareAtAmountPerQuantity?: Money | null;
|
|
78
|
-
};
|
|
79
|
-
[k: string]: unknown;
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
export interface ShopifyCart {
|
|
83
|
-
id: string;
|
|
84
|
-
checkoutUrl: string;
|
|
85
|
-
totalQuantity: number;
|
|
86
|
-
note?: string | null;
|
|
87
|
-
lines: { nodes: ShopifyCartLine[] };
|
|
88
|
-
cost: Record<string, Money | null | undefined>;
|
|
89
|
-
discountCodes: { code: string; applicable: boolean }[];
|
|
90
|
-
attributes: { key: string; value: string }[];
|
|
91
|
-
buyerIdentity?: { countryCode?: string | null; email?: string | null };
|
|
92
|
-
[k: string]: unknown;
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
export interface MarketsConfig {
|
|
96
|
-
/** true: saved choice, server hints, Webflow Localization. Or a list of those sources. false: off. */
|
|
97
|
-
detect?: boolean | ('saved' | 'server' | 'webflow')[];
|
|
98
|
-
/** Webflow locale (subdirectory or html lang) -> market. */
|
|
99
|
-
locales?: Record<string, { country?: string; language?: string; locale?: string }>;
|
|
100
|
-
/** Cookie with the visitor's country, set by your server (default "tether_country"). */
|
|
101
|
-
cookie?: string;
|
|
102
|
-
/** Remember the visitor's country choice (default true). */
|
|
103
|
-
remember?: boolean;
|
|
104
|
-
/** With locales: ignore an html lang that isn't in the map. */
|
|
105
|
-
strict?: boolean;
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
export interface TetherConfig {
|
|
109
|
-
/** your-store.myshopify.com */
|
|
110
|
-
domain: string;
|
|
111
|
-
/** Public Storefront API access token (never an Admin token). */
|
|
112
|
-
token: string;
|
|
113
|
-
/** Pinned Shopify API version, e.g. "2026-07". Never "unstable". */
|
|
114
|
-
apiVersion?: string;
|
|
115
|
-
/** ISO country code for prices and currency, e.g. "NL". */
|
|
116
|
-
country?: string;
|
|
117
|
-
/** Language for translated content, e.g. "NL". */
|
|
118
|
-
language?: string;
|
|
119
|
-
/** Intl locale for money and dates, e.g. "nl-NL". */
|
|
120
|
-
locale?: string;
|
|
121
|
-
markets?: MarketsConfig | null;
|
|
122
|
-
/** Attribute prefix (default "tether"). */
|
|
123
|
-
prefix?: string;
|
|
124
|
-
/** Product URL template: "/product" or "/product?handle={handle}" ({handle}, {id}). */
|
|
125
|
-
productPath?: string;
|
|
126
|
-
collectionPath?: string;
|
|
127
|
-
/** Metafields to fetch: "namespace.key" or { namespace, key }. */
|
|
128
|
-
metafields?: (string | { namespace: string; key: string })[];
|
|
129
|
-
imagesFirst?: number;
|
|
130
|
-
variantsFirst?: number;
|
|
131
|
-
sellingPlanGroupsFirst?: number;
|
|
132
|
-
sellingPlansFirst?: number;
|
|
133
|
-
collectionFirst?: number;
|
|
134
|
-
retries?: number;
|
|
135
|
-
/** Products handed over by the server (tether/server hydrate()): refresh once in the background (default true). */
|
|
136
|
-
revalidate?: boolean;
|
|
137
|
-
/** Seconds a Shopify answer may be cached (default 60). Shopify caches identical queries, prices included, for hours otherwise; 0 = Shopify's caching. */
|
|
138
|
-
maxAge?: number;
|
|
139
|
-
/** Analytics (optional part): GA4/GTM dataLayer events, Shopify's analytics (experimental), or your own handler. */
|
|
140
|
-
analytics?: {
|
|
141
|
-
dataLayer?: boolean | string;
|
|
142
|
-
shopify?: boolean | { consent?: 'no-banner' | 'default-banner' | 'custom-banner'; proxy?: string };
|
|
143
|
-
onEvent?: (name: string, data: Record<string, unknown>) => void;
|
|
144
|
-
} | null;
|
|
145
|
-
/** Customer accounts (optional part): the Headless channel's Customer Account API client id, and options. */
|
|
146
|
-
account?: {
|
|
147
|
-
/** Browser mode: the Customer Account API client id. */
|
|
148
|
-
clientId?: string;
|
|
149
|
-
/** Server mode (recommended): the Worker's account routes, a URL or a path on this site ('/_tether/account'). */
|
|
150
|
-
server?: string;
|
|
151
|
-
/** Your own order page: tether-order-bind="url" links there, e.g. '/account/order?id={id}' (else Shopify's status page). */
|
|
152
|
-
orderUrl?: string;
|
|
153
|
-
/** Shopify's subscription management page (tether-account-link="subscriptions"); payment methods are changed there too. */
|
|
154
|
-
subscriptionsUrl?: string;
|
|
155
|
-
/** A separate page for payment methods (tether-account-link="payment"); default subscriptionsUrl. */
|
|
156
|
-
paymentUrl?: string;
|
|
157
|
-
/** The page Shopify sends the visitor back to after login (registered as callback URI). Default: the current page. */
|
|
158
|
-
callbackUrl?: string;
|
|
159
|
-
/** Where Shopify sends the visitor after logout (registered as logout URI). Default: the home page. */
|
|
160
|
-
logoutUrl?: string;
|
|
161
|
-
/** Keep the login across tabs and browser restarts (localStorage instead of sessionStorage). */
|
|
162
|
-
remember?: boolean;
|
|
163
|
-
/** Your own token endpoint, if the browser can't call Shopify's (it forwards the form body). */
|
|
164
|
-
tokenUrl?: string;
|
|
165
|
-
/** The *.myshopify.com domain, if domain is something else. */
|
|
166
|
-
shopDomain?: string;
|
|
167
|
-
locale?: string;
|
|
168
|
-
/** Replaces location.assign for the login redirect (popups, tests). */
|
|
169
|
-
navigate?: (url: string) => void;
|
|
170
|
-
} | null;
|
|
171
|
-
/** tether-show="low-stock" at this many or fewer (default 5). */
|
|
172
|
-
lowStock?: number;
|
|
173
|
-
/** Milliseconds the search part waits after the last keystroke (default 150). */
|
|
174
|
-
searchDelay?: number;
|
|
175
|
-
/** true: ?variant= (and selling_plan=) follow the visitor's choice on the page's main product. */
|
|
176
|
-
variantUrl?: boolean;
|
|
177
|
-
/** Your text for Shopify's cart warnings (stock, codes), e.g. translated by code. Return nothing to keep Shopify's. */
|
|
178
|
-
warningText?: ((warning: CartWarning) => string | null | undefined) | null;
|
|
179
|
-
/** Mount on Astro View Transitions (astro:page-load) and close the cart on navigation (default true). */
|
|
180
|
-
astro?: boolean;
|
|
181
|
-
storageKey?: string | null;
|
|
182
|
-
cartDrawerOpenClass?: string;
|
|
183
|
-
openCartOnAdd?: boolean;
|
|
184
|
-
/** Move focus into the open cart, keep Tab inside it, restore it on close (default true). */
|
|
185
|
-
cartFocus?: boolean;
|
|
186
|
-
checkoutTarget?: '_self' | '_blank';
|
|
187
|
-
defaultPurchase?: 'one-time' | 'subscription';
|
|
188
|
-
/** Mount the document on DOMContentLoaded (default true). False with page transitions. */
|
|
189
|
-
autoMount?: boolean;
|
|
190
|
-
/** Mount elements added later (CMS load more, filters). */
|
|
191
|
-
observe?: boolean;
|
|
192
|
-
/** Folder of the optional parts (tether.markets.min.js, tether.diagnose.min.js) for the <script> build. */
|
|
193
|
-
partsUrl?: string | null;
|
|
194
|
-
formatMoney?: ((money: Money, locale?: string) => string) | null;
|
|
195
|
-
onLayoutChange?: ((reason: string) => void) | null;
|
|
196
|
-
onCartOpen?: ((drawers: HTMLElement[]) => void) | null;
|
|
197
|
-
onCartClose?: ((drawers: HTMLElement[]) => void) | null;
|
|
198
|
-
onLineEnter?: ((node: HTMLElement) => void) | null;
|
|
199
|
-
onLineLeave?: ((node: HTMLElement, done: () => void) => void) | null;
|
|
200
|
-
onValueChange?: ((el: HTMLElement, previousText: string) => void) | null;
|
|
201
|
-
/** Every failure that reaches the visitor. Send it to Sentry or similar. */
|
|
202
|
-
onError?: ((error: TetherError | Error, context: string) => void) | null;
|
|
203
|
-
debug?: boolean;
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
export type TetherErrorCode =
|
|
207
|
-
'NOT_FOUND' | 'NETWORK' | 'NOT_CONFIGURED' | 'INVALID_COUNTRY' | 'ERROR' | `HTTP_${number}`;
|
|
208
|
-
|
|
209
|
-
export declare class TetherError extends Error {
|
|
210
|
-
name: 'TetherError';
|
|
211
|
-
code: TetherErrorCode | string;
|
|
212
|
-
status?: number;
|
|
213
|
-
errors?: { message: string; extensions?: Record<string, unknown> }[];
|
|
214
|
-
userErrors?: { field?: string[]; message: string }[];
|
|
215
|
-
constructor(message: string, opts?: { status?: number; errors?: unknown[]; userErrors?: unknown[]; code?: string });
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
export type Attributes = Record<string, string | number | boolean> | { key: string; value: string }[];
|
|
219
|
-
|
|
220
|
-
export interface LineInput {
|
|
221
|
-
variantId?: string;
|
|
222
|
-
merchandiseId?: string;
|
|
223
|
-
quantity?: number;
|
|
224
|
-
sellingPlanId?: string | null;
|
|
225
|
-
attributes?: Attributes;
|
|
226
|
-
}
|
|
227
|
-
|
|
228
|
-
/** Shopify's note on the last cart change; target is the cart line id it's about. */
|
|
229
|
-
export interface CartWarning {
|
|
230
|
-
code: string;
|
|
231
|
-
message: string;
|
|
232
|
-
target?: string;
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
/**
|
|
236
|
-
* What the cart is known to be: `unknown` until the saved cart has loaded, `empty` without a cart, `error` after a
|
|
237
|
-
* failed load or change (with the cart as Shopify last sent it).
|
|
238
|
-
*/
|
|
239
|
-
export type CartStatus =
|
|
240
|
-
| { kind: 'unknown' }
|
|
241
|
-
| { kind: 'empty' }
|
|
242
|
-
| { kind: 'ready'; cart: ShopifyCart }
|
|
243
|
-
| { kind: 'error'; error: unknown; cart: ShopifyCart | null };
|
|
244
|
-
|
|
245
|
-
/** The logged-in customer the cart belongs to (set by the account part). */
|
|
246
|
-
export interface CustomerLink {
|
|
247
|
-
/** The Customer Account API token: carts created from now on belong to the customer. */
|
|
248
|
-
accessToken: string | null;
|
|
249
|
-
/** The account's own checkout URL; null from it, or no function, uses the cart's. */
|
|
250
|
-
beforeCheckout: (() => Promise<string | null>) | null;
|
|
251
|
-
}
|
|
252
|
-
|
|
253
|
-
export interface Cart {
|
|
254
|
-
readonly status: CartStatus;
|
|
255
|
-
readonly state: ShopifyCart | null;
|
|
256
|
-
readonly lines: ShopifyCartLine[];
|
|
257
|
-
readonly count: number;
|
|
258
|
-
lastError: Error | null;
|
|
259
|
-
/** Shopify's notes on the last change, e.g. less stock than asked (code MERCHANDISE_NOT_ENOUGH_STOCK). */
|
|
260
|
-
readonly warnings: CartWarning[];
|
|
261
|
-
/** true once the saved cart (or the absence of one) is known. */
|
|
262
|
-
readonly loaded: boolean;
|
|
263
|
-
/** Links the cart to a logged-in customer, or unlinks it with nulls. Fields left out keep their value. */
|
|
264
|
-
setCustomer(link: Partial<CustomerLink>): void;
|
|
265
|
-
id(): string | null;
|
|
266
|
-
init(): Promise<ShopifyCart | null>;
|
|
267
|
-
/** add(variantId, qty) · add({ variantId, quantity, sellingPlanId, attributes }) · add([line, line]) */
|
|
268
|
-
add(
|
|
269
|
-
input: string | LineInput | LineInput[],
|
|
270
|
-
quantity?: number,
|
|
271
|
-
opts?: Omit<LineInput, 'variantId' | 'quantity'>,
|
|
272
|
-
): Promise<ShopifyCart>;
|
|
273
|
-
/** updateLine(id, 3) · updateLine(id, { sellingPlanId: null }) switches to one-time. */
|
|
274
|
-
updateLine(lineId: string, patch: number | (LineInput & { quantity?: number })): Promise<ShopifyCart>;
|
|
275
|
-
removeLine(lineIds: string | string[]): Promise<ShopifyCart>;
|
|
276
|
-
/** +1 / -1 for a line; quick clicks add up and show at once (use it for your own +/- buttons). */
|
|
277
|
-
changeQuantity(lineId: string, delta: number): Promise<ShopifyCart | null>;
|
|
278
|
-
/** The quantity to show for a line: what the visitor asked for while an update is on its way. */
|
|
279
|
-
quantityOf(line: ShopifyCartLine): number;
|
|
280
|
-
clear(): Promise<ShopifyCart | null>;
|
|
281
|
-
setNote(note: string): Promise<ShopifyCart>;
|
|
282
|
-
setAttributes(attributes: Attributes): Promise<ShopifyCart>;
|
|
283
|
-
setDiscountCodes(codes: string[]): Promise<ShopifyCart>;
|
|
284
|
-
/** Rejects with code INVALID_DISCOUNT (and doesn't keep the code) when Shopify doesn't accept it. */
|
|
285
|
-
applyDiscount(code: string): Promise<ShopifyCart>;
|
|
286
|
-
removeDiscount(code: string): Promise<ShopifyCart>;
|
|
287
|
-
setBuyerIdentity(
|
|
288
|
-
identity: { countryCode?: string; email?: string; phone?: string },
|
|
289
|
-
opts?: { create?: boolean },
|
|
290
|
-
): Promise<ShopifyCart | null>;
|
|
291
|
-
checkout(target?: '_self' | '_blank'): Promise<void>;
|
|
292
|
-
open(): void;
|
|
293
|
-
close(): void;
|
|
294
|
-
toggle(): void;
|
|
295
|
-
isOpen(): boolean;
|
|
296
|
-
drawers(): HTMLElement[];
|
|
297
|
-
render(): void;
|
|
298
|
-
/** For framework islands: fn(cart, meta) now, when the saved cart has loaded and after every change. Returns unsubscribe. */
|
|
299
|
-
subscribe(
|
|
300
|
-
fn: (
|
|
301
|
-
cart: ShopifyCart | null,
|
|
302
|
-
meta: { open: boolean; count: number; loaded: boolean; warnings: CartWarning[] },
|
|
303
|
-
) => void,
|
|
304
|
-
): () => void;
|
|
305
|
-
}
|
|
306
|
-
|
|
307
|
-
export interface ProductScope {
|
|
308
|
-
readonly root: HTMLElement;
|
|
309
|
-
product: ShopifyProduct;
|
|
310
|
-
variant: ShopifyVariant | null;
|
|
311
|
-
selected: Record<string, string>;
|
|
312
|
-
quantity: number;
|
|
313
|
-
plans: ShopifySellingPlan[];
|
|
314
|
-
purchase: 'one-time' | 'subscription';
|
|
315
|
-
planId: string | null;
|
|
316
|
-
readonly plan: ShopifySellingPlan | null;
|
|
317
|
-
readonly isSubscription: boolean;
|
|
318
|
-
readonly subscriptionAvailable: boolean;
|
|
319
|
-
select(option: string, value: string): void;
|
|
320
|
-
selectVariant(id: string): void;
|
|
321
|
-
setPurchase(mode: 'one-time' | 'subscription'): void;
|
|
322
|
-
selectPlan(ref: string): void;
|
|
323
|
-
setQuantity(n: number | string): void;
|
|
324
|
-
getLine(): LineInput | null;
|
|
325
|
-
addToCart(): Promise<ShopifyCart | null>;
|
|
326
|
-
update(product: ShopifyProduct): void;
|
|
327
|
-
}
|
|
328
|
-
|
|
329
|
-
export interface SellingPlanHelpers {
|
|
330
|
-
allPlans(product: ShopifyProduct): ShopifySellingPlan[];
|
|
331
|
-
hasPlans(product: ShopifyProduct): boolean;
|
|
332
|
-
allocationFor(variant: ShopifyVariant, planId: string | null): unknown | null;
|
|
333
|
-
plansForVariant(product: ShopifyProduct, variant: ShopifyVariant): ShopifySellingPlan[];
|
|
334
|
-
planPrice(variant: ShopifyVariant, planId: string): Money | null;
|
|
335
|
-
planCheckoutCharge(variant: ShopifyVariant, planId: string): Money | null;
|
|
336
|
-
planSavings(variant: ShopifyVariant, planId: string): { amount: Money | null; percentage: number };
|
|
337
|
-
planAdjustment(
|
|
338
|
-
plan: ShopifySellingPlan | null | undefined,
|
|
339
|
-
): { type: 'percentage' | 'amount' | 'price'; value: number | Money } | null;
|
|
340
|
-
findPlan(product: ShopifyProduct, ref: string | null | undefined): ShopifySellingPlan | null;
|
|
341
|
-
toGid(value: string | number, type: string): string | null;
|
|
342
|
-
GID: {
|
|
343
|
-
product(v: string | number): string | null;
|
|
344
|
-
variant(v: string | number): string | null;
|
|
345
|
-
sellingPlan(v: string | number): string | null;
|
|
346
|
-
};
|
|
347
|
-
}
|
|
348
|
-
|
|
349
|
-
export interface ProductPage {
|
|
350
|
-
collection: Record<string, unknown> | null;
|
|
351
|
-
products: ShopifyProduct[];
|
|
352
|
-
pageInfo: { hasNextPage: boolean; endCursor: string | null };
|
|
353
|
-
}
|
|
354
|
-
|
|
355
|
-
export interface Localization {
|
|
356
|
-
country?: { isoCode: string; name: string; currency?: { isoCode: string; symbol: string } };
|
|
357
|
-
language?: { isoCode: string; name: string };
|
|
358
|
-
availableCountries: {
|
|
359
|
-
isoCode: string;
|
|
360
|
-
name: string;
|
|
361
|
-
currency?: { isoCode: string; symbol: string };
|
|
362
|
-
availableLanguages?: { isoCode: string; name: string }[];
|
|
363
|
-
}[];
|
|
364
|
-
}
|
|
365
|
-
|
|
366
|
-
export type MarketSource = 'saved' | 'server' | 'webflow';
|
|
367
|
-
|
|
368
|
-
/** The market fields detection found, and the source each came from (no sources with detect: false). */
|
|
369
|
-
export interface DetectedMarket {
|
|
370
|
-
country?: string;
|
|
371
|
-
language?: string;
|
|
372
|
-
locale?: string;
|
|
373
|
-
sources?: Partial<Record<'country' | 'language' | 'locale', MarketSource>>;
|
|
374
|
-
}
|
|
375
|
-
|
|
376
|
-
export interface DiagnoseReport {
|
|
377
|
-
version: string;
|
|
378
|
-
config: Record<string, unknown>;
|
|
379
|
-
apiVersion: { version: string; ok: boolean; monthsLeft?: number; next?: string; note: string };
|
|
380
|
-
/** The market in use (a visitor's choice included), and what detection would pick (null without markets.detect). */
|
|
381
|
-
market: { country: string | null; language: string | null; locale: string | null; detected: DetectedMarket | null };
|
|
382
|
-
reachable: boolean;
|
|
383
|
-
shop: { name?: string; url?: string; currency?: string } | null;
|
|
384
|
-
latencyMs: number | null;
|
|
385
|
-
products: {
|
|
386
|
-
key: string;
|
|
387
|
-
handle?: string;
|
|
388
|
-
title?: string;
|
|
389
|
-
plans?: number;
|
|
390
|
-
requiresSellingPlan?: boolean;
|
|
391
|
-
error?: string;
|
|
392
|
-
}[];
|
|
393
|
-
sellingPlans: { product: string; group?: string; plan: string; id: string }[];
|
|
394
|
-
problems: { level: 'error' | 'warn'; message: string; element?: string }[];
|
|
395
|
-
}
|
|
396
|
-
|
|
397
|
-
/** Events on document, as `tether:<name>` (or your prefix). Detail types for Tether.on(). */
|
|
398
|
-
export interface TetherEvents {
|
|
399
|
-
ready: { cart: ShopifyCart | null };
|
|
400
|
-
'product-ready': { product: ShopifyProduct; scope: ProductScope };
|
|
401
|
-
'product-updated': { product: ShopifyProduct; scope: ProductScope };
|
|
402
|
-
'product-not-found': { key: string | null; source: string };
|
|
403
|
-
'variant-changed': {
|
|
404
|
-
product: ShopifyProduct;
|
|
405
|
-
variant: ShopifyVariant;
|
|
406
|
-
selected: Record<string, string>;
|
|
407
|
-
purchase: 'one-time' | 'subscription';
|
|
408
|
-
sellingPlanId: string | null;
|
|
409
|
-
};
|
|
410
|
-
'product-added': { product: ShopifyProduct; variant: ShopifyVariant; line: LineInput };
|
|
411
|
-
added: { cart: ShopifyCart; lines: LineInput[] };
|
|
412
|
-
'group-added': { group: string | null; lines: LineInput[] };
|
|
413
|
-
'cart-warning': { warnings: CartWarning[] };
|
|
414
|
-
'cart-updated': { cart: ShopifyCart | null; reason: string };
|
|
415
|
-
'cart-toggled': { open: boolean };
|
|
416
|
-
'cart-error': { error: Error };
|
|
417
|
-
checkout: { url: string; cart: ShopifyCart };
|
|
418
|
-
'list-ready': { products: ShopifyProduct[]; collection: Record<string, unknown> | null };
|
|
419
|
-
'country-changed': { country: string; language?: string };
|
|
420
|
-
'discount-applied': { code: string };
|
|
421
|
-
'discount-invalid': { code: string };
|
|
422
|
-
'layout-changed': { reason: string };
|
|
423
|
-
error: { error: Error; context: string; key?: string };
|
|
424
|
-
}
|
|
425
|
-
|
|
426
|
-
export interface Tether {
|
|
427
|
-
readonly VERSION: string;
|
|
428
|
-
/** Configure (window.TETHER_CONFIG + overrides) and load the cart. */
|
|
429
|
-
init(overrides?: Partial<TetherConfig>): Promise<Tether | null>;
|
|
430
|
-
/** Mount product scopes and lists inside root (call per page container with Barba/Swup). */
|
|
431
|
-
mount(root?: ParentNode): number;
|
|
432
|
-
/** Call before a page transition removes the page (closes the cart drawer). */
|
|
433
|
-
unmount(): void;
|
|
434
|
-
readonly config: TetherConfig;
|
|
435
|
-
readonly ready: Promise<Tether | null>;
|
|
436
|
-
/** Any Storefront API query, with @inContext added for the current market. */
|
|
437
|
-
query<T = any>(query: string, variables?: Record<string, unknown>, opts?: { context?: boolean }): Promise<T>;
|
|
438
|
-
withContext(query: string, ctx?: { country?: string; language?: string }): string;
|
|
439
|
-
cart: Cart;
|
|
440
|
-
getProduct(handleOrId: string): Promise<ShopifyProduct>;
|
|
441
|
-
getProducts(opts?: {
|
|
442
|
-
collection?: string;
|
|
443
|
-
query?: string;
|
|
444
|
-
first?: number;
|
|
445
|
-
after?: string | null;
|
|
446
|
-
sortKey?: string;
|
|
447
|
-
reverse?: boolean;
|
|
448
|
-
filters?: unknown[];
|
|
449
|
-
}): Promise<ProductPage>;
|
|
450
|
-
getRecommendations(
|
|
451
|
-
product: string | Pick<ShopifyProduct, 'id'>,
|
|
452
|
-
intent?: 'RELATED' | 'COMPLEMENTARY',
|
|
453
|
-
): Promise<ShopifyProduct[]>;
|
|
454
|
-
getScope(el: Element | null | undefined): ProductScope | null;
|
|
455
|
-
addGroup(button: Element): Promise<ShopifyCart | null>;
|
|
456
|
-
/** Customer accounts (loads the account part): login(), logout(), customer(), orders(), query(gql, vars), getToken(). */
|
|
457
|
-
account: {
|
|
458
|
-
login(opts?: { returnTo?: string; locale?: string }): Promise<void>;
|
|
459
|
-
logout(opts?: { returnTo?: string }): Promise<void>;
|
|
460
|
-
customer(): Promise<{
|
|
461
|
-
id: string;
|
|
462
|
-
firstName?: string | null;
|
|
463
|
-
lastName?: string | null;
|
|
464
|
-
displayName?: string;
|
|
465
|
-
emailAddress?: { emailAddress: string } | null;
|
|
466
|
-
} | null>;
|
|
467
|
-
orders(opts?: { first?: number }): Promise<
|
|
468
|
-
Array<{
|
|
469
|
-
id: string;
|
|
470
|
-
name: string;
|
|
471
|
-
processedAt: string;
|
|
472
|
-
financialStatus?: string;
|
|
473
|
-
fulfillmentStatus?: string;
|
|
474
|
-
statusPageUrl: string;
|
|
475
|
-
totalPrice: Money;
|
|
476
|
-
}>
|
|
477
|
-
>;
|
|
478
|
-
query<T = any>(query: string, variables?: Record<string, unknown>): Promise<T>;
|
|
479
|
-
getToken(): Promise<string | null>;
|
|
480
|
-
/** True while a customer is logged in, as far as this page knows without asking. */
|
|
481
|
-
isLoggedIn(): Promise<boolean>;
|
|
482
|
-
/** Finishes a login coming back from Shopify (browser mode); true when there was one. */
|
|
483
|
-
handleCallback(): Promise<boolean>;
|
|
484
|
-
/** Fills the account markup in root: logged-in/out content, the customer, orders and the account pages. */
|
|
485
|
-
render(root?: ParentNode): Promise<void>;
|
|
486
|
-
/** What mount() runs: finishes a login coming back on the first call, then renders root. */
|
|
487
|
-
mountAccount(root?: ParentNode): Promise<void>;
|
|
488
|
-
/** One order in full (lines, totals, addresses, fulfillments with tracking, returnable lines); null if not the customer's. */
|
|
489
|
-
order(id: string | number): Promise<Record<string, any> | null>;
|
|
490
|
-
updateProfile(fields: {
|
|
491
|
-
firstName?: string;
|
|
492
|
-
lastName?: string;
|
|
493
|
-
}): Promise<{ firstName?: string | null; lastName?: string | null }>;
|
|
494
|
-
addresses(): Promise<Array<CustomerAddress & { isDefault: boolean }>>;
|
|
495
|
-
saveAddress(
|
|
496
|
-
address: Partial<CustomerAddressInput> | null,
|
|
497
|
-
opts?: { id?: string; isDefault?: boolean },
|
|
498
|
-
): Promise<CustomerAddress>;
|
|
499
|
-
deleteAddress(id: string): Promise<string>;
|
|
500
|
-
subscriptions(): Promise<Array<Record<string, any>>>;
|
|
501
|
-
subscriptionAction(
|
|
502
|
-
id: string | number,
|
|
503
|
-
action: 'pause' | 'resume' | 'skip' | 'unskip' | 'cancel',
|
|
504
|
-
): Promise<Record<string, any>>;
|
|
505
|
-
requestReturn(
|
|
506
|
-
orderId: string | number,
|
|
507
|
-
lines: Array<{ lineItemId: string; quantity: number; reasonId?: string; note?: string }>,
|
|
508
|
-
): Promise<{ id: string; status: string }>;
|
|
509
|
-
};
|
|
510
|
-
primeProduct(product: ShopifyProduct): void;
|
|
511
|
-
normalizeProductKey(raw: string | number): string | null;
|
|
512
|
-
clearProductCache(): void;
|
|
513
|
-
formatMoney(money: Money | null | undefined): string;
|
|
514
|
-
/** Shopify CDN image at a size: imageUrl(line.merchandise.image?.url, { width: 160 }). */
|
|
515
|
-
imageUrl(url: string | null | undefined, size?: { width?: number; height?: number; crop?: string }): string;
|
|
516
|
-
plans: SellingPlanHelpers;
|
|
517
|
-
TetherError: typeof TetherError;
|
|
518
|
-
resolveProductKey(el: Element, location?: Location | URL): { key: string | null; fromUrl: boolean; raw: string };
|
|
519
|
-
/** Switch market: prices, currency, cart and every product on the page follow. */
|
|
520
|
-
setCountry(code: string, opts?: SetCountryOptions): Promise<ShopifyCart | null>;
|
|
521
|
-
detectMarket(markets?: MarketsConfig | null): Promise<DetectedMarket>;
|
|
522
|
-
getLocalization(): Promise<Localization>;
|
|
523
|
-
/** Logs and returns what's wrong on this page (config, token, API version, plans, markup). */
|
|
524
|
-
diagnose(opts?: { root?: ParentNode; silent?: boolean }): Promise<DiagnoseReport>;
|
|
525
|
-
/** Listen to a Tether event; returns a function that stops listening. */
|
|
526
|
-
on<K extends keyof TetherEvents>(
|
|
527
|
-
name: K,
|
|
528
|
-
fn: (detail: TetherEvents[K], event: CustomEvent<TetherEvents[K]>) => void,
|
|
529
|
-
): () => void;
|
|
530
|
-
on(name: string, fn: (detail: any, event: CustomEvent) => void): () => void;
|
|
531
|
-
}
|
|
532
|
-
|
|
533
|
-
export declare const VERSION: string;
|
|
534
|
-
export declare function init(overrides?: Partial<TetherConfig>): Promise<Tether | null>;
|
|
535
|
-
export declare function mount(root?: ParentNode): number;
|
|
536
|
-
export declare function unmount(): void;
|
|
537
|
-
export declare function getScope(el: Element | null | undefined): ProductScope | null;
|
|
538
|
-
export declare function addGroup(button: Element): Promise<ShopifyCart | null>;
|
|
539
|
-
export interface SetCountryOptions {
|
|
540
|
-
/** Shopify language (translations); null clears it. Default: the markets.locales entry for that country, else unchanged. */
|
|
541
|
-
language?: string | null;
|
|
542
|
-
/** Money format, e.g. 'de-DE'. Default: the markets.locales entry for that country, else unchanged. */
|
|
543
|
-
locale?: string;
|
|
544
|
-
remember?: boolean;
|
|
545
|
-
}
|
|
546
|
-
export declare function setCountry(code: string, opts?: SetCountryOptions): Promise<ShopifyCart | null>;
|
|
547
|
-
export declare const api: Tether;
|
|
548
|
-
declare const tether: Tether;
|
|
549
|
-
export default tether;
|
|
550
|
-
|
|
551
|
-
declare global {
|
|
552
|
-
interface Window {
|
|
553
|
-
Tether: Tether;
|
|
554
|
-
TETHER_CONFIG?: Partial<TetherConfig>;
|
|
555
|
-
TETHER_COUNTRY?: string;
|
|
556
|
-
TETHER_LANGUAGE?: string;
|
|
557
|
-
}
|
|
558
|
-
}
|
|
559
|
-
|
|
560
|
-
export interface CustomerAddressInput {
|
|
561
|
-
firstName: string;
|
|
562
|
-
lastName: string;
|
|
563
|
-
company: string;
|
|
564
|
-
address1: string;
|
|
565
|
-
address2: string;
|
|
566
|
-
city: string;
|
|
567
|
-
zip: string;
|
|
568
|
-
zoneCode: string;
|
|
569
|
-
countryCode: string;
|
|
570
|
-
phoneNumber: string;
|
|
571
|
-
}
|
|
572
|
-
export interface CustomerAddress extends Partial<CustomerAddressInput> {
|
|
573
|
-
id: string;
|
|
574
|
-
province?: string | null;
|
|
575
|
-
country?: string | null;
|
|
576
|
-
formatted: string[];
|
|
577
|
-
}
|