@tiledev/sdk-shopify 0.9.1 → 0.10.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 +653 -50
- package/dist/alertSettings.d.ts.map +1 -1
- package/dist/alertSettings.js +2 -0
- package/dist/alertSettings.js.map +1 -1
- package/dist/attribution.d.ts +21 -0
- package/dist/attribution.d.ts.map +1 -1
- package/dist/attribution.js +17 -0
- package/dist/attribution.js.map +1 -1
- package/dist/auth/pkce.d.ts +30 -0
- package/dist/auth/pkce.d.ts.map +1 -0
- package/dist/auth/pkce.js +128 -0
- package/dist/auth/pkce.js.map +1 -0
- package/dist/auth/session.d.ts +118 -0
- package/dist/auth/session.d.ts.map +1 -0
- package/dist/auth/session.js +896 -0
- package/dist/auth/session.js.map +1 -0
- package/dist/auth/storeCredit.d.ts +64 -0
- package/dist/auth/storeCredit.d.ts.map +1 -0
- package/dist/auth/storeCredit.js +274 -0
- package/dist/auth/storeCredit.js.map +1 -0
- package/dist/cart.d.ts +25 -1
- package/dist/cart.d.ts.map +1 -1
- package/dist/cart.js +95 -2
- package/dist/cart.js.map +1 -1
- package/dist/cartPolicy.js +4 -4
- package/dist/checkout.d.ts +123 -0
- package/dist/checkout.d.ts.map +1 -0
- package/dist/checkout.js +205 -0
- package/dist/checkout.js.map +1 -0
- package/dist/customer.d.ts.map +1 -1
- package/dist/customer.js +8 -0
- package/dist/customer.js.map +1 -1
- package/dist/index.d.ts +12 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +74 -2
- package/dist/index.js.map +1 -1
- package/dist/messages.d.ts.map +1 -1
- package/dist/messages.js +2 -0
- package/dist/messages.js.map +1 -1
- package/dist/money.d.ts +16 -0
- package/dist/money.d.ts.map +1 -1
- package/dist/money.js +55 -0
- package/dist/money.js.map +1 -1
- package/dist/orders.d.ts +99 -0
- package/dist/orders.d.ts.map +1 -0
- package/dist/orders.js +439 -0
- package/dist/orders.js.map +1 -0
- package/dist/productPage.d.ts +100 -0
- package/dist/productPage.d.ts.map +1 -0
- package/dist/productPage.js +298 -0
- package/dist/productPage.js.map +1 -0
- package/dist/productStore.d.ts +1 -1
- package/dist/productStore.d.ts.map +1 -1
- package/dist/productStore.js +63 -5
- package/dist/productStore.js.map +1 -1
- package/dist/products.d.ts.map +1 -1
- package/dist/products.js +15 -3
- package/dist/products.js.map +1 -1
- package/dist/purchaseRules.d.ts +74 -0
- package/dist/purchaseRules.d.ts.map +1 -0
- package/dist/purchaseRules.js +73 -0
- package/dist/purchaseRules.js.map +1 -0
- package/dist/queries.d.ts +15 -13
- package/dist/queries.d.ts.map +1 -1
- package/dist/queries.js +43 -7
- package/dist/queries.js.map +1 -1
- package/dist/react/ShopifyProvider.d.ts +167 -25
- package/dist/react/ShopifyProvider.d.ts.map +1 -1
- package/dist/react/ShopifyProvider.js +352 -207
- package/dist/react/ShopifyProvider.js.map +1 -1
- package/dist/react/appForeground.d.ts +6 -0
- package/dist/react/appForeground.d.ts.map +1 -0
- package/dist/react/appForeground.js +19 -0
- package/dist/react/appForeground.js.map +1 -0
- package/dist/react/appForeground.native.d.ts +2 -0
- package/dist/react/appForeground.native.d.ts.map +1 -0
- package/dist/react/appForeground.native.js +23 -0
- package/dist/react/appForeground.native.js.map +1 -0
- package/dist/react/index.d.ts +7 -1
- package/dist/react/index.d.ts.map +1 -1
- package/dist/react/index.js +23 -1
- package/dist/react/index.js.map +1 -1
- package/dist/react/tileCreditClient.d.ts +4 -0
- package/dist/react/tileCreditClient.d.ts.map +1 -0
- package/dist/react/tileCreditClient.js +27 -0
- package/dist/react/tileCreditClient.js.map +1 -0
- package/dist/react/useAppDiscountCode.d.ts +19 -0
- package/dist/react/useAppDiscountCode.d.ts.map +1 -0
- package/dist/react/useAppDiscountCode.js +44 -0
- package/dist/react/useAppDiscountCode.js.map +1 -0
- package/dist/react/useCartStoreCredit.d.ts +25 -0
- package/dist/react/useCartStoreCredit.d.ts.map +1 -0
- package/dist/react/useCartStoreCredit.js +292 -0
- package/dist/react/useCartStoreCredit.js.map +1 -0
- package/dist/react/useOrders.d.ts +104 -0
- package/dist/react/useOrders.d.ts.map +1 -0
- package/dist/react/useOrders.js +287 -0
- package/dist/react/useOrders.js.map +1 -0
- package/dist/react/useProduct.d.ts.map +1 -1
- package/dist/react/useProduct.js +1 -9
- package/dist/react/useProduct.js.map +1 -1
- package/dist/react/useProductFeed.d.ts.map +1 -1
- package/dist/react/useProductFeed.js +33 -5
- package/dist/react/useProductFeed.js.map +1 -1
- package/dist/react/useProductPage.d.ts +148 -0
- package/dist/react/useProductPage.d.ts.map +1 -0
- package/dist/react/useProductPage.js +178 -0
- package/dist/react/useProductPage.js.map +1 -0
- package/dist/react/useProductRecommendations.d.ts +27 -0
- package/dist/react/useProductRecommendations.d.ts.map +1 -0
- package/dist/react/useProductRecommendations.js +76 -0
- package/dist/react/useProductRecommendations.js.map +1 -0
- package/dist/react/useStoreCredit.d.ts +58 -0
- package/dist/react/useStoreCredit.d.ts.map +1 -0
- package/dist/react/useStoreCredit.js +209 -0
- package/dist/react/useStoreCredit.js.map +1 -0
- package/dist/react/useTileCredit.d.ts +4 -3
- package/dist/react/useTileCredit.d.ts.map +1 -1
- package/dist/react/useTileCredit.js +63 -55
- package/dist/react/useTileCredit.js.map +1 -1
- package/dist/shopify.d.ts.map +1 -1
- package/dist/shopify.js +2 -0
- package/dist/shopify.js.map +1 -1
- package/dist/storedList.d.ts +27 -0
- package/dist/storedList.d.ts.map +1 -0
- package/dist/storedList.js +152 -0
- package/dist/storedList.js.map +1 -0
- package/dist/tileCredit.d.ts +25 -10
- package/dist/tileCredit.d.ts.map +1 -1
- package/dist/tileCredit.js +97 -45
- package/dist/tileCredit.js.map +1 -1
- package/dist/types.d.ts +407 -34
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +1 -2
- package/dist/types.js.map +1 -1
- package/dist/variants.d.ts.map +1 -1
- package/dist/variants.js +4 -3
- package/dist/variants.js.map +1 -1
- package/dist/waitlist.d.ts +4 -0
- package/dist/waitlist.d.ts.map +1 -0
- package/dist/waitlist.js +213 -0
- package/dist/waitlist.js.map +1 -0
- package/dist/wishlist.d.ts.map +1 -1
- package/dist/wishlist.js +70 -47
- package/dist/wishlist.js.map +1 -1
- package/package.json +2 -2
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
import { type DescriptionBlock, type OptionSelection, type OptionState, type ProductLike, type VariantPrice } from '../productPage';
|
|
2
|
+
import type { AttributionSource } from '../attribution';
|
|
3
|
+
import type { CartLineAttribute, CartWriteResult, ImageTransform, Product, ProductMedia, ProductOption, ProductVariant } from '../types';
|
|
4
|
+
import { type UseProductResult } from './useProduct';
|
|
5
|
+
import { type ProductRecommendations, type UseProductRecommendationsOptions } from './useProductRecommendations';
|
|
6
|
+
export interface UseVariantSelectionOptions {
|
|
7
|
+
/** Option names in display order (default Color, Colour, Size, then the rest). */
|
|
8
|
+
optionOrder?: readonly string[];
|
|
9
|
+
/** Keep an option as a selector (default: all but Shopify's "Default Title" placeholder). */
|
|
10
|
+
includeOption?: (option: ProductOption) => boolean;
|
|
11
|
+
/** The selection to start on (default: the first purchasable variant, else the first). */
|
|
12
|
+
initialSelection?: (variants: ProductVariant[]) => OptionSelection;
|
|
13
|
+
/** Start on this variant (e.g. a link to one), when it exists. Wins over `initialSelection`. */
|
|
14
|
+
initialVariantId?: string | null;
|
|
15
|
+
/** Can't be bought now (default: missing, not for sale, or 0 left). */
|
|
16
|
+
isUnavailable?: (variant: ProductVariant | null) => boolean;
|
|
17
|
+
/** Units across the product at or below which `lowStock` is true; null turns it off. Default 10. */
|
|
18
|
+
lowStockThreshold?: number | null;
|
|
19
|
+
/** Between values in `label` (default " / "). */
|
|
20
|
+
separator?: string;
|
|
21
|
+
/** The selection starts over when this changes (default: the product's id). */
|
|
22
|
+
resetKey?: string | null;
|
|
23
|
+
}
|
|
24
|
+
export interface VariantSelection {
|
|
25
|
+
/** The options shown as selectors, in display order. */
|
|
26
|
+
options: ProductOption[];
|
|
27
|
+
/** Each option with every value's state: selected, available, units left, the variant it picks. */
|
|
28
|
+
optionStates: OptionState[];
|
|
29
|
+
selection: OptionSelection;
|
|
30
|
+
setOption: (name: string, value: string) => void;
|
|
31
|
+
selectVariant: (variantId: string) => void;
|
|
32
|
+
/** Back to the initial selection. */
|
|
33
|
+
reset: () => void;
|
|
34
|
+
/** The variant the selection names; null while variants are unknown or for a combination not sold. */
|
|
35
|
+
variant: ProductVariant | null;
|
|
36
|
+
/** "Ivory / L". */
|
|
37
|
+
label: string;
|
|
38
|
+
/** Variants are known (always for a full product; for a preview since sdk-shopify 0.9). */
|
|
39
|
+
known: boolean;
|
|
40
|
+
/** The variant's price; without one, the product's lowest. */
|
|
41
|
+
price: VariantPrice;
|
|
42
|
+
/** The chosen variant can't be bought now (only meaningful when `known`). */
|
|
43
|
+
unavailable: boolean;
|
|
44
|
+
lowStock: boolean;
|
|
45
|
+
}
|
|
46
|
+
export declare function useVariantSelection(product: ProductLike | null | undefined, options?: UseVariantSelectionOptions): VariantSelection;
|
|
47
|
+
/** Why an add didn't land: the SDK's reasons, or `no-variant` (nothing chosen / not sold). */
|
|
48
|
+
export type AddToCartReason = NonNullable<CartWriteResult['reason']> | 'no-variant';
|
|
49
|
+
export interface AddToCartResult extends Omit<CartWriteResult, 'reason'> {
|
|
50
|
+
reason?: AddToCartReason;
|
|
51
|
+
/** Shopify refused the write; already reported as `cart:outOfStock`. */
|
|
52
|
+
error?: unknown;
|
|
53
|
+
}
|
|
54
|
+
export interface AddToCartInput {
|
|
55
|
+
quantity?: number;
|
|
56
|
+
attributes?: CartLineAttribute[];
|
|
57
|
+
sellingPlanId?: string | null;
|
|
58
|
+
/**
|
|
59
|
+
* Where the units came from (a live show, a replay), for the provider's `attribution`
|
|
60
|
+
* (`_apptile_attribution`). Passed on to `addLine`, never to Shopify. Left out: the app's own
|
|
61
|
+
* (`{ type: 'app' }`). Given to `useProductPage` / `useAddToCart`, it is every add's (SDK move 6).
|
|
62
|
+
*/
|
|
63
|
+
source?: AttributionSource;
|
|
64
|
+
}
|
|
65
|
+
export interface UseAddToCartOptions extends AddToCartInput {
|
|
66
|
+
/** The most of the variant the cart may hold (default: its stock, `stockCeiling`). null: no ceiling. */
|
|
67
|
+
maxQuantity?: (variant: ProductVariant) => number | null;
|
|
68
|
+
onAdded?: (result: AddToCartResult) => void;
|
|
69
|
+
/** Every refusal, including ones the SDK already raised an alert for (`stock`, `limit`, `outOfStock`). */
|
|
70
|
+
onRefused?: (result: AddToCartResult) => void;
|
|
71
|
+
}
|
|
72
|
+
export interface AddToCart {
|
|
73
|
+
/** Add the variant (overrides apply to this add only). Never throws. */
|
|
74
|
+
add: (input?: AddToCartInput) => Promise<AddToCartResult>;
|
|
75
|
+
adding: boolean;
|
|
76
|
+
/** Units of the variant already in the cart, across lines. */
|
|
77
|
+
inCart: number;
|
|
78
|
+
/** One more fits under the ceiling. */
|
|
79
|
+
canAddMore: boolean;
|
|
80
|
+
}
|
|
81
|
+
export declare function useAddToCart(variant: ProductVariant | null | undefined, options?: UseAddToCartOptions): AddToCart;
|
|
82
|
+
export interface UseProductPageOptions extends UseVariantSelectionOptions, UseAddToCartOptions {
|
|
83
|
+
/** For every image of the product read (e.g. `{ maxWidth: 1080 }` for a full-width gallery). */
|
|
84
|
+
imageTransform?: ImageTransform;
|
|
85
|
+
onError?: (error: unknown, context: {
|
|
86
|
+
at: string;
|
|
87
|
+
handle: string;
|
|
88
|
+
}) => void;
|
|
89
|
+
/** Open the gallery on the first video. */
|
|
90
|
+
playVideo?: boolean;
|
|
91
|
+
/** The product can't be bought at all (e.g. live in an auction): `status: 'blocked'`. */
|
|
92
|
+
isBlocked?: (product: ProductLike) => boolean;
|
|
93
|
+
/**
|
|
94
|
+
* Parse the description: true (default), false to wait (e.g. until after the screen's
|
|
95
|
+
* transition), or your own parser.
|
|
96
|
+
*/
|
|
97
|
+
parseDescription?: boolean | ((html: string) => DescriptionBlock[]);
|
|
98
|
+
/** Called once per product, when the full product is in hand (e.g. a productView event). */
|
|
99
|
+
onView?: (product: Product) => void;
|
|
100
|
+
/** For the share link's fallback (default: the configured store). */
|
|
101
|
+
storeDomain?: string;
|
|
102
|
+
/**
|
|
103
|
+
* "You may also like": Shopify's related products, read when this is true (or options). Below the
|
|
104
|
+
* fold, so a page usually passes it once settled. Leaves out the product itself and anything
|
|
105
|
+
* `isBlocked` says can't be bought, unless `exclude` is given. Unset: nothing is read.
|
|
106
|
+
*/
|
|
107
|
+
recommendations?: boolean | UseProductRecommendationsOptions;
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* - `loading`: nothing known yet. `available` / `unavailable`: the chosen variant can or can't be
|
|
111
|
+
* bought (unavailable is the waitlist case). `blocked`: `isBlocked` said no. `unknown`: a preview
|
|
112
|
+
* from before sdk-shopify 0.9, without variants, until the full product lands.
|
|
113
|
+
*/
|
|
114
|
+
export type ProductPageStatus = 'loading' | 'unknown' | 'available' | 'unavailable' | 'blocked';
|
|
115
|
+
export interface ProductPage extends Omit<UseProductResult, 'product' | 'preview'> {
|
|
116
|
+
/** The full product, once read. */
|
|
117
|
+
product: Product | null;
|
|
118
|
+
/** The store's preview (card keys, variants, description): render it while `product` is null. */
|
|
119
|
+
preview: UseProductResult['preview'];
|
|
120
|
+
/** `product ?? preview`: what to render now. */
|
|
121
|
+
shown: ProductLike | null;
|
|
122
|
+
status: ProductPageStatus;
|
|
123
|
+
selection: VariantSelection;
|
|
124
|
+
cart: AddToCart;
|
|
125
|
+
media: {
|
|
126
|
+
/** The gallery (from the full product; empty until then). */
|
|
127
|
+
items: ProductMedia[];
|
|
128
|
+
/** The slide to open on. */
|
|
129
|
+
initialIndex: number;
|
|
130
|
+
/** The first still image, for a thumbnail (the preview's featured image until the full product). */
|
|
131
|
+
firstImageUrl: string | null;
|
|
132
|
+
/** The image the device already has (the card's): draw it first. */
|
|
133
|
+
previewImageUrl: string | null;
|
|
134
|
+
};
|
|
135
|
+
description: {
|
|
136
|
+
html: string;
|
|
137
|
+
blocks: DescriptionBlock[];
|
|
138
|
+
};
|
|
139
|
+
favorite: {
|
|
140
|
+
isFavorite: boolean;
|
|
141
|
+
toggle: () => Promise<boolean>;
|
|
142
|
+
};
|
|
143
|
+
shareUrl: string | null;
|
|
144
|
+
/** "You may also like" (empty unless `recommendations` asked for them). */
|
|
145
|
+
recommendations: ProductRecommendations;
|
|
146
|
+
}
|
|
147
|
+
export declare function useProductPage(handle: string | null | undefined, options?: UseProductPageOptions): ProductPage;
|
|
148
|
+
//# sourceMappingURL=useProductPage.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useProductPage.d.ts","sourceRoot":"","sources":["../../src/react/useProductPage.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.useVariantSelection = useVariantSelection;
|
|
4
|
+
exports.useAddToCart = useAddToCart;
|
|
5
|
+
exports.useProductPage = useProductPage;
|
|
6
|
+
/**
|
|
7
|
+
* Product page hooks, from small to whole:
|
|
8
|
+
*
|
|
9
|
+
* - `useVariantSelection(product)`: the selection, every option value's state, the chosen variant,
|
|
10
|
+
* its price and stock. For any surface that sells a variant (a page, a buy sheet, a quick add).
|
|
11
|
+
* - `useAddToCart(variant)`: add with the stock ceiling checked first, the `adding` state, the result.
|
|
12
|
+
* - `useProductPage(handle)`: both, on `useProduct`'s cache-first product, plus the gallery's media,
|
|
13
|
+
* the parsed description, the favourite, the share link and, when asked, "You may also like"
|
|
14
|
+
* (`useProductRecommendations`).
|
|
15
|
+
*
|
|
16
|
+
* Everything is overridable: each rule takes an option, each returned section is plain data a
|
|
17
|
+
* screen can ignore, and the pure helpers (`../productPage`) are there for a page of its own.
|
|
18
|
+
*/
|
|
19
|
+
const react_1 = require("react");
|
|
20
|
+
const productPage_1 = require("../productPage");
|
|
21
|
+
const ShopifyProvider_1 = require("./ShopifyProvider");
|
|
22
|
+
const useProduct_1 = require("./useProduct");
|
|
23
|
+
const useProductRecommendations_1 = require("./useProductRecommendations");
|
|
24
|
+
function useVariantSelection(product, options = {}) {
|
|
25
|
+
var _a, _b, _c;
|
|
26
|
+
const variants = (0, react_1.useMemo)(() => { var _a; return (_a = product === null || product === void 0 ? void 0 : product.variants) !== null && _a !== void 0 ? _a : []; }, [product === null || product === void 0 ? void 0 : product.variants]);
|
|
27
|
+
const known = variants.length > 0;
|
|
28
|
+
const isUnavailable = (_a = options.isUnavailable) !== null && _a !== void 0 ? _a : productPage_1.isVariantUnavailable;
|
|
29
|
+
const orderKey = ((_b = options.optionOrder) !== null && _b !== void 0 ? _b : []).join('\u0001');
|
|
30
|
+
const includeRef = (0, react_1.useRef)(options.includeOption);
|
|
31
|
+
includeRef.current = options.includeOption;
|
|
32
|
+
const selectable = (0, react_1.useMemo)(() => (0, productPage_1.selectableOptions)(product === null || product === void 0 ? void 0 : product.options, { order: options.optionOrder, include: includeRef.current }),
|
|
33
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
34
|
+
[product === null || product === void 0 ? void 0 : product.options, orderKey]);
|
|
35
|
+
const startRef = (0, react_1.useRef)(options.initialSelection);
|
|
36
|
+
startRef.current = options.initialSelection;
|
|
37
|
+
const initial = (0, react_1.useMemo)(() => {
|
|
38
|
+
var _a;
|
|
39
|
+
const linked = options.initialVariantId ? variants.find((v) => v.id === options.initialVariantId) : null;
|
|
40
|
+
if (linked)
|
|
41
|
+
return (0, productPage_1.selectionForVariant)(linked);
|
|
42
|
+
return ((_a = startRef.current) !== null && _a !== void 0 ? _a : productPage_1.initialSelection)(variants);
|
|
43
|
+
}, [variants, options.initialVariantId]);
|
|
44
|
+
const [chosen, setChosen] = (0, react_1.useState)(null);
|
|
45
|
+
const resetKey = options.resetKey !== undefined ? options.resetKey : ((_c = product === null || product === void 0 ? void 0 : product.id) !== null && _c !== void 0 ? _c : null);
|
|
46
|
+
(0, react_1.useEffect)(() => setChosen(null), [resetKey]);
|
|
47
|
+
const selection = chosen !== null && chosen !== void 0 ? chosen : initial;
|
|
48
|
+
const variant = known ? (0, productPage_1.findVariant)(variants, selection) : null;
|
|
49
|
+
const setOption = (0, react_1.useCallback)((name, value) => setChosen((current) => ({ ...(current !== null && current !== void 0 ? current : initial), [name]: value })), [initial]);
|
|
50
|
+
const selectVariant = (0, react_1.useCallback)((variantId) => {
|
|
51
|
+
const found = variants.find((v) => v.id === variantId);
|
|
52
|
+
if (found)
|
|
53
|
+
setChosen((0, productPage_1.selectionForVariant)(found));
|
|
54
|
+
}, [variants]);
|
|
55
|
+
const reset = (0, react_1.useCallback)(() => setChosen(null), []);
|
|
56
|
+
const states = (0, react_1.useMemo)(() => (0, productPage_1.optionStates)(selectable, variants, selection, isUnavailable),
|
|
57
|
+
// isUnavailable is a rule, read each time; its identity isn't part of the key.
|
|
58
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
59
|
+
[selectable, variants, selection]);
|
|
60
|
+
const threshold = options.lowStockThreshold === undefined ? productPage_1.DEFAULT_LOW_STOCK_THRESHOLD : options.lowStockThreshold;
|
|
61
|
+
return {
|
|
62
|
+
options: selectable,
|
|
63
|
+
optionStates: states,
|
|
64
|
+
selection,
|
|
65
|
+
setOption,
|
|
66
|
+
selectVariant,
|
|
67
|
+
reset,
|
|
68
|
+
variant,
|
|
69
|
+
label: (0, productPage_1.selectionLabel)(selectable, selection, options.separator),
|
|
70
|
+
known,
|
|
71
|
+
price: (0, productPage_1.variantPrice)(variant, product),
|
|
72
|
+
unavailable: known && (!(product === null || product === void 0 ? void 0 : product.availableForSale) || isUnavailable(variant)),
|
|
73
|
+
lowStock: known && (0, productPage_1.isLowStock)(product === null || product === void 0 ? void 0 : product.totalInventory, product === null || product === void 0 ? void 0 : product.availableForSale, threshold),
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
function useAddToCart(variant, options = {}) {
|
|
77
|
+
const { addLine, cart } = (0, ShopifyProvider_1.useCart)();
|
|
78
|
+
const [adding, setAdding] = (0, react_1.useState)(false);
|
|
79
|
+
const optionsRef = (0, react_1.useRef)(options);
|
|
80
|
+
optionsRef.current = options;
|
|
81
|
+
const ceiling = variant ? (options.maxQuantity ? options.maxQuantity(variant) : (0, productPage_1.stockCeiling)(variant)) : 0;
|
|
82
|
+
const inCart = (0, productPage_1.quantityInCart)(cart, variant === null || variant === void 0 ? void 0 : variant.id);
|
|
83
|
+
const add = (0, react_1.useCallback)(async (input = {}) => {
|
|
84
|
+
var _a, _b, _c, _d, _e;
|
|
85
|
+
const o = optionsRef.current;
|
|
86
|
+
const done = (result) => {
|
|
87
|
+
var _a;
|
|
88
|
+
(_a = (result.ok ? o.onAdded : o.onRefused)) === null || _a === void 0 ? void 0 : _a(result);
|
|
89
|
+
return result;
|
|
90
|
+
};
|
|
91
|
+
if (!variant)
|
|
92
|
+
return done({ ok: false, reason: 'no-variant', cart });
|
|
93
|
+
const max = o.maxQuantity ? o.maxQuantity(variant) : (0, productPage_1.stockCeiling)(variant);
|
|
94
|
+
setAdding(true);
|
|
95
|
+
try {
|
|
96
|
+
const result = await addLine({
|
|
97
|
+
merchandiseId: variant.id,
|
|
98
|
+
quantity: (_b = (_a = input.quantity) !== null && _a !== void 0 ? _a : o.quantity) !== null && _b !== void 0 ? _b : 1,
|
|
99
|
+
attributes: (_c = input.attributes) !== null && _c !== void 0 ? _c : o.attributes,
|
|
100
|
+
sellingPlanId: (_d = input.sellingPlanId) !== null && _d !== void 0 ? _d : o.sellingPlanId,
|
|
101
|
+
maxQuantity: max,
|
|
102
|
+
source: (_e = input.source) !== null && _e !== void 0 ? _e : o.source,
|
|
103
|
+
});
|
|
104
|
+
return done(result);
|
|
105
|
+
}
|
|
106
|
+
catch (error) {
|
|
107
|
+
// Shopify refused the line: the provider has raised cart:outOfStock already.
|
|
108
|
+
return done({ ok: false, reason: 'outOfStock', error, cart });
|
|
109
|
+
}
|
|
110
|
+
finally {
|
|
111
|
+
setAdding(false);
|
|
112
|
+
}
|
|
113
|
+
}, [variant, addLine, cart]);
|
|
114
|
+
return { add, adding, inCart, canAddMore: !!variant && (0, productPage_1.withinCeiling)(ceiling, inCart, 1) };
|
|
115
|
+
}
|
|
116
|
+
function useProductPage(handle, options = {}) {
|
|
117
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l;
|
|
118
|
+
const result = (0, useProduct_1.useProduct)(handle, { imageTransform: options.imageTransform, onError: options.onError });
|
|
119
|
+
const { product, preview } = result;
|
|
120
|
+
const shown = (_a = product !== null && product !== void 0 ? product : preview) !== null && _a !== void 0 ? _a : null;
|
|
121
|
+
const selection = useVariantSelection(shown, { ...options, resetKey: options.resetKey !== undefined ? options.resetKey : (handle !== null && handle !== void 0 ? handle : null) });
|
|
122
|
+
const cart = useAddToCart(selection.variant, options);
|
|
123
|
+
const wishlist = (0, ShopifyProvider_1.useWishlist)();
|
|
124
|
+
// Once per product, when the full product lands.
|
|
125
|
+
const viewed = (0, react_1.useRef)(null);
|
|
126
|
+
const onViewRef = (0, react_1.useRef)(options.onView);
|
|
127
|
+
onViewRef.current = options.onView;
|
|
128
|
+
(0, react_1.useEffect)(() => {
|
|
129
|
+
var _a;
|
|
130
|
+
if (!product || viewed.current === product.id)
|
|
131
|
+
return;
|
|
132
|
+
viewed.current = product.id;
|
|
133
|
+
(_a = onViewRef.current) === null || _a === void 0 ? void 0 : _a.call(onViewRef, product);
|
|
134
|
+
}, [product]);
|
|
135
|
+
const html = (shown === null || shown === void 0 ? void 0 : shown.descriptionHtml) || (shown === null || shown === void 0 ? void 0 : shown.description) || '';
|
|
136
|
+
const parse = (_b = options.parseDescription) !== null && _b !== void 0 ? _b : true;
|
|
137
|
+
const blocks = (0, react_1.useMemo)(() => (parse === false ? [] : typeof parse === 'function' ? parse(html) : (0, productPage_1.parseDescriptionHtml)(html)), [parse, html]);
|
|
138
|
+
const blocked = !!shown && !!((_c = options.isBlocked) === null || _c === void 0 ? void 0 : _c.call(options, shown));
|
|
139
|
+
const status = !shown
|
|
140
|
+
? 'loading'
|
|
141
|
+
: blocked
|
|
142
|
+
? 'blocked'
|
|
143
|
+
: !selection.known
|
|
144
|
+
? 'unknown'
|
|
145
|
+
: selection.unavailable
|
|
146
|
+
? 'unavailable'
|
|
147
|
+
: 'available';
|
|
148
|
+
const toggle = (0, react_1.useCallback)(() => (shown ? wishlist.toggle(product !== null && product !== void 0 ? product : shown.id) : Promise.resolve(false)), [wishlist, product, shown]);
|
|
149
|
+
const asked = options.recommendations;
|
|
150
|
+
const recommendationOptions = typeof asked === 'object' ? asked : {};
|
|
151
|
+
const isBlocked = options.isBlocked;
|
|
152
|
+
const recommendations = (0, useProductRecommendations_1.useProductRecommendations)(shown === null || shown === void 0 ? void 0 : shown.id, {
|
|
153
|
+
...recommendationOptions,
|
|
154
|
+
enabled: !!asked && ((_d = recommendationOptions.enabled) !== null && _d !== void 0 ? _d : true),
|
|
155
|
+
exclude: (_e = recommendationOptions.exclude) !== null && _e !== void 0 ? _e : (isBlocked ? (p) => isBlocked(p) : undefined),
|
|
156
|
+
onError: (_f = recommendationOptions.onError) !== null && _f !== void 0 ? _f : (options.onError ? (error, ctx) => options.onError(error, { at: ctx.at, handle: handle !== null && handle !== void 0 ? handle : '' }) : undefined),
|
|
157
|
+
});
|
|
158
|
+
return {
|
|
159
|
+
...result,
|
|
160
|
+
product,
|
|
161
|
+
preview,
|
|
162
|
+
shown,
|
|
163
|
+
status,
|
|
164
|
+
selection,
|
|
165
|
+
cart,
|
|
166
|
+
media: {
|
|
167
|
+
items: (_g = product === null || product === void 0 ? void 0 : product.media) !== null && _g !== void 0 ? _g : [],
|
|
168
|
+
initialIndex: product ? (0, productPage_1.initialMediaIndex)(product.media, options.playVideo) : 0,
|
|
169
|
+
firstImageUrl: product ? (0, productPage_1.firstImageUrl)(product) : ((_j = (_h = preview === null || preview === void 0 ? void 0 : preview.featuredImage) === null || _h === void 0 ? void 0 : _h.url) !== null && _j !== void 0 ? _j : null),
|
|
170
|
+
previewImageUrl: (_l = (_k = preview === null || preview === void 0 ? void 0 : preview.featuredImage) === null || _k === void 0 ? void 0 : _k.url) !== null && _l !== void 0 ? _l : null,
|
|
171
|
+
},
|
|
172
|
+
description: { html, blocks },
|
|
173
|
+
favorite: { isFavorite: !!shown && wishlist.has(shown.id), toggle },
|
|
174
|
+
shareUrl: (0, productPage_1.productShareUrl)(product !== null && product !== void 0 ? product : shown, options.storeDomain),
|
|
175
|
+
recommendations,
|
|
176
|
+
};
|
|
177
|
+
}
|
|
178
|
+
//# sourceMappingURL=useProductPage.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useProductPage.js","sourceRoot":"","sources":["../../src/react/useProductPage.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { ImageTransform, Product } from '../types';
|
|
2
|
+
export interface UseProductRecommendationsOptions {
|
|
3
|
+
/** Read them. Below the fold on most pages: pass false until the page has settled. @default true */
|
|
4
|
+
enabled?: boolean;
|
|
5
|
+
/** At most this many. @default 10 */
|
|
6
|
+
limit?: number;
|
|
7
|
+
/** For the cards' images. A grid's card size keeps them in the same image cache as the grids. */
|
|
8
|
+
imageTransform?: ImageTransform;
|
|
9
|
+
/** Leave a product out (e.g. one that can't be bought). The product itself is always left out. */
|
|
10
|
+
exclude?: (product: Product) => boolean;
|
|
11
|
+
onError?: (error: unknown, context: {
|
|
12
|
+
at: string;
|
|
13
|
+
productId: string;
|
|
14
|
+
}) => void;
|
|
15
|
+
}
|
|
16
|
+
export interface ProductRecommendations {
|
|
17
|
+
products: Product[];
|
|
18
|
+
/** Reading, with nothing to show yet. */
|
|
19
|
+
loading: boolean;
|
|
20
|
+
/** The read failed; whatever was shown stays. */
|
|
21
|
+
error: boolean;
|
|
22
|
+
}
|
|
23
|
+
export declare const DEFAULT_RECOMMENDATION_LIMIT = 10;
|
|
24
|
+
export declare function useProductRecommendations(productId: string | null | undefined, options?: UseProductRecommendationsOptions): ProductRecommendations;
|
|
25
|
+
/** Tests only: forget this session's reads. */
|
|
26
|
+
export declare function clearRecommendationSession(): void;
|
|
27
|
+
//# sourceMappingURL=useProductRecommendations.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useProductRecommendations.d.ts","sourceRoot":"","sources":["../../src/react/useProductRecommendations.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,cAAc,EAAE,OAAO,EAAE,MAAM,UAAU,CAAC;AAGxD,MAAM,WAAW,gCAAgC;IAC/C,oGAAoG;IACpG,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,qCAAqC;IACrC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,iGAAiG;IACjG,cAAc,CAAC,EAAE,cAAc,CAAC;IAChC,kGAAkG;IAClG,OAAO,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,OAAO,CAAC;IACxC,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,CAAC;CAChF;AAED,MAAM,WAAW,sBAAsB;IACrC,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB,yCAAyC;IACzC,OAAO,EAAE,OAAO,CAAC;IACjB,iDAAiD;IACjD,KAAK,EAAE,OAAO,CAAC;CAChB;AAED,eAAO,MAAM,4BAA4B,KAAK,CAAC;AAY/C,wBAAgB,yBAAyB,CACvC,SAAS,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,EACpC,OAAO,GAAE,gCAAqC,GAC7C,sBAAsB,CA4CxB;AAED,+CAA+C;AAC/C,wBAAgB,0BAA0B,IAAI,IAAI,CAEjD"}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.DEFAULT_RECOMMENDATION_LIMIT = void 0;
|
|
4
|
+
exports.useProductRecommendations = useProductRecommendations;
|
|
5
|
+
exports.clearRecommendationSession = clearRecommendationSession;
|
|
6
|
+
/**
|
|
7
|
+
* "You may also like": Shopify's related products for a product (Storefront `productRecommendations`,
|
|
8
|
+
* the same list the online store's product page shows).
|
|
9
|
+
*
|
|
10
|
+
* Read once per product and kept for the session, so reopening a product shows them at once. Every
|
|
11
|
+
* product read also lands in the product store (base keys, variants included), so a recommendation
|
|
12
|
+
* tapped opens with its picker and Add to Cart in the first frame, like a grid's card.
|
|
13
|
+
*/
|
|
14
|
+
const react_1 = require("react");
|
|
15
|
+
const client_1 = require("../client");
|
|
16
|
+
const shopify_1 = require("../shopify");
|
|
17
|
+
const ShopifyProvider_1 = require("./ShopifyProvider");
|
|
18
|
+
exports.DEFAULT_RECOMMENDATION_LIMIT = 10;
|
|
19
|
+
/** This session's reads, by product and image size: the first render of a reopened product has them. */
|
|
20
|
+
const session = new Map();
|
|
21
|
+
const keyOf = (productId, transform) => `${productId}|${transform ? JSON.stringify(transform) : ''}`;
|
|
22
|
+
function pick(list, productId, limit, exclude) {
|
|
23
|
+
return list.filter((product) => product.id !== productId && !(exclude === null || exclude === void 0 ? void 0 : exclude(product))).slice(0, limit);
|
|
24
|
+
}
|
|
25
|
+
function useProductRecommendations(productId, options = {}) {
|
|
26
|
+
var _a, _b;
|
|
27
|
+
const { ready } = (0, ShopifyProvider_1.useShopify)();
|
|
28
|
+
const configured = ready || (0, client_1.isConfigured)();
|
|
29
|
+
const enabled = (_a = options.enabled) !== null && _a !== void 0 ? _a : true;
|
|
30
|
+
const limit = Math.max(1, Math.round((_b = options.limit) !== null && _b !== void 0 ? _b : exports.DEFAULT_RECOMMENDATION_LIMIT));
|
|
31
|
+
const transformKey = options.imageTransform ? JSON.stringify(options.imageTransform) : '';
|
|
32
|
+
const latest = (0, react_1.useRef)(options);
|
|
33
|
+
latest.current = options;
|
|
34
|
+
const cached = productId ? session.get(keyOf(productId, options.imageTransform)) : undefined;
|
|
35
|
+
const [state, setState] = (0, react_1.useState)(() => ({
|
|
36
|
+
products: cached ? pick(cached, productId, limit, options.exclude) : [],
|
|
37
|
+
loading: false,
|
|
38
|
+
error: false,
|
|
39
|
+
}));
|
|
40
|
+
(0, react_1.useEffect)(() => {
|
|
41
|
+
if (!productId || !enabled || !configured)
|
|
42
|
+
return;
|
|
43
|
+
const { imageTransform, exclude } = latest.current;
|
|
44
|
+
const key = keyOf(productId, imageTransform);
|
|
45
|
+
const known = session.get(key);
|
|
46
|
+
if (known) {
|
|
47
|
+
setState({ products: pick(known, productId, limit, exclude), loading: false, error: false });
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
let live = true;
|
|
51
|
+
setState((current) => ({ ...current, loading: current.products.length === 0, error: false }));
|
|
52
|
+
shopify_1.shopify.products
|
|
53
|
+
.recommended(productId, { imageTransform })
|
|
54
|
+
.then((list) => {
|
|
55
|
+
session.set(key, list);
|
|
56
|
+
if (live)
|
|
57
|
+
setState({ products: pick(list, productId, limit, latest.current.exclude), loading: false, error: false });
|
|
58
|
+
})
|
|
59
|
+
.catch((error) => {
|
|
60
|
+
var _a, _b;
|
|
61
|
+
(_b = (_a = latest.current).onError) === null || _b === void 0 ? void 0 : _b.call(_a, error, { at: 'useProductRecommendations', productId });
|
|
62
|
+
if (live)
|
|
63
|
+
setState((current) => ({ ...current, loading: false, error: true }));
|
|
64
|
+
});
|
|
65
|
+
return () => {
|
|
66
|
+
live = false;
|
|
67
|
+
};
|
|
68
|
+
// The options object is new every render; what it changes is read through `latest`.
|
|
69
|
+
}, [productId, enabled, configured, limit, transformKey]);
|
|
70
|
+
return state;
|
|
71
|
+
}
|
|
72
|
+
/** Tests only: forget this session's reads. */
|
|
73
|
+
function clearRecommendationSession() {
|
|
74
|
+
session.clear();
|
|
75
|
+
}
|
|
76
|
+
//# sourceMappingURL=useProductRecommendations.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useProductRecommendations.js","sourceRoot":"","sources":["../../src/react/useProductRecommendations.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import type { Money, StoreCreditEntry } from '../types';
|
|
2
|
+
export interface StoreCreditState {
|
|
3
|
+
/** The app's choice; null when it shows no store credit. */
|
|
4
|
+
source: 'shopify' | 'tile' | null;
|
|
5
|
+
/**
|
|
6
|
+
* The balance can be read for this shopper: signed in, and for `shopify`, signed in with Shopify.
|
|
7
|
+
* Shopify store credit is only readable through the Customer Account API, so it is unavailable
|
|
8
|
+
* to a password session (App Store review mode).
|
|
9
|
+
*/
|
|
10
|
+
available: boolean;
|
|
11
|
+
balance: Money | null;
|
|
12
|
+
loading: boolean;
|
|
13
|
+
error: Error | null;
|
|
14
|
+
refresh: () => Promise<void>;
|
|
15
|
+
}
|
|
16
|
+
export declare function useStoreCredit(): StoreCreditState;
|
|
17
|
+
export interface UseStoreCreditHistoryOptions {
|
|
18
|
+
/** Lines per page. Default `STORE_CREDIT_HISTORY_PAGE_SIZE` (25). */
|
|
19
|
+
pageSize?: number;
|
|
20
|
+
}
|
|
21
|
+
export interface StoreCreditHistoryState {
|
|
22
|
+
/** The app's choice; null when it shows no store credit. */
|
|
23
|
+
source: 'shopify' | 'tile' | null;
|
|
24
|
+
/** The history can be read for this shopper: the same rule as the balance (`useStoreCredit`). */
|
|
25
|
+
available: boolean;
|
|
26
|
+
/** Newest first. Empty when it can't be read. */
|
|
27
|
+
entries: StoreCreditEntry[];
|
|
28
|
+
/**
|
|
29
|
+
* True only before the first answer: while a stored session is read on app open, then until the
|
|
30
|
+
* first page arrives. A refresh never sets it; the list stays on screen.
|
|
31
|
+
*/
|
|
32
|
+
loading: boolean;
|
|
33
|
+
/** A next page is on its way (`loadMore`). */
|
|
34
|
+
loadingMore: boolean;
|
|
35
|
+
/** More lines than are loaded. */
|
|
36
|
+
hasMore: boolean;
|
|
37
|
+
/** The last read failed. Whatever was shown stays. Cleared by the next read that works. */
|
|
38
|
+
error: Error | null;
|
|
39
|
+
/** Reads the next page. Does nothing while another read is on its way, or at the end. */
|
|
40
|
+
loadMore: () => void;
|
|
41
|
+
/**
|
|
42
|
+
* Reads the newest page again (pull to refresh, a screen coming back into view) and starts the
|
|
43
|
+
* list over from it. Joins a first read already on its way. Never rejects.
|
|
44
|
+
*/
|
|
45
|
+
refresh: () => Promise<void>;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* The history behind the balance, from the same source as `useStoreCredit`, newest first, a page at a
|
|
49
|
+
* time:
|
|
50
|
+
* - `tile`: Tile Credit's ledger (`/public/me/ledger`), with the same service, token and shop as the
|
|
51
|
+
* balance. Either sign-in.
|
|
52
|
+
* - `shopify`: the Customer Account API's store-credit transactions, for a Shopify sign-in only.
|
|
53
|
+
*
|
|
54
|
+
* Signed out, or with no source, it is empty with no error and reads nothing. Loads when it becomes
|
|
55
|
+
* readable, and starts over for another shopper.
|
|
56
|
+
*/
|
|
57
|
+
export declare function useStoreCreditHistory(options?: UseStoreCreditHistoryOptions): StoreCreditHistoryState;
|
|
58
|
+
//# sourceMappingURL=useStoreCredit.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useStoreCredit.d.ts","sourceRoot":"","sources":["../../src/react/useStoreCredit.ts"],"names":[],"mappings":"AAuBA,OAAO,KAAK,EAAE,KAAK,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAExD,MAAM,WAAW,gBAAgB;IAC/B,4DAA4D;IAC5D,MAAM,EAAE,SAAS,GAAG,MAAM,GAAG,IAAI,CAAC;IAClC;;;;OAIG;IACH,SAAS,EAAE,OAAO,CAAC;IACnB,OAAO,EAAE,KAAK,GAAG,IAAI,CAAC;IACtB,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC;IACpB,OAAO,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC9B;AAED,wBAAgB,cAAc,IAAI,gBAAgB,CAqDjD;AAID,MAAM,WAAW,4BAA4B;IAC3C,qEAAqE;IACrE,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,uBAAuB;IACtC,4DAA4D;IAC5D,MAAM,EAAE,SAAS,GAAG,MAAM,GAAG,IAAI,CAAC;IAClC,iGAAiG;IACjG,SAAS,EAAE,OAAO,CAAC;IACnB,iDAAiD;IACjD,OAAO,EAAE,gBAAgB,EAAE,CAAC;IAC5B;;;OAGG;IACH,OAAO,EAAE,OAAO,CAAC;IACjB,8CAA8C;IAC9C,WAAW,EAAE,OAAO,CAAC;IACrB,kCAAkC;IAClC,OAAO,EAAE,OAAO,CAAC;IACjB,2FAA2F;IAC3F,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC;IACpB,yFAAyF;IACzF,QAAQ,EAAE,MAAM,IAAI,CAAC;IACrB;;;OAGG;IACH,OAAO,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC9B;AAyBD;;;;;;;;;GASG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,GAAE,4BAAiC,GAAG,uBAAuB,CA8GzG"}
|