@sixtyninecommerce/admin 0.10.0 → 0.11.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 (247) hide show
  1. package/README.md +4347 -171
  2. package/dist/catalog/assets.d.ts +120 -8
  3. package/dist/catalog/assets.js +98 -12
  4. package/dist/catalog/collections.d.ts +279 -14
  5. package/dist/catalog/collections.js +246 -15
  6. package/dist/catalog/index.d.ts +9 -2
  7. package/dist/catalog/index.js +4 -0
  8. package/dist/catalog/products.d.ts +159 -19
  9. package/dist/catalog/products.js +88 -13
  10. package/dist/catalog/properties.d.ts +102 -14
  11. package/dist/catalog/properties.js +13 -0
  12. package/dist/catalog/recommendations.d.ts +261 -0
  13. package/dist/catalog/recommendations.js +145 -0
  14. package/dist/catalog/reviews.d.ts +368 -0
  15. package/dist/catalog/reviews.js +318 -0
  16. package/dist/catalog/types.d.ts +17 -1
  17. package/dist/catalog/types.js +10 -0
  18. package/dist/catalog/variant-find.d.ts +136 -0
  19. package/dist/catalog/variant-find.js +239 -0
  20. package/dist/catalog/variants.d.ts +233 -26
  21. package/dist/catalog/variants.js +125 -7
  22. package/dist/catalog/visibility.d.ts +20 -5
  23. package/dist/catalog/visibility.js +19 -1
  24. package/dist/client.d.ts +95 -9
  25. package/dist/client.js +35 -7
  26. package/dist/content/assets.d.ts +286 -0
  27. package/dist/content/assets.js +181 -0
  28. package/dist/content/items.d.ts +269 -0
  29. package/dist/content/items.js +170 -0
  30. package/dist/content/types.d.ts +282 -0
  31. package/dist/content/types.js +100 -0
  32. package/dist/customers/age-verification.d.ts +66 -0
  33. package/dist/customers/age-verification.js +79 -0
  34. package/dist/customers/credit.d.ts +263 -0
  35. package/dist/customers/credit.js +244 -0
  36. package/dist/customers/delivery-preferences.d.ts +120 -0
  37. package/dist/customers/delivery-preferences.js +97 -0
  38. package/dist/customers/groups.d.ts +207 -0
  39. package/dist/customers/groups.js +438 -0
  40. package/dist/customers/index.d.ts +447 -37
  41. package/dist/customers/index.js +313 -40
  42. package/dist/customers/invitation-status.d.ts +57 -0
  43. package/dist/customers/invitation-status.js +21 -0
  44. package/dist/customers/notes.d.ts +67 -0
  45. package/dist/customers/notes.js +51 -0
  46. package/dist/customers/notification-recipients.d.ts +97 -0
  47. package/dist/customers/notification-recipients.js +84 -0
  48. package/dist/customers/saved-lists.d.ts +42 -0
  49. package/dist/customers/saved-lists.js +61 -0
  50. package/dist/customers/vat.d.ts +83 -0
  51. package/dist/customers/vat.js +46 -0
  52. package/dist/customers/wire.d.ts +20 -0
  53. package/dist/customers/wire.js +35 -0
  54. package/dist/documents/ar.d.ts +307 -0
  55. package/dist/documents/ar.js +254 -0
  56. package/dist/documents/index.d.ts +731 -21
  57. package/dist/documents/index.js +436 -24
  58. package/dist/documents/pdf.d.ts +2 -0
  59. package/dist/documents/pdf.js +11 -0
  60. package/dist/fulfillments/create.d.ts +167 -0
  61. package/dist/fulfillments/create.js +216 -0
  62. package/dist/fulfillments/index.d.ts +44 -10
  63. package/dist/fulfillments/index.js +11 -2
  64. package/dist/fulfillments/payment-policy.d.ts +64 -0
  65. package/dist/fulfillments/payment-policy.js +140 -0
  66. package/dist/fulfillments/warehouse.d.ts +724 -0
  67. package/dist/fulfillments/warehouse.js +914 -0
  68. package/dist/geo/index.d.ts +119 -0
  69. package/dist/geo/index.js +107 -0
  70. package/dist/index.d.ts +123 -35
  71. package/dist/index.js +45 -12
  72. package/dist/integrations/afas-actions.d.ts +234 -0
  73. package/dist/integrations/afas-actions.js +310 -0
  74. package/dist/integrations/afas-types.d.ts +483 -0
  75. package/dist/integrations/afas-types.js +5 -0
  76. package/dist/integrations/afas.d.ts +234 -0
  77. package/dist/integrations/afas.js +290 -0
  78. package/dist/integrations/connections.d.ts +103 -0
  79. package/dist/integrations/connections.js +55 -0
  80. package/dist/integrations/esp.d.ts +313 -0
  81. package/dist/integrations/esp.js +169 -0
  82. package/dist/integrations/exact-online-types.d.ts +423 -0
  83. package/dist/integrations/exact-online-types.js +6 -0
  84. package/dist/integrations/exact-online.d.ts +248 -0
  85. package/dist/integrations/exact-online.js +376 -0
  86. package/dist/integrations/index.d.ts +29 -3
  87. package/dist/integrations/index.js +18 -3
  88. package/dist/integrations/pipeline-keys.d.ts +13 -0
  89. package/dist/integrations/pipeline-keys.js +22 -0
  90. package/dist/integrations/pipelines.d.ts +15 -14
  91. package/dist/integrations/pipelines.js +6 -22
  92. package/dist/integrations/types.d.ts +146 -0
  93. package/dist/locations/index.d.ts +66 -0
  94. package/dist/locations/index.js +31 -0
  95. package/dist/meta/index.d.ts +162 -0
  96. package/dist/orders/cancel-with-money.d.ts +227 -0
  97. package/dist/orders/cancel-with-money.js +153 -0
  98. package/dist/orders/commit-edit.d.ts +7 -1
  99. package/dist/orders/commit-edit.js +5 -1
  100. package/dist/orders/drafts.d.ts +800 -0
  101. package/dist/orders/drafts.js +771 -0
  102. package/dist/orders/fields.d.ts +245 -0
  103. package/dist/orders/fields.js +188 -0
  104. package/dist/orders/get.d.ts +29 -19
  105. package/dist/orders/get.js +17 -8
  106. package/dist/orders/index.d.ts +49 -9
  107. package/dist/orders/index.js +22 -2
  108. package/dist/orders/lifecycle.d.ts +128 -0
  109. package/dist/orders/lifecycle.js +158 -0
  110. package/dist/orders/line-price-preview.d.ts +7 -2
  111. package/dist/orders/list.d.ts +222 -0
  112. package/dist/orders/list.js +377 -0
  113. package/dist/orders/manual-pricing.d.ts +5 -0
  114. package/dist/orders/order-entry.d.ts +20 -7
  115. package/dist/orders/plan-edit.d.ts +1 -1
  116. package/dist/orders/plan-edit.js +4 -1
  117. package/dist/orders/settings.d.ts +201 -0
  118. package/dist/orders/settings.js +325 -0
  119. package/dist/orders/status.d.ts +159 -13
  120. package/dist/orders/status.js +21 -0
  121. package/dist/orders/surcharges.d.ts +8 -1
  122. package/dist/orders/surcharges.js +3 -2
  123. package/dist/payments/account-credit.d.ts +30 -0
  124. package/dist/payments/account-credit.js +19 -0
  125. package/dist/payments/ar.d.ts +292 -0
  126. package/dist/payments/ar.js +223 -0
  127. package/dist/payments/connected-account.d.ts +47 -0
  128. package/dist/payments/connected-account.js +61 -0
  129. package/dist/payments/credit-noted-fields.d.ts +12 -0
  130. package/dist/payments/credit-noted-fields.js +37 -0
  131. package/dist/payments/index.d.ts +257 -11
  132. package/dist/payments/index.js +131 -1
  133. package/dist/payments/methods.d.ts +303 -8
  134. package/dist/payments/methods.js +337 -7
  135. package/dist/payments/mollie-methods.d.ts +159 -0
  136. package/dist/payments/mollie-methods.js +141 -0
  137. package/dist/payments/payment-links.d.ts +180 -0
  138. package/dist/payments/payment-links.js +97 -0
  139. package/dist/payments/provider-keys.d.ts +150 -0
  140. package/dist/payments/provider-keys.js +118 -0
  141. package/dist/payments/providers.d.ts +86 -11
  142. package/dist/payments/providers.js +29 -0
  143. package/dist/payments/requests.d.ts +144 -0
  144. package/dist/payments/requests.js +92 -0
  145. package/dist/payments/store-credit-fields.d.ts +15 -0
  146. package/dist/payments/store-credit-fields.js +51 -0
  147. package/dist/pickups/index.d.ts +104 -0
  148. package/dist/pickups/index.js +105 -0
  149. package/dist/platform/channels.d.ts +132 -0
  150. package/dist/platform/channels.js +128 -0
  151. package/dist/platform/geo.d.ts +123 -0
  152. package/dist/platform/geo.js +144 -0
  153. package/dist/platform/tax.d.ts +154 -0
  154. package/dist/platform/tax.js +139 -0
  155. package/dist/pos/anomalies.d.ts +158 -0
  156. package/dist/pos/anomalies.js +64 -0
  157. package/dist/pos/assisted-selling.d.ts +79 -0
  158. package/dist/pos/assisted-selling.js +38 -0
  159. package/dist/pos/exchanges.d.ts +103 -0
  160. package/dist/pos/exchanges.js +22 -0
  161. package/dist/pos/gift-cards.d.ts +135 -0
  162. package/dist/pos/gift-cards.js +47 -0
  163. package/dist/pos/index.d.ts +2125 -32
  164. package/dist/pos/index.js +742 -4
  165. package/dist/pos/no-receipt.d.ts +94 -0
  166. package/dist/pos/no-receipt.js +25 -0
  167. package/dist/pos/offline-sales.d.ts +187 -0
  168. package/dist/pos/offline-sales.js +116 -0
  169. package/dist/pos/pay-by-link.d.ts +143 -0
  170. package/dist/pos/pay-by-link.js +57 -0
  171. package/dist/pos/quick-keys.d.ts +103 -0
  172. package/dist/pos/quick-keys.js +45 -0
  173. package/dist/pos/reports.d.ts +360 -0
  174. package/dist/pos/reports.js +62 -0
  175. package/dist/pos/returns.d.ts +217 -0
  176. package/dist/pos/returns.js +53 -0
  177. package/dist/pricing/bulk-coupons.d.ts +139 -0
  178. package/dist/pricing/bulk-coupons.js +112 -0
  179. package/dist/pricing/index.d.ts +174 -4
  180. package/dist/pricing/index.js +174 -1
  181. package/dist/pricing/price-lists.d.ts +604 -0
  182. package/dist/pricing/price-lists.js +600 -0
  183. package/dist/purchasing/alerts.d.ts +89 -0
  184. package/dist/purchasing/alerts.js +62 -0
  185. package/dist/purchasing/cost.d.ts +110 -0
  186. package/dist/purchasing/cost.js +86 -0
  187. package/dist/purchasing/index.d.ts +36 -0
  188. package/dist/purchasing/index.js +16 -0
  189. package/dist/purchasing/purchase-orders.d.ts +548 -0
  190. package/dist/purchasing/purchase-orders.js +491 -0
  191. package/dist/purchasing/replenishment.d.ts +281 -0
  192. package/dist/purchasing/replenishment.js +240 -0
  193. package/dist/purchasing/settings.d.ts +152 -0
  194. package/dist/purchasing/settings.js +181 -0
  195. package/dist/purchasing/suppliers.d.ts +476 -0
  196. package/dist/purchasing/suppliers.js +438 -0
  197. package/dist/quotes/index.d.ts +501 -0
  198. package/dist/quotes/index.js +439 -0
  199. package/dist/reports/index.d.ts +71 -8
  200. package/dist/reports/index.js +74 -11
  201. package/dist/returns/index.d.ts +614 -21
  202. package/dist/returns/index.js +695 -11
  203. package/dist/search/index.d.ts +76 -1
  204. package/dist/search/index.js +63 -0
  205. package/dist/shipping/definitions.d.ts +29 -0
  206. package/dist/shipping/definitions.js +47 -0
  207. package/dist/shipping/fulfillment-profiles.d.ts +174 -0
  208. package/dist/shipping/fulfillment-profiles.js +104 -0
  209. package/dist/shipping/hendriks.d.ts +97 -0
  210. package/dist/shipping/hendriks.js +50 -0
  211. package/dist/shipping/index.d.ts +48 -0
  212. package/dist/shipping/index.js +25 -0
  213. package/dist/shipping/methods.d.ts +198 -0
  214. package/dist/shipping/methods.js +240 -0
  215. package/dist/shipping/myparcel.d.ts +254 -0
  216. package/dist/shipping/myparcel.js +178 -0
  217. package/dist/shipping/parcel-count-suggestion.d.ts +2 -0
  218. package/dist/shipping/parcel-rule.d.ts +6 -5
  219. package/dist/shipping/parcel-rule.js +21 -23
  220. package/dist/shipping/rate-tables.d.ts +179 -0
  221. package/dist/shipping/rate-tables.js +184 -0
  222. package/dist/stock/index.d.ts +10 -3
  223. package/dist/stock/index.js +3 -0
  224. package/dist/stock/locations.d.ts +144 -0
  225. package/dist/stock/locations.js +168 -0
  226. package/dist/stock/transfers.d.ts +216 -43
  227. package/dist/stock/transfers.js +140 -13
  228. package/dist/stored-value/index.d.ts +214 -4
  229. package/dist/stored-value/index.js +152 -0
  230. package/dist/subscriptions/index.d.ts +682 -0
  231. package/dist/subscriptions/index.js +815 -0
  232. package/dist/tax/index.d.ts +76 -1
  233. package/dist/tax/index.js +50 -0
  234. package/dist/tenant/email-style.d.ts +102 -0
  235. package/dist/tenant/email-style.js +72 -0
  236. package/dist/tenant/email-templates.d.ts +66 -0
  237. package/dist/tenant/email-templates.js +54 -0
  238. package/dist/tenant/notifications.d.ts +23 -17
  239. package/dist/tenant/settings-sources.d.ts +1 -1
  240. package/dist/tenant/time-zone.d.ts +17 -0
  241. package/dist/tenant/time-zone.js +11 -0
  242. package/dist/types.d.ts +50 -3
  243. package/dist/users/index.d.ts +3 -0
  244. package/dist/users/index.js +2 -0
  245. package/dist/users/warehouses.d.ts +50 -0
  246. package/dist/users/warehouses.js +51 -0
  247. package/package.json +2 -2
@@ -1,9 +1,14 @@
1
1
  import { NotFoundError, UpstreamError, ValidationError, } from '@sixtyninecommerce/core';
2
- import { ASSET_REF_FIELDS, assertDeleted, availabilityCustomFields, DELETION_FIELDS, FACET_VALUE_REF_FIELDS, fieldOf, vendureListPage, } from './types.js';
2
+ import { ASSET_REF_FIELDS, assertDeleted, availabilityCustomFields, DELETION_FIELDS, FACET_VALUE_REF_FIELDS, fieldOf, MAX_PAGE_SIZE, toAssetRef, vendureListPage, } from './types.js';
3
+ import { findVariants } from './variant-find.js';
3
4
  const PARCEL_PACKING_MODES = ['shared', 'separate', 'none'];
4
5
  /** The engine's bounds for `parcelCapacity` (shipping-calculator's `MAX_PARCEL_CAPACITY`). */
5
6
  const PARCEL_CAPACITY_MIN = 1;
6
7
  const PARCEL_CAPACITY_MAX = 10_000;
8
+ /** The variants {@link VariantsModule.optionSets} reads at most by default. */
9
+ export const DEFAULT_OPTION_SET_LIMIT = MAX_PAGE_SIZE;
10
+ /** The most variants one {@link VariantsModule.optionSets} call reads. */
11
+ export const MAX_OPTION_SET_LIMIT = 100_000;
7
12
  /** The engine's bound on one `revertPrice` call (`MAX_REVERT_VARIANTS`). */
8
13
  export const MAX_REVERT_PRICE_VARIANTS = 500;
9
14
  export const VARIANT_FIELDS = /* GraphQL */ `
@@ -15,9 +20,16 @@ export const VARIANT_FIELDS = /* GraphQL */ `
15
20
  name
16
21
  sku
17
22
  enabled
18
- price
19
- priceWithTax
20
- currencyCode
23
+ storePrice {
24
+ price
25
+ priceWithTax
26
+ currencyCode
27
+ }
28
+ prices {
29
+ currencyCode
30
+ price
31
+ }
32
+ stockOnHand
21
33
  taxCategory {
22
34
  id
23
35
  name
@@ -51,6 +63,18 @@ export const VARIANT_FIELDS = /* GraphQL */ `
51
63
  preorderLimit
52
64
  parcelCapacity
53
65
  parcelPacking
66
+ minOrderQuantity
67
+ salesUnit
68
+ position
69
+ cost
70
+ packageWeightGrams
71
+ packageLengthCm
72
+ packageWidthCm
73
+ packageHeightCm
74
+ backorderPolicy
75
+ backorderLimit
76
+ gtin
77
+ mpn
54
78
  }
55
79
  `;
56
80
  export const VARIANTS_QUERY = /* GraphQL */ `
@@ -61,6 +85,20 @@ export const VARIANTS_QUERY = /* GraphQL */ `
61
85
  }
62
86
  }
63
87
  `;
88
+ /** Two fields a row, for {@link VariantsModule.optionSets}: the id and its options' ids. */
89
+ export const VARIANT_OPTION_SETS_QUERY = /* GraphQL */ `
90
+ query CatalogVariantOptionSets($productId: ID!, $options: ProductVariantListOptions) {
91
+ productVariants(productId: $productId, options: $options) {
92
+ items {
93
+ id
94
+ options {
95
+ id
96
+ }
97
+ }
98
+ totalItems
99
+ }
100
+ }
101
+ `;
64
102
  export const VARIANT_QUERY = /* GraphQL */ `
65
103
  query CatalogVariant($id: ID!) {
66
104
  productVariant(id: $id) { ${VARIANT_FIELDS} }
@@ -112,13 +150,33 @@ export const PRICE_BASIS_QUERY = /* GraphQL */ `
112
150
  }
113
151
  }
114
152
  `;
153
+ /** The variant fields read out of `customFields` as they are, null for an unset one. */
154
+ export const LIFTED_CUSTOM_FIELDS = [
155
+ 'minOrderQuantity',
156
+ 'salesUnit',
157
+ 'position',
158
+ 'cost',
159
+ 'packageWeightGrams',
160
+ 'packageLengthCm',
161
+ 'packageWidthCm',
162
+ 'packageHeightCm',
163
+ 'backorderPolicy',
164
+ 'backorderLimit',
165
+ 'gtin',
166
+ 'mpn',
167
+ ];
115
168
  function isParcelPacking(value) {
116
169
  return PARCEL_PACKING_MODES.includes(value);
117
170
  }
171
+ /** Lift the custom fields to first-class fields. */
118
172
  export function toVariant(wire) {
119
- const { customFields, ...rest } = wire;
173
+ const { customFields, featuredAsset, assets, ...rest } = wire;
174
+ const lifted = Object.fromEntries(LIFTED_CUSTOM_FIELDS.map((key) => [key, customFields?.[key] ?? null]));
120
175
  return {
121
176
  ...rest,
177
+ ...lifted,
178
+ featuredAsset: featuredAsset ? toAssetRef(featuredAsset) : null,
179
+ assets: assets.map(toAssetRef),
122
180
  taxClassKey: customFields?.taxClassKey ?? null,
123
181
  availabilityState: customFields?.availabilityState ?? 'inherit',
124
182
  availableFrom: customFields?.availableFrom ?? null,
@@ -180,6 +238,40 @@ function toWireInput(input) {
180
238
  function refuse(code, message) {
181
239
  return new ValidationError({ code, message, status: 400, service: 'vendure' });
182
240
  }
241
+ const VARIANT_SORT_FIELDS = [
242
+ 'position',
243
+ 'name',
244
+ 'sku',
245
+ 'createdAt',
246
+ 'updatedAt',
247
+ ];
248
+ /**
249
+ * The engine's `ProductVariantListOptions` for {@link VariantListOptions}, without the page
250
+ * window. ONE sort key, never a tie-breaker beside it: graphql-js coerces an input object in the
251
+ * order its TYPE declares the fields, and `ProductVariantSortParameter` declares `id` before every
252
+ * field named here, so `{ position, id }` reaches the engine as `{ id, position }` and sorts by id
253
+ * alone (W10-113 finding). The engine completes the order itself: `productVariants(productId:)`
254
+ * (core's `getVariantsByProductId`) appends `id ASC` after the caller's key, which makes it total,
255
+ * so offset pages neither repeat nor skip a row even where `position` is null.
256
+ */
257
+ export function variantListOptions(options) {
258
+ const sort = options?.sort ?? { field: 'position', direction: 'ASC' };
259
+ if (!VARIANT_SORT_FIELDS.includes(sort.field) ||
260
+ (sort.direction !== 'ASC' && sort.direction !== 'DESC')) {
261
+ throw refuse('INVALID_VARIANT_SORT', `sort must name one of ${VARIANT_SORT_FIELDS.join(', ')} and the direction ASC or DESC; got ${JSON.stringify(sort)}. Nothing was sent.`);
262
+ }
263
+ const term = options?.term?.trim() ?? '';
264
+ return {
265
+ sort: { [sort.field]: sort.direction },
266
+ // `filterOperator` joins the top-level fields, which are exactly these two.
267
+ ...(term === ''
268
+ ? {}
269
+ : {
270
+ filter: { sku: { contains: term }, name: { contains: term } },
271
+ filterOperator: 'OR',
272
+ }),
273
+ };
274
+ }
183
275
  /**
184
276
  * Every priced input (`price`, or any `prices` entry) must be whole minor units and state its
185
277
  * basis, and the basis must be the store's. Read per call, with the call's own options, so a
@@ -239,13 +331,39 @@ export function createVariantsModule(transport) {
239
331
  return mapAll(rows, 'updateProductVariants');
240
332
  };
241
333
  return {
242
- list(productId, options) {
243
- return vendureListPage(transport, VARIANTS_QUERY, 'productVariants', (skip, take) => ({ productId, options: { skip, take } }), options, toVariant);
334
+ async list(productId, options) {
335
+ const listOptions = variantListOptions(options);
336
+ return vendureListPage(transport, VARIANTS_QUERY, 'productVariants', (skip, take) => ({ productId, options: { skip, take, ...listOptions } }), options, toVariant);
337
+ },
338
+ async optionSets(productId, options) {
339
+ const { limit = DEFAULT_OPTION_SET_LIMIT, ...call } = options ?? {};
340
+ if (!Number.isInteger(limit) || limit < 1 || limit > MAX_OPTION_SET_LIMIT) {
341
+ throw refuse('INVALID_OPTION_SET_LIMIT', `limit must be a whole number from 1 to ${String(MAX_OPTION_SET_LIMIT)}; got ${String(limit)}. Nothing was sent.`);
342
+ }
343
+ const combinations = [];
344
+ let totalItems = 0;
345
+ while (combinations.length < limit) {
346
+ const take = Math.min(MAX_PAGE_SIZE, limit - combinations.length);
347
+ const page = await fieldOf(transport, VARIANT_OPTION_SETS_QUERY, 'productVariants',
348
+ // By id alone (unique, so no page repeats a row of another): one key, as above.
349
+ { productId, options: { skip: combinations.length, take, sort: { id: 'ASC' } } }, call);
350
+ totalItems = page.totalItems;
351
+ for (const item of page.items) {
352
+ combinations.push(item.options.map((option) => option.id).sort());
353
+ }
354
+ // A short page is the end, whatever `totalItems` claims: never ask past it.
355
+ if (page.items.length < take || combinations.length >= totalItems)
356
+ break;
357
+ }
358
+ return { combinations, totalItems, truncated: totalItems > combinations.length };
244
359
  },
245
360
  async get(id, options) {
246
361
  const variant = await fieldOf(transport, VARIANT_QUERY, 'productVariant', { id }, options);
247
362
  return variant ? toVariant(variant) : null;
248
363
  },
364
+ find(input, options) {
365
+ return findVariants(transport, input, options);
366
+ },
249
367
  async create(inputs, options) {
250
368
  inputs.forEach(assertParcelRule);
251
369
  await assertPriceBasis(inputs, options);
@@ -1,5 +1,6 @@
1
- import { type Transport } from '@sixtyninecommerce/core';
1
+ import { type Page, type Transport } from '@sixtyninecommerce/core';
2
2
  import type { Call } from '../types.js';
3
+ import { type Product, type ProductListOptions } from './products.js';
3
4
  export type ProductVisibilityMode = 'public' | 'private';
4
5
  /**
5
6
  * Who a product is shown to on the storefront. A product with no row is
@@ -29,12 +30,20 @@ export interface SetProductVisibilityInput {
29
30
  * `USER_INPUT_ERROR` (`ValidationError`): "Product {id} not found in this
30
31
  * channel". A write from here is always `source: manual`, which a later
31
32
  * pipeline import leaves alone.
32
- *
33
- * The Admin API's `productsByVisibility` list is deliberately NOT exposed: it
34
- * counts and pages visibility rows across every store before narrowing to this
35
- * one, so its totals and pages are wrong (recorded as a finding).
36
33
  */
37
34
  export interface VisibilityModule {
35
+ /**
36
+ * This store's products in one mode, with `products.list`'s filter, sort and
37
+ * paging (filtered before paging; `totalItems` counts this store only).
38
+ * `public` lists products with an explicit public row, not every product
39
+ * without one. With no sort, newest product first.
40
+ *
41
+ * Needs an engine whose `productsByVisibility` honours its options: an older
42
+ * one ignored all but the page and counted other stores' products, so it is
43
+ * refused before running (`ValidationError`, `GRAPHQL_VALIDATION_FAILED` or
44
+ * `BAD_REQUEST`) rather than answered with an unfiltered page.
45
+ */
46
+ list(mode: ProductVisibilityMode, options?: ProductListOptions): Promise<Page<Product>>;
38
47
  /** Null when the product has no override (it is public). `NotFoundError` for an unknown product. */
39
48
  get(productId: string, options?: Call): Promise<ProductVisibility | null>;
40
49
  set(input: SetProductVisibilityInput, options?: Call): Promise<ProductVisibility>;
@@ -51,6 +60,12 @@ export interface VisibilityModule {
51
60
  clear(productId: string, options?: Call): Promise<void>;
52
61
  }
53
62
  export declare const PRODUCT_VISIBILITY_QUERY = "\n query CatalogProductVisibility($id: ID!) {\n product(id: $id) {\n id\n visibility { \n productId\n mode\n source\n allowedCustomerGroupIds\n createdAt\n updatedAt\n }\n }\n }\n";
63
+ /**
64
+ * The marker field is selected only so that an engine from before the list
65
+ * honoured its options refuses the document as an unknown field; nothing reads
66
+ * its answer. It must stay the SECOND root field.
67
+ */
68
+ export declare const PRODUCTS_BY_VISIBILITY_QUERY = "\n query CatalogProductsByVisibility($mode: ProductVisibilityMode!, $options: ProductListOptions) {\n productsByVisibility(mode: $mode, options: $options) {\n items { \n id\n \n catalogueOwnership {\n state\n organizationName\n editableHere\n }\n\n createdAt\n updatedAt\n languageCode\n name\n slug\n description\n enabled\n featuredAsset { \n id\n name\n preview\n source\n type\n mimeType\n customFields {\n altText\n }\n }\n assets { \n id\n name\n preview\n source\n type\n mimeType\n customFields {\n altText\n }\n }\n facetValues { \n id\n code\n name\n facet {\n id\n code\n name\n }\n }\n optionGroups {\n id\n code\n name\n customFields {\n isShared\n }\n options {\n id\n code\n name\n }\n translations {\n id\n languageCode\n name\n }\n }\n translations {\n id\n languageCode\n name\n slug\n description\n }\n excludedFromStore\n variantList(options: { take: 1 }) {\n totalItems\n }\n customFields {\n availabilityState\n availableFrom\n preorderLimit\n brand\n condition\n }\n }\n totalItems\n }\n productsByVisibilityHonoursListOptions\n }\n";
54
69
  export declare const SET_VISIBILITY_MUTATION = "\n mutation CatalogSetVisibility($input: SetProductVisibilityInput!) {\n setProductVisibility(input: $input) { \n productId\n mode\n source\n allowedCustomerGroupIds\n createdAt\n updatedAt\n }\n }\n";
55
70
  export declare const BULK_SET_VISIBILITY_MUTATION = "\n mutation CatalogBulkSetVisibility($input: BulkSetProductVisibilityInput!) {\n bulkSetProductVisibility(input: $input) {\n updated\n }\n }\n";
56
71
  export declare const CLEAR_VISIBILITY_MUTATION = "\n mutation CatalogClearVisibility($productId: ID!) {\n clearProductVisibility(productId: $productId)\n }\n";
@@ -1,5 +1,6 @@
1
1
  import { NotFoundError } from '@sixtyninecommerce/core';
2
- import { fieldOf } from './types.js';
2
+ import { PRODUCT_FIELDS, productListOptions, toProduct, } from './products.js';
3
+ import { fieldOf, vendureListPage } from './types.js';
3
4
  const VISIBILITY_FIELDS = /* GraphQL */ `
4
5
  productId
5
6
  mode
@@ -16,6 +17,20 @@ export const PRODUCT_VISIBILITY_QUERY = /* GraphQL */ `
16
17
  }
17
18
  }
18
19
  `;
20
+ /**
21
+ * The marker field is selected only so that an engine from before the list
22
+ * honoured its options refuses the document as an unknown field; nothing reads
23
+ * its answer. It must stay the SECOND root field.
24
+ */
25
+ export const PRODUCTS_BY_VISIBILITY_QUERY = /* GraphQL */ `
26
+ query CatalogProductsByVisibility($mode: ProductVisibilityMode!, $options: ProductListOptions) {
27
+ productsByVisibility(mode: $mode, options: $options) {
28
+ items { ${PRODUCT_FIELDS} }
29
+ totalItems
30
+ }
31
+ productsByVisibilityHonoursListOptions
32
+ }
33
+ `;
19
34
  export const SET_VISIBILITY_MUTATION = /* GraphQL */ `
20
35
  mutation CatalogSetVisibility($input: SetProductVisibilityInput!) {
21
36
  setProductVisibility(input: $input) { ${VISIBILITY_FIELDS} }
@@ -35,6 +50,9 @@ export const CLEAR_VISIBILITY_MUTATION = /* GraphQL */ `
35
50
  `;
36
51
  export function createVisibilityModule(transport) {
37
52
  return {
53
+ list(mode, options) {
54
+ return vendureListPage(transport, PRODUCTS_BY_VISIBILITY_QUERY, 'productsByVisibility', (skip, take) => ({ mode, options: productListOptions(options, skip, take) }), options, toProduct);
55
+ },
38
56
  async get(productId, options) {
39
57
  const product = await fieldOf(transport, PRODUCT_VISIBILITY_QUERY, 'product', { id: productId }, options);
40
58
  if (!product) {
package/dist/client.d.ts CHANGED
@@ -10,13 +10,17 @@ import { type AuthModule } from './auth/index.js';
10
10
  import { type BulkModule } from './bulk/index.js';
11
11
  import { type CatalogModule } from './catalog/index.js';
12
12
  import { type ComplianceModule } from './compliance/index.js';
13
+ import { type ContentAssetsModule } from './content/assets.js';
13
14
  import { type FormsModule } from './content/forms.js';
15
+ import { type ContentItemsModule } from './content/items.js';
16
+ import { type ContentFieldsModule, type ContentPageValuesModule, type ContentTypesModule } from './content/types.js';
14
17
  import { type CustomObjectsModule } from './custom-objects/index.js';
15
18
  import { type CustomersModule } from './customers/index.js';
16
19
  import { type DocumentsModule } from './documents/index.js';
17
20
  import { type EventsModule } from './events/index.js';
18
21
  import { type FeedsModule } from './feeds/index.js';
19
22
  import { type FulfillmentsModule } from './fulfillments/index.js';
23
+ import { type GeoModule } from './geo/index.js';
20
24
  import { type HeadsModule } from './heads/index.js';
21
25
  import { type HooksModule } from './hooks/index.js';
22
26
  import { type IntegrationsModule } from './integrations/index.js';
@@ -26,34 +30,43 @@ import { type MetaModule } from './meta/index.js';
26
30
  import { type MetafieldsModule } from './metafields/index.js';
27
31
  import { type OrdersModule } from './orders/index.js';
28
32
  import { type PaymentsModule } from './payments/index.js';
33
+ import { type PickupsModule } from './pickups/index.js';
29
34
  import { type PlatformAppsModule } from './platform/apps.js';
30
35
  import { type PlatformCatalogModule } from './platform/catalog.js';
36
+ import { type PlatformChannelsModule } from './platform/channels.js';
31
37
  import { type PlatformEntitlementsModule } from './platform/entitlements.js';
38
+ import { type PlatformGeoModule } from './platform/geo.js';
32
39
  import { type PlatformLegalEntitiesModule } from './platform/legal-entities.js';
33
40
  import { type PlatformOrganizationsModule } from './platform/organizations.js';
34
41
  import { type PlatformModule } from './platform/provision-store.js';
35
42
  import { type PlatformReportsModule } from './platform/reports.js';
36
43
  import { type PlatformServerMetricsModule } from './platform/server-metrics.js';
44
+ import { type PlatformTaxModule } from './platform/tax.js';
37
45
  import { type PosModule } from './pos/index.js';
38
46
  import { type PricingModule } from './pricing/index.js';
39
47
  import { type ProvenanceModule } from './provenance/index.js';
48
+ import { type PurchasingModule } from './purchasing/index.js';
49
+ import { type QuotesModule } from './quotes/index.js';
40
50
  import { type ReportsModule } from './reports/index.js';
41
51
  import { type ReturnsModule } from './returns/index.js';
42
52
  import { type SearchModule } from './search/index.js';
43
53
  import { type RedirectsModule } from './seo/redirects.js';
44
- import { type ParcelCountSuggestionMethod } from './shipping/parcel-count-suggestion.js';
45
- import { type ShippingModule } from './shipping/parcel-rule.js';
54
+ import { type ShippingModule } from './shipping/index.js';
46
55
  import { type StockModule } from './stock/index.js';
47
56
  import { type StoredValueModule } from './stored-value/index.js';
57
+ import { type SubscriptionsModule } from './subscriptions/index.js';
48
58
  import { type TaxModule } from './tax/index.js';
49
59
  import { type CapabilitiesModule } from './tenant/capabilities.js';
50
60
  import { type ChannelsModule } from './tenant/channels.js';
61
+ import { type EmailStyleModule } from './tenant/email-style.js';
62
+ import { type EmailTemplatesModule } from './tenant/email-templates.js';
51
63
  import { type TenantEntitlementsReader } from './tenant/entitlements.js';
52
64
  import { type FieldGroupOwnersReader, type FieldGroupSyncSourcesReader } from './tenant/field-groups.js';
53
65
  import { type LegalEntityModule } from './tenant/legal-entity.js';
54
66
  import { type NotificationsModule } from './tenant/notifications.js';
55
67
  import { type RetentionModule } from './tenant/retention.js';
56
68
  import { type SettingsSourcesModule } from './tenant/settings-sources.js';
69
+ import { type TenantTimeZoneReader } from './tenant/time-zone.js';
57
70
  import { type UploadsModule } from './uploads/index.js';
58
71
  import { type UsersModule } from './users/index.js';
59
72
  export interface AdminClientConfig {
@@ -120,13 +133,23 @@ export interface AdminClient {
120
133
  };
121
134
  audit: AuditModule;
122
135
  /**
123
- * Products, variants, options, facets, collections, assets, visibility and
124
- * properties (spec §9.2 `catalog`). Needs the catalog permissions.
136
+ * Products, variants, options, facets, collections, assets, visibility,
137
+ * properties and recommendations (spec §9.2 `catalog`). Needs the catalog
138
+ * permissions.
125
139
  */
126
140
  catalog: CatalogModule;
127
141
  channels: ChannelsModule;
142
+ /**
143
+ * The CMS's content: forms, content types (collections) with their fields, each type's
144
+ * index-page values, the types' items, and the media library (spec §9.2 `content`).
145
+ */
128
146
  content: {
129
147
  forms: FormsModule;
148
+ types: ContentTypesModule;
149
+ fields: ContentFieldsModule;
150
+ pageValues: ContentPageValuesModule;
151
+ items: ContentItemsModule;
152
+ assets: ContentAssetsModule;
130
153
  };
131
154
  /**
132
155
  * Compliance requests to installed apps: data requests, customer and
@@ -175,6 +198,11 @@ export interface AdminClient {
175
198
  * AI helpers. Channel-scoped throughout — no method takes a channel.
176
199
  */
177
200
  feeds: FeedsModule;
201
+ /**
202
+ * Countries and zones (spec §9.2, ruling G128): platform-wide reads, the same for every store.
203
+ * `mostSpecificZone` (exported beside it) answers the zone provisioning picks for a country.
204
+ */
205
+ geo: GeoModule;
178
206
  /** The store's head registry: every client surface it serves (spec §6.7). */
179
207
  heads: HeadsModule;
180
208
  /** Every long-running operation the platform runs, under one resource (spec §6.11). */
@@ -206,6 +234,12 @@ export interface AdminClient {
206
234
  * recorded against an order with what it stands at (spec §8.2).
207
235
  */
208
236
  payments: PaymentsModule;
237
+ /**
238
+ * Store pickup (click & collect, POS C1/33): the store's pickups, an order's pickup, and
239
+ * "ready". A location's pickup settings are `locations.pickup/setPickup`; the hand-over is the
240
+ * till's.
241
+ */
242
+ pickups: PickupsModule;
209
243
  /**
210
244
  * Point of sale on a machine principal (spec §8.8): register sessions, cash,
211
245
  * tenders, the sale, refunds, X and Z — with no paired tablet. Needs a `pos`
@@ -224,8 +258,32 @@ export interface AdminClient {
224
258
  * writer only; the history is the platform event log.
225
259
  */
226
260
  provenance: ProvenanceModule;
261
+ /**
262
+ * Buying stock from suppliers, per legal entity (purchase-orders spec §10.1): `settings` with
263
+ * its document `numbering`, `suppliers` with their `contacts`, `purchaseOrders` with their
264
+ * `lines`, `replenishment` (reorder rules and suggestions), and `cost` (a variant's cost
265
+ * ledger). Needs the Purchasing plugin on the store.
266
+ */
267
+ purchasing: PurchasingModule;
268
+ /**
269
+ * B2B quotes: list, read, build and price a quote, move it through its statuses, and convert an
270
+ * approved one into an order (keyed); its PDF, its email, the store's quote design and settings
271
+ * (headless W10-35a). `Quote.editable` / `convertible` are the engine's answer to "what can be
272
+ * done now".
273
+ */
274
+ quotes: QuotesModule;
227
275
  /** Tenant reporting in minor units and ISO-8601 UTC (spec §9.2 `reports`, §9.3). */
228
276
  reports: ReportsModule;
277
+ /**
278
+ * Subscription plans (list, read, create, update, products, delete, price breakdown) and the
279
+ * subscriptions sold on them (list, read, a customer's subscriptions and mandates, the store's
280
+ * billing readiness) (headless W10-36), and their lifecycle and billing commands: purchase,
281
+ * pause/resume/skip/reschedule, cancel, payment method replacement, recovery, reconciliation,
282
+ * renewal and settlement retries, attention clearing and price changes, each money command under
283
+ * one idempotency key per attempt (headless W10-114). Statuses are the meta catalog's lower-case
284
+ * words.
285
+ */
286
+ subscriptions: SubscriptionsModule;
229
287
  /**
230
288
  * Order returns (RMA): one return, an order's returns, what of an order can
231
289
  * still be returned, and the plan for settling a return (headless W9-47). The
@@ -243,11 +301,11 @@ export interface AdminClient {
243
301
  };
244
302
  /**
245
303
  * Shipping of the ACTIVE channel (spec §9.2 `shipping`): the channel's
246
- * `parcelRule`, and `parcelCountSuggestion` for a set of variant items.
304
+ * `parcelRule`, `parcelCountSuggestion` for a set of variant items, the
305
+ * C.J. Hendriks 3PL settings (`hendriks.config`) and the MyParcel set-up,
306
+ * carriers and parcel senders (`myparcel`).
247
307
  */
248
- shipping: ShippingModule & {
249
- parcelCountSuggestion: ParcelCountSuggestionMethod;
250
- };
308
+ shipping: ShippingModule;
251
309
  /**
252
310
  * Stock per location by state, the ledger with reasons, reason-carrying
253
311
  * adjustments, transfers and allocation release (spec §9.2 `stock`, §8.7).
@@ -259,7 +317,10 @@ export interface AdminClient {
259
317
  * payment on an order.
260
318
  */
261
319
  storedValue: StoredValueModule;
262
- /** The store's own tax classes and their per-country mappings (spec §8.6). */
320
+ /**
321
+ * The store's own tax classes and their per-country mappings (spec §8.6), and the platform-wide
322
+ * tax categories and rates they map onto.
323
+ */
263
324
  tax: TaxModule;
264
325
  /**
265
326
  * Signed direct-to-storage uploads (spec §6.11): reserve a place, PUT the
@@ -290,6 +351,10 @@ export interface AdminClient {
290
351
  retention: RetentionModule;
291
352
  /** Per notification event: on or off, who sends it (spec §8.15), and to whom. */
292
353
  notifications: NotificationsModule;
354
+ /** The look of the store's emails: colours, type, logo and layout (`settings.email`). */
355
+ emailStyle: EmailStyleModule;
356
+ /** The store's email templates, by type: previews rendered as the store would send them. */
357
+ emailTemplates: EmailTemplatesModule;
293
358
  /**
294
359
  * Where each settings group comes from — the store or its organization — and the store's
295
360
  * choice to keep its own values (multi-region spec §5.3).
@@ -300,6 +365,11 @@ export interface AdminClient {
300
365
  * Changing it needs `UpdateSeller` on every store of the entity.
301
366
  */
302
367
  legalEntity: LegalEntityModule;
368
+ /**
369
+ * The active store's IANA time zone as the engine resolves it (`Europe/Amsterdam` when unset
370
+ * or invalid): the zone the API counts calendar days in. Never the browser's.
371
+ */
372
+ timeZone: TenantTimeZoneReader;
303
373
  };
304
374
  /**
305
375
  * Human SuperAdmin surface. Every method refuses an API token or an app
@@ -310,11 +380,22 @@ export interface AdminClient {
310
380
  apps: PlatformAppsModule;
311
381
  /** Catalogue maintenance on a named store (the translation-language repair). */
312
382
  catalog: PlatformCatalogModule;
383
+ /**
384
+ * The codes renames hold against reuse, and their release: a release that must clear files
385
+ * first is finished by the engine itself — see {@link PlatformChannelsModule}.
386
+ */
387
+ channels: PlatformChannelsModule;
313
388
  /**
314
389
  * Which external plugins each store may use: read one store's grants or every store's, and
315
390
  * connect or disconnect a plugin for a store — see {@link PlatformEntitlementsModule}.
316
391
  */
317
392
  entitlements: PlatformEntitlementsModule;
393
+ /**
394
+ * The platform's zones and countries every store shares: create, rename, delete and change
395
+ * the members of a zone; switch a country on or off — see {@link PlatformGeoModule}. Reads
396
+ * are `geo`.
397
+ */
398
+ geo: PlatformGeoModule;
318
399
  /**
319
400
  * The platform's legal entities (multi-region spec §7.1): SuperAdmin list and create; read and
320
401
  * update through every store of an entity — see {@link PlatformLegalEntitiesModule}.
@@ -329,6 +410,11 @@ export interface AdminClient {
329
410
  reports: PlatformReportsModule;
330
411
  /** Basic health of the platform's own servers (CPU, memory, disk, network). */
331
412
  serverMetrics: PlatformServerMetricsModule;
413
+ /**
414
+ * The platform's tax categories and tax rates every store shares: create, change and delete
415
+ * them — see {@link PlatformTaxModule}. Reads are `tax.categories` / `tax.rates`.
416
+ */
417
+ tax: PlatformTaxModule;
332
418
  };
333
419
  /** A derived client on another tenant, sharing this one's principal. */
334
420
  withTenant(tenant: Partial<TenantContext> & {
package/dist/client.js CHANGED
@@ -10,13 +10,17 @@ import { createAuthModule } from './auth/index.js';
10
10
  import { createBulkModule } from './bulk/index.js';
11
11
  import { createCatalogModule } from './catalog/index.js';
12
12
  import { createComplianceModule } from './compliance/index.js';
13
+ import { createContentAssetsModule } from './content/assets.js';
13
14
  import { createFormsModule } from './content/forms.js';
15
+ import { createContentItemsModule } from './content/items.js';
16
+ import { createContentFieldsModule, createContentPageValuesModule, createContentTypesModule, } from './content/types.js';
14
17
  import { createCustomObjectsModule } from './custom-objects/index.js';
15
18
  import { createCustomersModule } from './customers/index.js';
16
19
  import { createDocumentsModule } from './documents/index.js';
17
20
  import { createEventsModule } from './events/index.js';
18
21
  import { createFeedsModule } from './feeds/index.js';
19
22
  import { createFulfillmentsModule } from './fulfillments/index.js';
23
+ import { createGeoModule } from './geo/index.js';
20
24
  import { createHeadsModule } from './heads/index.js';
21
25
  import { createHooksModule } from './hooks/index.js';
22
26
  import { createIntegrationsModule } from './integrations/index.js';
@@ -26,34 +30,43 @@ import { createMetaModule } from './meta/index.js';
26
30
  import { createMetafieldsModule } from './metafields/index.js';
27
31
  import { createOrdersModule } from './orders/index.js';
28
32
  import { createPaymentsModule } from './payments/index.js';
33
+ import { createPickupsModule } from './pickups/index.js';
29
34
  import { createPlatformAppsModule } from './platform/apps.js';
30
35
  import { createPlatformCatalogModule } from './platform/catalog.js';
36
+ import { createPlatformChannelsModule } from './platform/channels.js';
31
37
  import { createPlatformEntitlementsModule, } from './platform/entitlements.js';
38
+ import { createPlatformGeoModule } from './platform/geo.js';
32
39
  import { createPlatformLegalEntitiesModule, } from './platform/legal-entities.js';
33
40
  import { createPlatformOrganizationsModule, } from './platform/organizations.js';
34
41
  import { createPlatformModule } from './platform/provision-store.js';
35
42
  import { createPlatformReportsModule } from './platform/reports.js';
36
43
  import { createPlatformServerMetricsModule, } from './platform/server-metrics.js';
44
+ import { createPlatformTaxModule } from './platform/tax.js';
37
45
  import { createPosModule } from './pos/index.js';
38
46
  import { createPricingModule } from './pricing/index.js';
39
47
  import { createProvenanceModule } from './provenance/index.js';
48
+ import { createPurchasingModule } from './purchasing/index.js';
49
+ import { createQuotesModule } from './quotes/index.js';
40
50
  import { createReportsModule } from './reports/index.js';
41
51
  import { createReturnsModule } from './returns/index.js';
42
52
  import { createSearchModule } from './search/index.js';
43
53
  import { createRedirectsModule } from './seo/redirects.js';
44
- import { createParcelCountSuggestion, } from './shipping/parcel-count-suggestion.js';
45
- import { createShippingModule } from './shipping/parcel-rule.js';
54
+ import { createShippingModule } from './shipping/index.js';
46
55
  import { createStockModule } from './stock/index.js';
47
56
  import { createStoredValueModule } from './stored-value/index.js';
57
+ import { createSubscriptionsModule } from './subscriptions/index.js';
48
58
  import { createTaxModule } from './tax/index.js';
49
59
  import { createCapabilitiesModule } from './tenant/capabilities.js';
50
60
  import { createChannelsModule } from './tenant/channels.js';
61
+ import { createEmailStyleModule } from './tenant/email-style.js';
62
+ import { createEmailTemplatesModule } from './tenant/email-templates.js';
51
63
  import { createTenantEntitlementsReader, } from './tenant/entitlements.js';
52
64
  import { createFieldGroupOwnersReader, createFieldGroupSyncSourcesReader, } from './tenant/field-groups.js';
53
65
  import { createLegalEntityModule } from './tenant/legal-entity.js';
54
66
  import { createNotificationsModule } from './tenant/notifications.js';
55
67
  import { createRetentionModule } from './tenant/retention.js';
56
68
  import { createSettingsSourcesModule, } from './tenant/settings-sources.js';
69
+ import { createTenantTimeZoneReader } from './tenant/time-zone.js';
57
70
  import { createUploadsModule } from './uploads/index.js';
58
71
  import { createUsersModule } from './users/index.js';
59
72
  /**
@@ -395,7 +408,14 @@ function buildClient(config, overrides, resolver, shared, credential) {
395
408
  audit: createAuditModule(transport),
396
409
  catalog: createCatalogModule(transport),
397
410
  channels: createChannelsModule(resolver),
398
- content: { forms: createFormsModule(transport) },
411
+ content: {
412
+ forms: createFormsModule(transport),
413
+ types: createContentTypesModule(transport),
414
+ fields: createContentFieldsModule(transport),
415
+ pageValues: createContentPageValuesModule(transport),
416
+ items: createContentItemsModule(transport),
417
+ assets: createContentAssetsModule(transport),
418
+ },
399
419
  fulfillments: createFulfillmentsModule(transport),
400
420
  heads: createHeadsModule(transport),
401
421
  jobs: jobsModule,
@@ -405,9 +425,13 @@ function buildClient(config, overrides, resolver, shared, credential) {
405
425
  metafields: createMetafieldsModule(transport),
406
426
  orders: createOrdersModule(transport),
407
427
  payments: createPaymentsModule(transport),
428
+ pickups: createPickupsModule(transport),
408
429
  pos: createPosModule(transport),
409
430
  pricing: createPricingModule(transport),
410
431
  provenance: createProvenanceModule(transport),
432
+ purchasing: createPurchasingModule(transport),
433
+ quotes: createQuotesModule(transport),
434
+ subscriptions: createSubscriptionsModule(transport),
411
435
  reports: createReportsModule(transport, bulkModule, jobsModule, () => tenant.location),
412
436
  returns: createReturnsModule(transport),
413
437
  documents: createDocumentsModule(transport),
@@ -417,12 +441,10 @@ function buildClient(config, overrides, resolver, shared, credential) {
417
441
  customers: createCustomersModule(transport),
418
442
  compliance: createComplianceModule(transport),
419
443
  feeds: createFeedsModule(transport),
444
+ geo: createGeoModule(transport),
420
445
  search: createSearchModule(transport),
421
446
  seo: { redirects: createRedirectsModule(transport) },
422
- shipping: {
423
- ...createShippingModule(transport),
424
- parcelCountSuggestion: createParcelCountSuggestion(transport),
425
- },
447
+ shipping: createShippingModule(transport),
426
448
  stock: createStockModule(transport),
427
449
  storedValue: createStoredValueModule(transport),
428
450
  tax: createTaxModule(transport),
@@ -435,18 +457,24 @@ function buildClient(config, overrides, resolver, shared, credential) {
435
457
  fieldGroupSyncSources: createFieldGroupSyncSourcesReader(transport),
436
458
  retention: createRetentionModule(transport),
437
459
  notifications: createNotificationsModule(transport),
460
+ emailStyle: createEmailStyleModule(transport),
461
+ emailTemplates: createEmailTemplatesModule(transport),
438
462
  settingsSources: createSettingsSourcesModule(transport),
439
463
  legalEntity: createLegalEntityModule(transport),
464
+ timeZone: createTenantTimeZoneReader(transport),
440
465
  },
441
466
  platform: {
442
467
  ...createPlatformModule(transport, config),
443
468
  apps: createPlatformAppsModule(transport, config),
444
469
  catalog: createPlatformCatalogModule(transport, config),
470
+ channels: createPlatformChannelsModule(transport, config),
445
471
  entitlements: createPlatformEntitlementsModule(transport, config),
472
+ geo: createPlatformGeoModule(transport, config),
446
473
  legalEntities: createPlatformLegalEntitiesModule(transport, config),
447
474
  organizations: createPlatformOrganizationsModule(transport, config),
448
475
  reports: createPlatformReportsModule(transport, config),
449
476
  serverMetrics: createPlatformServerMetricsModule(transport, config),
477
+ tax: createPlatformTaxModule(transport, config),
450
478
  },
451
479
  withTenant(next) {
452
480
  // `mergeTenant`, not a spread: it merges `actor` FIELD BY FIELD, so a