@occluze/tether 0.6.7 → 0.7.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 +11 -11
- package/dist/esm/astro.js +2 -2
- package/dist/esm/chunks/account-UIPWJQ3Y.js +1 -0
- package/dist/esm/chunks/account-pages-6ROA6Y4V.js +1 -0
- package/dist/esm/chunks/analytics-2V632IRV.js +1 -0
- package/dist/esm/chunks/chunk-4GCXM764.js +1 -0
- package/dist/esm/chunks/chunk-56FCLJJD.js +1 -0
- package/dist/esm/chunks/chunk-5Z5O3767.js +1 -0
- package/dist/esm/chunks/chunk-6OZJCAGZ.js +1 -0
- package/dist/esm/chunks/chunk-A5SYCVQM.js +1 -0
- package/dist/esm/chunks/chunk-BA4LQJJQ.js +1 -0
- package/dist/esm/chunks/chunk-BFTZR4OB.js +4 -0
- package/dist/esm/chunks/chunk-C5JYQCWH.js +1 -0
- package/dist/esm/chunks/chunk-E5YO6274.js +1 -0
- package/dist/esm/chunks/chunk-MPDWM2NN.js +1 -0
- package/dist/esm/chunks/chunk-T44MUL4Y.js +1 -0
- package/dist/esm/chunks/chunk-YLUULATY.js +1 -0
- package/dist/esm/chunks/diagnose-3FEKRIEK.js +14 -0
- package/dist/esm/chunks/extras-6POFBNOP.js +1 -0
- package/dist/esm/chunks/markets-ui-FD6NI2OG.js +1 -0
- package/dist/esm/chunks/search-UJ73YBQ5.js +1 -0
- package/dist/esm/index.js +1 -1
- package/dist/esm/server.js +2 -1
- package/dist/presets/barba.esm.js +55 -39
- package/dist/tether.account-pages.js +781 -495
- package/dist/tether.account-pages.min.js +1 -1
- package/dist/tether.account.js +462 -381
- package/dist/tether.account.min.js +1 -1
- package/dist/tether.analytics.js +299 -194
- package/dist/tether.analytics.min.js +1 -1
- package/dist/tether.diagnose.js +354 -262
- package/dist/tether.diagnose.min.js +2 -2
- package/dist/tether.extras.js +82 -45
- package/dist/tether.extras.min.js +1 -1
- package/dist/tether.js +3653 -2116
- package/dist/tether.markets.js +238 -150
- package/dist/tether.markets.min.js +1 -1
- package/dist/tether.min.js +3 -3
- package/dist/tether.min.js.map +4 -4
- package/dist/tether.search.js +207 -136
- 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/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 +79 -0
- package/dist/types/src/cart/render.d.ts +17 -0
- package/dist/types/src/cart/store.d.ts +182 -0
- package/dist/types/src/cart.d.ts +106 -0
- package/dist/types/src/client.d.ts +100 -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 +185 -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 +88 -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 +42 -22
- package/src/account/addresses-view.ts +58 -0
- package/src/account/answers.ts +79 -0
- package/src/account/markup.ts +36 -0
- package/src/account/operations.ts +145 -0
- package/src/account/order-lines.ts +75 -0
- package/src/account/order-list.ts +107 -0
- package/src/account/order-page.ts +137 -0
- package/src/account/page-answers.ts +317 -0
- package/src/account/page-events.ts +253 -0
- package/src/account/server-client.ts +183 -0
- package/src/account/subscriptions-view.ts +115 -0
- package/src/account-api.ts +98 -0
- package/src/account-marks.ts +35 -0
- package/src/account-pages.ts +81 -0
- package/src/account.ts +284 -0
- package/src/amounts.ts +64 -0
- package/src/analytics-shopify.ts +246 -0
- package/src/analytics.ts +315 -0
- package/src/api-version.ts +79 -0
- package/src/astro.ts +272 -0
- package/src/cart/cart-shape.ts +25 -0
- package/src/cart/checkout.ts +101 -0
- package/src/cart/drawer.ts +125 -0
- package/src/cart/mutations.ts +237 -0
- package/src/cart/render.ts +266 -0
- package/src/cart/store.ts +279 -0
- package/src/cart.ts +345 -0
- package/src/client.ts +391 -0
- package/src/collection.ts +175 -0
- package/src/config-sections.ts +284 -0
- package/src/config.ts +480 -0
- package/src/controls/cart-controls.ts +123 -0
- package/src/controls/discount.ts +75 -0
- package/src/controls/extras.ts +54 -0
- package/src/controls/navigation.ts +77 -0
- package/src/diagnose-markup.ts +298 -0
- package/src/diagnose.ts +294 -0
- package/src/dom.ts +268 -0
- package/src/extras.ts +136 -0
- package/src/fragments.ts +261 -0
- package/src/globals.d.ts +15 -0
- package/src/images.ts +91 -0
- package/src/index.ts +415 -0
- package/src/initial.ts +101 -0
- package/src/lazy-iife.ts +197 -0
- package/src/lazy.ts +42 -0
- package/src/loader.ts +363 -0
- package/src/market-codes.ts +6 -0
- package/src/markets-ui.ts +227 -0
- package/src/markets.ts +246 -0
- package/src/markup.ts +127 -0
- package/src/mounting.ts +264 -0
- package/src/page-market.ts +110 -0
- package/src/part-integrity.ts +7 -0
- package/src/parts/account-pages.ts +7 -0
- package/src/parts/account.ts +7 -0
- package/src/parts/analytics.ts +7 -0
- package/src/parts/diagnose.ts +7 -0
- package/src/parts/extras.ts +7 -0
- package/src/parts/markets.ts +7 -0
- package/src/parts/search.ts +7 -0
- package/src/presets/barba.ts +194 -0
- package/src/product-events.ts +115 -0
- package/src/product-render.ts +218 -0
- package/src/product-shape.ts +49 -0
- package/src/product-state.ts +318 -0
- package/src/product.ts +308 -0
- package/src/repeaters.ts +161 -0
- package/src/search.ts +305 -0
- package/src/selling-plans.ts +145 -0
- package/src/server.ts +211 -0
- package/src/shopify-values.ts +91 -0
- package/src/status.ts +106 -0
- package/src/storage.ts +34 -0
- package/src/store-html.ts +359 -0
- package/src/storefront/catalog.ts +196 -0
- package/src/storefront/json-ld.ts +144 -0
- package/src/variant-render.ts +139 -0
- package/dist/esm/chunks/account-Q6E2TFEV.js +0 -1
- package/dist/esm/chunks/account-pages-UZXR4R5F.js +0 -1
- package/dist/esm/chunks/analytics-IJBKATUP.js +0 -1
- package/dist/esm/chunks/chunk-4QJKLPYR.js +0 -1
- package/dist/esm/chunks/chunk-64TUD3QR.js +0 -1
- package/dist/esm/chunks/chunk-AJLPU2JC.js +0 -4
- package/dist/esm/chunks/chunk-FIOZPPC5.js +0 -1
- package/dist/esm/chunks/chunk-K2YEQAIH.js +0 -1
- package/dist/esm/chunks/chunk-KIDH76B7.js +0 -1
- package/dist/esm/chunks/chunk-PAYT5ZD7.js +0 -1
- package/dist/esm/chunks/chunk-RREHGH4A.js +0 -1
- package/dist/esm/chunks/chunk-SSJT43CJ.js +0 -1
- package/dist/esm/chunks/chunk-VC46IEJQ.js +0 -1
- package/dist/esm/chunks/diagnose-3WVAWNTX.js +0 -14
- package/dist/esm/chunks/extras-7I7WJX35.js +0 -1
- package/dist/esm/chunks/markets-ui-545XLFTE.js +0 -1
- package/dist/esm/chunks/search-NILMGYXG.js +0 -1
- package/src/account-pages.js +0 -318
- package/src/account.js +0 -385
- package/src/analytics.js +0 -232
- package/src/api-version.js +0 -35
- package/src/astro.js +0 -101
- package/src/cart.js +0 -559
- package/src/client.js +0 -131
- package/src/collection.js +0 -114
- package/src/config.js +0 -85
- package/src/diagnose.js +0 -246
- package/src/dom.js +0 -288
- package/src/extras.js +0 -63
- package/src/fragments.js +0 -144
- package/src/index.js +0 -395
- package/src/initial.js +0 -75
- package/src/lazy-iife.js +0 -46
- package/src/lazy.js +0 -18
- package/src/loader.js +0 -198
- package/src/markets-ui.js +0 -90
- package/src/markets.js +0 -133
- package/src/mounting.js +0 -154
- package/src/parts/account-pages.js +0 -3
- package/src/parts/account.js +0 -3
- package/src/parts/analytics.js +0 -3
- package/src/parts/diagnose.js +0 -3
- package/src/parts/extras.js +0 -3
- package/src/parts/markets.js +0 -3
- package/src/parts/search.js +0 -3
- package/src/presets/barba.js +0 -100
- package/src/product.js +0 -570
- package/src/search.js +0 -153
- package/src/selling-plans.js +0 -94
- package/src/server.js +0 -252
- package/src/status.js +0 -66
- package/types/astro.d.ts +0 -17
- package/types/barba.d.ts +0 -16
- package/types/index.d.ts +0 -426
- package/types/server.d.ts +0 -110
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import type { TetherOptions } from './config.js';
|
|
2
|
+
import type { StorefrontOptions } from './server.js';
|
|
3
|
+
interface AstroLogger {
|
|
4
|
+
warn: (message: string) => void;
|
|
5
|
+
}
|
|
6
|
+
/** The argument of Astro's `astro:config:setup` hook. */
|
|
7
|
+
interface AstroConfigSetup {
|
|
8
|
+
injectScript: (stage: 'head-inline' | 'page', content: string) => void;
|
|
9
|
+
/** `dev`, `build`, `preview` or `sync`. */
|
|
10
|
+
command: string;
|
|
11
|
+
config: {
|
|
12
|
+
root?: URL;
|
|
13
|
+
};
|
|
14
|
+
logger: AstroLogger;
|
|
15
|
+
addWatchFile?: (path: string) => void;
|
|
16
|
+
/** Takes a partial Astro config. A method, so that Astro's own `DeepPartial<AstroConfig>` parameter fits. */
|
|
17
|
+
updateConfig?(config: {
|
|
18
|
+
env?: {
|
|
19
|
+
schema?: Record<string, unknown>;
|
|
20
|
+
};
|
|
21
|
+
}): unknown;
|
|
22
|
+
}
|
|
23
|
+
/** The config options a page can be handed as JSON: all but the functions. */
|
|
24
|
+
type SerializableOptions = {
|
|
25
|
+
[Key in keyof TetherOptions as Exclude<TetherOptions[Key], null | undefined> extends (...args: never[]) => unknown ? never : Key]?: TetherOptions[Key];
|
|
26
|
+
};
|
|
27
|
+
/** `createStorefront()`'s own options that a config shared with it may hold, which the page leaves out. */
|
|
28
|
+
type ServerOnlyOptions = Pick<StorefrontOptions, 'siteUrl' | 'pageSize'>;
|
|
29
|
+
/** Tether's serializable config and the storefront's own options, plus the integration's own options. */
|
|
30
|
+
interface TetherAstroOptions extends SerializableOptions, ServerOnlyOptions {
|
|
31
|
+
/** Add the Tether script to every page (default true). */
|
|
32
|
+
inject?: boolean;
|
|
33
|
+
/** Files that restart the dev server when they change. */
|
|
34
|
+
watch?: string[] | null;
|
|
35
|
+
}
|
|
36
|
+
export type { TetherAstroOptions, AstroConfigSetup };
|
|
37
|
+
export default function tether(options?: TetherAstroOptions): {
|
|
38
|
+
name: string;
|
|
39
|
+
hooks: {
|
|
40
|
+
'astro:config:setup': (setup: AstroConfigSetup) => Promise<void>;
|
|
41
|
+
};
|
|
42
|
+
};
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
export declare const CART: {
|
|
2
|
+
readonly id: "string";
|
|
3
|
+
readonly checkoutUrl: "string";
|
|
4
|
+
readonly totalQuantity: "number";
|
|
5
|
+
readonly attributes: readonly ["object"];
|
|
6
|
+
readonly discountCodes: readonly ["object"];
|
|
7
|
+
readonly cost: {
|
|
8
|
+
readonly totalAmount: {
|
|
9
|
+
readonly amount: "string";
|
|
10
|
+
readonly currencyCode: "string";
|
|
11
|
+
};
|
|
12
|
+
readonly subtotalAmount: {
|
|
13
|
+
readonly amount: "string";
|
|
14
|
+
readonly currencyCode: "string";
|
|
15
|
+
};
|
|
16
|
+
};
|
|
17
|
+
readonly lines: {
|
|
18
|
+
readonly nodes: readonly [{
|
|
19
|
+
readonly id: "string";
|
|
20
|
+
readonly quantity: "number";
|
|
21
|
+
readonly attributes: readonly ["object"];
|
|
22
|
+
readonly cost: {
|
|
23
|
+
readonly totalAmount: {
|
|
24
|
+
readonly amount: "string";
|
|
25
|
+
readonly currencyCode: "string";
|
|
26
|
+
};
|
|
27
|
+
readonly subtotalAmount: {
|
|
28
|
+
readonly amount: "string";
|
|
29
|
+
readonly currencyCode: "string";
|
|
30
|
+
};
|
|
31
|
+
readonly amountPerQuantity: {
|
|
32
|
+
readonly amount: "string";
|
|
33
|
+
readonly currencyCode: "string";
|
|
34
|
+
};
|
|
35
|
+
};
|
|
36
|
+
readonly merchandise: {
|
|
37
|
+
readonly id: "string";
|
|
38
|
+
readonly selectedOptions: readonly ["object"];
|
|
39
|
+
readonly product: "object";
|
|
40
|
+
};
|
|
41
|
+
}];
|
|
42
|
+
};
|
|
43
|
+
};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { CheckoutTarget } from '../config.js';
|
|
2
|
+
/**
|
|
3
|
+
* The logged-in customer's checkout URL for the cart; `null` when nobody is logged in, so the cart's own checkout URL
|
|
4
|
+
* is used.
|
|
5
|
+
*/
|
|
6
|
+
type CheckoutResolver = () => Promise<string | null>;
|
|
7
|
+
/** Sets the account part's checkout URL, or clears it with `null`. A URL it answers opens checkout logged in. */
|
|
8
|
+
export declare function setCheckoutResolver(resolver: CheckoutResolver | null): void;
|
|
9
|
+
/**
|
|
10
|
+
* Goes to Shopify's checkout. With `_blank` the tab opens inside the click (Safari blocks `window.open` after an
|
|
11
|
+
* await) and gets its URL once there is one.
|
|
12
|
+
*
|
|
13
|
+
* @returns The checkout URL, `null` with nothing to check out or after a reported failure.
|
|
14
|
+
*/
|
|
15
|
+
export declare function checkout(target?: CheckoutTarget): Promise<string | null>;
|
|
16
|
+
export {};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/** Every cart drawer on the page. */
|
|
2
|
+
export declare const drawers: () => HTMLElement[];
|
|
3
|
+
/** True while a drawer, or the drawer-less cart, is open. */
|
|
4
|
+
export declare function isOpen(): boolean;
|
|
5
|
+
/**
|
|
6
|
+
* `aria-expanded` on the open buttons, and dialog semantics on the drawers unless their markup has its own. A closed
|
|
7
|
+
* drawer is hidden from screen readers and, with `cartFocus`, out of the Tab order (inert), like a closed dialog.
|
|
8
|
+
*/
|
|
9
|
+
export declare function syncDrawerAria(open: boolean): void;
|
|
10
|
+
/** Opens every drawer except `tether-cart-drawer="manual"` ones, which the site opens itself. */
|
|
11
|
+
export declare function openCart(): void;
|
|
12
|
+
export declare function closeCart(): void;
|
|
13
|
+
export declare function toggleCart(): void;
|
|
14
|
+
/**
|
|
15
|
+
* Keeps Tab inside the open drawer (`cartFocus`): from the last focusable element it wraps to the first, with Shift
|
|
16
|
+
* from the first to the last, and from outside the drawer it goes in. For a document `keydown` listener.
|
|
17
|
+
*/
|
|
18
|
+
export declare function trapFocus(event: KeyboardEvent): void;
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import type { AttributeValue } from '../dom.js';
|
|
2
|
+
import type { ShopifyCart, Attribute } from './store.js';
|
|
3
|
+
export type Attributes = Record<string, AttributeValue> | {
|
|
4
|
+
key: string | number;
|
|
5
|
+
value?: AttributeValue;
|
|
6
|
+
}[];
|
|
7
|
+
/** A line to add, in any of the shapes `Cart.add` takes. */
|
|
8
|
+
export interface LineSpec {
|
|
9
|
+
variantId?: string | number;
|
|
10
|
+
merchandiseId?: string | number;
|
|
11
|
+
id?: string | number;
|
|
12
|
+
quantity?: number | string;
|
|
13
|
+
sellingPlanId?: string | number | null;
|
|
14
|
+
sellingPlan?: string | number | null;
|
|
15
|
+
attributes?: Attributes | null;
|
|
16
|
+
}
|
|
17
|
+
/** Shopify's `CartLineInput`. */
|
|
18
|
+
export interface CartLineInput {
|
|
19
|
+
merchandiseId: string;
|
|
20
|
+
quantity: number;
|
|
21
|
+
sellingPlanId?: string;
|
|
22
|
+
attributes?: Attribute[];
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* @returns True when `error` says Shopify doesn't have the cart, false for any other failure (the network, the token,
|
|
26
|
+
* a line it refused), after which the saved cart is still good.
|
|
27
|
+
*/
|
|
28
|
+
export declare function isCartGone(error: unknown): boolean;
|
|
29
|
+
/**
|
|
30
|
+
* @param input A variant id, or a line.
|
|
31
|
+
* @param quantity For a variant id.
|
|
32
|
+
* @param options For a variant id.
|
|
33
|
+
* @throws {TetherError} `ERROR` without a variant id.
|
|
34
|
+
*/
|
|
35
|
+
export declare function toLineInput(input: string | number | LineSpec | null | undefined, quantity?: number, options?: Omit<LineSpec, 'variantId' | 'quantity'>): CartLineInput;
|
|
36
|
+
/** A mutation on the saved cart. */
|
|
37
|
+
interface CartMutation {
|
|
38
|
+
/** The mutation, e.g. `cartLinesAdd`. */
|
|
39
|
+
name: string;
|
|
40
|
+
/** Its variable definitions besides `$cartId`. */
|
|
41
|
+
args: string;
|
|
42
|
+
/** Its arguments besides `cartId`. */
|
|
43
|
+
inner: string;
|
|
44
|
+
variables: Record<string, unknown>;
|
|
45
|
+
/**
|
|
46
|
+
* The `CartInput` of a new cart that does what the mutation asks, when there is no cart (or Shopify no longer has
|
|
47
|
+
* it); `null` leaves the visitor without a cart instead.
|
|
48
|
+
*/
|
|
49
|
+
createInput: Record<string, unknown> | null;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Runs a mutation on the saved cart, or creates a cart from `createInput` when there is none to change.
|
|
53
|
+
*
|
|
54
|
+
* @returns The changed cart; `null` without a cart and without a `createInput`.
|
|
55
|
+
* @throws {TetherError} For a failed request or Shopify's user errors; also when the cart is gone and there is no
|
|
56
|
+
* `createInput` (the saved cart is forgotten first).
|
|
57
|
+
*/
|
|
58
|
+
export declare function mutateCart({ name, args, inner, variables, createInput, }: CartMutation): Promise<ShopifyCart | null>;
|
|
59
|
+
/** @returns The cart, `null` when Shopify doesn't have it (expired or checked out). */
|
|
60
|
+
export declare function fetchCart(id: string): Promise<ShopifyCart | null>;
|
|
61
|
+
/** @returns The cart's current checkout URL, `null` when Shopify doesn't have the cart. */
|
|
62
|
+
export declare function fetchCheckoutUrl(id: string): Promise<string | null>;
|
|
63
|
+
/** A change to one line, for `updateLine`. */
|
|
64
|
+
export interface LinePatch {
|
|
65
|
+
/** 0 or less removes the line. */
|
|
66
|
+
quantity?: number;
|
|
67
|
+
/** `null` switches the line back to one-time purchase. */
|
|
68
|
+
sellingPlanId?: string | number | null;
|
|
69
|
+
attributes?: Attributes;
|
|
70
|
+
merchandiseId?: string | number;
|
|
71
|
+
variantId?: string | number;
|
|
72
|
+
}
|
|
73
|
+
/** @returns Shopify's `CartLineUpdateInput`. */
|
|
74
|
+
export declare function toLineUpdate(lineId: string, patch: number | LinePatch): Record<string, unknown>;
|
|
75
|
+
export declare const updateLines: (lines: Record<string, unknown>[]) => Promise<ShopifyCart | null>;
|
|
76
|
+
export declare const removeLines: (lineIds: string[]) => Promise<ShopifyCart | null>;
|
|
77
|
+
/** @returns The cart once `lineId` has `target` (0 removes it). */
|
|
78
|
+
export declare const setLineQuantity: (lineId: string, target: number) => Promise<ShopifyCart | null>;
|
|
79
|
+
export {};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { CartWarning } from '../config.js';
|
|
2
|
+
import type { ShopifyCart, ShopifyCartLine, PendingQuantity } from './store.js';
|
|
3
|
+
/** What a render shows. */
|
|
4
|
+
interface CartView {
|
|
5
|
+
cart: ShopifyCart | null;
|
|
6
|
+
warnings: readonly CartWarning[];
|
|
7
|
+
/** Line id → the quantity quick clicks asked for. */
|
|
8
|
+
pending: ReadonlyMap<string, PendingQuantity>;
|
|
9
|
+
/** The last load or change failed (`tether-show="cart-error"`). */
|
|
10
|
+
failed: boolean;
|
|
11
|
+
}
|
|
12
|
+
/** @returns The quantity to show: the one asked for while an update is on its way. */
|
|
13
|
+
export declare const quantityOf: (line: ShopifyCartLine, pending: ReadonlyMap<string, PendingQuantity>) => number;
|
|
14
|
+
export declare function renderCart(view: CartView): void;
|
|
15
|
+
/** Shows the count a saved cart had on the last page in the cart counts the page left at 0, until it has loaded. */
|
|
16
|
+
export declare function showSavedCount(count: number): void;
|
|
17
|
+
export {};
|
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
import type { CartWarning } from '../config.js';
|
|
2
|
+
import type { Image } from '../fragments.js';
|
|
3
|
+
import type { Money } from '../shopify-values.js';
|
|
4
|
+
export interface Attribute {
|
|
5
|
+
key: string;
|
|
6
|
+
value: string;
|
|
7
|
+
}
|
|
8
|
+
/** A line's `merchandise`: Shopify's `Merchandise` union has only `ProductVariant`. */
|
|
9
|
+
export interface CartVariant {
|
|
10
|
+
id: string;
|
|
11
|
+
title: string;
|
|
12
|
+
sku: string | null;
|
|
13
|
+
availableForSale: boolean;
|
|
14
|
+
requiresShipping: boolean;
|
|
15
|
+
/** Absent when the store's token can't read inventory. */
|
|
16
|
+
quantityAvailable?: number | null;
|
|
17
|
+
image: Image | null;
|
|
18
|
+
price: Money;
|
|
19
|
+
compareAtPrice: Money | null;
|
|
20
|
+
selectedOptions: {
|
|
21
|
+
name: string;
|
|
22
|
+
value: string;
|
|
23
|
+
}[];
|
|
24
|
+
product: {
|
|
25
|
+
id: string;
|
|
26
|
+
title: string;
|
|
27
|
+
handle: string;
|
|
28
|
+
vendor: string;
|
|
29
|
+
featuredImage: Image | null;
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
interface LinePlanAllocation {
|
|
33
|
+
sellingPlan: {
|
|
34
|
+
id: string;
|
|
35
|
+
name: string;
|
|
36
|
+
description: string | null;
|
|
37
|
+
recurringDeliveries: boolean;
|
|
38
|
+
options: {
|
|
39
|
+
name: string;
|
|
40
|
+
value: string;
|
|
41
|
+
}[];
|
|
42
|
+
};
|
|
43
|
+
checkoutChargeAmount: Money;
|
|
44
|
+
priceAdjustments: {
|
|
45
|
+
price: Money;
|
|
46
|
+
compareAtPrice: Money;
|
|
47
|
+
perDeliveryPrice: Money;
|
|
48
|
+
}[];
|
|
49
|
+
}
|
|
50
|
+
export interface ShopifyCartLine {
|
|
51
|
+
id: string;
|
|
52
|
+
quantity: number;
|
|
53
|
+
attributes: Attribute[];
|
|
54
|
+
cost: {
|
|
55
|
+
totalAmount: Money;
|
|
56
|
+
subtotalAmount: Money;
|
|
57
|
+
amountPerQuantity: Money;
|
|
58
|
+
compareAtAmountPerQuantity: Money | null;
|
|
59
|
+
};
|
|
60
|
+
discountAllocations: {
|
|
61
|
+
discountedAmount: Money;
|
|
62
|
+
}[];
|
|
63
|
+
sellingPlanAllocation: LinePlanAllocation | null;
|
|
64
|
+
merchandise: CartVariant;
|
|
65
|
+
/** Only on a bundle (`ComponentizableCartLine`). */
|
|
66
|
+
lineComponents?: {
|
|
67
|
+
id: string;
|
|
68
|
+
quantity: number;
|
|
69
|
+
merchandise: {
|
|
70
|
+
id: string;
|
|
71
|
+
title: string;
|
|
72
|
+
product: {
|
|
73
|
+
title: string;
|
|
74
|
+
handle: string;
|
|
75
|
+
};
|
|
76
|
+
};
|
|
77
|
+
}[];
|
|
78
|
+
}
|
|
79
|
+
/** The fields of `fragment TetherCart`. */
|
|
80
|
+
export interface ShopifyCart {
|
|
81
|
+
id: string;
|
|
82
|
+
checkoutUrl: string;
|
|
83
|
+
totalQuantity: number;
|
|
84
|
+
note: string | null;
|
|
85
|
+
createdAt: string;
|
|
86
|
+
updatedAt: string;
|
|
87
|
+
attributes: Attribute[];
|
|
88
|
+
buyerIdentity: {
|
|
89
|
+
countryCode: string | null;
|
|
90
|
+
email: string | null;
|
|
91
|
+
};
|
|
92
|
+
discountCodes: {
|
|
93
|
+
code: string;
|
|
94
|
+
applicable: boolean;
|
|
95
|
+
}[];
|
|
96
|
+
cost: {
|
|
97
|
+
subtotalAmount: Money;
|
|
98
|
+
totalAmount: Money;
|
|
99
|
+
checkoutChargeAmount: Money;
|
|
100
|
+
};
|
|
101
|
+
lines: {
|
|
102
|
+
nodes: ShopifyCartLine[];
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* `unknown` until the saved cart has loaded (the page's own markup shows); `empty` without a cart (none saved, or
|
|
107
|
+
* Shopify no longer has it); `error` after a failed load or change, with the cart as Shopify last sent it.
|
|
108
|
+
*/
|
|
109
|
+
export type CartStatus = {
|
|
110
|
+
kind: 'unknown';
|
|
111
|
+
} | {
|
|
112
|
+
kind: 'empty';
|
|
113
|
+
} | {
|
|
114
|
+
kind: 'ready';
|
|
115
|
+
cart: ShopifyCart;
|
|
116
|
+
} | {
|
|
117
|
+
kind: 'error';
|
|
118
|
+
error: unknown;
|
|
119
|
+
cart: ShopifyCart | null;
|
|
120
|
+
};
|
|
121
|
+
/** What one quick +/- click asked for; a newer click replaces it. */
|
|
122
|
+
export interface PendingQuantity {
|
|
123
|
+
quantity: number;
|
|
124
|
+
}
|
|
125
|
+
/** The second argument of a `subscribe` listener. */
|
|
126
|
+
interface CartMeta {
|
|
127
|
+
open: boolean;
|
|
128
|
+
count: number;
|
|
129
|
+
loaded: boolean;
|
|
130
|
+
/** A copy of Shopify's notes on the last change. */
|
|
131
|
+
warnings: CartWarning[];
|
|
132
|
+
}
|
|
133
|
+
/** Line id → what quick +/- clicks asked for, until Shopify has answered. */
|
|
134
|
+
export declare const pendingQuantities: Map<string, PendingQuantity>;
|
|
135
|
+
export declare const cartStatus: () => CartStatus;
|
|
136
|
+
/** The cart as Shopify last sent it. */
|
|
137
|
+
export declare function currentCart(): ShopifyCart | null;
|
|
138
|
+
export declare const currentWarnings: () => readonly CartWarning[];
|
|
139
|
+
/** The id of the visitor's cart, kept across pages. */
|
|
140
|
+
export declare const savedCartId: () => string | null;
|
|
141
|
+
/** Forgets the saved cart, which Shopify no longer has. */
|
|
142
|
+
export declare function forgetSavedCart(): void;
|
|
143
|
+
/** Keeps a cart Shopify sent without showing it, for an answer a newer change will replace. */
|
|
144
|
+
export declare function keepQuietly(cart: ShopifyCart | null): void;
|
|
145
|
+
/** Renders the document with the store's cart. */
|
|
146
|
+
export declare function render(): void;
|
|
147
|
+
/** @param reason The `reason` of `tether:cart-updated`. */
|
|
148
|
+
export declare function announce(reason: string): void;
|
|
149
|
+
/**
|
|
150
|
+
* Keeps a cart Shopify sent after a change, shows it, and tells this page and the visitor's other tabs.
|
|
151
|
+
*
|
|
152
|
+
* @returns `cart`.
|
|
153
|
+
*/
|
|
154
|
+
export declare function commit(cart: ShopifyCart | null, reason: string): ShopifyCart | null;
|
|
155
|
+
/** The outcome of loading the saved cart: the cart, `null` when there is none, or the failure. */
|
|
156
|
+
export declare function settleLoad(outcome: {
|
|
157
|
+
kind: 'loaded';
|
|
158
|
+
cart: ShopifyCart | null;
|
|
159
|
+
} | {
|
|
160
|
+
kind: 'failed';
|
|
161
|
+
error: unknown;
|
|
162
|
+
}): void;
|
|
163
|
+
/** Until the saved cart has loaded, the counts show the count it had on the last page instead of the page's 0. */
|
|
164
|
+
export declare function showLastKnownCount(): void;
|
|
165
|
+
/** Sets Shopify's notes on the last change: each message once, in the site's words (`warningText`). */
|
|
166
|
+
export declare function setWarnings(notes: readonly CartWarning[]): void;
|
|
167
|
+
/** @returns A runner that starts each task once the one before has settled, whether it succeeded or failed. */
|
|
168
|
+
export declare function serial(): <T>(task: () => Promise<T>) => Promise<T>;
|
|
169
|
+
/**
|
|
170
|
+
* Runs a cart change after the ones before it, so quick clicks never race. A failure sets the `error` status (shown by
|
|
171
|
+
* `tether-show="cart-error"` until the next change succeeds), emits `tether:cart-error` and rejects.
|
|
172
|
+
*/
|
|
173
|
+
export declare function enqueue<T>(task: () => Promise<T>): Promise<T>;
|
|
174
|
+
/** @returns The quantity to show for `line`. */
|
|
175
|
+
export declare const pendingQuantityOf: (line: ShopifyCartLine) => number;
|
|
176
|
+
/**
|
|
177
|
+
* Calls `listener` now and after every change of the cart or the drawer.
|
|
178
|
+
*
|
|
179
|
+
* @returns Stops listening.
|
|
180
|
+
*/
|
|
181
|
+
export declare function subscribe(listener: (cart: ShopifyCart | null, meta: CartMeta) => void): () => void;
|
|
182
|
+
export {};
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import { checkout, setCheckoutResolver } from './cart/checkout.js';
|
|
2
|
+
import { isOpen, openCart, closeCart, toggleCart, trapFocus } from './cart/drawer.js';
|
|
3
|
+
import { render, subscribe } from './cart/store.js';
|
|
4
|
+
import type { CartWarning } from './config.js';
|
|
5
|
+
import type { Attributes, LineSpec, LinePatch } from './cart/mutations.js';
|
|
6
|
+
import type { ShopifyCart, ShopifyCartLine, CartStatus } from './cart/store.js';
|
|
7
|
+
export { trapFocus };
|
|
8
|
+
type DiscountCodes = string[] | string | ((current: string[]) => string[]);
|
|
9
|
+
/**
|
|
10
|
+
* +1 / -1 for a line. Quick clicks add up: each builds on the quantity the click before asked for, which shows at once
|
|
11
|
+
* (`tether-line="quantity"`, `quantityOf`) until Shopify has answered. Only the latest target is sent; the ones it
|
|
12
|
+
* replaced are skipped.
|
|
13
|
+
*/
|
|
14
|
+
declare function changeQuantity(lineId: string, delta: number): Promise<ShopifyCart | null>;
|
|
15
|
+
/**
|
|
16
|
+
* Loads the saved cart. A cart Shopify no longer has is forgotten; one it can't be asked about (the network, the
|
|
17
|
+
* token) is kept, because it is probably fine.
|
|
18
|
+
*/
|
|
19
|
+
declare function init(): Promise<ShopifyCart | null>;
|
|
20
|
+
export declare const Cart: {
|
|
21
|
+
init: typeof init;
|
|
22
|
+
/** The saved cart's id. */
|
|
23
|
+
id: () => string | null;
|
|
24
|
+
readonly status: CartStatus;
|
|
25
|
+
readonly state: ShopifyCart | null;
|
|
26
|
+
/** The cart's lines, a copy: changing it changes nothing in the cart. */
|
|
27
|
+
readonly lines: ShopifyCartLine[];
|
|
28
|
+
readonly count: number;
|
|
29
|
+
/** True once the saved cart, or that there is none, is known. */
|
|
30
|
+
readonly loaded: boolean;
|
|
31
|
+
/**
|
|
32
|
+
* The failure of the last load or change, until a change succeeds. Requests fail with an `Error`; anything else
|
|
33
|
+
* thrown is wrapped, so the public type holds.
|
|
34
|
+
*/
|
|
35
|
+
readonly lastError: Error | null;
|
|
36
|
+
/** Shopify's notes on the last change, a copy. */
|
|
37
|
+
readonly warnings: CartWarning[];
|
|
38
|
+
/** Line id → the quantity quick clicks asked for. */
|
|
39
|
+
readonly pendingQty: ReadonlyMap<string, {
|
|
40
|
+
quantity: number;
|
|
41
|
+
}>;
|
|
42
|
+
/**
|
|
43
|
+
* Sets where a logged-in customer checks out, or clears it with `null`: the account part's resolver answers the
|
|
44
|
+
* customer's checkout URL for the cart (`null` uses the cart's own).
|
|
45
|
+
*/
|
|
46
|
+
setCheckoutResolver: typeof setCheckoutResolver;
|
|
47
|
+
/**
|
|
48
|
+
* Forgets the saved cart on this device, as if there were none: the page shows an empty cart and
|
|
49
|
+
* `tether:cart-updated` fires with reason `load`. The next add starts a new cart.
|
|
50
|
+
*/
|
|
51
|
+
forgetSaved(): void;
|
|
52
|
+
render: typeof render;
|
|
53
|
+
subscribe: typeof subscribe;
|
|
54
|
+
/**
|
|
55
|
+
* `add(variantId, 2)`, `add({ variantId, quantity, sellingPlanId, attributes })`, or `add([line, line])` for
|
|
56
|
+
* bundles in one request. Creates the cart when there is none.
|
|
57
|
+
*
|
|
58
|
+
* @throws {TetherError} (rejected) When the add fails, or Shopify answers it without a cart.
|
|
59
|
+
*/
|
|
60
|
+
add(input: string | number | LineSpec | (string | number | LineSpec)[], quantity?: number, options?: Omit<LineSpec, "variantId" | "quantity">): Promise<ShopifyCart>;
|
|
61
|
+
/**
|
|
62
|
+
* `updateLine(lineId, 3)` or `updateLine(lineId, { quantity, sellingPlanId, attributes })`.
|
|
63
|
+
*
|
|
64
|
+
* @param patch A quantity of 0 or less removes the line.
|
|
65
|
+
*/
|
|
66
|
+
updateLine(lineId: string, patch: number | LinePatch): Promise<ShopifyCart | null>;
|
|
67
|
+
changeQuantity: typeof changeQuantity;
|
|
68
|
+
/** The quantity to show: the one asked for while an update is on its way. */
|
|
69
|
+
quantityOf: (line: ShopifyCartLine) => number;
|
|
70
|
+
removeLine(lineIds: string | string[]): Promise<ShopifyCart | null>;
|
|
71
|
+
clear(): Promise<ShopifyCart | null>;
|
|
72
|
+
setNote(note: string | null | undefined): Promise<ShopifyCart | null>;
|
|
73
|
+
/**
|
|
74
|
+
* Cart attributes, merged with the cart's (as it is when the change runs, so quick calls don't drop each other).
|
|
75
|
+
*
|
|
76
|
+
* @param attributes The value `''` removes a key.
|
|
77
|
+
*/
|
|
78
|
+
setAttributes(attributes: Attributes): Promise<ShopifyCart | null>;
|
|
79
|
+
/** Replaces the discount codes; `[]` removes them all. */
|
|
80
|
+
setDiscountCodes(codes: DiscountCodes): Promise<ShopifyCart | null>;
|
|
81
|
+
/**
|
|
82
|
+
* Adds a code. A code Shopify doesn't accept is removed again, so it doesn't warn on every later change.
|
|
83
|
+
*
|
|
84
|
+
* @throws {TetherError} `INVALID_DISCOUNT` (rejected) when Shopify doesn't accept the code.
|
|
85
|
+
*/
|
|
86
|
+
applyDiscount(code: string): Promise<ShopifyCart | null>;
|
|
87
|
+
removeDiscount(code: string): Promise<ShopifyCart | null>;
|
|
88
|
+
/**
|
|
89
|
+
* Sets who is buying; a country changes the cart's currency and prices to that market's.
|
|
90
|
+
*
|
|
91
|
+
* @param options `create: false` forgets an expired cart instead of creating an empty one.
|
|
92
|
+
*/
|
|
93
|
+
setBuyerIdentity(buyerIdentity: {
|
|
94
|
+
countryCode?: string;
|
|
95
|
+
email?: string;
|
|
96
|
+
phone?: string;
|
|
97
|
+
}, { create }?: {
|
|
98
|
+
create?: boolean;
|
|
99
|
+
}): Promise<ShopifyCart | null>;
|
|
100
|
+
checkout: typeof checkout;
|
|
101
|
+
drawers: () => HTMLElement[];
|
|
102
|
+
isOpen: typeof isOpen;
|
|
103
|
+
open: typeof openCart;
|
|
104
|
+
close: typeof closeCart;
|
|
105
|
+
toggle: typeof toggleCart;
|
|
106
|
+
};
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import type { TetherConfig } from './config.js';
|
|
2
|
+
export type TetherErrorCode = 'NOT_FOUND' | 'NETWORK' | 'NOT_CONFIGURED' | 'NOT_LOGGED_IN' | 'INVALID' | 'INVALID_COUNTRY' | 'INVALID_DISCOUNT' | 'ERROR' | `HTTP_${number}`;
|
|
3
|
+
export interface GraphQLError {
|
|
4
|
+
message: string;
|
|
5
|
+
extensions?: {
|
|
6
|
+
code?: string;
|
|
7
|
+
};
|
|
8
|
+
}
|
|
9
|
+
export interface UserError {
|
|
10
|
+
message: string;
|
|
11
|
+
field?: string[] | null;
|
|
12
|
+
code?: string | null;
|
|
13
|
+
}
|
|
14
|
+
interface TetherErrorDetails {
|
|
15
|
+
/** Default `HTTP_<status>` with a status, else `ERROR`. */
|
|
16
|
+
code?: TetherErrorCode;
|
|
17
|
+
/** The HTTP status of the response that failed. */
|
|
18
|
+
status?: number;
|
|
19
|
+
/** The GraphQL errors of that response. */
|
|
20
|
+
errors?: GraphQLError[];
|
|
21
|
+
/** A mutation's user errors. */
|
|
22
|
+
userErrors?: readonly UserError[];
|
|
23
|
+
}
|
|
24
|
+
export declare class TetherError extends Error {
|
|
25
|
+
name: "TetherError";
|
|
26
|
+
code: TetherErrorCode;
|
|
27
|
+
status: number | undefined;
|
|
28
|
+
errors: GraphQLError[] | undefined;
|
|
29
|
+
userErrors: readonly UserError[] | undefined;
|
|
30
|
+
constructor(message: string, { status, errors, userErrors, code }?: TetherErrorDetails);
|
|
31
|
+
}
|
|
32
|
+
/** What a request needs from a config: the browser's `cfg`, or a config the server helpers build. */
|
|
33
|
+
export type StorefrontConfig = Pick<TetherConfig, 'domain' | 'token' | 'apiVersion' | 'country' | 'language' | 'maxAge' | 'retries'> & {
|
|
34
|
+
fetch?: typeof fetch;
|
|
35
|
+
};
|
|
36
|
+
/** Checks a query's `data` before its caller reads it as a `T`. */
|
|
37
|
+
export type DataCheck<T> = (data: unknown) => data is T;
|
|
38
|
+
/**
|
|
39
|
+
* The structure of JSON a check accepts: a `typeof` name, `'object'` for a plain object, `[item]` for a list of
|
|
40
|
+
* items, an object's fields, or a check of its own. Fields it doesn't name aren't checked, so a shape names only what
|
|
41
|
+
* its reader walks without a fallback.
|
|
42
|
+
*/
|
|
43
|
+
export type Shape = 'string' | 'number' | 'boolean' | 'object' | ((value: unknown) => boolean) | readonly [Shape] | {
|
|
44
|
+
readonly [key: string]: Shape;
|
|
45
|
+
};
|
|
46
|
+
/** @returns True when `value` has the structure `shape` describes. */
|
|
47
|
+
export declare function matches(value: unknown, shape: Shape): boolean;
|
|
48
|
+
/** @returns The shape of `null` or a value with the structure `shape` describes. */
|
|
49
|
+
export declare const orNull: (shape: Shape) => (value: unknown) => boolean;
|
|
50
|
+
/** @returns A check that `data` has the structure `shape` describes, which `T` states. */
|
|
51
|
+
export declare const shaped: <T>(shape: Shape) => DataCheck<T>;
|
|
52
|
+
/** `context: false` sends the query without `@inContext`. */
|
|
53
|
+
interface RequestOptions {
|
|
54
|
+
context?: boolean;
|
|
55
|
+
}
|
|
56
|
+
/** What the store's token may read beyond the defaults. */
|
|
57
|
+
export interface StoreAccess {
|
|
58
|
+
inventory: boolean;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* A query's text, or a function that writes it for what the token may read: Tether's own queries, built from
|
|
62
|
+
* `fragments.ts`, leave out inventory for a token that can't read it.
|
|
63
|
+
*/
|
|
64
|
+
export type QueryText = string | ((access: StoreAccess) => string);
|
|
65
|
+
/** @returns The Storefront GraphQL endpoint of `conf`'s store. */
|
|
66
|
+
export declare function endpoint(conf?: Pick<TetherConfig, 'domain' | 'apiVersion'>): string;
|
|
67
|
+
/**
|
|
68
|
+
* `inContext` for any country and language, as the public `Tether.withContext` takes them: one that isn't a valid
|
|
69
|
+
* code is left out, so page input never becomes query text.
|
|
70
|
+
*/
|
|
71
|
+
export declare function withContext(query: string, ctx?: {
|
|
72
|
+
country?: string | undefined;
|
|
73
|
+
language?: string | undefined;
|
|
74
|
+
}): string;
|
|
75
|
+
/**
|
|
76
|
+
* One Storefront API request, for any config: the browser's shared one (`gql`) or one the server helpers build.
|
|
77
|
+
* Queries carry a time bucket so Shopify's cache of an identical query text is at most `maxAge` seconds old. A query
|
|
78
|
+
* written for the store's access leaves out inventory once the token turns out not to read it (`INVENTORY_FIELD`);
|
|
79
|
+
* a fixed query text is the caller's own, and that refusal is its error.
|
|
80
|
+
*
|
|
81
|
+
* @param isData Checks that `data` has what the caller then reads, so a malformed answer fails here.
|
|
82
|
+
* @throws {TetherError} `NOT_CONFIGURED` without a domain or token, `NETWORK` when the store can't be reached,
|
|
83
|
+
* `HTTP_<status>` for an HTTP or GraphQL failure, or for `data` that `isData` refuses.
|
|
84
|
+
*/
|
|
85
|
+
export declare function request<T>(conf: StorefrontConfig, query: QueryText, variables: Record<string, unknown>, isData: DataCheck<T>, { context }?: RequestOptions): Promise<T>;
|
|
86
|
+
/** `request` with the browser's shared config. */
|
|
87
|
+
export declare function gql<T>(query: QueryText, variables: Record<string, unknown>, isData: DataCheck<T>, options?: RequestOptions): Promise<T>;
|
|
88
|
+
/** The check of `Tether.query()` and the server's `query()`, whose callers read `data` themselves. */
|
|
89
|
+
export declare const hasData: (data: unknown) => data is object;
|
|
90
|
+
/** `Tether.query()`: the caller's own query text decides the shape of `data`, and the caller's `T` states it. */
|
|
91
|
+
export declare function query<T>(text: QueryText, variables?: Record<string, unknown>, options?: RequestOptions): Promise<T>;
|
|
92
|
+
/**
|
|
93
|
+
* @param payload A mutation's payload.
|
|
94
|
+
* @param name The mutation, for the error message.
|
|
95
|
+
* @throws {TetherError} `ERROR` on an empty payload or on user errors (in `userErrors`).
|
|
96
|
+
*/
|
|
97
|
+
export declare function unwrap<Payload extends {
|
|
98
|
+
userErrors?: readonly UserError[] | null;
|
|
99
|
+
}>(payload: Payload | null | undefined, name: string): Payload;
|
|
100
|
+
export {};
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { Product } from './fragments.js';
|
|
2
|
+
import type { Collection, PageInfo, ProductQuery } from './loader.js';
|
|
3
|
+
export declare const listSelector: () => string;
|
|
4
|
+
export declare class ListScope {
|
|
5
|
+
readonly root: HTMLElement;
|
|
6
|
+
products: Product[];
|
|
7
|
+
pageInfo: PageInfo | null;
|
|
8
|
+
collection: Collection | null;
|
|
9
|
+
/** Counts loads, so only the latest one renders. */
|
|
10
|
+
loadToken: number;
|
|
11
|
+
constructor(root: HTMLElement);
|
|
12
|
+
$(selector: string): HTMLElement[];
|
|
13
|
+
/** The collection or search query of the list's attributes. */
|
|
14
|
+
options(): ProductQuery;
|
|
15
|
+
/**
|
|
16
|
+
* The product of a recommendations list: a handle, `url:…` (one dynamic product page), or empty inside a product
|
|
17
|
+
* scope for that product.
|
|
18
|
+
*
|
|
19
|
+
* @throws {TetherError} `NOT_FOUND` when there is no product to recommend for.
|
|
20
|
+
*/
|
|
21
|
+
loadRecommendations(): Promise<Product[]>;
|
|
22
|
+
/** @param more Appends the next page instead of replacing the products. */
|
|
23
|
+
load(more?: boolean): Promise<void>;
|
|
24
|
+
render(): void;
|
|
25
|
+
}
|