@occluze/tether 0.6.8 → 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.
Files changed (259) hide show
  1. package/README.md +11 -11
  2. package/dist/esm/astro.js +2 -2
  3. package/dist/esm/chunks/account-UIPWJQ3Y.js +1 -0
  4. package/dist/esm/chunks/account-pages-6ROA6Y4V.js +1 -0
  5. package/dist/esm/chunks/analytics-2V632IRV.js +1 -0
  6. package/dist/esm/chunks/chunk-4GCXM764.js +1 -0
  7. package/dist/esm/chunks/chunk-56FCLJJD.js +1 -0
  8. package/dist/esm/chunks/chunk-5Z5O3767.js +1 -0
  9. package/dist/esm/chunks/chunk-6OZJCAGZ.js +1 -0
  10. package/dist/esm/chunks/chunk-A5SYCVQM.js +1 -0
  11. package/dist/esm/chunks/chunk-BA4LQJJQ.js +1 -0
  12. package/dist/esm/chunks/chunk-BFTZR4OB.js +4 -0
  13. package/dist/esm/chunks/chunk-C5JYQCWH.js +1 -0
  14. package/dist/esm/chunks/chunk-E5YO6274.js +1 -0
  15. package/dist/esm/chunks/chunk-MPDWM2NN.js +1 -0
  16. package/dist/esm/chunks/chunk-T44MUL4Y.js +1 -0
  17. package/dist/esm/chunks/chunk-YLUULATY.js +1 -0
  18. package/dist/esm/chunks/diagnose-3FEKRIEK.js +14 -0
  19. package/dist/esm/chunks/extras-6POFBNOP.js +1 -0
  20. package/dist/esm/chunks/markets-ui-FD6NI2OG.js +1 -0
  21. package/dist/esm/chunks/search-UJ73YBQ5.js +1 -0
  22. package/dist/esm/index.js +1 -1
  23. package/dist/esm/server.js +2 -2
  24. package/dist/presets/barba.esm.js +19 -23
  25. package/dist/tether.account-pages.js +320 -365
  26. package/dist/tether.account-pages.min.js +1 -1
  27. package/dist/tether.account.js +242 -491
  28. package/dist/tether.account.min.js +1 -1
  29. package/dist/tether.analytics.js +66 -88
  30. package/dist/tether.analytics.min.js +1 -1
  31. package/dist/tether.diagnose.js +36 -33
  32. package/dist/tether.diagnose.min.js +2 -2
  33. package/dist/tether.extras.js +28 -36
  34. package/dist/tether.extras.min.js +1 -1
  35. package/dist/tether.js +1270 -894
  36. package/dist/tether.markets.js +73 -90
  37. package/dist/tether.markets.min.js +1 -1
  38. package/dist/tether.min.js +0 -0
  39. package/dist/tether.min.js.map +4 -4
  40. package/dist/tether.search.js +44 -68
  41. package/dist/tether.search.min.js +1 -1
  42. package/dist/types/server/src/shared/account-orders.d.ts +44 -0
  43. package/dist/types/server/src/shared/account-routes.d.ts +153 -0
  44. package/dist/types/server/src/shared/api-versions.d.ts +13 -0
  45. package/dist/types/server/src/shared/error-message.d.ts +2 -0
  46. package/dist/types/server/src/shared/json.d.ts +25 -0
  47. package/dist/types/server/src/shared/market-codes.d.ts +16 -0
  48. package/dist/types/src/account/addresses-view.d.ts +5 -0
  49. package/dist/types/src/account/answers.d.ts +40 -0
  50. package/dist/types/src/account/markup.d.ts +19 -0
  51. package/dist/types/src/account/operations.d.ts +41 -0
  52. package/dist/types/src/account/order-lines.d.ts +13 -0
  53. package/dist/types/src/account/order-list.d.ts +12 -0
  54. package/dist/types/src/account/order-page.d.ts +6 -0
  55. package/dist/types/src/account/page-answers.d.ts +182 -0
  56. package/dist/types/src/account/page-events.d.ts +2 -0
  57. package/dist/types/src/account/server-client.d.ts +60 -0
  58. package/dist/types/src/account/subscriptions-view.d.ts +2 -0
  59. package/dist/types/src/account-api.d.ts +18 -0
  60. package/dist/types/src/account-marks.d.ts +15 -0
  61. package/dist/types/src/account-pages.d.ts +8 -0
  62. package/dist/types/src/account.d.ts +64 -0
  63. package/dist/types/src/amounts.d.ts +12 -0
  64. package/dist/types/src/analytics-shopify.d.ts +41 -0
  65. package/dist/types/src/analytics.d.ts +2 -0
  66. package/dist/types/src/api-version.d.ts +28 -0
  67. package/dist/types/src/astro.d.ts +42 -0
  68. package/dist/types/src/cart/cart-shape.d.ts +43 -0
  69. package/dist/types/src/cart/checkout.d.ts +16 -0
  70. package/dist/types/src/cart/drawer.d.ts +18 -0
  71. package/dist/types/src/cart/mutations.d.ts +79 -0
  72. package/dist/types/src/cart/render.d.ts +17 -0
  73. package/dist/types/src/cart/store.d.ts +182 -0
  74. package/dist/types/src/cart.d.ts +106 -0
  75. package/dist/types/src/client.d.ts +100 -0
  76. package/dist/types/src/collection.d.ts +25 -0
  77. package/dist/types/src/config-sections.d.ts +40 -0
  78. package/dist/types/src/config.d.ts +185 -0
  79. package/dist/types/src/controls/cart-controls.d.ts +2 -0
  80. package/dist/types/src/controls/discount.d.ts +2 -0
  81. package/dist/types/src/controls/extras.d.ts +5 -0
  82. package/dist/types/src/controls/navigation.d.ts +12 -0
  83. package/dist/types/src/diagnose-markup.d.ts +19 -0
  84. package/dist/types/src/diagnose.d.ts +60 -0
  85. package/dist/types/src/dom.d.ts +75 -0
  86. package/dist/types/src/extras.d.ts +21 -0
  87. package/dist/types/src/fragments.d.ts +158 -0
  88. package/dist/types/src/globals.d.ts +15 -0
  89. package/dist/types/src/images.d.ts +20 -0
  90. package/dist/types/src/index.d.ts +167 -0
  91. package/dist/types/src/initial.d.ts +56 -0
  92. package/dist/types/src/lazy.d.ts +28 -0
  93. package/dist/types/src/loader.d.ts +84 -0
  94. package/dist/types/src/market-codes.d.ts +6 -0
  95. package/dist/types/src/markets-ui.d.ts +32 -0
  96. package/dist/types/src/markets.d.ts +72 -0
  97. package/dist/types/src/markup.d.ts +131 -0
  98. package/dist/types/src/mounting.d.ts +46 -0
  99. package/dist/types/src/page-market.d.ts +27 -0
  100. package/dist/types/src/presets/barba.d.ts +56 -0
  101. package/dist/types/src/product-events.d.ts +2 -0
  102. package/dist/types/src/product-render.d.ts +17 -0
  103. package/dist/types/src/product-shape.d.ts +88 -0
  104. package/dist/types/src/product-state.d.ts +110 -0
  105. package/dist/types/src/product.d.ts +66 -0
  106. package/dist/types/src/repeaters.d.ts +16 -0
  107. package/dist/types/src/search.d.ts +33 -0
  108. package/dist/types/src/selling-plans.d.ts +64 -0
  109. package/dist/types/src/server.d.ts +88 -0
  110. package/dist/types/src/shopify-values.d.ts +46 -0
  111. package/dist/types/src/status.d.ts +33 -0
  112. package/dist/types/src/storage.d.ts +12 -0
  113. package/dist/types/src/store-html.d.ts +39 -0
  114. package/dist/types/src/storefront/catalog.d.ts +38 -0
  115. package/dist/types/src/storefront/json-ld.d.ts +20 -0
  116. package/dist/types/src/variant-render.d.ts +14 -0
  117. package/package.json +24 -23
  118. package/src/account/addresses-view.ts +58 -0
  119. package/src/account/answers.ts +79 -0
  120. package/src/account/markup.ts +36 -0
  121. package/src/account/operations.ts +145 -0
  122. package/src/account/{order-lines.js → order-lines.ts} +20 -41
  123. package/src/account/order-list.ts +107 -0
  124. package/src/account/order-page.ts +137 -0
  125. package/src/account/page-answers.ts +317 -0
  126. package/src/account/{page-events.js → page-events.ts} +55 -90
  127. package/src/account/server-client.ts +183 -0
  128. package/src/account/{subscriptions-view.js → subscriptions-view.ts} +25 -68
  129. package/src/account-api.ts +98 -0
  130. package/src/account-marks.ts +35 -0
  131. package/src/{account-pages.js → account-pages.ts} +29 -37
  132. package/src/account.ts +284 -0
  133. package/src/amounts.ts +64 -0
  134. package/src/{analytics-shopify.js → analytics-shopify.ts} +112 -107
  135. package/src/analytics.ts +315 -0
  136. package/src/{api-version.js → api-version.ts} +25 -31
  137. package/src/{astro.js → astro.ts} +110 -104
  138. package/src/cart/cart-shape.ts +25 -0
  139. package/src/cart/checkout.ts +101 -0
  140. package/src/cart/{drawer.js → drawer.ts} +18 -31
  141. package/src/cart/mutations.ts +237 -0
  142. package/src/cart/{render.js → render.ts} +68 -96
  143. package/src/cart/store.ts +279 -0
  144. package/src/{cart.js → cart.ts} +82 -128
  145. package/src/client.ts +391 -0
  146. package/src/{collection.js → collection.ts} +30 -38
  147. package/src/config-sections.ts +284 -0
  148. package/src/config.ts +480 -0
  149. package/src/controls/{cart-controls.js → cart-controls.ts} +22 -54
  150. package/src/controls/{discount.js → discount.ts} +13 -34
  151. package/src/controls/{extras.js → extras.ts} +15 -24
  152. package/src/controls/{navigation.js → navigation.ts} +24 -30
  153. package/src/{diagnose-markup.js → diagnose-markup.ts} +37 -72
  154. package/src/{diagnose.js → diagnose.ts} +95 -96
  155. package/src/dom.ts +268 -0
  156. package/src/{extras.js → extras.ts} +43 -52
  157. package/src/fragments.ts +261 -0
  158. package/src/globals.d.ts +15 -0
  159. package/src/{images.js → images.ts} +30 -43
  160. package/src/index.ts +415 -0
  161. package/src/initial.ts +101 -0
  162. package/src/lazy-iife.ts +197 -0
  163. package/src/lazy.ts +42 -0
  164. package/src/{loader.js → loader.ts} +149 -123
  165. package/src/market-codes.ts +6 -0
  166. package/src/{markets-ui.js → markets-ui.ts} +91 -68
  167. package/src/markets.ts +246 -0
  168. package/src/markup.ts +127 -0
  169. package/src/{mounting.js → mounting.ts} +88 -101
  170. package/src/{page-market.js → page-market.ts} +32 -38
  171. package/src/part-integrity.ts +7 -0
  172. package/src/parts/account-pages.ts +7 -0
  173. package/src/parts/account.ts +7 -0
  174. package/src/parts/analytics.ts +7 -0
  175. package/src/parts/diagnose.ts +7 -0
  176. package/src/parts/extras.ts +7 -0
  177. package/src/parts/markets.ts +7 -0
  178. package/src/parts/search.ts +7 -0
  179. package/src/presets/barba.ts +194 -0
  180. package/src/{product-events.js → product-events.ts} +33 -48
  181. package/src/{product-render.js → product-render.ts} +38 -77
  182. package/src/product-shape.ts +49 -0
  183. package/src/product-state.ts +318 -0
  184. package/src/{product.js → product.ts} +90 -126
  185. package/src/{repeaters.js → repeaters.ts} +40 -52
  186. package/src/{search.js → search.ts} +85 -103
  187. package/src/selling-plans.ts +145 -0
  188. package/src/server.ts +211 -0
  189. package/src/{shopify-values.js → shopify-values.ts} +24 -22
  190. package/src/{status.js → status.ts} +34 -54
  191. package/src/storage.ts +34 -0
  192. package/src/store-html.ts +359 -0
  193. package/src/storefront/catalog.ts +196 -0
  194. package/src/storefront/{json-ld.js → json-ld.ts} +45 -68
  195. package/src/{variant-render.js → variant-render.ts} +24 -50
  196. package/dist/esm/chunks/account-C3NP6HFB.js +0 -1
  197. package/dist/esm/chunks/account-pages-WLK374FO.js +0 -1
  198. package/dist/esm/chunks/analytics-G3SAWMNL.js +0 -1
  199. package/dist/esm/chunks/chunk-27PJJZGC.js +0 -1
  200. package/dist/esm/chunks/chunk-2FSXS55U.js +0 -1
  201. package/dist/esm/chunks/chunk-FCSWQDVV.js +0 -1
  202. package/dist/esm/chunks/chunk-FOMSMIAM.js +0 -1
  203. package/dist/esm/chunks/chunk-GZJTCLLW.js +0 -1
  204. package/dist/esm/chunks/chunk-HEQILZVR.js +0 -1
  205. package/dist/esm/chunks/chunk-JOOEXYF3.js +0 -4
  206. package/dist/esm/chunks/chunk-MPTQYLSM.js +0 -1
  207. package/dist/esm/chunks/chunk-NEHZ37TU.js +0 -3
  208. package/dist/esm/chunks/chunk-V74KGEJF.js +0 -1
  209. package/dist/esm/chunks/chunk-VT4CDUJJ.js +0 -1
  210. package/dist/esm/chunks/chunk-YJLWX2HK.js +0 -1
  211. package/dist/esm/chunks/diagnose-6VVGZNTY.js +0 -14
  212. package/dist/esm/chunks/extras-GJVRDFM3.js +0 -1
  213. package/dist/esm/chunks/markets-ui-UNB4PTA7.js +0 -1
  214. package/dist/esm/chunks/search-OU75RNQL.js +0 -1
  215. package/src/account/addresses-view.js +0 -92
  216. package/src/account/browser-session.js +0 -359
  217. package/src/account/markup.js +0 -48
  218. package/src/account/operations.js +0 -180
  219. package/src/account/order-list.js +0 -91
  220. package/src/account/order-page.js +0 -192
  221. package/src/account/server-client.js +0 -172
  222. package/src/account/shared.js +0 -111
  223. package/src/account/shopify-auth.js +0 -150
  224. package/src/account-api.js +0 -118
  225. package/src/account-links.js +0 -35
  226. package/src/account.js +0 -342
  227. package/src/amounts.js +0 -36
  228. package/src/analytics.js +0 -352
  229. package/src/cart/checkout.js +0 -97
  230. package/src/cart/mutations.js +0 -234
  231. package/src/cart/store.js +0 -326
  232. package/src/client.js +0 -267
  233. package/src/config.js +0 -349
  234. package/src/dom.js +0 -287
  235. package/src/fragments.js +0 -237
  236. package/src/index.js +0 -353
  237. package/src/initial.js +0 -87
  238. package/src/lazy-iife.js +0 -116
  239. package/src/lazy.js +0 -39
  240. package/src/market-codes.js +0 -35
  241. package/src/markets.js +0 -334
  242. package/src/markup.js +0 -64
  243. package/src/parts/account-pages.js +0 -6
  244. package/src/parts/account.js +0 -6
  245. package/src/parts/analytics.js +0 -6
  246. package/src/parts/diagnose.js +0 -6
  247. package/src/parts/extras.js +0 -6
  248. package/src/parts/markets.js +0 -6
  249. package/src/parts/search.js +0 -6
  250. package/src/presets/barba.js +0 -190
  251. package/src/product-state.js +0 -318
  252. package/src/selling-plans.js +0 -154
  253. package/src/server.js +0 -215
  254. package/src/store-html.js +0 -0
  255. package/src/storefront/catalog.js +0 -199
  256. package/types/astro.d.ts +0 -28
  257. package/types/barba.d.ts +0 -16
  258. package/types/index.d.ts +0 -577
  259. 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.js
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.js
26
- var m = window.Tether.__core["config.js"];
27
- var { DEFAULTS, cfg, configure, isConfigured, log, reportError, resolveConfig, toMetafieldIdentifier, warn } = m;
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.js
30
- var m2 = window.Tether.__core["dom.js"];
31
- var { attr, busy, cdnUrl, emit, formatDate, formatMoney, formatPercent, get, has, hasTemplate, imageUrl, notifyLayoutChanged, parseJSONAttr, productUrl, qsa, repeat, repeatKeyed, sameImage, scoped, sel, setImage, setSelected, setStoreHtml, setText, setTextTracked, show, toAttributes, watchImages } = m2;
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.js
34
- var m3 = window.Tether.__core["client.js"];
35
- var { TetherError, endpoint, gql, request, unwrap, withContext } = m3;
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-ops.js
38
- var InputError = class extends Error {
39
- /**
40
- * @param {string} message
41
- * @param {{ status?: number, userErrors?: UserError[] }} [details]
42
- */
43
- constructor(message, { status = 400, userErrors = [] } = {}) {
44
- super(message);
45
- this.name = "InputError";
46
- this.status = status;
47
- this.userErrors = userErrors;
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"
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 }
76
47
  },
77
- cancel: {
78
- document: `mutation TetherCancel($id:ID!){subscriptionContractCancel(subscriptionContractId:$id){contract{id status}${USER_ERRORS}}}`,
79
- payload: "subscriptionContractCancel",
80
- input: "contract"
81
- },
82
- skip: {
83
- document: `mutation TetherSkip($input:SubscriptionBillingCycleInput!){subscriptionBillingCycleSkip(billingCycleInput:$input){billingCycle{cycleIndex skipped}${USER_ERRORS}}}`,
84
- payload: "subscriptionBillingCycleSkip",
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
- function isSubscriptionAction(value) {
94
- return typeof value === "string" && Object.hasOwn(SUBSCRIPTION_ACTIONS, value);
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
- if (value === null || typeof value !== "object") return void 0;
98
- return (
99
- /** @type {Record<string, unknown>} */
100
- value[key]
101
- );
76
+ return isRecord(value) ? value[key] : void 0;
102
77
  }
103
- function nodes(value) {
104
- const list = field(value, "nodes");
105
- return Array.isArray(list) ? list : [];
78
+ function asList(value) {
79
+ return Array.isArray(value) ? value : [];
106
80
  }
107
- var NUMERIC_ID = /^\d{1,20}$/;
108
- function idOf(type, value) {
109
- const raw = typeof value === "string" || typeof value === "number" ? String(value) : "";
110
- const id = NUMERIC_ID.test(raw) ? `gid://shopify/${type}/${raw}` : raw;
111
- if (!new RegExp(`^gid://shopify/${type}/\\d+(\\?[\\w=&.-]{1,80})?$`).test(id)) throw new InputError(`${type} id`);
81
+ function textOrNull(value) {
82
+ return typeof value === "string" && value !== "" ? value : null;
83
+ }
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
- var CONTROL_CHARACTERS = /[\u0000-\u001f\u007f]/g;
115
- function text(value, maxLength = 255) {
116
- if (value === null || value === void 0 || value === "") return void 0;
117
- if (typeof value !== "string" && typeof value !== "number") throw new InputError("text");
118
- const clean = String(value).replace(CONTROL_CHARACTERS, "").trim();
119
- if (clean.length > maxLength) throw new InputError("too long");
120
- return clean;
121
- }
122
- var ADDRESS_FIELDS = [
123
- "firstName",
124
- "lastName",
125
- "company",
126
- "address1",
127
- "address2",
128
- "city",
129
- "zip",
130
- "zoneCode",
131
- "phoneNumber"
132
- ];
133
- function addressInput(address, { clear = false } = {}) {
134
- if (address === null || typeof address !== "object" || Array.isArray(address)) throw new InputError("address");
135
- const source = (
136
- /** @type {Record<string, unknown>} */
137
- address
138
- );
139
- const out = {};
140
- for (const key of ADDRESS_FIELDS) {
141
- const value = text(source[key]);
142
- if (value !== void 0) out[key] = value;
143
- else if (clear && key in source && (source[key] === "" || source[key] === null)) out[key] = "";
144
- }
145
- const country = text(source["countryCode"]);
146
- if (country !== void 0) {
147
- const code = country.toUpperCase();
148
- if (!/^[A-Z]{2}$/.test(code)) throw new InputError("countryCode");
149
- out["countryCode"] = code;
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
- return out;
152
- }
153
- function payloadOf(data, name) {
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
- return payload;
247
+ throw unexpected("changed subscription");
164
248
  }
165
- var ops = {
166
- async order(ask, { id }) {
167
- const data = await ask(QUERIES.order, { id: idOf("Order", id) });
168
- return { order: field(data, "order") ?? null };
169
- },
170
- async profile(ask, { firstName, lastName }) {
171
- const input = {};
172
- if (firstName !== void 0) input["firstName"] = text(firstName, 100) ?? "";
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.js
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
- var ROUTE = {
254
- order: (input) => ["GET", `/order?id=${encodeURIComponent(String(input["id"]))}`],
255
- addresses: () => ["GET", "/addresses"],
256
- subscriptions: () => ["GET", "/subscriptions"],
257
- profile: () => ["POST", "/profile"],
258
- saveAddress: () => ["POST", "/address"],
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({ firstName, lastName } = {}) {
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.js
350
- var m4 = window.Tether.__core["shopify-values.js"];
351
- var { STORE_ENV_NAMES, formatMoney: formatMoney2, isHttpsUrl, isSecretShopifyToken, productKey, productUrl: productUrl2 } = m4;
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.js
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.js
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 text2 = ownValue(texts, key);
416
- if (text2 !== void 0) setText(el, text2);
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.js
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: localDate(detail.processedAt),
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: detail.cancelledAt ? localDate(detail.cancelledAt) : ""
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: localDate(fulfillment.createdAt),
456
- eta: fulfillment.estimatedDeliveryAt ? localDate(fulfillment.estimatedDeliveryAt) : "",
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 && url) el.setAttribute("href", url);
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 text2 = ownValue(texts, key);
470
- if (text2 !== void 0) setText(el, text2);
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
- if (detail.statusPageUrl && isHttpsUrl(detail.statusPageUrl)) bind.setAttribute("href", detail.statusPageUrl);
445
+ const statusPage = detail.statusPageUrl;
446
+ if (statusPage !== null && isHttpsUrl(statusPage)) bind.setAttribute("href", statusPage);
486
447
  return;
487
448
  }
488
- const text2 = ownValue(texts, key);
489
- if (text2 !== void 0) setText(bind, text2);
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.js
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 text2 = ownValue(texts, get(el, "address-bind") ?? "");
555
- if (text2 !== void 0) setText(el, text2);
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.js
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: contract.nextBillingDate ? localDate(contract.nextBillingDate) : "",
569
+ next: formatDate(contract.nextBillingDate),
609
570
  interval: intervalText(contract),
610
- products: lines.map((line) => `${line.quantity}\xD7 ${line.title}`).join(", "),
611
- total: lines.length ? formatMoney({ amount: String(total), currencyCode: contract.currencyCode }) : "",
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 text2 = ownValue(texts, key);
629
- if (text2 !== void 0) setText(el, text2);
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 text2 = ownValue(texts, get(el, "subscription-bind") ?? "");
638
- if (text2 !== void 0) setText(el, text2);
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.js
674
- var SUBSCRIPTION_ACTIONS2 = ["pause", "resume", "skip", "unskip", "cancel"];
675
- var isSubscriptionAction2 = (value) => SUBSCRIPTION_ACTIONS2.some((action) => action === value);
676
- var isInput2 = (el) => el.tagName === "INPUT";
677
- var isForm = (el) => el.tagName === "FORM";
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 (!isInput2(field2) && field2.tagName !== "SELECT" && field2.tagName !== "TEXTAREA") continue;
682
- const input = (
683
- /** @type {HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement} */
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 messageOf(error) {
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 text2 = error instanceof Error && error.message ? error.message : "Something went wrong";
696
- return text2.replace(/^Customer accounts: /, "");
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, messageOf(error));
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 (!isInput2(field2) && field2.tagName !== "SELECT" && field2.tagName !== "TEXTAREA") continue;
758
- const input = (
759
- /** @type {HTMLInputElement} */
760
- field2
761
- );
762
- if (input.name === "isDefault") input.checked = address.isDefault;
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) || !isSubscriptionAction2(action) || disabled || !confirmed(button)) return;
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 = { lineItemId: row.dataset["tetherLine"] ?? "", quantity: Number.parseInt(valueOf(quantity) || "0", 10) };
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.js
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
- const customer = await pagesContext().customer().catch((error) => {
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 null;
879
- });
880
- if (!customer || form.tagName !== "FORM") return;
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,8 @@
913
871
  });
914
872
  }
915
873
 
916
- // src/parts/account-pages.js
917
- var { Tether } = (
918
- /** @type {Window & { Tether?: { __parts: Record<string, unknown> } }} */
919
- window
920
- );
874
+ // src/parts/account-pages.ts
875
+ var { Tether } = window;
921
876
  if (!Tether) throw new Error("tether.account-pages.js runs after the Tether script, which loads it");
922
877
  Tether.__parts["account-pages"] = account_pages_exports;
923
878
  })();