@occluze/tether 0.6.8 → 0.7.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +28 -28
- package/dist/esm/astro.js +2 -2
- package/dist/esm/chunks/account-CXMA5RPZ.js +1 -0
- package/dist/esm/chunks/account-pages-IZO7FEOZ.js +1 -0
- package/dist/esm/chunks/analytics-PG5FPRDN.js +1 -0
- package/dist/esm/chunks/chunk-4HD4J5JC.js +1 -0
- package/dist/esm/chunks/chunk-6TFMLT4A.js +4 -0
- package/dist/esm/chunks/chunk-BBVUVPMO.js +1 -0
- package/dist/esm/chunks/chunk-E5YO6274.js +1 -0
- package/dist/esm/chunks/chunk-EW5SYO6L.js +1 -0
- package/dist/esm/chunks/chunk-HJY2JSNB.js +1 -0
- package/dist/esm/chunks/chunk-MQYB6BH4.js +1 -0
- package/dist/esm/chunks/chunk-N3V45JPS.js +1 -0
- package/dist/esm/chunks/chunk-RPMBCAGS.js +1 -0
- package/dist/esm/chunks/chunk-VFNHIGCS.js +1 -0
- package/dist/esm/chunks/chunk-WT7RGGJU.js +1 -0
- package/dist/esm/chunks/chunk-YN6LEBEN.js +1 -0
- package/dist/esm/chunks/chunk-Z6HS3H7K.js +1 -0
- package/dist/esm/chunks/diagnose-XCEBQKBO.js +14 -0
- package/dist/esm/chunks/extras-4HU3VSBQ.js +1 -0
- package/dist/esm/chunks/markets-ui-M4IQ62CT.js +1 -0
- package/dist/esm/chunks/search-A5DS2IOS.js +1 -0
- package/dist/esm/index.js +1 -1
- package/dist/esm/server.js +2 -2
- package/dist/presets/barba.esm.js +19 -23
- package/dist/tether.account-pages.js +332 -367
- package/dist/tether.account-pages.min.js +1 -1
- package/dist/tether.account.js +253 -492
- package/dist/tether.account.min.js +1 -1
- package/dist/tether.analytics.js +82 -89
- package/dist/tether.analytics.min.js +1 -1
- package/dist/tether.diagnose.js +52 -34
- package/dist/tether.diagnose.min.js +2 -2
- package/dist/tether.extras.js +42 -37
- package/dist/tether.extras.min.js +1 -1
- package/dist/tether.js +1361 -935
- package/dist/tether.markets.js +89 -91
- package/dist/tether.markets.min.js +1 -1
- package/dist/tether.min.js +0 -0
- package/dist/tether.min.js.map +4 -4
- package/dist/tether.search.js +60 -69
- package/dist/tether.search.min.js +1 -1
- package/dist/types/server/src/shared/account-orders.d.ts +44 -0
- package/dist/types/server/src/shared/account-routes.d.ts +153 -0
- package/dist/types/server/src/shared/api-versions.d.ts +13 -0
- package/dist/types/server/src/shared/cart-id.d.ts +2 -0
- package/dist/types/server/src/shared/error-message.d.ts +2 -0
- package/dist/types/server/src/shared/json.d.ts +25 -0
- package/dist/types/server/src/shared/market-codes.d.ts +16 -0
- package/dist/types/src/account/addresses-view.d.ts +5 -0
- package/dist/types/src/account/answers.d.ts +40 -0
- package/dist/types/src/account/markup.d.ts +19 -0
- package/dist/types/src/account/operations.d.ts +41 -0
- package/dist/types/src/account/order-lines.d.ts +13 -0
- package/dist/types/src/account/order-list.d.ts +12 -0
- package/dist/types/src/account/order-page.d.ts +6 -0
- package/dist/types/src/account/page-answers.d.ts +182 -0
- package/dist/types/src/account/page-events.d.ts +2 -0
- package/dist/types/src/account/server-client.d.ts +60 -0
- package/dist/types/src/account/subscriptions-view.d.ts +2 -0
- package/dist/types/src/account-api.d.ts +18 -0
- package/dist/types/src/account-marks.d.ts +15 -0
- package/dist/types/src/account-pages.d.ts +8 -0
- package/dist/types/src/account.d.ts +64 -0
- package/dist/types/src/amounts.d.ts +12 -0
- package/dist/types/src/analytics-shopify.d.ts +41 -0
- package/dist/types/src/analytics.d.ts +2 -0
- package/dist/types/src/api-version.d.ts +28 -0
- package/dist/types/src/astro.d.ts +42 -0
- package/dist/types/src/cart/cart-shape.d.ts +43 -0
- package/dist/types/src/cart/checkout.d.ts +16 -0
- package/dist/types/src/cart/drawer.d.ts +18 -0
- package/dist/types/src/cart/mutations.d.ts +85 -0
- package/dist/types/src/cart/render.d.ts +17 -0
- package/dist/types/src/cart/store.d.ts +185 -0
- package/dist/types/src/cart.d.ts +106 -0
- package/dist/types/src/client.d.ts +134 -0
- package/dist/types/src/collection.d.ts +25 -0
- package/dist/types/src/config-sections.d.ts +40 -0
- package/dist/types/src/config.d.ts +190 -0
- package/dist/types/src/controls/cart-controls.d.ts +2 -0
- package/dist/types/src/controls/discount.d.ts +2 -0
- package/dist/types/src/controls/extras.d.ts +5 -0
- package/dist/types/src/controls/navigation.d.ts +12 -0
- package/dist/types/src/diagnose-markup.d.ts +19 -0
- package/dist/types/src/diagnose.d.ts +60 -0
- package/dist/types/src/dom.d.ts +75 -0
- package/dist/types/src/extras.d.ts +21 -0
- package/dist/types/src/fragments.d.ts +158 -0
- package/dist/types/src/globals.d.ts +15 -0
- package/dist/types/src/images.d.ts +20 -0
- package/dist/types/src/index.d.ts +167 -0
- package/dist/types/src/initial.d.ts +56 -0
- package/dist/types/src/lazy.d.ts +28 -0
- package/dist/types/src/loader.d.ts +84 -0
- package/dist/types/src/market-codes.d.ts +6 -0
- package/dist/types/src/markets-ui.d.ts +32 -0
- package/dist/types/src/markets.d.ts +72 -0
- package/dist/types/src/markup.d.ts +131 -0
- package/dist/types/src/mounting.d.ts +46 -0
- package/dist/types/src/page-market.d.ts +27 -0
- package/dist/types/src/presets/barba.d.ts +56 -0
- package/dist/types/src/product-events.d.ts +2 -0
- package/dist/types/src/product-render.d.ts +17 -0
- package/dist/types/src/product-shape.d.ts +90 -0
- package/dist/types/src/product-state.d.ts +110 -0
- package/dist/types/src/product.d.ts +66 -0
- package/dist/types/src/repeaters.d.ts +16 -0
- package/dist/types/src/search.d.ts +33 -0
- package/dist/types/src/selling-plans.d.ts +64 -0
- package/dist/types/src/server.d.ts +88 -0
- package/dist/types/src/shopify-values.d.ts +46 -0
- package/dist/types/src/status.d.ts +33 -0
- package/dist/types/src/storage.d.ts +12 -0
- package/dist/types/src/store-html.d.ts +39 -0
- package/dist/types/src/storefront/catalog.d.ts +38 -0
- package/dist/types/src/storefront/json-ld.d.ts +20 -0
- package/dist/types/src/variant-render.d.ts +14 -0
- package/package.json +24 -24
- package/dist/esm/chunks/account-C3NP6HFB.js +0 -1
- package/dist/esm/chunks/account-pages-WLK374FO.js +0 -1
- package/dist/esm/chunks/analytics-G3SAWMNL.js +0 -1
- package/dist/esm/chunks/chunk-27PJJZGC.js +0 -1
- package/dist/esm/chunks/chunk-2FSXS55U.js +0 -1
- package/dist/esm/chunks/chunk-FCSWQDVV.js +0 -1
- package/dist/esm/chunks/chunk-FOMSMIAM.js +0 -1
- package/dist/esm/chunks/chunk-GZJTCLLW.js +0 -1
- package/dist/esm/chunks/chunk-HEQILZVR.js +0 -1
- package/dist/esm/chunks/chunk-JOOEXYF3.js +0 -4
- package/dist/esm/chunks/chunk-MPTQYLSM.js +0 -1
- package/dist/esm/chunks/chunk-NEHZ37TU.js +0 -3
- package/dist/esm/chunks/chunk-V74KGEJF.js +0 -1
- package/dist/esm/chunks/chunk-VT4CDUJJ.js +0 -1
- package/dist/esm/chunks/chunk-YJLWX2HK.js +0 -1
- package/dist/esm/chunks/diagnose-6VVGZNTY.js +0 -14
- package/dist/esm/chunks/extras-GJVRDFM3.js +0 -1
- package/dist/esm/chunks/markets-ui-UNB4PTA7.js +0 -1
- package/dist/esm/chunks/search-OU75RNQL.js +0 -1
- package/src/account/addresses-view.js +0 -92
- package/src/account/browser-session.js +0 -359
- package/src/account/markup.js +0 -48
- package/src/account/operations.js +0 -180
- package/src/account/order-lines.js +0 -96
- package/src/account/order-list.js +0 -91
- package/src/account/order-page.js +0 -192
- package/src/account/page-events.js +0 -288
- package/src/account/server-client.js +0 -172
- package/src/account/shared.js +0 -111
- package/src/account/shopify-auth.js +0 -150
- package/src/account/subscriptions-view.js +0 -158
- package/src/account-api.js +0 -118
- package/src/account-links.js +0 -35
- package/src/account-pages.js +0 -89
- package/src/account.js +0 -342
- package/src/amounts.js +0 -36
- package/src/analytics-shopify.js +0 -241
- package/src/analytics.js +0 -352
- package/src/api-version.js +0 -85
- package/src/astro.js +0 -266
- package/src/cart/checkout.js +0 -97
- package/src/cart/drawer.js +0 -138
- package/src/cart/mutations.js +0 -234
- package/src/cart/render.js +0 -294
- package/src/cart/store.js +0 -326
- package/src/cart.js +0 -391
- package/src/client.js +0 -267
- package/src/collection.js +0 -183
- package/src/config.js +0 -349
- package/src/controls/cart-controls.js +0 -155
- package/src/controls/discount.js +0 -96
- package/src/controls/extras.js +0 -63
- package/src/controls/navigation.js +0 -83
- package/src/diagnose-markup.js +0 -333
- package/src/diagnose.js +0 -295
- package/src/dom.js +0 -287
- package/src/extras.js +0 -145
- package/src/fragments.js +0 -237
- package/src/images.js +0 -104
- package/src/index.js +0 -353
- package/src/initial.js +0 -87
- package/src/lazy-iife.js +0 -116
- package/src/lazy.js +0 -39
- package/src/loader.js +0 -337
- package/src/market-codes.js +0 -35
- package/src/markets-ui.js +0 -204
- package/src/markets.js +0 -334
- package/src/markup.js +0 -64
- package/src/mounting.js +0 -277
- package/src/page-market.js +0 -116
- package/src/parts/account-pages.js +0 -6
- package/src/parts/account.js +0 -6
- package/src/parts/analytics.js +0 -6
- package/src/parts/diagnose.js +0 -6
- package/src/parts/extras.js +0 -6
- package/src/parts/markets.js +0 -6
- package/src/parts/search.js +0 -6
- package/src/presets/barba.js +0 -190
- package/src/product-events.js +0 -130
- package/src/product-render.js +0 -257
- package/src/product-state.js +0 -318
- package/src/product.js +0 -344
- package/src/repeaters.js +0 -173
- package/src/search.js +0 -323
- package/src/selling-plans.js +0 -154
- package/src/server.js +0 -215
- package/src/shopify-values.js +0 -89
- package/src/status.js +0 -126
- package/src/store-html.js +0 -0
- package/src/storefront/catalog.js +0 -199
- package/src/storefront/json-ld.js +0 -167
- package/src/variant-render.js +0 -165
- package/types/astro.d.ts +0 -28
- package/types/barba.d.ts +0 -16
- package/types/index.d.ts +0 -577
- package/types/server.d.ts +0 -182
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
"use strict";
|
|
2
1
|
(() => {
|
|
3
2
|
var __defProp = Object.defineProperty;
|
|
4
3
|
var __export = (target, all) => {
|
|
@@ -6,7 +5,7 @@
|
|
|
6
5
|
__defProp(target, name, { get: all[name], enumerable: true });
|
|
7
6
|
};
|
|
8
7
|
|
|
9
|
-
// src/account-pages.
|
|
8
|
+
// src/account-pages.ts
|
|
10
9
|
var account_pages_exports = {};
|
|
11
10
|
__export(account_pages_exports, {
|
|
12
11
|
addresses: () => addresses,
|
|
@@ -22,226 +21,241 @@
|
|
|
22
21
|
updateProfile: () => updateProfile
|
|
23
22
|
});
|
|
24
23
|
|
|
25
|
-
// tether-core:config.
|
|
26
|
-
var m = window.Tether.__core["config.
|
|
27
|
-
var
|
|
24
|
+
// tether-core:config.ts
|
|
25
|
+
var m = window.Tether.__core["config.ts"];
|
|
26
|
+
var [cfg, isConfigured, log, MARKET_SOURCES, parseMarkets, reportError, warn] = m;
|
|
28
27
|
|
|
29
|
-
// tether-core:dom.
|
|
30
|
-
var m2 = window.Tether.__core["dom.
|
|
31
|
-
var
|
|
28
|
+
// tether-core:dom.ts
|
|
29
|
+
var m2 = window.Tether.__core["dom.ts"];
|
|
30
|
+
var [ANALYTICS_EVENTS, attr, attributesFromJson, emit, formatDate, formatMoney, get, has, hasTemplate, isOwnEvent, parseJSONAttr, productUrl, qsa, repeat, sel, setImage, setText, show] = m2;
|
|
32
31
|
|
|
33
|
-
// tether-core:client.
|
|
34
|
-
var m3 = window.Tether.__core["client.
|
|
35
|
-
var
|
|
32
|
+
// tether-core:client.ts
|
|
33
|
+
var m3 = window.Tether.__core["client.ts"];
|
|
34
|
+
var [endpoint, gql, orNull, shaped, TetherError] = m3;
|
|
36
35
|
|
|
37
|
-
// server/src/shared/account-
|
|
38
|
-
var
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
}
|
|
49
|
-
};
|
|
50
|
-
var MONEY = "amount currencyCode";
|
|
51
|
-
var ADDRESS = "id firstName lastName company address1 address2 city province zoneCode zip country countryCode phoneNumber formatted";
|
|
52
|
-
var USER_ERRORS = "userErrors { field message }";
|
|
53
|
-
var QUERIES = {
|
|
54
|
-
order: `query TetherOrder($id:ID!){order(id:$id){id name number processedAt cancelledAt financialStatus fulfillmentStatus statusPageUrl requiresShipping totalPrice{${MONEY}}subtotal{${MONEY}}totalShipping{${MONEY}}totalTax{${MONEY}}shippingAddress{${ADDRESS}}billingAddress{${ADDRESS}}lineItems(first:50){nodes{id name title variantTitle quantity sku image{url altText}price{${MONEY}}totalPrice{${MONEY}}suggestedReturnReasonDefinitions(first:10){nodes{id name handle}}}}fulfillments(first:10){nodes{id status createdAt estimatedDeliveryAt latestShipmentStatus trackingInformation{company number url}}}returnInformation{returnableLineItems(first:50){nodes{quantity lineItem{id}}}}returns(first:10){nodes{id status}}}}`,
|
|
55
|
-
addresses: `query TetherAddresses{customer{defaultAddress{id}addresses(first:20){nodes{${ADDRESS}}}}}`,
|
|
56
|
-
subscriptions: `query TetherSubscriptions{customer{subscriptionContracts(first:20,reverse:true){nodes{id status nextBillingDate currencyCode deliveryPrice{${MONEY}}deliveryPolicy{interval intervalCount{count}}lines(first:20){nodes{id name title variantTitle quantity sku currentPrice{${MONEY}}lineDiscountedPrice{${MONEY}}image{url altText}}}upcomingBillingCycles(first:3){nodes{cycleIndex skipped billingAttemptExpectedDate}}}}}}`,
|
|
57
|
-
contract: `query TetherContract($id:ID!){customer{subscriptionContract(id:$id){id status upcomingBillingCycles(first:3){nodes{cycleIndex skipped}}}}}`
|
|
58
|
-
};
|
|
59
|
-
var MUTATIONS = {
|
|
60
|
-
profile: `mutation TetherProfile($input:CustomerUpdateInput!){customerUpdate(input:$input){customer{firstName lastName}${USER_ERRORS}}}`,
|
|
61
|
-
addressCreate: `mutation TetherAddressCreate($address:CustomerAddressInput!,$default:Boolean){customerAddressCreate(address:$address,defaultAddress:$default){customerAddress{${ADDRESS}}${USER_ERRORS}}}`,
|
|
62
|
-
addressUpdate: `mutation TetherAddressUpdate($id:ID!,$address:CustomerAddressInput,$default:Boolean){customerAddressUpdate(addressId:$id,address:$address,defaultAddress:$default){customerAddress{${ADDRESS}}${USER_ERRORS}}}`,
|
|
63
|
-
addressDelete: `mutation TetherAddressDelete($id:ID!){customerAddressDelete(addressId:$id){deletedAddressId ${USER_ERRORS}}}`,
|
|
64
|
-
returnRequest: `mutation TetherReturn($orderId:ID!,$lines:[RequestedLineItemInput!]!){orderRequestReturn(orderId:$orderId,requestedLineItems:$lines){return{id status}${USER_ERRORS}}}`
|
|
65
|
-
};
|
|
66
|
-
var SUBSCRIPTION_ACTIONS = {
|
|
67
|
-
pause: {
|
|
68
|
-
document: `mutation TetherPause($id:ID!){subscriptionContractPause(subscriptionContractId:$id){contract{id status}${USER_ERRORS}}}`,
|
|
69
|
-
payload: "subscriptionContractPause",
|
|
70
|
-
input: "contract"
|
|
71
|
-
},
|
|
72
|
-
resume: {
|
|
73
|
-
document: `mutation TetherResume($id:ID!){subscriptionContractActivate(subscriptionContractId:$id){contract{id status}${USER_ERRORS}}}`,
|
|
74
|
-
payload: "subscriptionContractActivate",
|
|
75
|
-
input: "contract"
|
|
76
|
-
},
|
|
77
|
-
cancel: {
|
|
78
|
-
document: `mutation TetherCancel($id:ID!){subscriptionContractCancel(subscriptionContractId:$id){contract{id status}${USER_ERRORS}}}`,
|
|
79
|
-
payload: "subscriptionContractCancel",
|
|
80
|
-
input: "contract"
|
|
36
|
+
// server/src/shared/account-routes.ts
|
|
37
|
+
var OPERATION_ROUTES = {
|
|
38
|
+
order: { name: "order", method: "GET", path: "/order", fields: { id: true } },
|
|
39
|
+
addresses: { name: "addresses", method: "GET", path: "/addresses", fields: {} },
|
|
40
|
+
subscriptions: { name: "subscriptions", method: "GET", path: "/subscriptions", fields: {} },
|
|
41
|
+
profile: { name: "profile", method: "POST", path: "/profile", fields: { firstName: true, lastName: true } },
|
|
42
|
+
saveAddress: {
|
|
43
|
+
name: "saveAddress",
|
|
44
|
+
method: "POST",
|
|
45
|
+
path: "/address",
|
|
46
|
+
fields: { id: true, address: true, isDefault: true }
|
|
81
47
|
},
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
input: "billingCycle"
|
|
86
|
-
},
|
|
87
|
-
unskip: {
|
|
88
|
-
document: `mutation TetherUnskip($input:SubscriptionBillingCycleInput!){subscriptionBillingCycleUnskip(billingCycleInput:$input){billingCycle{cycleIndex skipped}${USER_ERRORS}}}`,
|
|
89
|
-
payload: "subscriptionBillingCycleUnskip",
|
|
90
|
-
input: "billingCycle"
|
|
91
|
-
}
|
|
48
|
+
deleteAddress: { name: "deleteAddress", method: "POST", path: "/address/delete", fields: { id: true } },
|
|
49
|
+
subscription: { name: "subscription", method: "POST", path: "/subscription", fields: { id: true, action: true } },
|
|
50
|
+
requestReturn: { name: "requestReturn", method: "POST", path: "/return", fields: { orderId: true, lines: true } }
|
|
92
51
|
};
|
|
93
|
-
|
|
94
|
-
|
|
52
|
+
var ROUTE_BY_REQUEST = new Map(
|
|
53
|
+
Object.values(OPERATION_ROUTES).map((route) => [
|
|
54
|
+
`${route.method} ${route.path}`,
|
|
55
|
+
{ ...route, fields: Object.keys(route.fields) }
|
|
56
|
+
])
|
|
57
|
+
);
|
|
58
|
+
function operationRequest(name, input) {
|
|
59
|
+
const route = OPERATION_ROUTES[name];
|
|
60
|
+
if (route.method === "POST") return { method: "POST", path: route.path };
|
|
61
|
+
const values = input;
|
|
62
|
+
const query = new URLSearchParams();
|
|
63
|
+
for (const fieldName of Object.keys(route.fields)) {
|
|
64
|
+
const value = values[fieldName];
|
|
65
|
+
if (typeof value === "string" || typeof value === "number") query.set(fieldName, String(value));
|
|
66
|
+
}
|
|
67
|
+
const search = query.toString();
|
|
68
|
+
return { method: "GET", path: search ? `${route.path}?${search}` : route.path };
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// server/src/shared/json.ts
|
|
72
|
+
function isRecord(value) {
|
|
73
|
+
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
95
74
|
}
|
|
96
75
|
function field(value, key) {
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
);
|
|
76
|
+
return isRecord(value) ? value[key] : void 0;
|
|
77
|
+
}
|
|
78
|
+
function asList(value) {
|
|
79
|
+
return Array.isArray(value) ? value : [];
|
|
102
80
|
}
|
|
103
|
-
function
|
|
104
|
-
|
|
105
|
-
return Array.isArray(list) ? list : [];
|
|
81
|
+
function textOrNull(value) {
|
|
82
|
+
return typeof value === "string" && value !== "" ? value : null;
|
|
106
83
|
}
|
|
107
|
-
var
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
84
|
+
var numberOrNull = (value) => typeof value === "number" && Number.isFinite(value) ? value : null;
|
|
85
|
+
var countOrZero = (value) => numberOrNull(value) ?? 0;
|
|
86
|
+
var listOf = (value, read) => asList(value).map((item) => read(item));
|
|
87
|
+
var nodesOf = (connection, read) => ({
|
|
88
|
+
nodes: listOf(field(connection, "nodes"), read)
|
|
89
|
+
});
|
|
90
|
+
var textList = (value) => listOf(value, textOrNull).filter((line) => line !== null);
|
|
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
|
+
|
|
109
|
+
// src/account/answers.ts
|
|
110
|
+
var unexpected = (what) => new TetherError(`Customer accounts: the answer has no ${what}`);
|
|
111
|
+
function requiredId(value, what) {
|
|
112
|
+
const id = textOrNull(value);
|
|
113
|
+
if (!id) throw unexpected(what);
|
|
112
114
|
return id;
|
|
113
115
|
}
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
)
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
116
|
+
|
|
117
|
+
// src/account/page-answers.ts
|
|
118
|
+
function toMailingAddress(value) {
|
|
119
|
+
const text = (name) => textOrNull(field(value, name));
|
|
120
|
+
return {
|
|
121
|
+
id: text("id"),
|
|
122
|
+
firstName: text("firstName"),
|
|
123
|
+
lastName: text("lastName"),
|
|
124
|
+
company: text("company"),
|
|
125
|
+
address1: text("address1"),
|
|
126
|
+
address2: text("address2"),
|
|
127
|
+
city: text("city"),
|
|
128
|
+
province: text("province"),
|
|
129
|
+
zoneCode: text("zoneCode"),
|
|
130
|
+
zip: text("zip"),
|
|
131
|
+
country: text("country"),
|
|
132
|
+
countryCode: text("countryCode"),
|
|
133
|
+
phoneNumber: text("phoneNumber"),
|
|
134
|
+
formatted: textList(field(value, "formatted"))
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
var mailingAddressOrNull = (value) => isRecord(value) ? toMailingAddress(value) : null;
|
|
138
|
+
var toAccountAddress = (value) => ({
|
|
139
|
+
...toMailingAddress(value),
|
|
140
|
+
id: requiredId(field(value, "id"), "address id")
|
|
141
|
+
});
|
|
142
|
+
var toCustomerAddresses = (value) => listOf(value, (address) => ({ ...toAccountAddress(address), isDefault: field(address, "isDefault") === true }));
|
|
143
|
+
var toOrderDetailLine = (value) => ({
|
|
144
|
+
...toOrderLine(value),
|
|
145
|
+
id: requiredId(field(value, "id"), "line item id"),
|
|
146
|
+
name: textOrNull(field(value, "name")),
|
|
147
|
+
sku: textOrNull(field(value, "sku")),
|
|
148
|
+
price: moneyOrNull(field(value, "price")),
|
|
149
|
+
totalPrice: moneyOrNull(field(value, "totalPrice")),
|
|
150
|
+
suggestedReturnReasonDefinitions: nodesOf(field(value, "suggestedReturnReasonDefinitions"), (reason) => ({
|
|
151
|
+
id: requiredId(field(reason, "id"), "return reason id"),
|
|
152
|
+
name: textOrNull(field(reason, "name")),
|
|
153
|
+
handle: textOrNull(field(reason, "handle"))
|
|
154
|
+
}))
|
|
155
|
+
});
|
|
156
|
+
var toFulfillment = (value) => ({
|
|
157
|
+
id: textOrNull(field(value, "id")),
|
|
158
|
+
status: textOrNull(field(value, "status")),
|
|
159
|
+
createdAt: textOrNull(field(value, "createdAt")),
|
|
160
|
+
estimatedDeliveryAt: textOrNull(field(value, "estimatedDeliveryAt")),
|
|
161
|
+
latestShipmentStatus: textOrNull(field(value, "latestShipmentStatus")),
|
|
162
|
+
trackingInformation: listOf(field(value, "trackingInformation"), (tracking) => ({
|
|
163
|
+
company: textOrNull(field(tracking, "company")),
|
|
164
|
+
number: textOrNull(field(tracking, "number")),
|
|
165
|
+
url: textOrNull(field(tracking, "url"))
|
|
166
|
+
}))
|
|
167
|
+
});
|
|
168
|
+
function toReturnableLine(value) {
|
|
169
|
+
const lineId = textOrNull(field(field(value, "lineItem"), "id"));
|
|
170
|
+
return { quantity: countOrZero(field(value, "quantity")), lineItem: lineId === null ? null : { id: lineId } };
|
|
171
|
+
}
|
|
172
|
+
function toReturnInformation(value) {
|
|
173
|
+
if (!isRecord(value)) return null;
|
|
174
|
+
return { returnableLineItems: nodesOf(value["returnableLineItems"], toReturnableLine) };
|
|
175
|
+
}
|
|
176
|
+
function toOrderDetail(value) {
|
|
177
|
+
if (!isRecord(value)) return null;
|
|
178
|
+
const text = (name) => textOrNull(value[name]);
|
|
179
|
+
const money = (name) => moneyOrNull(value[name]);
|
|
180
|
+
const requiresShipping = value["requiresShipping"];
|
|
181
|
+
return {
|
|
182
|
+
id: requiredId(value["id"], "order id"),
|
|
183
|
+
name: text("name"),
|
|
184
|
+
number: numberOrNull(value["number"]),
|
|
185
|
+
processedAt: text("processedAt"),
|
|
186
|
+
cancelledAt: text("cancelledAt"),
|
|
187
|
+
financialStatus: text("financialStatus"),
|
|
188
|
+
fulfillmentStatus: text("fulfillmentStatus"),
|
|
189
|
+
statusPageUrl: text("statusPageUrl"),
|
|
190
|
+
requiresShipping: typeof requiresShipping === "boolean" ? requiresShipping : null,
|
|
191
|
+
totalPrice: money("totalPrice"),
|
|
192
|
+
subtotal: money("subtotal"),
|
|
193
|
+
totalShipping: money("totalShipping"),
|
|
194
|
+
totalTax: money("totalTax"),
|
|
195
|
+
shippingAddress: mailingAddressOrNull(value["shippingAddress"]),
|
|
196
|
+
billingAddress: mailingAddressOrNull(value["billingAddress"]),
|
|
197
|
+
lineItems: nodesOf(value["lineItems"], toOrderDetailLine),
|
|
198
|
+
fulfillments: nodesOf(value["fulfillments"], toFulfillment),
|
|
199
|
+
returnInformation: toReturnInformation(value["returnInformation"]),
|
|
200
|
+
returns: nodesOf(value["returns"], toReturn)
|
|
201
|
+
};
|
|
202
|
+
}
|
|
203
|
+
var toSubscriptionLine = (value) => ({
|
|
204
|
+
id: textOrNull(field(value, "id")),
|
|
205
|
+
name: textOrNull(field(value, "name")),
|
|
206
|
+
title: textOrNull(field(value, "title")),
|
|
207
|
+
variantTitle: textOrNull(field(value, "variantTitle")),
|
|
208
|
+
quantity: countOrZero(field(value, "quantity")),
|
|
209
|
+
sku: textOrNull(field(value, "sku")),
|
|
210
|
+
currentPrice: moneyOrNull(field(value, "currentPrice")),
|
|
211
|
+
lineDiscountedPrice: moneyOrNull(field(value, "lineDiscountedPrice")),
|
|
212
|
+
image: imageOrNull(field(value, "image"))
|
|
213
|
+
});
|
|
214
|
+
var toBillingCycle = (value) => ({
|
|
215
|
+
cycleIndex: numberOrNull(field(value, "cycleIndex")),
|
|
216
|
+
skipped: field(value, "skipped") === true,
|
|
217
|
+
billingAttemptExpectedDate: textOrNull(field(value, "billingAttemptExpectedDate"))
|
|
218
|
+
});
|
|
219
|
+
function toDeliveryPolicy(value) {
|
|
220
|
+
if (!isRecord(value)) return null;
|
|
221
|
+
const intervalCount = value["intervalCount"];
|
|
222
|
+
return {
|
|
223
|
+
interval: textOrNull(value["interval"]),
|
|
224
|
+
intervalCount: isRecord(intervalCount) ? { count: countOrZero(intervalCount["count"]) } : null
|
|
225
|
+
};
|
|
226
|
+
}
|
|
227
|
+
var toSubscriptionContract = (value) => ({
|
|
228
|
+
id: requiredId(field(value, "id"), "subscription id"),
|
|
229
|
+
status: textOrNull(field(value, "status")),
|
|
230
|
+
nextBillingDate: textOrNull(field(value, "nextBillingDate")),
|
|
231
|
+
currencyCode: textOrNull(field(value, "currencyCode")),
|
|
232
|
+
deliveryPrice: moneyOrNull(field(value, "deliveryPrice")),
|
|
233
|
+
deliveryPolicy: toDeliveryPolicy(field(value, "deliveryPolicy")),
|
|
234
|
+
lines: nodesOf(field(value, "lines"), toSubscriptionLine),
|
|
235
|
+
upcomingBillingCycles: nodesOf(field(value, "upcomingBillingCycles"), toBillingCycle)
|
|
236
|
+
});
|
|
237
|
+
var toSubscriptionContracts = (value) => listOf(value, toSubscriptionContract);
|
|
238
|
+
function toSubscriptionChange(result) {
|
|
239
|
+
const { contract, billingCycle } = result;
|
|
240
|
+
if (isRecord(contract)) {
|
|
241
|
+
return { contract: { id: textOrNull(contract["id"]), status: textOrNull(contract["status"]) } };
|
|
150
242
|
}
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
const payload = field(data, name);
|
|
155
|
-
const errors = field(payload, "userErrors");
|
|
156
|
-
if (Array.isArray(errors) && errors.length) {
|
|
157
|
-
const userErrors = (
|
|
158
|
-
/** @type {UserError[]} */
|
|
159
|
-
errors
|
|
160
|
-
);
|
|
161
|
-
throw new InputError(userErrors.map((error) => error.message).join(" | "), { userErrors });
|
|
243
|
+
if (isRecord(billingCycle)) {
|
|
244
|
+
const { cycleIndex, skipped } = toBillingCycle(billingCycle);
|
|
245
|
+
return { billingCycle: { cycleIndex, skipped } };
|
|
162
246
|
}
|
|
163
|
-
|
|
247
|
+
throw unexpected("changed subscription");
|
|
164
248
|
}
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
if (lastName !== void 0) input["lastName"] = text(lastName, 100) ?? "";
|
|
174
|
-
if (!Object.keys(input).length) throw new InputError("nothing to change");
|
|
175
|
-
const payload = payloadOf(await ask(MUTATIONS.profile, { input }), "customerUpdate");
|
|
176
|
-
return { customer: field(payload, "customer") };
|
|
177
|
-
},
|
|
178
|
-
async addresses(ask) {
|
|
179
|
-
const customer = field(await ask(QUERIES.addresses, {}), "customer");
|
|
180
|
-
const defaultId = field(field(customer, "defaultAddress"), "id") ?? null;
|
|
181
|
-
const addresses2 = nodes(field(customer, "addresses")).map((address) => ({
|
|
182
|
-
.../** @type {object} */
|
|
183
|
-
address,
|
|
184
|
-
isDefault: field(address, "id") === defaultId
|
|
185
|
-
}));
|
|
186
|
-
return { addresses: addresses2 };
|
|
187
|
-
},
|
|
188
|
-
async saveAddress(ask, { id, address, isDefault }) {
|
|
189
|
-
const fields = addressInput(address ?? {}, { clear: Boolean(id) });
|
|
190
|
-
const makeDefault = isDefault === true;
|
|
191
|
-
if (!id) {
|
|
192
|
-
const created = await ask(MUTATIONS.addressCreate, { address: fields, default: makeDefault });
|
|
193
|
-
return { address: field(payloadOf(created, "customerAddressCreate"), "customerAddress") };
|
|
194
|
-
}
|
|
195
|
-
const updated = await ask(MUTATIONS.addressUpdate, {
|
|
196
|
-
id: idOf("CustomerAddress", id),
|
|
197
|
-
address: Object.keys(fields).length ? fields : null,
|
|
198
|
-
default: makeDefault ? true : null
|
|
199
|
-
});
|
|
200
|
-
return { address: field(payloadOf(updated, "customerAddressUpdate"), "customerAddress") };
|
|
201
|
-
},
|
|
202
|
-
async deleteAddress(ask, { id }) {
|
|
203
|
-
const data = await ask(MUTATIONS.addressDelete, { id: idOf("CustomerAddress", id) });
|
|
204
|
-
return { deleted: field(payloadOf(data, "customerAddressDelete"), "deletedAddressId") };
|
|
205
|
-
},
|
|
206
|
-
async subscriptions(ask) {
|
|
207
|
-
const contracts = field(field(await ask(QUERIES.subscriptions, {}), "customer"), "subscriptionContracts");
|
|
208
|
-
return { subscriptions: nodes(contracts) };
|
|
209
|
-
},
|
|
210
|
-
async subscription(ask, { id, action }) {
|
|
211
|
-
if (!isSubscriptionAction(action)) throw new InputError("action");
|
|
212
|
-
const contractId = idOf("SubscriptionContract", id);
|
|
213
|
-
const contract = field(field(await ask(QUERIES.contract, { id: contractId }), "customer"), "subscriptionContract");
|
|
214
|
-
if (!contract) throw new InputError("not found", { status: 404 });
|
|
215
|
-
const { document: document2, payload, input } = SUBSCRIPTION_ACTIONS[action];
|
|
216
|
-
if (input === "contract") {
|
|
217
|
-
return { contract: field(payloadOf(await ask(document2, { id: contractId }), payload), "contract") };
|
|
218
|
-
}
|
|
219
|
-
const cycles = nodes(field(contract, "upcomingBillingCycles"));
|
|
220
|
-
const wantSkipped = action === "unskip";
|
|
221
|
-
const cycle = cycles.find((candidate) => Boolean(field(candidate, "skipped")) === wantSkipped);
|
|
222
|
-
if (!cycle) throw new InputError(wantSkipped ? "nothing skipped" : "no upcoming delivery to skip");
|
|
223
|
-
const variables = { input: { contractId, selector: { index: field(cycle, "cycleIndex") } } };
|
|
224
|
-
return { billingCycle: field(payloadOf(await ask(document2, variables), payload), "billingCycle") };
|
|
225
|
-
},
|
|
226
|
-
async requestReturn(ask, { orderId, lines }) {
|
|
227
|
-
const order2 = idOf("Order", orderId);
|
|
228
|
-
if (!Array.isArray(lines) || !lines.length || lines.length > 50) throw new InputError("lines");
|
|
229
|
-
const requested = lines.map((line) => {
|
|
230
|
-
const quantity = Number(field(line, "quantity"));
|
|
231
|
-
if (!Number.isInteger(quantity) || quantity < 1 || quantity > 1e3) throw new InputError("quantity");
|
|
232
|
-
const out = { lineItemId: idOf("LineItem", field(line, "lineItemId")), quantity };
|
|
233
|
-
const reason = field(line, "reasonId");
|
|
234
|
-
if (reason) out["returnReasonDefinitionId"] = idOf("ReturnReasonDefinition", reason);
|
|
235
|
-
const note = text(field(line, "note"), 300);
|
|
236
|
-
if (note) out["customerNote"] = note;
|
|
237
|
-
return out;
|
|
238
|
-
});
|
|
239
|
-
const data = await ask(MUTATIONS.returnRequest, { orderId: order2, lines: requested });
|
|
240
|
-
return { return: field(payloadOf(data, "orderRequestReturn"), "return") };
|
|
241
|
-
}
|
|
242
|
-
};
|
|
249
|
+
function toReturn(value) {
|
|
250
|
+
return { id: requiredId(field(value, "id"), "return id"), status: textOrNull(field(value, "status")) };
|
|
251
|
+
}
|
|
252
|
+
var toDeletedId = (value) => requiredId(value, "deleted address id");
|
|
253
|
+
var toProfile = (value) => ({
|
|
254
|
+
firstName: textOrNull(field(value, "firstName")),
|
|
255
|
+
lastName: textOrNull(field(value, "lastName"))
|
|
256
|
+
});
|
|
243
257
|
|
|
244
|
-
// src/account/operations.
|
|
258
|
+
// src/account/operations.ts
|
|
245
259
|
var context = null;
|
|
246
260
|
function setup(shared) {
|
|
247
261
|
context = shared;
|
|
@@ -250,38 +264,12 @@
|
|
|
250
264
|
if (!context) throw new Error("account-pages: loaded without the account part");
|
|
251
265
|
return context;
|
|
252
266
|
}
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
deleteAddress: () => ["POST", "/address/delete"],
|
|
260
|
-
subscription: () => ["POST", "/subscription"],
|
|
261
|
-
requestReturn: () => ["POST", "/return"]
|
|
262
|
-
};
|
|
263
|
-
async function run(name, input = {}) {
|
|
264
|
-
const { serverBase, serverFetch, query } = pagesContext();
|
|
265
|
-
if (serverBase()) {
|
|
266
|
-
const [method, path] = ROUTE[name](input);
|
|
267
|
-
const answer = await serverFetch(path, method === "POST" ? { method, body: input } : {});
|
|
268
|
-
if (answer.kind === "logged-out") throw new TetherError("Not logged in", { code: "NOT_LOGGED_IN", status: 401 });
|
|
269
|
-
return answer.data;
|
|
270
|
-
}
|
|
271
|
-
const operation = ops[name];
|
|
272
|
-
if (!operation) throw new TetherError(`Customer accounts: no operation ${name}`);
|
|
273
|
-
try {
|
|
274
|
-
return await operation(
|
|
275
|
-
async (document2, variables) => (
|
|
276
|
-
/** @type {Record<string, unknown> | null} */
|
|
277
|
-
await query(document2, variables)
|
|
278
|
-
),
|
|
279
|
-
input
|
|
280
|
-
);
|
|
281
|
-
} catch (error) {
|
|
282
|
-
if (!(error instanceof InputError)) throw error;
|
|
283
|
-
throw new TetherError(error.message, { code: "INVALID", userErrors: error.userErrors });
|
|
284
|
-
}
|
|
267
|
+
async function run(name, input) {
|
|
268
|
+
const { serverFetch } = pagesContext();
|
|
269
|
+
const { method, path } = operationRequest(name, input);
|
|
270
|
+
const answer = await serverFetch(path, method === "POST" ? { method, body: input } : {});
|
|
271
|
+
if (answer.kind === "logged-out") throw new TetherError("Not logged in", { code: "NOT_LOGGED_IN", status: 401 });
|
|
272
|
+
return answer.data;
|
|
285
273
|
}
|
|
286
274
|
function changed(what) {
|
|
287
275
|
pagesContext().reset();
|
|
@@ -289,78 +277,50 @@
|
|
|
289
277
|
}
|
|
290
278
|
async function order(id) {
|
|
291
279
|
const result = await run("order", { id });
|
|
292
|
-
return (
|
|
293
|
-
/** @type {OrderDetail | null} */
|
|
294
|
-
result["order"] ?? null
|
|
295
|
-
);
|
|
280
|
+
return toOrderDetail(result["order"]);
|
|
296
281
|
}
|
|
297
|
-
async function updateProfile({
|
|
282
|
+
async function updateProfile({
|
|
283
|
+
firstName,
|
|
284
|
+
lastName
|
|
285
|
+
} = {}) {
|
|
298
286
|
const result = await run("profile", { firstName, lastName });
|
|
299
287
|
changed("profile");
|
|
300
|
-
return (
|
|
301
|
-
/** @type {{ firstName: string | null, lastName: string | null }} */
|
|
302
|
-
result["customer"]
|
|
303
|
-
);
|
|
288
|
+
return toProfile(result["customer"]);
|
|
304
289
|
}
|
|
305
290
|
async function addresses() {
|
|
306
|
-
const result = await run("addresses");
|
|
307
|
-
return (
|
|
308
|
-
/** @type {CustomerAddress[]} */
|
|
309
|
-
result["addresses"]
|
|
310
|
-
);
|
|
291
|
+
const result = await run("addresses", {});
|
|
292
|
+
return toCustomerAddresses(result["addresses"]);
|
|
311
293
|
}
|
|
312
294
|
async function saveAddress(address, { id, isDefault } = {}) {
|
|
313
295
|
const result = await run("saveAddress", { id, address, isDefault });
|
|
314
296
|
changed("addresses");
|
|
315
|
-
return (
|
|
316
|
-
/** @type {CustomerAddress} */
|
|
317
|
-
result["address"]
|
|
318
|
-
);
|
|
297
|
+
return toAccountAddress(result["address"]);
|
|
319
298
|
}
|
|
320
299
|
async function deleteAddress(id) {
|
|
321
300
|
const result = await run("deleteAddress", { id });
|
|
322
301
|
changed("addresses");
|
|
323
|
-
return (
|
|
324
|
-
/** @type {string} */
|
|
325
|
-
result["deleted"]
|
|
326
|
-
);
|
|
302
|
+
return toDeletedId(result["deleted"]);
|
|
327
303
|
}
|
|
328
304
|
async function subscriptions() {
|
|
329
|
-
const result = await run("subscriptions");
|
|
330
|
-
return (
|
|
331
|
-
/** @type {SubscriptionContract[]} */
|
|
332
|
-
result["subscriptions"]
|
|
333
|
-
);
|
|
305
|
+
const result = await run("subscriptions", {});
|
|
306
|
+
return toSubscriptionContracts(result["subscriptions"]);
|
|
334
307
|
}
|
|
335
308
|
async function subscriptionAction(id, action) {
|
|
336
309
|
const result = await run("subscription", { id, action });
|
|
337
310
|
changed("subscriptions");
|
|
338
|
-
return result;
|
|
311
|
+
return toSubscriptionChange(result);
|
|
339
312
|
}
|
|
340
313
|
async function requestReturn(orderId, lines) {
|
|
341
314
|
const result = await run("requestReturn", { orderId, lines });
|
|
342
315
|
changed("orders");
|
|
343
|
-
return (
|
|
344
|
-
/** @type {{ id: string, status: string }} */
|
|
345
|
-
result["return"]
|
|
346
|
-
);
|
|
316
|
+
return toReturn(result["return"]);
|
|
347
317
|
}
|
|
348
318
|
|
|
349
|
-
// tether-core:shopify-values.
|
|
350
|
-
var m4 = window.Tether.__core["shopify-values.
|
|
351
|
-
var
|
|
352
|
-
|
|
353
|
-
// src/account-links.js
|
|
354
|
-
function localDate(iso) {
|
|
355
|
-
try {
|
|
356
|
-
return new Date(iso).toLocaleDateString(cfg.locale);
|
|
357
|
-
} catch (error) {
|
|
358
|
-
if (error instanceof RangeError) return iso;
|
|
359
|
-
throw error;
|
|
360
|
-
}
|
|
361
|
-
}
|
|
319
|
+
// tether-core:shopify-values.ts
|
|
320
|
+
var m4 = window.Tether.__core["shopify-values.ts"];
|
|
321
|
+
var [isHttpsUrl] = m4;
|
|
362
322
|
|
|
363
|
-
// src/account/markup.
|
|
323
|
+
// src/account/markup.ts
|
|
364
324
|
function showIn(root, name, conditions) {
|
|
365
325
|
qsa(root, sel(name)).forEach((el) => {
|
|
366
326
|
const key = get(el, name) ?? "";
|
|
@@ -372,9 +332,9 @@
|
|
|
372
332
|
var addressText = (address) => (address?.formatted ?? []).join(", ");
|
|
373
333
|
var ownValue = (values, key) => Object.hasOwn(values, key) ? values[key] : void 0;
|
|
374
334
|
|
|
375
|
-
// src/account/order-lines.
|
|
335
|
+
// src/account/order-lines.ts
|
|
376
336
|
var lineTexts = (line, returnable) => ({
|
|
377
|
-
title: line.title || line.name,
|
|
337
|
+
title: line.title || line.name || "",
|
|
378
338
|
"variant-title": line.variantTitle || "",
|
|
379
339
|
quantity: String(line.quantity),
|
|
380
340
|
price: formatMoney(line.price),
|
|
@@ -396,7 +356,7 @@
|
|
|
396
356
|
if (select.dataset["tetherFilled"] === line.id) return;
|
|
397
357
|
select.dataset["tetherFilled"] = line.id;
|
|
398
358
|
(line.suggestedReturnReasonDefinitions?.nodes ?? []).forEach((reason) => {
|
|
399
|
-
select.appendChild(new Option(reason.name, reason.id));
|
|
359
|
+
select.appendChild(new Option(reason.name ?? "", reason.id));
|
|
400
360
|
});
|
|
401
361
|
});
|
|
402
362
|
}
|
|
@@ -409,17 +369,17 @@
|
|
|
409
369
|
bindsIn(row, "order-line").forEach((el) => {
|
|
410
370
|
const key = get(el, "order-line") ?? "";
|
|
411
371
|
if (key === "image") {
|
|
412
|
-
if (line.image) setImage(el, line.image.url, line.image.altText || line.title);
|
|
372
|
+
if (line.image) setImage(el, line.image.url, line.image.altText || line.title || "");
|
|
413
373
|
return;
|
|
414
374
|
}
|
|
415
|
-
const
|
|
416
|
-
if (
|
|
375
|
+
const text = ownValue(texts, key);
|
|
376
|
+
if (text !== void 0) setText(el, text);
|
|
417
377
|
});
|
|
418
378
|
if (id && returnable !== null) fillReturnControls(row, { ...line, id }, returnable);
|
|
419
379
|
});
|
|
420
380
|
}
|
|
421
381
|
|
|
422
|
-
// src/account/order-page.
|
|
382
|
+
// src/account/order-page.ts
|
|
423
383
|
function orderKey(el) {
|
|
424
384
|
const raw = get(el, "order") || "";
|
|
425
385
|
if (!raw.startsWith("url:")) return raw;
|
|
@@ -435,8 +395,8 @@
|
|
|
435
395
|
});
|
|
436
396
|
}
|
|
437
397
|
var orderTexts = (detail) => ({
|
|
438
|
-
name: detail.name,
|
|
439
|
-
date:
|
|
398
|
+
name: detail.name ?? "",
|
|
399
|
+
date: formatDate(detail.processedAt),
|
|
440
400
|
total: formatMoney(detail.totalPrice),
|
|
441
401
|
subtotal: formatMoney(detail.subtotal),
|
|
442
402
|
shipping: formatMoney(detail.totalShipping),
|
|
@@ -445,29 +405,29 @@
|
|
|
445
405
|
fulfillment: enumText(detail.fulfillmentStatus),
|
|
446
406
|
"shipping-address": addressText(detail.shippingAddress),
|
|
447
407
|
"billing-address": addressText(detail.billingAddress),
|
|
448
|
-
items: detail.lineItems.nodes.map((line) => `${line.quantity}\xD7 ${line.title || line.name}`).join(", "),
|
|
449
|
-
cancelled:
|
|
408
|
+
items: detail.lineItems.nodes.map((line) => `${String(line.quantity)}\xD7 ${line.title || line.name || ""}`).join(", "),
|
|
409
|
+
cancelled: formatDate(detail.cancelledAt)
|
|
450
410
|
});
|
|
451
411
|
function fillFulfillment(row, fulfillment) {
|
|
452
412
|
const tracking = fulfillment.trackingInformation[0];
|
|
453
413
|
const texts = {
|
|
454
414
|
status: enumText(fulfillment.latestShipmentStatus || fulfillment.status),
|
|
455
|
-
date:
|
|
456
|
-
eta:
|
|
415
|
+
date: formatDate(fulfillment.createdAt),
|
|
416
|
+
eta: formatDate(fulfillment.estimatedDeliveryAt),
|
|
457
417
|
company: tracking?.company || "",
|
|
458
418
|
number: tracking?.number || ""
|
|
459
419
|
};
|
|
460
420
|
bindsIn(row, "fulfillment-bind").forEach((el) => {
|
|
461
421
|
const key = get(el, "fulfillment-bind") ?? "";
|
|
462
422
|
if (key === "url") {
|
|
463
|
-
const url = tracking?.url;
|
|
464
|
-
const linked = isHttpsUrl(url);
|
|
465
|
-
if (linked
|
|
423
|
+
const url = tracking?.url ?? null;
|
|
424
|
+
const linked = url !== null && isHttpsUrl(url);
|
|
425
|
+
if (linked) el.setAttribute("href", url);
|
|
466
426
|
show(el, linked);
|
|
467
427
|
return;
|
|
468
428
|
}
|
|
469
|
-
const
|
|
470
|
-
if (
|
|
429
|
+
const text = ownValue(texts, key);
|
|
430
|
+
if (text !== void 0) setText(el, text);
|
|
471
431
|
});
|
|
472
432
|
}
|
|
473
433
|
function fillOrder(el, detail) {
|
|
@@ -482,11 +442,12 @@
|
|
|
482
442
|
qsa(el, sel("order-bind")).forEach((bind) => {
|
|
483
443
|
const key = get(bind, "order-bind") ?? "";
|
|
484
444
|
if (key === "url") {
|
|
485
|
-
|
|
445
|
+
const statusPage = detail.statusPageUrl;
|
|
446
|
+
if (statusPage !== null && isHttpsUrl(statusPage)) bind.setAttribute("href", statusPage);
|
|
486
447
|
return;
|
|
487
448
|
}
|
|
488
|
-
const
|
|
489
|
-
if (
|
|
449
|
+
const text = ownValue(texts, key);
|
|
450
|
+
if (text !== void 0) setText(bind, text);
|
|
490
451
|
});
|
|
491
452
|
qsa(el, sel("order-lines")).forEach((box) => {
|
|
492
453
|
fillLines(box, detail.lineItems.nodes, returnable);
|
|
@@ -532,7 +493,7 @@
|
|
|
532
493
|
fillOrder(el, detail);
|
|
533
494
|
}
|
|
534
495
|
|
|
535
|
-
// src/account/addresses-view.
|
|
496
|
+
// src/account/addresses-view.ts
|
|
536
497
|
var shown = [];
|
|
537
498
|
var shownAddress = (id) => shown.find((address) => address.id === id);
|
|
538
499
|
var addressTexts = (address) => ({
|
|
@@ -551,8 +512,8 @@
|
|
|
551
512
|
row.dataset["tetherAddress"] = address.id;
|
|
552
513
|
const texts = addressTexts(address);
|
|
553
514
|
bindsIn(row, "address-bind").forEach((el) => {
|
|
554
|
-
const
|
|
555
|
-
if (
|
|
515
|
+
const text = ownValue(texts, get(el, "address-bind") ?? "");
|
|
516
|
+
if (text !== void 0) setText(el, text);
|
|
556
517
|
});
|
|
557
518
|
showIn(row, "address-show", { default: address.isDefault, "not-default": !address.isDefault });
|
|
558
519
|
}
|
|
@@ -575,7 +536,7 @@
|
|
|
575
536
|
});
|
|
576
537
|
}
|
|
577
538
|
|
|
578
|
-
// src/account/subscriptions-view.
|
|
539
|
+
// src/account/subscriptions-view.ts
|
|
579
540
|
function conditionsOf(contract) {
|
|
580
541
|
const next = contract.upcomingBillingCycles.nodes[0];
|
|
581
542
|
const status = contract.status;
|
|
@@ -598,23 +559,25 @@
|
|
|
598
559
|
const unit = enumText(contract.deliveryPolicy?.interval);
|
|
599
560
|
if (!unit) return "";
|
|
600
561
|
const count = contract.deliveryPolicy?.intervalCount?.count ?? 1;
|
|
601
|
-
return count <= 1 ? unit : `${count} ${unit}s`;
|
|
562
|
+
return count <= 1 ? unit : `${String(count)} ${unit}s`;
|
|
602
563
|
}
|
|
603
564
|
function contractTexts(contract) {
|
|
604
565
|
const lines = contract.lines.nodes;
|
|
605
566
|
const total = lines.reduce((sum, line) => sum + Number.parseFloat(line.lineDiscountedPrice?.amount ?? "0"), 0);
|
|
606
567
|
return {
|
|
607
568
|
status: enumText(contract.status),
|
|
608
|
-
next:
|
|
569
|
+
next: formatDate(contract.nextBillingDate),
|
|
609
570
|
interval: intervalText(contract),
|
|
610
|
-
products: lines.map((line) => `${line.quantity}\xD7 ${line.title}`).join(", "),
|
|
611
|
-
total:
|
|
571
|
+
products: lines.map((line) => `${String(line.quantity)}\xD7 ${line.title ?? ""}`).join(", "),
|
|
572
|
+
total: formatMoney(
|
|
573
|
+
lines.length && contract.currencyCode ? { amount: String(total), currencyCode: contract.currencyCode } : null
|
|
574
|
+
),
|
|
612
575
|
delivery: formatMoney(contract.deliveryPrice)
|
|
613
576
|
};
|
|
614
577
|
}
|
|
615
578
|
function fillLine(row, line) {
|
|
616
579
|
const texts = {
|
|
617
|
-
title: line.title,
|
|
580
|
+
title: line.title ?? "",
|
|
618
581
|
"variant-title": line.variantTitle || "",
|
|
619
582
|
quantity: String(line.quantity),
|
|
620
583
|
price: formatMoney(line.currentPrice)
|
|
@@ -622,11 +585,11 @@
|
|
|
622
585
|
bindsIn(row, "subscription-line").forEach((el) => {
|
|
623
586
|
const key = get(el, "subscription-line") ?? "";
|
|
624
587
|
if (key === "image") {
|
|
625
|
-
if (line.image) setImage(el, line.image.url, line.image.altText || line.title);
|
|
588
|
+
if (line.image) setImage(el, line.image.url, line.image.altText || line.title || "");
|
|
626
589
|
return;
|
|
627
590
|
}
|
|
628
|
-
const
|
|
629
|
-
if (
|
|
591
|
+
const text = ownValue(texts, key);
|
|
592
|
+
if (text !== void 0) setText(el, text);
|
|
630
593
|
});
|
|
631
594
|
}
|
|
632
595
|
function fillContract(row, contract) {
|
|
@@ -634,8 +597,8 @@
|
|
|
634
597
|
row.setAttribute(attr("subscription-status"), enumText(contract.status));
|
|
635
598
|
const texts = contractTexts(contract);
|
|
636
599
|
qsa(row, sel("subscription-bind")).forEach((el) => {
|
|
637
|
-
const
|
|
638
|
-
if (
|
|
600
|
+
const text = ownValue(texts, get(el, "subscription-bind") ?? "");
|
|
601
|
+
if (text !== void 0) setText(el, text);
|
|
639
602
|
});
|
|
640
603
|
qsa(row, sel("subscription-lines")).forEach((box) => {
|
|
641
604
|
repeat(box, contract.lines.nodes, fillLine);
|
|
@@ -670,30 +633,26 @@
|
|
|
670
633
|
});
|
|
671
634
|
}
|
|
672
635
|
|
|
673
|
-
// src/account/page-events.
|
|
674
|
-
var
|
|
675
|
-
var
|
|
676
|
-
var
|
|
677
|
-
var isForm = (el) => el
|
|
636
|
+
// src/account/page-events.ts
|
|
637
|
+
var SUBSCRIPTION_ACTIONS = ["pause", "resume", "skip", "unskip", "cancel"];
|
|
638
|
+
var isSubscriptionAction = (value) => SUBSCRIPTION_ACTIONS.some((action) => action === value);
|
|
639
|
+
var isField = (el) => el instanceof window.HTMLInputElement || el instanceof window.HTMLSelectElement || el instanceof window.HTMLTextAreaElement;
|
|
640
|
+
var isForm = (el) => el instanceof window.HTMLFormElement;
|
|
678
641
|
function fieldsOf(form) {
|
|
679
642
|
const fields = {};
|
|
680
643
|
for (const field2 of form.elements) {
|
|
681
|
-
if (!
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
field2
|
|
685
|
-
);
|
|
686
|
-
if (!input.name || input.type === "submit" || input.type === "button" || input.type === "checkbox") continue;
|
|
687
|
-
fields[input.name] = input.value;
|
|
644
|
+
if (!isField(field2)) continue;
|
|
645
|
+
if (!field2.name || field2.type === "submit" || field2.type === "button" || field2.type === "checkbox") continue;
|
|
646
|
+
fields[field2.name] = field2.value;
|
|
688
647
|
}
|
|
689
648
|
return fields;
|
|
690
649
|
}
|
|
691
|
-
function
|
|
650
|
+
function customerMessage(error) {
|
|
692
651
|
const userErrors = error instanceof TetherError ? error.userErrors ?? [] : [];
|
|
693
652
|
const message = userErrors.map((userError) => userError.message).join(" ");
|
|
694
653
|
if (message) return message;
|
|
695
|
-
const
|
|
696
|
-
return
|
|
654
|
+
const text = error instanceof Error && error.message ? error.message : "Something went wrong";
|
|
655
|
+
return text.replace(/^Customer accounts: /, "");
|
|
697
656
|
}
|
|
698
657
|
async function act(el, change) {
|
|
699
658
|
if (el.getAttribute("aria-busy") === "true") return "busy";
|
|
@@ -711,7 +670,7 @@
|
|
|
711
670
|
} catch (error) {
|
|
712
671
|
el.setAttribute(attr("form-state"), "error");
|
|
713
672
|
errorBoxes.forEach((box) => {
|
|
714
|
-
setText(box,
|
|
673
|
+
setText(box, customerMessage(error));
|
|
715
674
|
});
|
|
716
675
|
return "error";
|
|
717
676
|
} finally {
|
|
@@ -753,16 +712,14 @@
|
|
|
753
712
|
const form = document.querySelector(sel("address-form"));
|
|
754
713
|
if (!address || !form || !isForm(form)) return;
|
|
755
714
|
form.dataset["tetherAddressId"] = address.id;
|
|
715
|
+
const valuesByName = { ...address };
|
|
756
716
|
for (const field2 of form.elements) {
|
|
757
|
-
if (!
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
else if (input.name && Object.hasOwn(address, input.name)) {
|
|
764
|
-
const value = Object.entries(address).find(([key]) => key === input.name)?.[1];
|
|
765
|
-
input.value = typeof value === "string" ? value : "";
|
|
717
|
+
if (!isField(field2)) continue;
|
|
718
|
+
if (field2.name === "isDefault") {
|
|
719
|
+
if (field2 instanceof window.HTMLInputElement) field2.checked = address.isDefault;
|
|
720
|
+
} else if (field2.name && Object.hasOwn(valuesByName, field2.name)) {
|
|
721
|
+
const value = valuesByName[field2.name];
|
|
722
|
+
field2.value = typeof value === "string" ? value : "";
|
|
766
723
|
}
|
|
767
724
|
}
|
|
768
725
|
form.scrollIntoView({ block: "nearest" });
|
|
@@ -802,7 +759,7 @@
|
|
|
802
759
|
const row = button.closest("[data-tether-subscription]");
|
|
803
760
|
const action = get(button, "subscription-action");
|
|
804
761
|
const disabled = "disabled" in button && button.disabled === true || button.classList.contains("is-disabled");
|
|
805
|
-
if (!(row instanceof window.HTMLElement) || !
|
|
762
|
+
if (!(row instanceof window.HTMLElement) || !isSubscriptionAction(action) || disabled || !confirmed(button)) return;
|
|
806
763
|
const id = row.dataset["tetherSubscription"] ?? "";
|
|
807
764
|
row.setAttribute(attr("subscription-state"), "pending");
|
|
808
765
|
void act(row, async () => {
|
|
@@ -820,7 +777,10 @@
|
|
|
820
777
|
const reason = row.querySelector(sel("return-reason"));
|
|
821
778
|
const note = row.querySelector(sel("return-note"));
|
|
822
779
|
const valueOf = (field2) => field2 && "value" in field2 && typeof field2.value === "string" ? field2.value : "";
|
|
823
|
-
const line = {
|
|
780
|
+
const line = {
|
|
781
|
+
lineItemId: row.dataset["tetherLine"] ?? "",
|
|
782
|
+
quantity: Number.parseInt(valueOf(quantity) || "0", 10)
|
|
783
|
+
};
|
|
824
784
|
const reasonId = valueOf(reason);
|
|
825
785
|
if (reasonId) line.reasonId = reasonId;
|
|
826
786
|
const noteText = valueOf(note);
|
|
@@ -867,21 +827,19 @@
|
|
|
867
827
|
document.addEventListener("click", onClick);
|
|
868
828
|
}
|
|
869
829
|
|
|
870
|
-
// src/account-pages.
|
|
871
|
-
var PROFILE_FIELDS =
|
|
872
|
-
/** @type {const} */
|
|
873
|
-
["firstName", "lastName"]
|
|
874
|
-
);
|
|
830
|
+
// src/account-pages.ts
|
|
831
|
+
var PROFILE_FIELDS = ["firstName", "lastName"];
|
|
875
832
|
async function renderProfile(form) {
|
|
876
|
-
|
|
833
|
+
if (!(form instanceof window.HTMLFormElement)) return;
|
|
834
|
+
let customer;
|
|
835
|
+
try {
|
|
836
|
+
customer = await pagesContext().customer();
|
|
837
|
+
} catch (error) {
|
|
877
838
|
reportError(error, "account");
|
|
878
|
-
return
|
|
879
|
-
}
|
|
880
|
-
if (!customer
|
|
881
|
-
const fields =
|
|
882
|
-
/** @type {HTMLFormElement} */
|
|
883
|
-
form.elements
|
|
884
|
-
);
|
|
839
|
+
return;
|
|
840
|
+
}
|
|
841
|
+
if (!customer) return;
|
|
842
|
+
const fields = form.elements;
|
|
885
843
|
PROFILE_FIELDS.forEach((name) => {
|
|
886
844
|
const input = fields.namedItem(name);
|
|
887
845
|
const isTextField = input instanceof window.HTMLInputElement || input instanceof window.HTMLTextAreaElement;
|
|
@@ -913,11 +871,18 @@
|
|
|
913
871
|
});
|
|
914
872
|
}
|
|
915
873
|
|
|
916
|
-
// src/
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
)
|
|
921
|
-
|
|
922
|
-
|
|
874
|
+
// src/part-registry.ts
|
|
875
|
+
function isTetherInternals(value) {
|
|
876
|
+
return isRecord(value) && isRecord(value["__core"]) && isRecord(value["__parts"]);
|
|
877
|
+
}
|
|
878
|
+
function registerPart(name, part) {
|
|
879
|
+
const tether = Reflect.get(window, "Tether");
|
|
880
|
+
if (!isTetherInternals(tether)) {
|
|
881
|
+
throw new Error(`tether.${name}.js runs after the Tether script, which loads it, and needs its window.Tether`);
|
|
882
|
+
}
|
|
883
|
+
tether.__parts[name] = part;
|
|
884
|
+
}
|
|
885
|
+
|
|
886
|
+
// src/parts/account-pages.ts
|
|
887
|
+
registerPart("account-pages", account_pages_exports);
|
|
923
888
|
})();
|