@occluze/tether 0.6.7 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (250) 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 -1
  24. package/dist/presets/barba.esm.js +55 -39
  25. package/dist/tether.account-pages.js +781 -495
  26. package/dist/tether.account-pages.min.js +1 -1
  27. package/dist/tether.account.js +462 -381
  28. package/dist/tether.account.min.js +1 -1
  29. package/dist/tether.analytics.js +299 -194
  30. package/dist/tether.analytics.min.js +1 -1
  31. package/dist/tether.diagnose.js +354 -262
  32. package/dist/tether.diagnose.min.js +2 -2
  33. package/dist/tether.extras.js +82 -45
  34. package/dist/tether.extras.min.js +1 -1
  35. package/dist/tether.js +3653 -2116
  36. package/dist/tether.markets.js +238 -150
  37. package/dist/tether.markets.min.js +1 -1
  38. package/dist/tether.min.js +3 -3
  39. package/dist/tether.min.js.map +4 -4
  40. package/dist/tether.search.js +207 -136
  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 +42 -22
  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.ts +75 -0
  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.ts +253 -0
  127. package/src/account/server-client.ts +183 -0
  128. package/src/account/subscriptions-view.ts +115 -0
  129. package/src/account-api.ts +98 -0
  130. package/src/account-marks.ts +35 -0
  131. package/src/account-pages.ts +81 -0
  132. package/src/account.ts +284 -0
  133. package/src/amounts.ts +64 -0
  134. package/src/analytics-shopify.ts +246 -0
  135. package/src/analytics.ts +315 -0
  136. package/src/api-version.ts +79 -0
  137. package/src/astro.ts +272 -0
  138. package/src/cart/cart-shape.ts +25 -0
  139. package/src/cart/checkout.ts +101 -0
  140. package/src/cart/drawer.ts +125 -0
  141. package/src/cart/mutations.ts +237 -0
  142. package/src/cart/render.ts +266 -0
  143. package/src/cart/store.ts +279 -0
  144. package/src/cart.ts +345 -0
  145. package/src/client.ts +391 -0
  146. package/src/collection.ts +175 -0
  147. package/src/config-sections.ts +284 -0
  148. package/src/config.ts +480 -0
  149. package/src/controls/cart-controls.ts +123 -0
  150. package/src/controls/discount.ts +75 -0
  151. package/src/controls/extras.ts +54 -0
  152. package/src/controls/navigation.ts +77 -0
  153. package/src/diagnose-markup.ts +298 -0
  154. package/src/diagnose.ts +294 -0
  155. package/src/dom.ts +268 -0
  156. package/src/extras.ts +136 -0
  157. package/src/fragments.ts +261 -0
  158. package/src/globals.d.ts +15 -0
  159. package/src/images.ts +91 -0
  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.ts +363 -0
  165. package/src/market-codes.ts +6 -0
  166. package/src/markets-ui.ts +227 -0
  167. package/src/markets.ts +246 -0
  168. package/src/markup.ts +127 -0
  169. package/src/mounting.ts +264 -0
  170. package/src/page-market.ts +110 -0
  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.ts +115 -0
  181. package/src/product-render.ts +218 -0
  182. package/src/product-shape.ts +49 -0
  183. package/src/product-state.ts +318 -0
  184. package/src/product.ts +308 -0
  185. package/src/repeaters.ts +161 -0
  186. package/src/search.ts +305 -0
  187. package/src/selling-plans.ts +145 -0
  188. package/src/server.ts +211 -0
  189. package/src/shopify-values.ts +91 -0
  190. package/src/status.ts +106 -0
  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.ts +144 -0
  195. package/src/variant-render.ts +139 -0
  196. package/dist/esm/chunks/account-Q6E2TFEV.js +0 -1
  197. package/dist/esm/chunks/account-pages-UZXR4R5F.js +0 -1
  198. package/dist/esm/chunks/analytics-IJBKATUP.js +0 -1
  199. package/dist/esm/chunks/chunk-4QJKLPYR.js +0 -1
  200. package/dist/esm/chunks/chunk-64TUD3QR.js +0 -1
  201. package/dist/esm/chunks/chunk-AJLPU2JC.js +0 -4
  202. package/dist/esm/chunks/chunk-FIOZPPC5.js +0 -1
  203. package/dist/esm/chunks/chunk-K2YEQAIH.js +0 -1
  204. package/dist/esm/chunks/chunk-KIDH76B7.js +0 -1
  205. package/dist/esm/chunks/chunk-PAYT5ZD7.js +0 -1
  206. package/dist/esm/chunks/chunk-RREHGH4A.js +0 -1
  207. package/dist/esm/chunks/chunk-SSJT43CJ.js +0 -1
  208. package/dist/esm/chunks/chunk-VC46IEJQ.js +0 -1
  209. package/dist/esm/chunks/diagnose-3WVAWNTX.js +0 -14
  210. package/dist/esm/chunks/extras-7I7WJX35.js +0 -1
  211. package/dist/esm/chunks/markets-ui-545XLFTE.js +0 -1
  212. package/dist/esm/chunks/search-NILMGYXG.js +0 -1
  213. package/src/account-pages.js +0 -318
  214. package/src/account.js +0 -385
  215. package/src/analytics.js +0 -232
  216. package/src/api-version.js +0 -35
  217. package/src/astro.js +0 -101
  218. package/src/cart.js +0 -559
  219. package/src/client.js +0 -131
  220. package/src/collection.js +0 -114
  221. package/src/config.js +0 -85
  222. package/src/diagnose.js +0 -246
  223. package/src/dom.js +0 -288
  224. package/src/extras.js +0 -63
  225. package/src/fragments.js +0 -144
  226. package/src/index.js +0 -395
  227. package/src/initial.js +0 -75
  228. package/src/lazy-iife.js +0 -46
  229. package/src/lazy.js +0 -18
  230. package/src/loader.js +0 -198
  231. package/src/markets-ui.js +0 -90
  232. package/src/markets.js +0 -133
  233. package/src/mounting.js +0 -154
  234. package/src/parts/account-pages.js +0 -3
  235. package/src/parts/account.js +0 -3
  236. package/src/parts/analytics.js +0 -3
  237. package/src/parts/diagnose.js +0 -3
  238. package/src/parts/extras.js +0 -3
  239. package/src/parts/markets.js +0 -3
  240. package/src/parts/search.js +0 -3
  241. package/src/presets/barba.js +0 -100
  242. package/src/product.js +0 -570
  243. package/src/search.js +0 -153
  244. package/src/selling-plans.js +0 -94
  245. package/src/server.js +0 -252
  246. package/src/status.js +0 -66
  247. package/types/astro.d.ts +0 -17
  248. package/types/barba.d.ts +0 -16
  249. package/types/index.d.ts +0 -426
  250. package/types/server.d.ts +0 -110
@@ -0,0 +1,25 @@
1
+ /**
2
+ * Reading JSON that arrives from outside (Shopify's answers, a Worker request body) field by field, for the browser
3
+ * script and the Worker alike. Every reader takes `unknown`, so a missing or mistyped field is `undefined`, never a
4
+ * crash.
5
+ */
6
+ /** A plain object, as parsed JSON holds it. */
7
+ export declare function isRecord(value: unknown): value is Record<string, unknown>;
8
+ /** The field `key` of `value`, or `undefined` when `value` is not a plain object. */
9
+ export declare function field(value: unknown, key: string): unknown;
10
+ /** The value when it is an array, else an empty list. */
11
+ export declare function asList(value: unknown): unknown[];
12
+ /** A non-empty string, or `null`: Shopify sends `""` and `null` alike for an unset text field. */
13
+ export declare function textOrNull(value: unknown): string | null;
14
+ export declare const numberOrNull: (value: unknown) => number | null;
15
+ /** A count Shopify always sends; 0 for an answer without it. */
16
+ export declare const countOrZero: (value: unknown) => number;
17
+ export declare const listOf: <T>(value: unknown, read: (item: unknown) => T) => T[];
18
+ /**
19
+ * @param connection A GraphQL connection: `{ nodes: [...] }`.
20
+ */
21
+ export declare const nodesOf: <T>(connection: unknown, read: (item: unknown) => T) => {
22
+ nodes: T[];
23
+ };
24
+ /** The non-empty strings of a list. */
25
+ export declare const textList: (value: unknown) => string[];
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Country and language codes as Shopify takes them, parsed the same way in the browser and the Worker: anything that
3
+ * isn't a code is dropped rather than repaired.
4
+ */
5
+ /** An ISO 3166-1 alpha-2 code, upper case. */
6
+ export type CountryCode = string & {
7
+ readonly __brand: 'CountryCode';
8
+ };
9
+ /** A Shopify `LanguageCode` value. */
10
+ export type LanguageCode = string & {
11
+ readonly __brand: 'LanguageCode';
12
+ };
13
+ /** @returns `'de'` → `'DE'`; `null` for anything that is not a country code. */
14
+ export declare function toCountry(value: unknown): CountryCode | null;
15
+ /** @returns `'de-DE'` → `'DE'`, `'pt-BR'` → `'PT_BR'`, `'en'` → `'EN'`; `null` otherwise. */
16
+ export declare function toLanguage(value: unknown): LanguageCode | null;
@@ -0,0 +1,5 @@
1
+ import type { CustomerAddress } from './page-answers.js';
2
+ /** @returns The address with this id in the list shown last. */
3
+ export declare const shownAddress: (id: string) => CustomerAddress | undefined;
4
+ /** Loads and renders the addresses. A failure is reported and shows `addresses-error`, never "no addresses yet". */
5
+ export declare function renderAddresses(root: ParentNode): Promise<void>;
@@ -0,0 +1,40 @@
1
+ /**
2
+ * The Worker's account answers as typed values. The Worker passes on what Shopify answers to its fixed documents, and
3
+ * each answer is read once, field by field. Every field a document selects is kept. One that is missing or of another
4
+ * type reads as `null` (a list as empty, a count as 0): a page with one blank field is better than no page. The ids
5
+ * the pages act on are required, and an answer without one is an error. This module reads what the account part
6
+ * shows (the customer, their orders through the reader the Worker shares, Shopify's `userErrors`); page-answers.ts
7
+ * reads the account pages' answers.
8
+ */
9
+ import { TetherError } from '../client.js';
10
+ import type { UserError } from '../client.js';
11
+ import type { AccountOrder } from '../../server/src/shared/account-orders.js';
12
+ /** The logged-in customer. */
13
+ export interface AccountCustomer {
14
+ /** The customer's gid; left out when the Worker's `/me` doesn't send it. */
15
+ id?: string;
16
+ firstName: string | null;
17
+ lastName: string | null;
18
+ displayName: string | null;
19
+ emailAddress: {
20
+ emailAddress: string;
21
+ } | null;
22
+ defaultAddress: {
23
+ formatted: string[];
24
+ } | null;
25
+ }
26
+ export declare const unexpected: (what: string) => TetherError;
27
+ /**
28
+ * @param what Named in the error.
29
+ * @throws {TetherError} Without an id.
30
+ */
31
+ export declare function requiredId(value: unknown, what: string): string;
32
+ /** @param value The `customer` of the Worker's `/me`, which flattens the email and the default address. */
33
+ export declare function toAccountCustomer(value: unknown): AccountCustomer;
34
+ /**
35
+ * @param value The `orders` of the Worker's `/orders`.
36
+ * @throws {TetherError} For an order without an id.
37
+ */
38
+ export declare function toAccountOrders(value: unknown): AccountOrder[];
39
+ /** @param value Shopify's `userErrors`, as Shopify or the Worker sends them. */
40
+ export declare const toUserErrors: (value: unknown) => UserError[];
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Shows or hides each `name` element whose value is one of `conditions`' keys; other values are left alone.
3
+ *
4
+ * @param name `show`, `order-show`, `address-show`…
5
+ */
6
+ export declare function showIn(root: ParentNode, name: string, conditions: Readonly<Record<string, boolean>>): void;
7
+ /**
8
+ * @param row A copy of a repeater's template.
9
+ * @returns The `name` elements in `row`, and `row` itself when it carries `name`.
10
+ */
11
+ export declare const bindsIn: (row: HTMLElement, name: string) => HTMLElement[];
12
+ /** @returns A Shopify enum as text: `PARTIALLY_FULFILLED` → `partially fulfilled`. */
13
+ export declare const enumText: (value: string | null | undefined) => string;
14
+ /** @returns Shopify's formatted address on one line. */
15
+ export declare const addressText: (address: {
16
+ formatted?: string[] | null;
17
+ } | null | undefined) => string;
18
+ /** A bind's value, looked up by the attribute's text: only the table's own keys, never `constructor` and the like. */
19
+ export declare const ownValue: <T>(values: Readonly<Record<string, T>>, key: string) => T | undefined;
@@ -0,0 +1,41 @@
1
+ import type { AddressFields, ReturnLine, SubscriptionAction } from '../../server/src/shared/account-routes.js';
2
+ export type { AddressFields, ReturnLine };
3
+ import type { AccountAddress, CustomerAddress, OpenedReturn, OrderDetail, Profile, SubscriptionChange, SubscriptionContract } from './page-answers.js';
4
+ import type { ServerAnswer, ServerRequest } from './server-client.js';
5
+ import type { AccountCustomer } from './answers.js';
6
+ /** The account part's session, shared so both parts act as one customer. */
7
+ interface PagesContext {
8
+ serverFetch: (path: string, request?: ServerRequest) => Promise<ServerAnswer>;
9
+ customer: () => Promise<AccountCustomer | null>;
10
+ bindCustomer: (root: ParentNode) => Promise<void>;
11
+ /** Forgets the cached customer after a change of their data. */
12
+ reset: () => void;
13
+ }
14
+ /** Called by the account part once, when it loads this part. */
15
+ export declare function setup(shared: PagesContext): void;
16
+ /** @throws {Error} Before `setup`: this part is only ever loaded by the account part, which calls it first. */
17
+ export declare function pagesContext(): PagesContext;
18
+ /**
19
+ * One of the customer's orders, in full (lines, totals, addresses, fulfillments, returns).
20
+ *
21
+ * @param id A gid or the numeric order id.
22
+ * @returns `null` when the customer has no such order.
23
+ */
24
+ export declare function order(id: string | number): Promise<OrderDetail | null>;
25
+ export declare function updateProfile({ firstName, lastName, }?: {
26
+ firstName?: string;
27
+ lastName?: string;
28
+ }): Promise<Profile>;
29
+ /** @returns The customer's addresses, the default one marked `isDefault`. */
30
+ export declare function addresses(): Promise<CustomerAddress[]>;
31
+ /** Creates an address, or updates the one with `id`; without fields, only makes it the default. */
32
+ export declare function saveAddress(address: AddressFields | null, { id, isDefault }?: {
33
+ id?: string | undefined;
34
+ isDefault?: boolean;
35
+ }): Promise<AccountAddress>;
36
+ /** @returns The deleted address's id. */
37
+ export declare function deleteAddress(id: string): Promise<string>;
38
+ export declare function subscriptions(): Promise<SubscriptionContract[]>;
39
+ /** @returns The changed contract or billing cycle. */
40
+ export declare function subscriptionAction(id: string | number, action: SubscriptionAction): Promise<SubscriptionChange>;
41
+ export declare function requestReturn(orderId: string | number, lines: ReturnLine[]): Promise<OpenedReturn>;
@@ -0,0 +1,13 @@
1
+ import type { AccountOrderLine } from '../../server/src/shared/account-orders.js';
2
+ import type { OrderDetailLine } from './page-answers.js';
3
+ /** A line of the order list, or of the order page, which has the fields after `image` too. */
4
+ type OrderLine = AccountOrderLine & Partial<Pick<OrderDetailLine, 'id' | 'name' | 'sku' | 'price' | 'totalPrice' | 'suggestedReturnReasonDefinitions'>>;
5
+ /** Line id → how many of it can still be returned. */
6
+ type Returnable = ReadonlyMap<string, number>;
7
+ /**
8
+ * Renders `lines` into a `tether-order-lines` repeater.
9
+ *
10
+ * @param returns `null` for the order list.
11
+ */
12
+ export declare function fillLines(box: HTMLElement, lines: readonly OrderLine[], returns: Returnable | null): void;
13
+ export {};
@@ -0,0 +1,12 @@
1
+ import type { AccountOrder } from '../../server/src/shared/account-orders.js';
2
+ /** How many orders `orders()` answers, and a `tether-orders` list shows, without being told. */
3
+ export declare const DEFAULT_ORDER_COUNT = 10;
4
+ /** The most orders one request asks for: the Worker answers no more. */
5
+ export declare const MAX_ORDER_COUNT = 50;
6
+ /** @returns True for a number of orders one request can ask for: a whole number from 1 to `MAX_ORDER_COUNT`. */
7
+ export declare const isOrderCount: (value: unknown) => value is number;
8
+ /**
9
+ * Fills every `tether-orders` list in `root`. A failure is reported and leaves the lists empty, without claiming the
10
+ * customer has no orders.
11
+ */
12
+ export declare function renderOrderList(root: ParentNode, loadOrders: (first: number) => Promise<AccountOrder[]>): Promise<void>;
@@ -0,0 +1,6 @@
1
+ type OrderState = 'loading' | 'ready' | 'not-found' | 'error';
2
+ /** Every state but `ready`, which shows with the order. */
3
+ export declare function showOrderState(el: HTMLElement, state: Exclude<OrderState, 'ready'>): void;
4
+ /** Loads and renders the order `el` names. A failure is reported and shows the error state. */
5
+ export declare function renderOrder(el: HTMLElement): Promise<void>;
6
+ export {};
@@ -0,0 +1,182 @@
1
+ import type { AccountImage, AccountOrderLine } from '../../server/src/shared/account-orders.js';
2
+ import type { Money } from '../shopify-values.js';
3
+ /** An address as the documents select it. */
4
+ export interface MailingAddress {
5
+ id: string | null;
6
+ firstName: string | null;
7
+ lastName: string | null;
8
+ company: string | null;
9
+ address1: string | null;
10
+ address2: string | null;
11
+ city: string | null;
12
+ province: string | null;
13
+ zoneCode: string | null;
14
+ zip: string | null;
15
+ country: string | null;
16
+ countryCode: string | null;
17
+ phoneNumber: string | null;
18
+ /** One line per entry. */
19
+ formatted: string[];
20
+ }
21
+ /** One of the customer's saved addresses. */
22
+ export type AccountAddress = MailingAddress & {
23
+ id: string;
24
+ };
25
+ export type CustomerAddress = AccountAddress & {
26
+ isDefault: boolean;
27
+ };
28
+ interface ReturnReason {
29
+ id: string;
30
+ name: string | null;
31
+ handle: string | null;
32
+ }
33
+ /** A line of the order page's document. */
34
+ export type OrderDetailLine = AccountOrderLine & {
35
+ id: string;
36
+ name: string | null;
37
+ sku: string | null;
38
+ price: Money | null;
39
+ totalPrice: Money | null;
40
+ suggestedReturnReasonDefinitions: {
41
+ nodes: ReturnReason[];
42
+ };
43
+ };
44
+ interface Tracking {
45
+ company: string | null;
46
+ number: string | null;
47
+ url: string | null;
48
+ }
49
+ export interface Fulfillment {
50
+ id: string | null;
51
+ status: string | null;
52
+ createdAt: string | null;
53
+ estimatedDeliveryAt: string | null;
54
+ latestShipmentStatus: string | null;
55
+ trackingInformation: Tracking[];
56
+ }
57
+ interface ReturnableLine {
58
+ quantity: number;
59
+ lineItem: {
60
+ id: string;
61
+ } | null;
62
+ }
63
+ /** A return Shopify opened. */
64
+ export interface OpenedReturn {
65
+ id: string;
66
+ status: string | null;
67
+ }
68
+ /** The order page's document. */
69
+ export interface OrderDetail {
70
+ id: string;
71
+ name: string | null;
72
+ number: number | null;
73
+ processedAt: string | null;
74
+ cancelledAt: string | null;
75
+ financialStatus: string | null;
76
+ fulfillmentStatus: string | null;
77
+ statusPageUrl: string | null;
78
+ requiresShipping: boolean | null;
79
+ totalPrice: Money | null;
80
+ subtotal: Money | null;
81
+ totalShipping: Money | null;
82
+ totalTax: Money | null;
83
+ shippingAddress: MailingAddress | null;
84
+ billingAddress: MailingAddress | null;
85
+ lineItems: {
86
+ nodes: OrderDetailLine[];
87
+ };
88
+ fulfillments: {
89
+ nodes: Fulfillment[];
90
+ };
91
+ returnInformation: {
92
+ returnableLineItems: {
93
+ nodes: ReturnableLine[];
94
+ };
95
+ } | null;
96
+ returns: {
97
+ nodes: OpenedReturn[];
98
+ };
99
+ }
100
+ export interface SubscriptionLine {
101
+ id: string | null;
102
+ name: string | null;
103
+ title: string | null;
104
+ variantTitle: string | null;
105
+ quantity: number;
106
+ sku: string | null;
107
+ currentPrice: Money | null;
108
+ lineDiscountedPrice: Money | null;
109
+ image: AccountImage | null;
110
+ }
111
+ interface BillingCycle {
112
+ cycleIndex: number | null;
113
+ skipped: boolean;
114
+ billingAttemptExpectedDate: string | null;
115
+ }
116
+ /** The subscriptions document. */
117
+ export interface SubscriptionContract {
118
+ id: string;
119
+ /** `ACTIVE`, `PAUSED`, `CANCELLED`, `EXPIRED` or `FAILED`. */
120
+ status: string | null;
121
+ nextBillingDate: string | null;
122
+ currencyCode: string | null;
123
+ deliveryPrice: Money | null;
124
+ deliveryPolicy: {
125
+ interval: string | null;
126
+ intervalCount: {
127
+ count: number;
128
+ } | null;
129
+ } | null;
130
+ lines: {
131
+ nodes: SubscriptionLine[];
132
+ };
133
+ upcomingBillingCycles: {
134
+ nodes: BillingCycle[];
135
+ };
136
+ }
137
+ export interface Profile {
138
+ firstName: string | null;
139
+ lastName: string | null;
140
+ }
141
+ /** What a subscription action changed: the contract (pause, resume, cancel) or its next billing cycle (skip, unskip). */
142
+ export type SubscriptionChange = {
143
+ contract: {
144
+ id: string | null;
145
+ status: string | null;
146
+ };
147
+ } | {
148
+ billingCycle: {
149
+ cycleIndex: number | null;
150
+ skipped: boolean;
151
+ };
152
+ };
153
+ /** @throws {TetherError} Without an id. */
154
+ export declare const toAccountAddress: (value: unknown) => AccountAddress;
155
+ /**
156
+ * @param value The addresses operation's list, each address with the `isDefault` it adds.
157
+ * @throws {TetherError} For an address without an id.
158
+ */
159
+ export declare const toCustomerAddresses: (value: unknown) => CustomerAddress[];
160
+ /**
161
+ * @param value The order operation's `order`.
162
+ * @returns `null` when the customer has no such order.
163
+ * @throws {TetherError} For an order, line, reason or return without an id.
164
+ */
165
+ export declare function toOrderDetail(value: unknown): OrderDetail | null;
166
+ /**
167
+ * @param value The subscriptions operation's list.
168
+ * @throws {TetherError} For a contract without an id.
169
+ */
170
+ export declare const toSubscriptionContracts: (value: unknown) => SubscriptionContract[];
171
+ /**
172
+ * @param result The subscription operation's result.
173
+ * @throws {TetherError} With neither a contract nor a billing cycle.
174
+ */
175
+ export declare function toSubscriptionChange(result: Record<string, unknown>): SubscriptionChange;
176
+ /** @throws {TetherError} Without an id. */
177
+ export declare function toReturn(value: unknown): OpenedReturn;
178
+ /** @throws {TetherError} Without an id. */
179
+ export declare const toDeletedId: (value: unknown) => string;
180
+ /** @param value The profile operation's `customer`. */
181
+ export declare const toProfile: (value: unknown) => Profile;
182
+ export {};
@@ -0,0 +1,2 @@
1
+ /** Listens on the document once, for every account page rendered into it. */
2
+ export declare function listenToPages(): void;
@@ -0,0 +1,60 @@
1
+ import type { AccountCustomer } from './answers.js';
2
+ /** The Worker's answer, or a 401: the session cookie is missing, has expired, or Shopify ended the login. */
3
+ export type ServerAnswer = {
4
+ kind: 'answer';
5
+ data: Record<string, unknown>;
6
+ } | {
7
+ kind: 'logged-out';
8
+ };
9
+ type ServerLogin = {
10
+ loggedIn: true;
11
+ customer: AccountCustomer;
12
+ } | {
13
+ loggedIn: false;
14
+ };
15
+ export interface ServerRequest {
16
+ method?: 'GET' | 'POST';
17
+ body?: Record<string, unknown>;
18
+ }
19
+ /**
20
+ * One request to the Worker, with the session cookie. A POST carries the header the Worker requires against
21
+ * cross-site forms.
22
+ *
23
+ * @throws {TetherError} `NOT_CONFIGURED` without `account.server`, `INVALID` for refused input, `HTTP_<status>` for
24
+ * any other failure but a 401, with the Worker's `userErrors`; `NETWORK` when the Worker can't be reached.
25
+ */
26
+ export declare function serverFetch(path: string, { method, body }?: ServerRequest): Promise<ServerAnswer>;
27
+ /**
28
+ * Who is logged in, asked once and then kept; the "may be logged in" hint follows the answer.
29
+ *
30
+ * @throws {TetherError} When the Worker can't be reached or fails: that says nothing about the login.
31
+ */
32
+ export declare function serverLogin(): Promise<ServerLogin>;
33
+ /** @returns True when the Worker last said a customer is logged in. */
34
+ export declare const isServerLoggedIn: () => boolean;
35
+ /** Asks the Worker again on the next `serverLogin()`, after a change of the customer's data. */
36
+ export declare function forgetServerLogin(): void;
37
+ /**
38
+ * To the Worker's login, which comes back to `returnTo` with `?account=<outcome>`. The cart is linked later, at
39
+ * checkout, through the Worker's protected `POST /cart`.
40
+ *
41
+ * @throws {TetherError} `NOT_CONFIGURED` without `account.server`.
42
+ */
43
+ export declare function serverLoginRedirect({ returnTo, locale }: {
44
+ returnTo: string;
45
+ locale?: string | undefined;
46
+ }): void;
47
+ /**
48
+ * The logged-in customer's checkout, for `Cart.setCheckoutResolver`: the Worker links the cart to the customer and
49
+ * answers with its checkout URL.
50
+ *
51
+ * @returns `null` when nobody is logged in or the Worker linked no cart, so the cart's own checkout URL is used.
52
+ * @throws {TetherError} When the Worker fails; the cart reports it and checks out without the login.
53
+ */
54
+ export declare function serverCheckoutUrl(): Promise<string | null>;
55
+ /**
56
+ * Ends the session at the Worker, which also unlinks the cart, then goes on to Shopify's logout when the Worker says
57
+ * where. Sends `tether:account-logout`.
58
+ */
59
+ export declare function serverLogout(returnTo: string): Promise<'redirected' | 'stayed'>;
60
+ export {};
@@ -0,0 +1,2 @@
1
+ /** Loads and renders the subscriptions. A failure is reported and shows `subscriptions-error`. */
2
+ export declare function renderSubscriptions(root: ParentNode): Promise<void>;
@@ -0,0 +1,18 @@
1
+ import type { Parts } from './lazy.js';
2
+ type AccountPart = Parts['account'];
3
+ type AccountResult<Name extends keyof AccountPart> = Awaited<ReturnType<AccountPart[Name]>>;
4
+ type AccountFunction<Name extends keyof AccountPart> = (...args: Parameters<AccountPart[Name]>) => Promise<AccountResult<Name>>;
5
+ type AccountApi = {
6
+ [Name in keyof AccountPart]: AccountFunction<Name>;
7
+ };
8
+ /**
9
+ * Loads the account part and mounts it on `root`, when accounts are configured and the page needs them: account
10
+ * markup in `root`, a login coming back from the Worker (`?account=`), or the "may be logged in" hint.
11
+ */
12
+ export declare function mountAccountIfUsed(root: ParentNode): void;
13
+ /**
14
+ * `Tether.account`: the account part's functions, each loading the part on first call. A plain object, so `await
15
+ * Tether.account` and `Object.keys(Tether.account)` behave as for any object.
16
+ */
17
+ export declare const accountApi: AccountApi;
18
+ export {};
@@ -0,0 +1,15 @@
1
+ /**
2
+ * What the Worker's login redirect says in `?account=`: `in` after a login, `expired` when the login took too long,
3
+ * `error` when it failed.
4
+ */
5
+ type LoginOutcome = 'in' | 'expired' | 'error';
6
+ /** The "may be logged in" hint's key: it makes the core load the part on the next page, and holds no secret. */
7
+ export declare const hintKey: () => string;
8
+ /**
9
+ * Removes the customer tokens and pending login that Tether 0.6's browser-mode accounts kept in this browser. The
10
+ * session held a refresh token with the customer's full scope, so it must not stay behind once accounts run through
11
+ * the Worker. TODO: remove in 0.8.0, when no visitor's browser still holds a 0.6 session.
12
+ */
13
+ export declare function forgetBrowserModeTokens(): void;
14
+ export declare const isLoginOutcome: (value: string | null) => value is LoginOutcome;
15
+ export {};
@@ -0,0 +1,8 @@
1
+ export { setup, order, updateProfile, addresses, saveAddress, deleteAddress, subscriptions, subscriptionAction, requestReturn, } from './account/operations.js';
2
+ /** Renders the order page, profile form, addresses and subscriptions in `root`: only what it has. */
3
+ export declare function renderPages(root?: ParentNode): Promise<void>;
4
+ /**
5
+ * The error state of every account page in `root`, for when nobody can say whether a customer is logged in (the
6
+ * Worker or Shopify can't be reached).
7
+ */
8
+ export declare function showUnavailable(root: ParentNode): void;
@@ -0,0 +1,64 @@
1
+ import type { AccountCustomer } from './account/answers.js';
2
+ import type { AccountOrder } from '../server/src/shared/account-orders.js';
3
+ import type { AddressFields, ReturnLine } from './account/operations.js';
4
+ import type { AccountAddress, CustomerAddress, OpenedReturn, OrderDetail, Profile, SubscriptionChange, SubscriptionContract } from './account/page-answers.js';
5
+ import type { SubscriptionAction } from '../server/src/shared/account-routes.js';
6
+ /** @returns True when the Worker last said a customer is logged in; false before it has been asked. */
7
+ export declare const isLoggedIn: () => boolean;
8
+ /**
9
+ * Through the Worker to Shopify's login page; the visitor comes back to `returnTo`.
10
+ *
11
+ * @throws {TetherError} `NOT_CONFIGURED` without `account.server`.
12
+ */
13
+ export declare function login({ returnTo, locale, }?: {
14
+ returnTo?: string;
15
+ locale?: string;
16
+ }): Promise<void>;
17
+ /**
18
+ * @returns The logged-in customer, `null` when nobody is.
19
+ * @throws {TetherError} When the Worker can't be reached or fails.
20
+ */
21
+ export declare function customer(): Promise<AccountCustomer | null>;
22
+ /**
23
+ * @param options `first`: a whole number from 1 to `MAX_ORDER_COUNT`.
24
+ * @returns The customer's most recent orders, newest first; none when nobody is logged in.
25
+ * @throws {TetherError} `INVALID` for another `first`, which is refused before any request; else when the Worker or
26
+ * Shopify can't answer.
27
+ */
28
+ export declare function orders({ first }?: {
29
+ first?: number;
30
+ }): Promise<AccountOrder[]>;
31
+ /**
32
+ * Logs out here and at Shopify, and unlinks the cart. Sends `tether:account-logout`.
33
+ *
34
+ * @param options `returnTo`: where Shopify sends the visitor afterwards.
35
+ */
36
+ export declare function logout({ returnTo, }?: {
37
+ returnTo?: string;
38
+ }): Promise<void>;
39
+ /**
40
+ * Fills the account markup in `root`: what shows when logged in or out, the customer, their orders, and the account
41
+ * pages.
42
+ */
43
+ export declare function render(root?: ParentNode): Promise<void>;
44
+ /** One of the customer's orders, in full (lines, totals, addresses, fulfillments, returns). */
45
+ export declare const order: (id: string | number) => Promise<OrderDetail | null>;
46
+ export declare const updateProfile: (fields?: {
47
+ firstName?: string;
48
+ lastName?: string;
49
+ }) => Promise<Profile>;
50
+ export declare const addresses: () => Promise<CustomerAddress[]>;
51
+ /** Creates an address, or updates the one with `id`. */
52
+ export declare const saveAddress: (address: AddressFields | null, options?: {
53
+ id?: string;
54
+ isDefault?: boolean;
55
+ }) => Promise<AccountAddress>;
56
+ export declare const deleteAddress: (id: string) => Promise<string>;
57
+ export declare const subscriptions: () => Promise<SubscriptionContract[]>;
58
+ export declare const subscriptionAction: (id: string | number, action: SubscriptionAction) => Promise<SubscriptionChange>;
59
+ export declare const requestReturn: (orderId: string | number, lines: ReturnLine[]) => Promise<OpenedReturn>;
60
+ /**
61
+ * Called by the core on mount: on the first one, finishes a login that's coming back and lets the Worker link the
62
+ * cart at checkout; then fills the page.
63
+ */
64
+ export declare function mountAccount(root?: ParentNode): Promise<void>;
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Arithmetic on Shopify's money amounts, which are decimal strings (`'27.50'`). Comparisons go digit by digit, as
3
+ * integers of the smallest unit present, so two amounts that differ only past float precision aren't misjudged. Sums
4
+ * and differences are taken in the currency's own smallest unit, so JPY stays whole and KWD keeps its three digits.
5
+ */
6
+ import type { Money } from './shopify-values.js';
7
+ /** @returns True when both are decimal numbers and `amount` is the larger one. */
8
+ export declare function isGreaterAmount(amount: string | null | undefined, other: string | null | undefined): boolean;
9
+ /** @returns The amount in the currency's smallest unit (cents, yen, fils), rounded to a whole one. */
10
+ export declare function toMinorUnits(money: Money): number;
11
+ /** @returns The amount written with the currency's own number of digits. */
12
+ export declare function fromMinorUnits(minorUnits: number, currencyCode: string): Money;
@@ -0,0 +1,41 @@
1
+ export type EventPayload = Record<string, unknown>;
2
+ interface TrackingValues {
3
+ uniqueToken: string;
4
+ visitToken: string;
5
+ }
6
+ interface DestinationContext {
7
+ getTrackingValues: () => TrackingValues;
8
+ }
9
+ type Subscriber = (payload: EventPayload, context: DestinationContext) => void;
10
+ type Subscribe = (event: string, subscriber: Subscriber) => () => void;
11
+ interface BusConfig {
12
+ shop: {
13
+ shopId: string;
14
+ channel: 'headless';
15
+ };
16
+ consent: {
17
+ mode: string;
18
+ };
19
+ }
20
+ /** What shopify.js registers. */
21
+ interface DestinationSpec {
22
+ name: string;
23
+ setup?: (api: {
24
+ subscribe: Subscribe;
25
+ getConfig: () => BusConfig;
26
+ }) => unknown;
27
+ }
28
+ /** Hydrogen's `window.Shopify.analytics`. */
29
+ export interface AnalyticsBus {
30
+ getConfig: () => BusConfig;
31
+ publish: (event: string, payload?: EventPayload) => void;
32
+ addDestination: (destination: DestinationSpec) => () => void;
33
+ }
34
+ /**
35
+ * Sets up `window.Shopify` for Shopify's scripts and loads them.
36
+ *
37
+ * @param isProductPage Asked by Shopify's script for the page template.
38
+ * @returns The bus, the page's own when a theme already set one up.
39
+ */
40
+ export declare function startShopifyAnalytics(isProductPage: () => boolean): Promise<AnalyticsBus>;
41
+ export {};
@@ -0,0 +1,2 @@
1
+ /** Called by the core with the events it buffered while this part loaded; the queue then handles events as they come. */
2
+ export declare function startAnalytics(queue: Event[]): Promise<void>;
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Shopify API versions are quarterly (YYYY-01, -04, -07, -10) and supported for 12 months. Tether pins a dated version
3
+ * and never targets `unstable` (it changes without notice). Used by the config, the diagnose part and the release
4
+ * scripts.
5
+ */
6
+ import type { ApiVersion } from '../server/src/shared/api-versions.js';
7
+ export interface ApiVersionStatus {
8
+ version: string;
9
+ /** Released and still supported. */
10
+ ok: boolean;
11
+ /** What to do about it, for people. */
12
+ note: string;
13
+ /** Months of support left, rounded; negative once support ended. */
14
+ monthsLeft?: number;
15
+ /** The version after this one. */
16
+ next?: string;
17
+ }
18
+ /** @returns True for a dated version such as `2026-07`. */
19
+ export declare const isQuarterlyVersion: (version: unknown) => version is ApiVersion;
20
+ /**
21
+ * `'2026-07'` → `'2026-10'`, `'2026-10'` → `'2027-01'`.
22
+ *
23
+ * @param steps Quarters ahead.
24
+ * @throws {Error} When `version` isn't a quarterly version.
25
+ */
26
+ export declare function nextApiVersion(version: string, steps?: number): string;
27
+ /** The support window of `version`, relative to `now`. */
28
+ export declare function apiVersionStatus(version: string, now?: Date): ApiVersionStatus;