@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
package/dist/tether.account.js
CHANGED
|
@@ -5,21 +5,18 @@
|
|
|
5
5
|
__defProp(target, name, { get: all[name], enumerable: true });
|
|
6
6
|
};
|
|
7
7
|
|
|
8
|
-
// src/account.
|
|
8
|
+
// src/account.ts
|
|
9
9
|
var account_exports = {};
|
|
10
10
|
__export(account_exports, {
|
|
11
11
|
addresses: () => addresses,
|
|
12
12
|
customer: () => customer,
|
|
13
13
|
deleteAddress: () => deleteAddress,
|
|
14
|
-
getToken: () => getToken,
|
|
15
|
-
handleCallback: () => handleCallback,
|
|
16
14
|
isLoggedIn: () => isLoggedIn,
|
|
17
15
|
login: () => login,
|
|
18
16
|
logout: () => logout,
|
|
19
17
|
mountAccount: () => mountAccount,
|
|
20
18
|
order: () => order,
|
|
21
19
|
orders: () => orders,
|
|
22
|
-
query: () => query,
|
|
23
20
|
render: () => render,
|
|
24
21
|
requestReturn: () => requestReturn,
|
|
25
22
|
saveAddress: () => saveAddress,
|
|
@@ -28,432 +25,516 @@
|
|
|
28
25
|
updateProfile: () => updateProfile
|
|
29
26
|
});
|
|
30
27
|
|
|
31
|
-
// tether-core:config.
|
|
32
|
-
var m = window.Tether.__core["config.
|
|
33
|
-
var
|
|
28
|
+
// tether-core:config.ts
|
|
29
|
+
var m = window.Tether.__core["config.ts"];
|
|
30
|
+
var [cfg, isConfigured, log, MARKET_SOURCES, parseMarkets, reportError, warn] = m;
|
|
34
31
|
|
|
35
|
-
// tether-core:client.
|
|
36
|
-
var m2 = window.Tether.__core["client.
|
|
37
|
-
var
|
|
32
|
+
// tether-core:client.ts
|
|
33
|
+
var m2 = window.Tether.__core["client.ts"];
|
|
34
|
+
var [endpoint, gql, orNull, shaped, TetherError] = m2;
|
|
38
35
|
|
|
39
|
-
// tether-core:dom.
|
|
40
|
-
var m3 = window.Tether.__core["dom.
|
|
41
|
-
var
|
|
36
|
+
// tether-core:dom.ts
|
|
37
|
+
var m3 = window.Tether.__core["dom.ts"];
|
|
38
|
+
var [ANALYTICS_EVENTS, attr, attributesFromJson, emit, formatDate, formatMoney, get, has, hasTemplate, isOwnEvent, parseJSONAttr, productUrl, qsa, repeat, sel, setImage, setText, show] = m3;
|
|
42
39
|
|
|
43
|
-
// tether-core:cart.
|
|
44
|
-
var m4 = window.Tether.__core["cart.
|
|
45
|
-
var
|
|
40
|
+
// tether-core:cart.ts
|
|
41
|
+
var m4 = window.Tether.__core["cart.ts"];
|
|
42
|
+
var [Cart] = m4;
|
|
46
43
|
|
|
47
|
-
// tether-core:lazy.
|
|
48
|
-
var m5 = window.Tether.__core["lazy.
|
|
49
|
-
var
|
|
44
|
+
// tether-core:lazy.ts
|
|
45
|
+
var m5 = window.Tether.__core["lazy.ts"];
|
|
46
|
+
var [loadPart] = m5;
|
|
50
47
|
|
|
51
|
-
// src/
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
var
|
|
48
|
+
// server/src/shared/json.ts
|
|
49
|
+
function isRecord(value) {
|
|
50
|
+
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
51
|
+
}
|
|
52
|
+
function field(value, key) {
|
|
53
|
+
return isRecord(value) ? value[key] : void 0;
|
|
54
|
+
}
|
|
55
|
+
function asList(value) {
|
|
56
|
+
return Array.isArray(value) ? value : [];
|
|
57
|
+
}
|
|
58
|
+
function textOrNull(value) {
|
|
59
|
+
return typeof value === "string" && value !== "" ? value : null;
|
|
60
|
+
}
|
|
61
|
+
var numberOrNull = (value) => typeof value === "number" && Number.isFinite(value) ? value : null;
|
|
62
|
+
var countOrZero = (value) => numberOrNull(value) ?? 0;
|
|
63
|
+
var listOf = (value, read) => asList(value).map((item) => read(item));
|
|
64
|
+
var nodesOf = (connection, read) => ({
|
|
65
|
+
nodes: listOf(field(connection, "nodes"), read)
|
|
66
|
+
});
|
|
67
|
+
var textList = (value) => listOf(value, textOrNull).filter((line) => line !== null);
|
|
68
|
+
|
|
69
|
+
// server/src/shared/error-message.ts
|
|
70
|
+
function messageOf(error) {
|
|
71
|
+
return error instanceof Error ? error.message : String(error);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// src/storage.ts
|
|
75
|
+
function setStored(key, value, area = "localStorage") {
|
|
67
76
|
try {
|
|
68
|
-
|
|
69
|
-
else s.removeItem(k);
|
|
77
|
+
window[area].setItem(key, value);
|
|
70
78
|
} catch {
|
|
71
79
|
}
|
|
72
|
-
};
|
|
73
|
-
var discovery = null;
|
|
74
|
-
var session = null;
|
|
75
|
-
var refreshing = null;
|
|
76
|
-
var customerCache = null;
|
|
77
|
-
var server = () => cfg.account?.server ? new URL(String(cfg.account.server), window.location.href).href.replace(/\/$/, "") : "";
|
|
78
|
-
var HINT = () => `${cfg.prefix}:account-hint:${cfg.domain}`;
|
|
79
|
-
var serverState = null;
|
|
80
|
-
async function serverFetch(path, { method = "GET", body } = {}) {
|
|
81
|
-
const res = await fetch(`${server()}${path}`, {
|
|
82
|
-
method,
|
|
83
|
-
credentials: "include",
|
|
84
|
-
headers: method === "POST" ? { "Content-Type": "application/json", "X-Tether-Account": "1" } : {},
|
|
85
|
-
body: body ? JSON.stringify(body) : void 0
|
|
86
|
-
});
|
|
87
|
-
const data = await res.json().catch(() => ({}));
|
|
88
|
-
if (!res.ok && res.status !== 401) throw new TetherError(`Customer accounts: ${data.error || res.status}`, { status: res.status, userErrors: data.userErrors });
|
|
89
|
-
return data;
|
|
90
80
|
}
|
|
91
|
-
|
|
92
|
-
serverState || (serverState = await serverFetch("/me"));
|
|
81
|
+
function removeStored(key, area = "localStorage") {
|
|
93
82
|
try {
|
|
94
|
-
|
|
95
|
-
else window.localStorage.removeItem(HINT());
|
|
83
|
+
window[area].removeItem(key);
|
|
96
84
|
} catch {
|
|
97
85
|
}
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
const
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// src/account-marks.ts
|
|
89
|
+
var hintKey = () => `${cfg.prefix}:account-hint:${cfg.domain}`;
|
|
90
|
+
var isLoginOutcome = (value) => value === "in" || value === "expired" || value === "error";
|
|
91
|
+
|
|
92
|
+
// server/src/shared/account-orders.ts
|
|
93
|
+
function moneyOrNull(value) {
|
|
94
|
+
const amount = textOrNull(field(value, "amount"));
|
|
95
|
+
const currencyCode = textOrNull(field(value, "currencyCode"));
|
|
96
|
+
return amount === null || currencyCode === null ? null : { amount, currencyCode };
|
|
97
|
+
}
|
|
98
|
+
function imageOrNull(value) {
|
|
99
|
+
const url = textOrNull(field(value, "url"));
|
|
100
|
+
return url === null ? null : { url, altText: textOrNull(field(value, "altText")) };
|
|
101
|
+
}
|
|
102
|
+
var toOrderLine = (value) => ({
|
|
103
|
+
title: textOrNull(field(value, "title")),
|
|
104
|
+
variantTitle: textOrNull(field(value, "variantTitle")),
|
|
105
|
+
quantity: countOrZero(field(value, "quantity")),
|
|
106
|
+
image: imageOrNull(field(value, "image"))
|
|
107
|
+
});
|
|
108
|
+
var toAccountOrder = (value, id) => ({
|
|
109
|
+
id,
|
|
110
|
+
name: textOrNull(field(value, "name")),
|
|
111
|
+
processedAt: textOrNull(field(value, "processedAt")),
|
|
112
|
+
financialStatus: textOrNull(field(value, "financialStatus")),
|
|
113
|
+
fulfillmentStatus: textOrNull(field(value, "fulfillmentStatus")),
|
|
114
|
+
statusPageUrl: textOrNull(field(value, "statusPageUrl")),
|
|
115
|
+
totalPrice: moneyOrNull(field(value, "totalPrice")),
|
|
116
|
+
lineItems: nodesOf(field(value, "lineItems"), toOrderLine)
|
|
117
|
+
});
|
|
118
|
+
function readOrders(value) {
|
|
119
|
+
const orders2 = [];
|
|
120
|
+
for (const item of asList(value)) {
|
|
121
|
+
const id = textOrNull(field(item, "id"));
|
|
122
|
+
if (id === null) return { kind: "missing-id" };
|
|
123
|
+
orders2.push(toAccountOrder(item, id));
|
|
124
124
|
}
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
const
|
|
133
|
-
const
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
125
|
+
return { kind: "read", orders: orders2 };
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
// src/account/answers.ts
|
|
129
|
+
var unexpected = (what) => new TetherError(`Customer accounts: the answer has no ${what}`);
|
|
130
|
+
function toAccountCustomer(value) {
|
|
131
|
+
const customer2 = isRecord(value) ? value : {};
|
|
132
|
+
const id = textOrNull(customer2["id"]);
|
|
133
|
+
const email = textOrNull(customer2["email"]);
|
|
134
|
+
const address = customer2["address"];
|
|
135
|
+
return {
|
|
136
|
+
...id === null ? {} : { id },
|
|
137
|
+
firstName: textOrNull(customer2["firstName"]),
|
|
138
|
+
lastName: textOrNull(customer2["lastName"]),
|
|
139
|
+
displayName: textOrNull(customer2["displayName"]),
|
|
140
|
+
emailAddress: email === null ? null : { emailAddress: email },
|
|
141
|
+
defaultAddress: Array.isArray(address) ? { formatted: textList(address) } : null
|
|
142
142
|
};
|
|
143
|
-
const lang = locale || cfg.account.locale || (cfg.locale || "").split("-")[0];
|
|
144
|
-
if (lang) p.locale = lang;
|
|
145
|
-
if (cfg.country) p.region_country = String(cfg.country).toUpperCase();
|
|
146
|
-
Object.entries(p).forEach(([k, v]) => u.searchParams.set(k, v));
|
|
147
|
-
go(u.toString());
|
|
148
|
-
}
|
|
149
|
-
async function tokenRequest(params) {
|
|
150
|
-
const d = await discover();
|
|
151
|
-
const res = await fetch(cfg.account.tokenUrl || d.token_endpoint, { method: "POST", body: new URLSearchParams(params) });
|
|
152
|
-
const data = await res.json().catch(() => ({}));
|
|
153
|
-
if (!res.ok || !data.access_token) throw new TetherError(`Customer accounts: token ${res.status} ${data.error || ""}`.trim(), { status: res.status, code: res.status === 400 || res.status === 401 ? "SESSION_ENDED" : "TOKEN_FAILED" });
|
|
154
|
-
return data;
|
|
155
|
-
}
|
|
156
|
-
function decodeJwt(t) {
|
|
157
|
-
try {
|
|
158
|
-
return JSON.parse(atob(t.split(".")[1].replace(/-/g, "+").replace(/_/g, "/")));
|
|
159
|
-
} catch {
|
|
160
|
-
return null;
|
|
161
|
-
}
|
|
162
143
|
}
|
|
163
|
-
function
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
144
|
+
function toAccountOrders(value) {
|
|
145
|
+
const reading = readOrders(value);
|
|
146
|
+
if (reading.kind === "missing-id") throw unexpected("order id");
|
|
147
|
+
return reading.orders;
|
|
148
|
+
}
|
|
149
|
+
function toUserError(value) {
|
|
150
|
+
const message = textOrNull(field(value, "message"));
|
|
151
|
+
if (message === null) return null;
|
|
152
|
+
const fieldPath = field(value, "field");
|
|
153
|
+
return {
|
|
154
|
+
message,
|
|
155
|
+
field: Array.isArray(fieldPath) ? textList(fieldPath) : null,
|
|
156
|
+
code: textOrNull(field(value, "code"))
|
|
169
157
|
};
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
window.history.replaceState(window.history.state, "", clean);
|
|
180
|
-
if (q.has("error")) {
|
|
181
|
-
emit("account-error", { error: q.get("error") });
|
|
182
|
-
return false;
|
|
183
|
-
}
|
|
184
|
-
if (Date.now() - pending.at > 10 * 6e4) throw new TetherError("Customer accounts: the login took too long, please try again");
|
|
185
|
-
const data = await tokenRequest({
|
|
186
|
-
grant_type: "authorization_code",
|
|
187
|
-
client_id: cfg.account.clientId,
|
|
188
|
-
redirect_uri: pending.redirect,
|
|
189
|
-
code: q.get("code"),
|
|
190
|
-
code_verifier: pending.verifier
|
|
191
|
-
});
|
|
192
|
-
const d = await discover();
|
|
193
|
-
const claims = decodeJwt(data.id_token || "");
|
|
194
|
-
const aud = [].concat(claims?.aud || []);
|
|
195
|
-
if (!claims || claims.nonce !== pending.nonce || claims.iss !== d.issuer || !aud.includes(cfg.account.clientId) || claims.exp * 1e3 < Date.now()) {
|
|
196
|
-
throw new TetherError("Customer accounts: the login answer did not check out (nonce/issuer/audience)");
|
|
158
|
+
}
|
|
159
|
+
var toUserErrors = (value) => listOf(value, toUserError).filter((error) => error !== null);
|
|
160
|
+
|
|
161
|
+
// src/account/server-client.ts
|
|
162
|
+
var known = null;
|
|
163
|
+
function serverBase() {
|
|
164
|
+
const server = cfg.account?.server;
|
|
165
|
+
if (!server) {
|
|
166
|
+
throw new TetherError("Customer accounts need the Worker: set account.server", { code: "NOT_CONFIGURED" });
|
|
197
167
|
}
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
endSession();
|
|
212
|
-
return null;
|
|
168
|
+
return new URL(server, window.location.href).href.replace(/\/$/, "");
|
|
169
|
+
}
|
|
170
|
+
function setLoginHint(loggedIn) {
|
|
171
|
+
if (loggedIn) setStored(hintKey(), "1");
|
|
172
|
+
else removeStored(hintKey());
|
|
173
|
+
}
|
|
174
|
+
async function fetchFromWorker(url, init) {
|
|
175
|
+
try {
|
|
176
|
+
return await fetch(url, init);
|
|
177
|
+
} catch (error) {
|
|
178
|
+
throw new TetherError(`Network error: ${messageOf(error)}`, {
|
|
179
|
+
code: "NETWORK"
|
|
180
|
+
});
|
|
213
181
|
}
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
} finally {
|
|
222
|
-
refreshing = null;
|
|
223
|
-
}
|
|
224
|
-
})());
|
|
225
|
-
await refreshing;
|
|
226
|
-
return session?.access || null;
|
|
227
|
-
}
|
|
228
|
-
function endSession() {
|
|
229
|
-
session = null;
|
|
230
|
-
customerCache = null;
|
|
231
|
-
write(store(), KEY(), null);
|
|
232
|
-
Cart.customerAccessToken = null;
|
|
233
|
-
}
|
|
234
|
-
async function linkCart() {
|
|
235
|
-
Cart.customerAccessToken = session?.access || null;
|
|
236
|
-
if (Cart.id() && session?.access) {
|
|
237
|
-
await Cart.setBuyerIdentity({ customerAccessToken: session.access }, { create: false }).catch((err) => reportError(err, "account cart"));
|
|
182
|
+
}
|
|
183
|
+
async function readJsonObjectOrEmpty(response) {
|
|
184
|
+
let json;
|
|
185
|
+
try {
|
|
186
|
+
json = await response.json();
|
|
187
|
+
} catch {
|
|
188
|
+
return {};
|
|
238
189
|
}
|
|
190
|
+
return isRecord(json) ? json : {};
|
|
239
191
|
}
|
|
240
|
-
async function
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
if (
|
|
244
|
-
const
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
if (
|
|
248
|
-
|
|
249
|
-
|
|
192
|
+
async function serverFetch(path, { method = "GET", body } = {}) {
|
|
193
|
+
const init = { method, credentials: "include" };
|
|
194
|
+
if (method === "POST") init.headers = { "Content-Type": "application/json", "X-Tether-Account": "1" };
|
|
195
|
+
if (body) init.body = JSON.stringify(body);
|
|
196
|
+
const response = await fetchFromWorker(`${serverBase()}${path}`, init);
|
|
197
|
+
if (response.status === 401) return { kind: "logged-out" };
|
|
198
|
+
const data = await readJsonObjectOrEmpty(response);
|
|
199
|
+
if (!response.ok) {
|
|
200
|
+
const reason = textOrNull(data["error"]) ?? String(response.status);
|
|
201
|
+
const userErrors = toUserErrors(data["userErrors"]);
|
|
202
|
+
throw new TetherError(`Customer accounts: ${reason}`, {
|
|
203
|
+
status: response.status,
|
|
204
|
+
...userErrors.length > 0 && { userErrors },
|
|
205
|
+
// The Worker marks refused input (a 400, or a 404 for a contract that isn't the customer's) with `code`.
|
|
206
|
+
...data["code"] === "INVALID" && { code: "INVALID" }
|
|
207
|
+
});
|
|
250
208
|
}
|
|
251
|
-
|
|
252
|
-
if (!res.ok || json.errors?.length) throw new TetherError(json.errors?.map((e) => e.message).join(" | ") || `Customer accounts: ${res.status}`, { status: res.status });
|
|
253
|
-
return json.data;
|
|
209
|
+
return { kind: "answer", data };
|
|
254
210
|
}
|
|
255
|
-
async function
|
|
256
|
-
if (
|
|
257
|
-
const
|
|
258
|
-
|
|
211
|
+
async function serverLogin() {
|
|
212
|
+
if (!known) {
|
|
213
|
+
const answer = await serverFetch("/me");
|
|
214
|
+
known = answer.kind === "answer" && answer.data["loggedIn"] === true ? { loggedIn: true, customer: toAccountCustomer(answer.data["customer"]) } : { loggedIn: false };
|
|
259
215
|
}
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
216
|
+
setLoginHint(known.loggedIn);
|
|
217
|
+
return known;
|
|
218
|
+
}
|
|
219
|
+
var isServerLoggedIn = () => known?.loggedIn === true;
|
|
220
|
+
function forgetServerLogin() {
|
|
221
|
+
known = null;
|
|
222
|
+
}
|
|
223
|
+
function navigate(url) {
|
|
224
|
+
const replacement = cfg.account?.navigate;
|
|
225
|
+
if (replacement) replacement(url);
|
|
226
|
+
else window.location.assign(url);
|
|
227
|
+
}
|
|
228
|
+
var loginLanguage = (locale) => locale || cfg.account?.locale || (cfg.locale || "").split("-")[0] || "";
|
|
229
|
+
function serverLoginRedirect({ returnTo, locale }) {
|
|
230
|
+
const url = new URL(`${serverBase()}/login`);
|
|
231
|
+
url.searchParams.set("returnTo", returnTo);
|
|
232
|
+
const language = loginLanguage(locale);
|
|
233
|
+
if (language) url.searchParams.set("locale", language);
|
|
234
|
+
if (cfg.country) url.searchParams.set("country", cfg.country.toUpperCase());
|
|
235
|
+
navigate(url.toString());
|
|
236
|
+
}
|
|
237
|
+
async function serverCheckoutUrl() {
|
|
238
|
+
const cartId = Cart.id();
|
|
239
|
+
if (!(await serverLogin()).loggedIn || !cartId) return null;
|
|
240
|
+
const answer = await serverFetch("/cart", { method: "POST", body: { cartId } });
|
|
241
|
+
if (answer.kind === "logged-out") return null;
|
|
242
|
+
return textOrNull(answer.data["checkoutUrl"]);
|
|
243
|
+
}
|
|
244
|
+
async function serverLogout(returnTo) {
|
|
245
|
+
const answer = await serverFetch("/logout", { method: "POST", body: { returnTo, cartId: Cart.id() } });
|
|
246
|
+
known = null;
|
|
247
|
+
setLoginHint(false);
|
|
248
|
+
emit("account-logout", {});
|
|
249
|
+
const logoutUrl = answer.kind === "answer" ? textOrNull(answer.data["logoutUrl"]) : null;
|
|
250
|
+
if (!logoutUrl) return "stayed";
|
|
251
|
+
navigate(logoutUrl);
|
|
252
|
+
return "redirected";
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
// tether-core:shopify-values.ts
|
|
256
|
+
var m6 = window.Tether.__core["shopify-values.ts"];
|
|
257
|
+
var [isHttpsUrl] = m6;
|
|
258
|
+
|
|
259
|
+
// src/account/markup.ts
|
|
260
|
+
function showIn(root, name, conditions) {
|
|
261
|
+
qsa(root, sel(name)).forEach((el) => {
|
|
262
|
+
const key = get(el, name) ?? "";
|
|
263
|
+
if (Object.hasOwn(conditions, key)) show(el, conditions[key] === true);
|
|
264
|
+
});
|
|
265
|
+
}
|
|
266
|
+
var bindsIn = (row, name) => qsa(row, sel(name)).concat(row.matches(sel(name)) ? [row] : []);
|
|
267
|
+
var ownValue = (values, key) => Object.hasOwn(values, key) ? values[key] : void 0;
|
|
268
|
+
|
|
269
|
+
// src/account/order-lines.ts
|
|
270
|
+
var lineTexts = (line, returnable) => ({
|
|
271
|
+
title: line.title || line.name || "",
|
|
272
|
+
"variant-title": line.variantTitle || "",
|
|
273
|
+
quantity: String(line.quantity),
|
|
274
|
+
price: formatMoney(line.price),
|
|
275
|
+
total: formatMoney(line.totalPrice),
|
|
276
|
+
sku: line.sku || "",
|
|
277
|
+
returnable: returnable === null ? void 0 : String(returnable)
|
|
278
|
+
});
|
|
279
|
+
var isInput = (el) => el.tagName === "INPUT";
|
|
280
|
+
function fillReturnControls(row, line, returnable) {
|
|
281
|
+
showIn(row, "order-line-show", { returnable: returnable > 0 });
|
|
282
|
+
qsa(row, sel("return-quantity")).forEach((input) => {
|
|
283
|
+
if (!isInput(input)) return;
|
|
284
|
+
input.max = String(returnable);
|
|
285
|
+
input.min = "0";
|
|
286
|
+
if (!input.value) input.value = "0";
|
|
287
|
+
input.disabled = returnable < 1;
|
|
288
|
+
});
|
|
289
|
+
qsa(row, `select${sel("return-reason")}`).forEach((select) => {
|
|
290
|
+
if (select.dataset["tetherFilled"] === line.id) return;
|
|
291
|
+
select.dataset["tetherFilled"] = line.id;
|
|
292
|
+
(line.suggestedReturnReasonDefinitions?.nodes ?? []).forEach((reason) => {
|
|
293
|
+
select.appendChild(new Option(reason.name ?? "", reason.id));
|
|
294
|
+
});
|
|
295
|
+
});
|
|
296
|
+
}
|
|
297
|
+
function fillLines(box, lines, returns) {
|
|
298
|
+
repeat(box, lines, (row, line) => {
|
|
299
|
+
const id = line.id;
|
|
300
|
+
const returnable = returns && id ? returns.get(id) ?? 0 : null;
|
|
301
|
+
if (id) row.dataset["tetherLine"] = id;
|
|
302
|
+
const texts = lineTexts(line, returnable);
|
|
303
|
+
bindsIn(row, "order-line").forEach((el) => {
|
|
304
|
+
const key = get(el, "order-line") ?? "";
|
|
305
|
+
if (key === "image") {
|
|
306
|
+
if (line.image) setImage(el, line.image.url, line.image.altText || line.title || "");
|
|
307
|
+
return;
|
|
308
|
+
}
|
|
309
|
+
const text = ownValue(texts, key);
|
|
310
|
+
if (text !== void 0) setText(el, text);
|
|
311
|
+
});
|
|
312
|
+
if (id && returnable !== null) fillReturnControls(row, { ...line, id }, returnable);
|
|
313
|
+
});
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
// src/account/order-list.ts
|
|
317
|
+
var DEFAULT_ORDER_COUNT = 10;
|
|
318
|
+
var MAX_ORDER_COUNT = 50;
|
|
319
|
+
var isOrderCount = (value) => typeof value === "number" && Number.isInteger(value) && value >= 1 && value <= MAX_ORDER_COUNT;
|
|
320
|
+
function listLimit(limit) {
|
|
321
|
+
const asked = Number.parseInt(limit || String(DEFAULT_ORDER_COUNT), 10) || DEFAULT_ORDER_COUNT;
|
|
322
|
+
return Math.min(Math.max(asked, 1), MAX_ORDER_COUNT);
|
|
323
|
+
}
|
|
324
|
+
var numericId = (gid) => gid.replace(/\?.*$/, "").replace(/^.*\//, "");
|
|
325
|
+
function orderUrl(order2) {
|
|
326
|
+
const template = cfg.account?.orderUrl;
|
|
327
|
+
if (template) return template.replaceAll("{id}", encodeURIComponent(numericId(order2.id)));
|
|
328
|
+
const statusPage = order2.statusPageUrl;
|
|
329
|
+
return statusPage !== null && isHttpsUrl(statusPage) ? statusPage : null;
|
|
330
|
+
}
|
|
331
|
+
var orderTexts = (order2) => ({
|
|
332
|
+
name: order2.name ?? "",
|
|
333
|
+
date: formatDate(order2.processedAt),
|
|
334
|
+
total: formatMoney(order2.totalPrice),
|
|
335
|
+
status: order2.financialStatus?.toLowerCase(),
|
|
336
|
+
fulfillment: order2.fulfillmentStatus?.toLowerCase(),
|
|
337
|
+
items: order2.lineItems.nodes.map((line) => `${String(line.quantity)}\xD7 ${line.title ?? ""}`).join(", ")
|
|
338
|
+
});
|
|
339
|
+
function fillOrder(node, order2) {
|
|
340
|
+
const lines = order2.lineItems.nodes;
|
|
341
|
+
const url = orderUrl(order2);
|
|
342
|
+
const texts = orderTexts(order2);
|
|
343
|
+
qsa(node, sel("order-bind")).forEach((el) => {
|
|
344
|
+
const key = get(el, "order-bind") ?? "";
|
|
345
|
+
if (key === "url") {
|
|
346
|
+
if (url) el.setAttribute("href", url);
|
|
347
|
+
return;
|
|
277
348
|
}
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
349
|
+
if (key === "image") {
|
|
350
|
+
const image = lines.find((line) => line.image)?.image;
|
|
351
|
+
if (image) setImage(el, image.url, image.altText || lines[0]?.title || "");
|
|
352
|
+
return;
|
|
353
|
+
}
|
|
354
|
+
const text = ownValue(texts, key);
|
|
355
|
+
if (text !== void 0) setText(el, text);
|
|
285
356
|
});
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
return;
|
|
291
|
-
}
|
|
292
|
-
const d = await discover();
|
|
293
|
-
const u = new URL(d.end_session_endpoint);
|
|
294
|
-
u.searchParams.set("id_token_hint", idToken);
|
|
295
|
-
u.searchParams.set("post_logout_redirect_uri", returnTo);
|
|
296
|
-
go(u.toString());
|
|
357
|
+
qsa(node, sel("order-lines")).forEach((box) => {
|
|
358
|
+
fillLines(box, lines, null);
|
|
359
|
+
});
|
|
360
|
+
if (get(node, "order-bind") === "url" && url) node.setAttribute("href", url);
|
|
297
361
|
}
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
var date = (s) => {
|
|
362
|
+
async function renderOrderList(root, loadOrders) {
|
|
363
|
+
const lists = qsa(root, sel("orders"));
|
|
364
|
+
const first = lists[0];
|
|
365
|
+
if (!first) return;
|
|
366
|
+
showIn(root, "show", { "orders-loading": true, "orders-empty": false });
|
|
367
|
+
const limit = listLimit(get(first, "limit"));
|
|
368
|
+
let orders2;
|
|
306
369
|
try {
|
|
307
|
-
|
|
308
|
-
} catch {
|
|
309
|
-
|
|
370
|
+
orders2 = await loadOrders(limit);
|
|
371
|
+
} catch (error) {
|
|
372
|
+
reportError(error, "orders");
|
|
373
|
+
orders2 = null;
|
|
310
374
|
}
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
qsa(root, sel("show")).forEach((el) => {
|
|
315
|
-
const k = get(el, "show");
|
|
316
|
-
if (k === "logged-in") show(el, logged);
|
|
317
|
-
if (k === "logged-out") show(el, !logged);
|
|
375
|
+
showIn(root, "show", { "orders-loading": false, "orders-empty": orders2?.length === 0 });
|
|
376
|
+
lists.forEach((list) => {
|
|
377
|
+
repeat(list, orders2 ?? [], fillOrder);
|
|
318
378
|
});
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
// src/account.ts
|
|
382
|
+
var PAGE_ATTRIBUTES = ["order", "addresses", "subscriptions", "profile-form", "address-form"];
|
|
383
|
+
var isLoggedIn = isServerLoggedIn;
|
|
384
|
+
function login({
|
|
385
|
+
returnTo = window.location.href,
|
|
386
|
+
locale
|
|
387
|
+
} = {}) {
|
|
388
|
+
return new Promise((resolve) => {
|
|
389
|
+
serverLoginRedirect({ returnTo, locale });
|
|
390
|
+
resolve();
|
|
323
391
|
});
|
|
324
|
-
if (!logged) return;
|
|
325
|
-
await bindCustomer(root);
|
|
326
|
-
await Promise.all([renderOrderList(root), PAGE_ATTRS.some((n) => qsa(root, sel(n)).length) ? pages().then((m6) => m6.renderPages(root)) : null]);
|
|
327
392
|
}
|
|
328
|
-
async function
|
|
329
|
-
const
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
ordersShow(true, false);
|
|
337
|
-
let failed = false;
|
|
338
|
-
const list = await orders({ first: parseInt(get(lists[0], "limit") || "10", 10) }).catch((err) => {
|
|
339
|
-
reportError(err, "orders");
|
|
340
|
-
failed = true;
|
|
341
|
-
return [];
|
|
393
|
+
async function customer() {
|
|
394
|
+
const me = await serverLogin();
|
|
395
|
+
return me.loggedIn ? me.customer : null;
|
|
396
|
+
}
|
|
397
|
+
async function orders({ first = DEFAULT_ORDER_COUNT } = {}) {
|
|
398
|
+
if (!isOrderCount(first)) {
|
|
399
|
+
throw new TetherError(`Customer accounts: orders() takes first from 1 to ${String(MAX_ORDER_COUNT)}`, {
|
|
400
|
+
code: "INVALID"
|
|
342
401
|
});
|
|
343
|
-
ordersShow(false, !failed && list.length === 0);
|
|
344
|
-
lists.forEach((c) => repeat(c, list, (node, o) => {
|
|
345
|
-
const items = o.lineItems?.nodes || [];
|
|
346
|
-
qsa(node, sel("order-bind")).forEach((el) => {
|
|
347
|
-
const k = get(el, "order-bind");
|
|
348
|
-
if (k === "url") {
|
|
349
|
-
const u = orderUrl(o);
|
|
350
|
-
if (u) el.setAttribute("href", u);
|
|
351
|
-
return;
|
|
352
|
-
}
|
|
353
|
-
if (k === "image") {
|
|
354
|
-
const im = items.find((l) => l.image)?.image;
|
|
355
|
-
if (im) setImage(el, im.url, im.altText || items[0]?.title || "");
|
|
356
|
-
return;
|
|
357
|
-
}
|
|
358
|
-
const v = { name: o.name, date: date(o.processedAt), total: formatMoney(o.totalPrice), status: o.financialStatus?.toLowerCase(), fulfillment: o.fulfillmentStatus?.toLowerCase(), items: items.map((l) => `${l.quantity}\xD7 ${l.title}`).join(", ") }[k];
|
|
359
|
-
if (v != null) setText(el, v);
|
|
360
|
-
});
|
|
361
|
-
qsa(node, sel("order-lines")).forEach((box) => fillLines(box, items));
|
|
362
|
-
if (get(node, "order-bind") === "url" && orderUrl(o)) node.setAttribute("href", orderUrl(o));
|
|
363
|
-
}));
|
|
364
402
|
}
|
|
403
|
+
const answer = await serverFetch(`/orders?${new URLSearchParams({ first: String(first) }).toString()}`);
|
|
404
|
+
return answer.kind === "logged-out" ? [] : toAccountOrders(answer.data["orders"]);
|
|
365
405
|
}
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
if (
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
});
|
|
406
|
+
async function logout({
|
|
407
|
+
returnTo = cfg.account?.logoutUrl || `${window.location.origin}/`
|
|
408
|
+
} = {}) {
|
|
409
|
+
if (await serverLogout(returnTo) === "stayed") await render(document);
|
|
410
|
+
}
|
|
411
|
+
async function loginState() {
|
|
412
|
+
try {
|
|
413
|
+
return (await serverLogin()).loggedIn ? { kind: "logged-in" } : { kind: "logged-out" };
|
|
414
|
+
} catch (error) {
|
|
415
|
+
return { kind: "unknown", error };
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
var usesPages = (root) => PAGE_ATTRIBUTES.some((name) => qsa(root, sel(name)).length > 0);
|
|
419
|
+
function linkShopifyPages(root) {
|
|
420
|
+
qsa(root, sel("account-link")).forEach((link) => {
|
|
421
|
+
link.setAttribute("href", shopifyPageUrl(get(link, "account-link")));
|
|
383
422
|
});
|
|
384
423
|
}
|
|
385
|
-
|
|
386
|
-
|
|
424
|
+
function shopifyPageUrl(page) {
|
|
425
|
+
const account = cfg.account;
|
|
426
|
+
const fallback = `https://${cfg.domain}/account`;
|
|
427
|
+
if (page === "payment") return account?.paymentUrl || account?.subscriptionsUrl || fallback;
|
|
428
|
+
if (page === "subscriptions") return account?.subscriptionsUrl || fallback;
|
|
429
|
+
return fallback;
|
|
430
|
+
}
|
|
431
|
+
async function render(root = document) {
|
|
432
|
+
const state = await loginState();
|
|
433
|
+
if (state.kind === "unknown") reportError(state.error, "account");
|
|
434
|
+
const loggedIn = state.kind === "logged-in";
|
|
435
|
+
qsa(root, sel("show")).forEach((el) => {
|
|
436
|
+
const condition = get(el, "show");
|
|
437
|
+
if (condition === "logged-in") show(el, loggedIn);
|
|
438
|
+
if (condition === "logged-out") show(el, !loggedIn);
|
|
439
|
+
});
|
|
440
|
+
linkShopifyPages(root);
|
|
441
|
+
if (state.kind === "unknown" && usesPages(root)) {
|
|
442
|
+
(await pages()).showUnavailable(root);
|
|
443
|
+
return;
|
|
444
|
+
}
|
|
445
|
+
if (!loggedIn) return;
|
|
446
|
+
await bindCustomer(root);
|
|
447
|
+
await Promise.all([
|
|
448
|
+
renderOrderList(root, (first) => orders({ first })),
|
|
449
|
+
usesPages(root) ? pages().then((part) => part.renderPages(root)) : null
|
|
450
|
+
]);
|
|
451
|
+
}
|
|
387
452
|
async function bindCustomer(root) {
|
|
388
453
|
const binds = qsa(root, sel("account-bind"));
|
|
389
454
|
if (!binds.length) return;
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
})
|
|
455
|
+
let profile;
|
|
456
|
+
try {
|
|
457
|
+
profile = await customer();
|
|
458
|
+
} catch (error) {
|
|
459
|
+
reportError(error, "account");
|
|
460
|
+
return;
|
|
461
|
+
}
|
|
462
|
+
if (!profile) return;
|
|
463
|
+
const texts = {
|
|
464
|
+
"first-name": profile.firstName,
|
|
465
|
+
"last-name": profile.lastName,
|
|
466
|
+
name: profile.displayName,
|
|
467
|
+
email: profile.emailAddress?.emailAddress,
|
|
468
|
+
address: profile.defaultAddress?.formatted.join(", ")
|
|
469
|
+
};
|
|
394
470
|
binds.forEach((el) => {
|
|
395
|
-
const
|
|
396
|
-
if (
|
|
471
|
+
const text = ownValue(texts, get(el, "account-bind") ?? "");
|
|
472
|
+
if (text != null) setText(el, text);
|
|
397
473
|
});
|
|
398
474
|
}
|
|
475
|
+
var pagesPart = null;
|
|
399
476
|
function pages() {
|
|
400
|
-
pagesPart
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
serverState = null;
|
|
404
|
-
} });
|
|
405
|
-
return m6;
|
|
477
|
+
pagesPart ?? (pagesPart = loadPart("account-pages").then((part) => {
|
|
478
|
+
part.setup({ serverFetch, customer, bindCustomer, reset: forgetServerLogin });
|
|
479
|
+
return part;
|
|
406
480
|
}));
|
|
407
481
|
return pagesPart;
|
|
408
482
|
}
|
|
409
|
-
var
|
|
410
|
-
var
|
|
411
|
-
var
|
|
412
|
-
var
|
|
413
|
-
var
|
|
414
|
-
var
|
|
415
|
-
var
|
|
416
|
-
var
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
if (
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
if (t.closest?.(sel("account-login"))) {
|
|
425
|
-
e.preventDefault();
|
|
426
|
-
login().catch((err) => reportError(err, "login"));
|
|
427
|
-
} else if (t.closest?.(sel("account-logout"))) {
|
|
428
|
-
e.preventDefault();
|
|
429
|
-
logout().catch((err) => reportError(err, "logout"));
|
|
430
|
-
}
|
|
483
|
+
var order = (id) => pages().then((part) => part.order(id));
|
|
484
|
+
var updateProfile = (fields) => pages().then((part) => part.updateProfile(fields));
|
|
485
|
+
var addresses = () => pages().then((part) => part.addresses());
|
|
486
|
+
var saveAddress = (address, options) => pages().then((part) => part.saveAddress(address, options));
|
|
487
|
+
var deleteAddress = (id) => pages().then((part) => part.deleteAddress(id));
|
|
488
|
+
var subscriptions = () => pages().then((part) => part.subscriptions());
|
|
489
|
+
var subscriptionAction = (id, action) => pages().then((part) => part.subscriptionAction(id, action));
|
|
490
|
+
var requestReturn = (orderId, lines) => pages().then((part) => part.requestReturn(orderId, lines));
|
|
491
|
+
function onClick(event) {
|
|
492
|
+
const target = event.target;
|
|
493
|
+
if (!(target instanceof window.Element)) return;
|
|
494
|
+
if (target.closest(sel("account-login"))) {
|
|
495
|
+
event.preventDefault();
|
|
496
|
+
login().catch((error) => {
|
|
497
|
+
reportError(error, "login");
|
|
431
498
|
});
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
499
|
+
} else if (target.closest(sel("account-logout"))) {
|
|
500
|
+
event.preventDefault();
|
|
501
|
+
logout().catch((error) => {
|
|
502
|
+
reportError(error, "logout");
|
|
503
|
+
});
|
|
504
|
+
}
|
|
505
|
+
}
|
|
506
|
+
function finishServerLogin() {
|
|
507
|
+
const url = new URL(window.location.href);
|
|
508
|
+
const outcome = url.searchParams.get("account");
|
|
509
|
+
if (!isLoginOutcome(outcome)) return;
|
|
510
|
+
url.searchParams.delete("account");
|
|
511
|
+
window.history.replaceState(window.history.state, "", url);
|
|
512
|
+
switch (outcome) {
|
|
513
|
+
case "in":
|
|
514
|
+
emit("account-login", {});
|
|
515
|
+
break;
|
|
516
|
+
case "expired":
|
|
517
|
+
case "error":
|
|
518
|
+
emit("account-error", { error: outcome });
|
|
519
|
+
break;
|
|
520
|
+
}
|
|
521
|
+
}
|
|
522
|
+
var started = false;
|
|
523
|
+
async function mountAccount(root = document) {
|
|
524
|
+
if (started) {
|
|
525
|
+
await render(root);
|
|
526
|
+
return;
|
|
453
527
|
}
|
|
528
|
+
started = true;
|
|
529
|
+
document.addEventListener("click", onClick);
|
|
530
|
+
finishServerLogin();
|
|
531
|
+
Cart.setCheckoutResolver(serverCheckoutUrl);
|
|
454
532
|
await render(root);
|
|
533
|
+
log("account", isLoggedIn() ? "logged in" : "logged out");
|
|
455
534
|
}
|
|
456
535
|
|
|
457
|
-
// src/parts/account.
|
|
458
|
-
|
|
536
|
+
// src/parts/account.ts
|
|
537
|
+
var { Tether } = window;
|
|
538
|
+
if (!Tether) throw new Error("tether.account.js runs after the Tether script, which loads it");
|
|
539
|
+
Tether.__parts.account = account_exports;
|
|
459
540
|
})();
|