@sixtyninecommerce/admin 0.10.0 → 0.12.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 (302) hide show
  1. package/README.md +5772 -118
  2. package/dist/auth/index.d.ts +7 -1
  3. package/dist/auth/index.js +8 -1
  4. package/dist/catalog/assets.d.ts +120 -8
  5. package/dist/catalog/assets.js +98 -12
  6. package/dist/catalog/collections.d.ts +279 -14
  7. package/dist/catalog/collections.js +246 -15
  8. package/dist/catalog/documents.d.ts +142 -0
  9. package/dist/catalog/documents.js +114 -0
  10. package/dist/catalog/index.d.ts +54 -6
  11. package/dist/catalog/index.js +10 -1
  12. package/dist/catalog/metadata.d.ts +244 -0
  13. package/dist/catalog/metadata.js +220 -0
  14. package/dist/catalog/products.d.ts +159 -19
  15. package/dist/catalog/products.js +88 -13
  16. package/dist/catalog/properties.d.ts +140 -14
  17. package/dist/catalog/properties.js +65 -1
  18. package/dist/catalog/recommendations.d.ts +288 -0
  19. package/dist/catalog/recommendations.js +237 -0
  20. package/dist/catalog/reviews.d.ts +381 -0
  21. package/dist/catalog/reviews.js +325 -0
  22. package/dist/catalog/types.d.ts +17 -1
  23. package/dist/catalog/types.js +10 -0
  24. package/dist/catalog/variant-find.d.ts +136 -0
  25. package/dist/catalog/variant-find.js +239 -0
  26. package/dist/catalog/variants.d.ts +293 -26
  27. package/dist/catalog/variants.js +164 -7
  28. package/dist/catalog/visibility.d.ts +38 -7
  29. package/dist/catalog/visibility.js +19 -1
  30. package/dist/client.d.ts +121 -9
  31. package/dist/client.js +53 -14
  32. package/dist/content/assets.d.ts +285 -0
  33. package/dist/content/assets.js +181 -0
  34. package/dist/content/forms.d.ts +332 -1
  35. package/dist/content/forms.js +140 -4
  36. package/dist/content/items.d.ts +292 -0
  37. package/dist/content/items.js +170 -0
  38. package/dist/content/menus.d.ts +254 -0
  39. package/dist/content/menus.js +70 -0
  40. package/dist/content/strings.d.ts +137 -0
  41. package/dist/content/strings.js +82 -0
  42. package/dist/content/types.d.ts +282 -0
  43. package/dist/content/types.js +100 -0
  44. package/dist/customers/age-verification.d.ts +66 -0
  45. package/dist/customers/age-verification.js +79 -0
  46. package/dist/customers/credit.d.ts +263 -0
  47. package/dist/customers/credit.js +244 -0
  48. package/dist/customers/delivery-preferences.d.ts +120 -0
  49. package/dist/customers/delivery-preferences.js +97 -0
  50. package/dist/customers/delivery-terms.d.ts +44 -0
  51. package/dist/customers/delivery-terms.js +32 -0
  52. package/dist/customers/groups.d.ts +207 -0
  53. package/dist/customers/groups.js +438 -0
  54. package/dist/customers/index.d.ts +462 -37
  55. package/dist/customers/index.js +317 -40
  56. package/dist/customers/invitation-status.d.ts +57 -0
  57. package/dist/customers/invitation-status.js +21 -0
  58. package/dist/customers/notes.d.ts +67 -0
  59. package/dist/customers/notes.js +51 -0
  60. package/dist/customers/notification-recipients.d.ts +97 -0
  61. package/dist/customers/notification-recipients.js +84 -0
  62. package/dist/customers/saved-lists.d.ts +42 -0
  63. package/dist/customers/saved-lists.js +61 -0
  64. package/dist/customers/vat.d.ts +83 -0
  65. package/dist/customers/vat.js +46 -0
  66. package/dist/customers/wire.d.ts +20 -0
  67. package/dist/customers/wire.js +35 -0
  68. package/dist/documents/ar.d.ts +307 -0
  69. package/dist/documents/ar.js +254 -0
  70. package/dist/documents/emails.d.ts +150 -0
  71. package/dist/documents/emails.js +220 -0
  72. package/dist/documents/index.d.ts +744 -21
  73. package/dist/documents/index.js +438 -24
  74. package/dist/documents/pdf.d.ts +2 -0
  75. package/dist/documents/pdf.js +11 -0
  76. package/dist/fulfillments/create.d.ts +167 -0
  77. package/dist/fulfillments/create.js +216 -0
  78. package/dist/fulfillments/index.d.ts +163 -11
  79. package/dist/fulfillments/index.js +135 -6
  80. package/dist/fulfillments/payment-policy.d.ts +64 -0
  81. package/dist/fulfillments/payment-policy.js +140 -0
  82. package/dist/fulfillments/warehouse.d.ts +724 -0
  83. package/dist/fulfillments/warehouse.js +914 -0
  84. package/dist/geo/index.d.ts +119 -0
  85. package/dist/geo/index.js +107 -0
  86. package/dist/index.d.ts +147 -39
  87. package/dist/index.js +51 -12
  88. package/dist/integrations/afas-actions.d.ts +234 -0
  89. package/dist/integrations/afas-actions.js +310 -0
  90. package/dist/integrations/afas-types.d.ts +483 -0
  91. package/dist/integrations/afas-types.js +5 -0
  92. package/dist/integrations/afas.d.ts +234 -0
  93. package/dist/integrations/afas.js +290 -0
  94. package/dist/integrations/connections.d.ts +103 -0
  95. package/dist/integrations/connections.js +55 -0
  96. package/dist/integrations/esp.d.ts +313 -0
  97. package/dist/integrations/esp.js +169 -0
  98. package/dist/integrations/exact-online-types.d.ts +965 -0
  99. package/dist/integrations/exact-online-types.js +6 -0
  100. package/dist/integrations/exact-online.d.ts +784 -0
  101. package/dist/integrations/exact-online.js +1089 -0
  102. package/dist/integrations/index.d.ts +44 -3
  103. package/dist/integrations/index.js +23 -3
  104. package/dist/integrations/pipeline-discoveries.d.ts +65 -0
  105. package/dist/integrations/pipeline-discoveries.js +65 -0
  106. package/dist/integrations/pipeline-keys.d.ts +13 -0
  107. package/dist/integrations/pipeline-keys.js +22 -0
  108. package/dist/integrations/pipeline-runs.d.ts +119 -0
  109. package/dist/integrations/pipeline-runs.js +87 -0
  110. package/dist/integrations/pipelines.d.ts +87 -15
  111. package/dist/integrations/pipelines.js +41 -22
  112. package/dist/integrations/price-import.d.ts +223 -0
  113. package/dist/integrations/price-import.js +124 -0
  114. package/dist/integrations/types.d.ts +367 -3
  115. package/dist/integrations/types.js +4 -3
  116. package/dist/locations/index.d.ts +66 -0
  117. package/dist/locations/index.js +31 -0
  118. package/dist/meta/index.d.ts +172 -0
  119. package/dist/metafields/index.d.ts +8 -1
  120. package/dist/metafields/index.js +10 -0
  121. package/dist/orders/cancel-with-money.d.ts +237 -0
  122. package/dist/orders/cancel-with-money.js +155 -0
  123. package/dist/orders/commit-edit.d.ts +23 -1
  124. package/dist/orders/commit-edit.js +19 -2
  125. package/dist/orders/deposit-policy.d.ts +3 -1
  126. package/dist/orders/drafts.d.ts +800 -0
  127. package/dist/orders/drafts.js +771 -0
  128. package/dist/orders/fields.d.ts +245 -0
  129. package/dist/orders/fields.js +188 -0
  130. package/dist/orders/get.d.ts +29 -19
  131. package/dist/orders/get.js +17 -8
  132. package/dist/orders/index.d.ts +66 -15
  133. package/dist/orders/index.js +25 -2
  134. package/dist/orders/lifecycle.d.ts +128 -0
  135. package/dist/orders/lifecycle.js +158 -0
  136. package/dist/orders/line-price-preview.d.ts +7 -2
  137. package/dist/orders/list.d.ts +243 -0
  138. package/dist/orders/list.js +487 -0
  139. package/dist/orders/manual-discounts.d.ts +13 -5
  140. package/dist/orders/manual-pricing.d.ts +5 -0
  141. package/dist/orders/money-view.d.ts +149 -0
  142. package/dist/orders/money-view.js +99 -0
  143. package/dist/orders/order-entry.d.ts +20 -7
  144. package/dist/orders/plan-edit.d.ts +34 -2
  145. package/dist/orders/plan-edit.js +112 -11
  146. package/dist/orders/settings.d.ts +201 -0
  147. package/dist/orders/settings.js +325 -0
  148. package/dist/orders/status.d.ts +159 -13
  149. package/dist/orders/status.js +21 -0
  150. package/dist/orders/surcharges.d.ts +20 -1
  151. package/dist/orders/surcharges.js +37 -11
  152. package/dist/payments/account-credit.d.ts +46 -0
  153. package/dist/payments/account-credit.js +42 -0
  154. package/dist/payments/ar.d.ts +292 -0
  155. package/dist/payments/ar.js +223 -0
  156. package/dist/payments/connected-account.d.ts +47 -0
  157. package/dist/payments/connected-account.js +61 -0
  158. package/dist/payments/credit-noted-fields.d.ts +19 -0
  159. package/dist/payments/credit-noted-fields.js +69 -0
  160. package/dist/payments/customer-consent.d.ts +30 -0
  161. package/dist/payments/customer-consent.js +49 -0
  162. package/dist/payments/index.d.ts +340 -19
  163. package/dist/payments/index.js +151 -1
  164. package/dist/payments/methods.d.ts +303 -8
  165. package/dist/payments/methods.js +337 -7
  166. package/dist/payments/mollie-methods.d.ts +159 -0
  167. package/dist/payments/mollie-methods.js +141 -0
  168. package/dist/payments/payment-links.d.ts +180 -0
  169. package/dist/payments/payment-links.js +97 -0
  170. package/dist/payments/provider-keys.d.ts +150 -0
  171. package/dist/payments/provider-keys.js +118 -0
  172. package/dist/payments/providers.d.ts +86 -11
  173. package/dist/payments/providers.js +29 -0
  174. package/dist/payments/requests.d.ts +147 -0
  175. package/dist/payments/requests.js +93 -0
  176. package/dist/payments/store-credit-fields.d.ts +15 -0
  177. package/dist/payments/store-credit-fields.js +51 -0
  178. package/dist/pickups/index.d.ts +106 -0
  179. package/dist/pickups/index.js +108 -0
  180. package/dist/platform/channels.d.ts +132 -0
  181. package/dist/platform/channels.js +128 -0
  182. package/dist/platform/email-gateways.d.ts +165 -0
  183. package/dist/platform/email-gateways.js +78 -0
  184. package/dist/platform/geo.d.ts +123 -0
  185. package/dist/platform/geo.js +144 -0
  186. package/dist/platform/tax.d.ts +162 -0
  187. package/dist/platform/tax.js +169 -0
  188. package/dist/pos/anomalies.d.ts +158 -0
  189. package/dist/pos/anomalies.js +64 -0
  190. package/dist/pos/assisted-selling.d.ts +79 -0
  191. package/dist/pos/assisted-selling.js +38 -0
  192. package/dist/pos/exchanges.d.ts +108 -0
  193. package/dist/pos/exchanges.js +22 -0
  194. package/dist/pos/gift-cards.d.ts +135 -0
  195. package/dist/pos/gift-cards.js +47 -0
  196. package/dist/pos/index.d.ts +2370 -58
  197. package/dist/pos/index.js +854 -7
  198. package/dist/pos/no-receipt.d.ts +94 -0
  199. package/dist/pos/no-receipt.js +25 -0
  200. package/dist/pos/offline-sales.d.ts +228 -0
  201. package/dist/pos/offline-sales.js +170 -0
  202. package/dist/pos/pay-by-link.d.ts +143 -0
  203. package/dist/pos/pay-by-link.js +57 -0
  204. package/dist/pos/quick-keys.d.ts +103 -0
  205. package/dist/pos/quick-keys.js +45 -0
  206. package/dist/pos/reports.d.ts +360 -0
  207. package/dist/pos/reports.js +62 -0
  208. package/dist/pos/returns.d.ts +244 -0
  209. package/dist/pos/returns.js +83 -0
  210. package/dist/pricing/bulk-coupons.d.ts +139 -0
  211. package/dist/pricing/bulk-coupons.js +112 -0
  212. package/dist/pricing/index.d.ts +174 -4
  213. package/dist/pricing/index.js +174 -1
  214. package/dist/pricing/price-lists.d.ts +606 -0
  215. package/dist/pricing/price-lists.js +600 -0
  216. package/dist/purchasing/alerts.d.ts +104 -0
  217. package/dist/purchasing/alerts.js +88 -0
  218. package/dist/purchasing/backorders.d.ts +61 -0
  219. package/dist/purchasing/backorders.js +92 -0
  220. package/dist/purchasing/cost.d.ts +110 -0
  221. package/dist/purchasing/cost.js +86 -0
  222. package/dist/purchasing/index.d.ts +54 -0
  223. package/dist/purchasing/index.js +24 -0
  224. package/dist/purchasing/links.d.ts +263 -0
  225. package/dist/purchasing/links.js +192 -0
  226. package/dist/purchasing/purchase-orders.d.ts +551 -0
  227. package/dist/purchasing/purchase-orders.js +491 -0
  228. package/dist/purchasing/receipts.d.ts +396 -0
  229. package/dist/purchasing/receipts.js +287 -0
  230. package/dist/purchasing/replenishment.d.ts +281 -0
  231. package/dist/purchasing/replenishment.js +240 -0
  232. package/dist/purchasing/returns.d.ts +273 -0
  233. package/dist/purchasing/returns.js +229 -0
  234. package/dist/purchasing/settings.d.ts +152 -0
  235. package/dist/purchasing/settings.js +181 -0
  236. package/dist/purchasing/suppliers.d.ts +476 -0
  237. package/dist/purchasing/suppliers.js +438 -0
  238. package/dist/quotes/index.d.ts +518 -0
  239. package/dist/quotes/index.js +439 -0
  240. package/dist/reports/index.d.ts +71 -8
  241. package/dist/reports/index.js +74 -11
  242. package/dist/returns/index.d.ts +675 -21
  243. package/dist/returns/index.js +756 -11
  244. package/dist/search/index.d.ts +76 -1
  245. package/dist/search/index.js +63 -0
  246. package/dist/seo/config.d.ts +128 -0
  247. package/dist/seo/config.js +95 -0
  248. package/dist/seo/redirects.d.ts +125 -0
  249. package/dist/seo/redirects.js +60 -1
  250. package/dist/seo/settings.d.ts +147 -0
  251. package/dist/seo/settings.js +209 -0
  252. package/dist/shipping/definitions.d.ts +29 -0
  253. package/dist/shipping/definitions.js +47 -0
  254. package/dist/shipping/fulfillment-profiles.d.ts +174 -0
  255. package/dist/shipping/fulfillment-profiles.js +104 -0
  256. package/dist/shipping/hendriks.d.ts +97 -0
  257. package/dist/shipping/hendriks.js +50 -0
  258. package/dist/shipping/index.d.ts +54 -0
  259. package/dist/shipping/index.js +27 -0
  260. package/dist/shipping/methods.d.ts +205 -0
  261. package/dist/shipping/methods.js +240 -0
  262. package/dist/shipping/myparcel.d.ts +668 -0
  263. package/dist/shipping/myparcel.js +466 -0
  264. package/dist/shipping/parcel-count-suggestion.d.ts +2 -0
  265. package/dist/shipping/parcel-rule.d.ts +6 -5
  266. package/dist/shipping/parcel-rule.js +21 -23
  267. package/dist/shipping/rate-tables.d.ts +324 -0
  268. package/dist/shipping/rate-tables.js +390 -0
  269. package/dist/shipping/ship-to-countries.d.ts +75 -0
  270. package/dist/shipping/ship-to-countries.js +47 -0
  271. package/dist/stock/by-location.d.ts +86 -0
  272. package/dist/stock/by-location.js +94 -0
  273. package/dist/stock/index.d.ts +18 -4
  274. package/dist/stock/index.js +7 -0
  275. package/dist/stock/locations.d.ts +144 -0
  276. package/dist/stock/locations.js +168 -0
  277. package/dist/stock/settings.d.ts +106 -0
  278. package/dist/stock/settings.js +103 -0
  279. package/dist/stock/transfers.d.ts +386 -52
  280. package/dist/stock/transfers.js +222 -17
  281. package/dist/stored-value/index.d.ts +312 -11
  282. package/dist/stored-value/index.js +223 -4
  283. package/dist/subscriptions/index.d.ts +682 -0
  284. package/dist/subscriptions/index.js +815 -0
  285. package/dist/tax/display-policy.d.ts +105 -0
  286. package/dist/tax/display-policy.js +84 -0
  287. package/dist/tax/index.d.ts +79 -1
  288. package/dist/tax/index.js +52 -0
  289. package/dist/tenant/email-style.d.ts +102 -0
  290. package/dist/tenant/email-style.js +72 -0
  291. package/dist/tenant/email-templates.d.ts +287 -0
  292. package/dist/tenant/email-templates.js +271 -0
  293. package/dist/tenant/notifications.d.ts +23 -17
  294. package/dist/tenant/settings-sources.d.ts +1 -1
  295. package/dist/tenant/time-zone.d.ts +17 -0
  296. package/dist/tenant/time-zone.js +11 -0
  297. package/dist/types.d.ts +50 -3
  298. package/dist/users/index.d.ts +3 -0
  299. package/dist/users/index.js +2 -0
  300. package/dist/users/warehouses.d.ts +50 -0
  301. package/dist/users/warehouses.js +51 -0
  302. package/package.json +2 -2
@@ -2,8 +2,8 @@ import { type Page, type Transport } from '@sixtyninecommerce/core';
2
2
  import type { JobHandle } from '../jobs/index.js';
3
3
  import type { Call, ListOptions } from '../types.js';
4
4
  import { type ProductBulkInput, type ProductBulkRun } from './products-bulk.js';
5
- import { type AssetRef, type Availability, type AvailabilityInput, type CatalogueOwnership, type FacetValueRef, type LanguageCode, type PriceBasis, type ProductAvailabilityState, type TranslationInput, type VariantAvailabilityState } from './types.js';
6
- import { type ParcelPacking, type VariantBackorderPolicy, type VariantPriceInput } from './variants.js';
5
+ import { type AssetRef, type Availability, type AvailabilityInput, type CatalogueOwnership, type FacetValueRef, type LanguageCode, type PriceBasis, type ProductAvailabilityState, type TranslationInput, type VariantAvailabilityState, type WireAssetRef } from './types.js';
6
+ import { type ParcelPacking, type VariantBackorderPolicy, type VariantPriceInput, type VariantStorePrice } from './variants.js';
7
7
  export interface ProductOptionRef {
8
8
  id: string;
9
9
  code: string;
@@ -13,7 +13,18 @@ export interface ProductOptionGroupRef {
13
13
  id: string;
14
14
  code: string;
15
15
  name: string;
16
+ /**
17
+ * The group is offered for reuse on the store's other products (the option-group editor's
18
+ * "shared" switch); false for a group made for this product alone.
19
+ */
20
+ isShared: boolean;
16
21
  options: ProductOptionRef[];
22
+ /** The group's name in each language it has one in. */
23
+ translations: Array<{
24
+ id: string;
25
+ languageCode: LanguageCode;
26
+ name: string;
27
+ }>;
17
28
  }
18
29
  export interface ProductTranslation {
19
30
  id: string;
@@ -51,6 +62,27 @@ export interface Product extends Availability<ProductAvailabilityState> {
51
62
  * product and in an organization's workspace.
52
63
  */
53
64
  excludedFromStore: boolean;
65
+ /** The brand feeds name; null when none is set. */
66
+ brand: string | null;
67
+ /**
68
+ * The condition feeds state; null when none is set. A string on the wire: a stored value
69
+ * outside {@link ProductCondition} is answered as it is.
70
+ */
71
+ condition: ProductCondition | (string & {}) | null;
72
+ }
73
+ /** A collection a product is in, as {@link ProductsModule.get} names it. */
74
+ export interface ProductCollectionRef {
75
+ id: string;
76
+ name: string;
77
+ slug: string;
78
+ }
79
+ /** A product as {@link ProductsModule.get} reads it: the {@link Product} and its collections. */
80
+ export interface ProductDetail extends Product {
81
+ /**
82
+ * Every collection of the store the product is in, by hand or through a collection's other
83
+ * filters, in the language the call asked for.
84
+ */
85
+ collections: ProductCollectionRef[];
54
86
  }
55
87
  export interface ProductTranslationInput extends TranslationInput {
56
88
  name?: string;
@@ -102,6 +134,24 @@ export interface ProductListOptions extends ListOptions {
102
134
  }
103
135
  /** The engine's bound on one `exclude` or `include` call (`STORE_EXCLUSION_BATCH_LIMIT`). */
104
136
  export declare const MAX_STORE_EXCLUSION_PRODUCTS = 500;
137
+ /** At most this many distinct products per {@link ProductsModule.storePriceRanges} call. */
138
+ export declare const MAX_STORE_PRICE_RANGE_PRODUCTS = 100;
139
+ /**
140
+ * The cheapest and the dearest of a product's variants in the ACTIVE store and the request's
141
+ * currency, as `ProductVariant.storePrice` prices them (stored prices and prices converted at the
142
+ * store's rate, compared). `price` is net and `priceWithTax` gross, as on `storePrice`.
143
+ */
144
+ export interface ProductStorePriceRange {
145
+ min: VariantStorePrice;
146
+ max: VariantStorePrice;
147
+ /** At least one variant the store holds has no price in it; it is left out of min and max, never counted as 0. */
148
+ someVariantsUnpriced: boolean;
149
+ }
150
+ export interface ProductStorePriceRangeEntry {
151
+ productId: string;
152
+ /** Null when the store prices none of the product's variants it holds. */
153
+ range: ProductStorePriceRange | null;
154
+ }
105
155
  /**
106
156
  * The engine's bounds on one `setAvailabilityInStores` or `availabilityInStores` call
107
157
  * (`AVAILABILITY_*_LIMIT`).
@@ -320,14 +370,66 @@ export interface SaveProductResult {
320
370
  * refuses".
321
371
  */
322
372
  export interface ProductsModule {
373
+ /** @effect read */
323
374
  list(options?: ProductListOptions): Promise<Page<Product>>;
324
- /** Null for an id this store does not have — the same answer another tenant's product gets. */
325
- get(id: string, options?: Call): Promise<Product | null>;
375
+ /**
376
+ * One product with the collections it is in; null for an id this store does not have — the
377
+ * same answer another tenant's product gets. Its variants are not part of it, however few: read
378
+ * them a page at a time with `catalog.variants.list(productId)` (a product can have 100,000).
379
+ *
380
+ * @effect read
381
+ */
382
+ get(id: string, options?: Call): Promise<ProductDetail | null>;
383
+ /**
384
+ * Create a product, without variants (`catalog.variants.create` adds them). Needs
385
+ * `CreateCatalog` or `CreateProduct`.
386
+ *
387
+ * A new translation needs a name; its slug, when left out, is made from the name in that
388
+ * language, and its description is `''` (multi-region decision 106).
389
+ *
390
+ * Refusals (nothing is written):
391
+ * - `INVALID_PRODUCT_INPUT` → `ValidationError` (400): no translation; refused before sending.
392
+ * - `TRANSLATION_INPUT_INVALID` → `ValidationError` (400): a translation without a name, or
393
+ * with a name no slug can be made from (`!!!`) and no slug. One `details` entry per refused
394
+ * field, each message naming the language and the field; the entries carry no `field`
395
+ * pointer (the engine refuses below the call's arguments).
396
+ * - `TRANSLATION_LANGUAGE_NOT_OFFERED` → `BusinessRuleError` (422): a translation in a
397
+ * language the store does not offer. `details[].field` points at the translation entry
398
+ * (`/input/translations/<i>`); `message` names the language and the ones the store offers.
399
+ * - `FEED_IDENTIFIER_INVALID` → `ValidationError` (400): a brand over 70 characters.
400
+ * - `INVALID_DATETIME` → `ValidationError` (400): an `availableFrom` without an offset;
401
+ * refused before sending.
402
+ *
403
+ * @effect write
404
+ */
326
405
  create(input: CreateProductInput, options?: Call): Promise<Product>;
406
+ /**
407
+ * A PATCH of the product's own fields. A translation for a language the product has no row in
408
+ * is a NEW row, judged as on {@link create}; an existing row keeps what the input leaves out,
409
+ * and setting its name or slug to null is refused `TRANSLATION_INPUT_INVALID`. The other
410
+ * refusals are {@link create}'s, plus `FIELD_GROUP_LOCKED` and `MANAGED_BY_ORGANIZATION`
411
+ * (see above).
412
+ *
413
+ * @effect write
414
+ */
327
415
  update(input: UpdateProductInput, options?: Call): Promise<Product>;
328
416
  /**
329
- * Soft-deletes the product and its variants. `PRODUCT_NOT_DELETED`
330
- * (`ConflictError`) carries the engine's own reason when it refuses.
417
+ * Soft-deletes the product and its variants: they are no longer listed, and orders keep the
418
+ * lines that name them. Nothing in this SDK restores it. Needs `DeleteCatalog` or
419
+ * `DeleteProduct`.
420
+ *
421
+ * Refusals (nothing is deleted):
422
+ * - `PRODUCT_NOT_DELETED` → `ConflictError` (409): the engine declined, in its own words.
423
+ * - `ENTITY_NOT_FOUND` → `NotFoundError` (404): a product this store does not hold.
424
+ * - `SHARED_PRODUCT_NOT_ALLOWED` → `PermissionDeniedError` (403): another store also holds it,
425
+ * and you may not delete there.
426
+ * - `MANAGED_BY_ORGANIZATION` → `BusinessRuleError` (422): a product of the store's
427
+ * organization.
428
+ * - `FIELD_GROUP_LOCKED` → `BusinessRuleError` (422): an app or API token owns a field group of
429
+ * the product or its variants.
430
+ * - `EXTERNAL_LINE_CARRIER_PROTECTED` → `BusinessRuleError` (422): the platform's carrier.
431
+ *
432
+ * @effect destructive
331
433
  */
332
434
  delete(id: string, options?: Call): Promise<void>;
333
435
  /**
@@ -428,6 +530,23 @@ export interface ProductsModule {
428
530
  * store that is not a member.
429
531
  */
430
532
  availabilityInStores(input: AvailabilityInStoresInput, options?: Call): Promise<OrganizationProductStoreAvailability[]>;
533
+ /**
534
+ * Each product's price range in the ACTIVE store and the request's currency
535
+ * (`Product.storePriceRange`), for a page of products in ONE request: the engine ranks only the
536
+ * variants the store holds, by the store's own prices. Use it rather than the first and last
537
+ * variant of a price-sorted variant list, which cannot compare stored prices with converted ones
538
+ * nor say that some variants are unpriced. One entry per distinct product, in the order named;
539
+ * a product the store does not hold is left out, the same answer another tenant's product gets.
540
+ * No ids answers none, without a request. Needs `ReadCatalog`.
541
+ *
542
+ * Refusals:
543
+ * - `PRODUCT_STORE_PRICE_RANGE_INPUT_INVALID` → `ValidationError` (400): more than
544
+ * {@link MAX_STORE_PRICE_RANGE_PRODUCTS} distinct ids; refused before sending.
545
+ * - An engine without `Product.storePriceRange` (vendure-server before #1580) refuses the
546
+ * document before running it: `ValidationError`, `GRAPHQL_VALIDATION_FAILED` (or
547
+ * `BAD_REQUEST`), never an empty answer.
548
+ */
549
+ storePriceRanges(productIds: string[], options?: Call): Promise<ProductStorePriceRangeEntry[]>;
431
550
  /**
432
551
  * Make the ACTIVE member store's own copy of a product its organization shares with it, and
433
552
  * stop offering the shared one, in one step (a local copy, or detach; spec §7.2.8). The copy
@@ -617,28 +736,46 @@ export interface ProductsModule {
617
736
  */
618
737
  bulkRun(runId: string, options?: Call): Promise<ProductBulkRun>;
619
738
  }
620
- export declare const PRODUCT_FIELDS = "\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 }\n assets { \n id\n name\n preview\n source\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 options {\n id\n code\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 }\n";
621
- export declare const PRODUCTS_QUERY = "\n query CatalogProducts($options: ProductListOptions) {\n products(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 }\n assets { \n id\n name\n preview\n source\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 options {\n id\n code\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 }\n }\n totalItems\n }\n }\n";
622
- export declare const PRODUCT_QUERY = "\n query CatalogProduct($id: ID!) {\n product(id: $id) { \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 }\n assets { \n id\n name\n preview\n source\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 options {\n id\n code\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 }\n }\n }\n";
623
- export declare const CREATE_PRODUCT_MUTATION = "\n mutation CatalogCreateProduct($input: CreateProductInput!) {\n createProduct(input: $input) { \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 }\n assets { \n id\n name\n preview\n source\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 options {\n id\n code\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 }\n }\n }\n";
624
- export declare const UPDATE_PRODUCT_MUTATION = "\n mutation CatalogUpdateProduct($input: UpdateProductInput!) {\n updateProduct(input: $input) { \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 }\n assets { \n id\n name\n preview\n source\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 options {\n id\n code\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 }\n }\n }\n";
739
+ export declare const PRODUCT_FIELDS = "\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";
740
+ export declare const PRODUCTS_QUERY = "\n query CatalogProducts($options: ProductListOptions) {\n products(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 }\n";
741
+ export declare const PRODUCT_STORE_PRICE_RANGES_QUERY = "\n query CatalogProductStorePriceRanges($options: ProductListOptions) {\n products(options: $options) {\n items {\n id\n storePriceRange {\n min { price priceWithTax currencyCode }\n max { price priceWithTax currencyCode }\n someVariantsUnpriced\n }\n }\n }\n }\n";
742
+ /**
743
+ * One product, with the collections it is in. No variant data beyond `variantList`'s count: a
744
+ * product can have 100,000 variants, and core's `variants` would hand back the first 1,000 with
745
+ * no sign of the rest (`catalog.variants.list` pages them).
746
+ */
747
+ export declare const PRODUCT_QUERY = "\n query CatalogProduct($id: ID!) {\n product(id: $id) {\n \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 collections {\n id\n name\n slug\n }\n }\n }\n";
748
+ export declare const CREATE_PRODUCT_MUTATION = "\n mutation CatalogCreateProduct($input: CreateProductInput!) {\n createProduct(input: $input) { \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 }\n";
749
+ export declare const UPDATE_PRODUCT_MUTATION = "\n mutation CatalogUpdateProduct($input: UpdateProductInput!) {\n updateProduct(input: $input) { \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 }\n";
625
750
  export declare const DELETE_PRODUCT_MUTATION = "\n mutation CatalogDeleteProduct($id: ID!) {\n deleteProduct(id: $id) { \n result\n message\n }\n }\n";
626
751
  export declare const CLONE_PRODUCT_MUTATION = "\n mutation CatalogCloneProduct($id: ID!) {\n cloneProduct(id: $id)\n }\n";
627
- export declare const ADD_OPTION_GROUP_MUTATION = "\n mutation CatalogAddOptionGroup($productId: ID!, $optionGroupId: ID!) {\n addOptionGroupToProduct(productId: $productId, optionGroupId: $optionGroupId) { \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 }\n assets { \n id\n name\n preview\n source\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 options {\n id\n code\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 }\n }\n }\n";
628
- export declare const REMOVE_OPTION_GROUP_MUTATION = "\n mutation CatalogRemoveOptionGroup($productId: ID!, $optionGroupId: ID!, $force: Boolean) {\n removeOptionGroupFromProduct(productId: $productId, optionGroupId: $optionGroupId, force: $force) {\n ... on Product { \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 }\n assets { \n id\n name\n preview\n source\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 options {\n id\n code\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 }\n }\n ... on ErrorResult {\n errorCode\n message\n }\n }\n }\n";
629
- export declare const EXCLUDE_PRODUCTS_FROM_STORE_MUTATION = "\n mutation CatalogExcludeProductsFromStore($productIds: [ID!]!) {\n excludeProductsFromStore(productIds: $productIds) { \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 }\n assets { \n id\n name\n preview\n source\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 options {\n id\n code\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 }\n }\n }\n";
630
- export declare const INCLUDE_PRODUCTS_IN_STORE_MUTATION = "\n mutation CatalogIncludeProductsInStore($productIds: [ID!]!) {\n includeProductsInStore(productIds: $productIds) { \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 }\n assets { \n id\n name\n preview\n source\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 options {\n id\n code\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 }\n }\n }\n";
752
+ export declare const ADD_OPTION_GROUP_MUTATION = "\n mutation CatalogAddOptionGroup($productId: ID!, $optionGroupId: ID!) {\n addOptionGroupToProduct(productId: $productId, optionGroupId: $optionGroupId) { \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 }\n";
753
+ export declare const REMOVE_OPTION_GROUP_MUTATION = "\n mutation CatalogRemoveOptionGroup($productId: ID!, $optionGroupId: ID!, $force: Boolean) {\n removeOptionGroupFromProduct(productId: $productId, optionGroupId: $optionGroupId, force: $force) {\n ... on Product { \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 ... on ErrorResult {\n errorCode\n message\n }\n }\n }\n";
754
+ export declare const EXCLUDE_PRODUCTS_FROM_STORE_MUTATION = "\n mutation CatalogExcludeProductsFromStore($productIds: [ID!]!) {\n excludeProductsFromStore(productIds: $productIds) { \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 }\n";
755
+ export declare const INCLUDE_PRODUCTS_IN_STORE_MUTATION = "\n mutation CatalogIncludeProductsInStore($productIds: [ID!]!) {\n includeProductsInStore(productIds: $productIds) { \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 }\n";
631
756
  export declare const SET_ORGANIZATION_PRODUCT_AVAILABILITY_MUTATION = "\n mutation CatalogSetOrganizationProductAvailability(\n $productIds: [ID!]!\n $channelIds: [ID!]!\n $available: Boolean!\n ) {\n setOrganizationProductAvailability(\n productIds: $productIds\n channelIds: $channelIds\n available: $available\n ) {\n productId\n channelId\n action\n }\n }\n";
632
757
  export declare const ORGANIZATION_PRODUCT_AVAILABILITY_QUERY = "\n query CatalogOrganizationProductAvailability($productIds: [ID!]!, $channelIds: [ID!]!) {\n organizationProductAvailability(productIds: $productIds, channelIds: $channelIds) {\n productId\n channelId\n state\n localCopyId\n }\n }\n";
633
- export declare const MAKE_LOCAL_COPY_MUTATION = "\n mutation CatalogMakeLocalCopy($productId: ID!, $skus: [LocalCopySkuInput!]) {\n makeLocalCopy(productId: $productId, skus: $skus) {\n product { \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 }\n assets { \n id\n name\n preview\n source\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 options {\n id\n code\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 }\n }\n originalProductId\n original\n droppedOrganizationPropertyCount\n }\n }\n";
758
+ export declare const MAKE_LOCAL_COPY_MUTATION = "\n mutation CatalogMakeLocalCopy($productId: ID!, $skus: [LocalCopySkuInput!]) {\n makeLocalCopy(productId: $productId, skus: $skus) {\n product { \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 originalProductId\n original\n droppedOrganizationPropertyCount\n }\n }\n";
634
759
  export declare const SET_PRODUCT_COLLECTIONS_MUTATION = "\n mutation CatalogSetProductCollections(\n $productId: ID!\n $collectionIds: [ID!]!\n $fromCollectionIds: [ID!]\n ) {\n setProductCollections(\n productId: $productId\n collectionIds: $collectionIds\n fromCollectionIds: $fromCollectionIds\n ) {\n added\n removed\n unchanged\n notRemoved {\n collectionId\n reason\n }\n }\n }\n";
635
- export declare const SAVE_PRODUCT_MUTATION = "\n mutation CatalogSaveProduct($input: SaveProductInput!, $idempotencyKey: String) {\n saveProduct(input: $input, idempotencyKey: $idempotencyKey) {\n product { \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 }\n assets { \n id\n name\n preview\n source\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 options {\n id\n code\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 }\n }\n collections {\n added\n removed\n unchanged\n notRemoved {\n collectionId\n reason\n }\n }\n warnings {\n code\n message\n propertyIds\n }\n }\n }\n";
760
+ export declare const SAVE_PRODUCT_MUTATION = "\n mutation CatalogSaveProduct($input: SaveProductInput!, $idempotencyKey: String) {\n saveProduct(input: $input, idempotencyKey: $idempotencyKey) {\n product { \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 collections {\n added\n removed\n unchanged\n notRemoved {\n collectionId\n reason\n }\n }\n warnings {\n code\n message\n propertyIds\n }\n }\n }\n";
761
+ /** An option group as the Admin API answers it inside a product, before `toProduct`. */
762
+ interface WireProductOptionGroup extends Omit<ProductOptionGroupRef, 'isShared'> {
763
+ customFields: {
764
+ isShared?: boolean | null;
765
+ } | null;
766
+ }
636
767
  /** The product as the Admin API answers it, before `toProduct`. */
637
- export interface WireProduct extends Omit<Product, keyof Availability<string> | 'variantCount'> {
768
+ export interface WireProduct extends Omit<Product, keyof Availability<string> | 'variantCount' | 'featuredAsset' | 'assets' | 'optionGroups' | 'brand' | 'condition'> {
769
+ featuredAsset: WireAssetRef | null;
770
+ assets: WireAssetRef[];
771
+ optionGroups: WireProductOptionGroup[];
638
772
  variantList: {
639
773
  totalItems: number;
640
774
  };
641
- customFields: Partial<Availability<ProductAvailabilityState>> | null;
775
+ customFields: (Partial<Availability<ProductAvailabilityState>> & {
776
+ brand?: string | null;
777
+ condition?: string | null;
778
+ }) | null;
642
779
  }
643
780
  /**
644
781
  * Lift the availability custom fields to first-class fields. A server older
@@ -647,4 +784,7 @@ export interface WireProduct extends Omit<Product, keyof Availability<string> |
647
784
  */
648
785
  export declare function toProduct(wire: WireProduct): Product;
649
786
  export declare function productFilter(filter: ProductListFilter | undefined): Record<string, unknown>;
787
+ /** The engine's `ProductListOptions` for one page of {@link ProductListOptions}. */
788
+ export declare function productListOptions(options: ProductListOptions | undefined, skip: number, take: number): Record<string, unknown>;
650
789
  export declare function createProductsModule(transport: Transport): ProductsModule;
790
+ export {};
@@ -1,9 +1,11 @@
1
1
  import { ValidationError } from '@sixtyninecommerce/core';
2
2
  import { bulkProducts, readProductBulkRun, } from './products-bulk.js';
3
- import { ASSET_REF_FIELDS, assertDeleted, availabilityCustomFields, CATALOGUE_OWNERSHIP_FIELDS, DELETION_FIELDS, FACET_VALUE_REF_FIELDS, fieldOf, unwrapResult, vendureListPage, } from './types.js';
3
+ import { ASSET_REF_FIELDS, assertDeleted, availabilityCustomFields, CATALOGUE_OWNERSHIP_FIELDS, DELETION_FIELDS, FACET_VALUE_REF_FIELDS, fieldOf, toAssetRef, unwrapResult, vendureListPage, } from './types.js';
4
4
  import { assertPricesStateBasis, } from './variants.js';
5
5
  /** The engine's bound on one `exclude` or `include` call (`STORE_EXCLUSION_BATCH_LIMIT`). */
6
6
  export const MAX_STORE_EXCLUSION_PRODUCTS = 500;
7
+ /** At most this many distinct products per {@link ProductsModule.storePriceRanges} call. */
8
+ export const MAX_STORE_PRICE_RANGE_PRODUCTS = 100;
7
9
  /**
8
10
  * The engine's bounds on one `setAvailabilityInStores` or `availabilityInStores` call
9
11
  * (`AVAILABILITY_*_LIMIT`).
@@ -29,11 +31,19 @@ export const PRODUCT_FIELDS = /* GraphQL */ `
29
31
  id
30
32
  code
31
33
  name
34
+ customFields {
35
+ isShared
36
+ }
32
37
  options {
33
38
  id
34
39
  code
35
40
  name
36
41
  }
42
+ translations {
43
+ id
44
+ languageCode
45
+ name
46
+ }
37
47
  }
38
48
  translations {
39
49
  id
@@ -50,6 +60,8 @@ export const PRODUCT_FIELDS = /* GraphQL */ `
50
60
  availabilityState
51
61
  availableFrom
52
62
  preorderLimit
63
+ brand
64
+ condition
53
65
  }
54
66
  `;
55
67
  export const PRODUCTS_QUERY = /* GraphQL */ `
@@ -60,9 +72,36 @@ export const PRODUCTS_QUERY = /* GraphQL */ `
60
72
  }
61
73
  }
62
74
  `;
75
+ const STORE_PRICE_FIELDS = 'price priceWithTax currencyCode';
76
+ export const PRODUCT_STORE_PRICE_RANGES_QUERY = /* GraphQL */ `
77
+ query CatalogProductStorePriceRanges($options: ProductListOptions) {
78
+ products(options: $options) {
79
+ items {
80
+ id
81
+ storePriceRange {
82
+ min { ${STORE_PRICE_FIELDS} }
83
+ max { ${STORE_PRICE_FIELDS} }
84
+ someVariantsUnpriced
85
+ }
86
+ }
87
+ }
88
+ }
89
+ `;
90
+ /**
91
+ * One product, with the collections it is in. No variant data beyond `variantList`'s count: a
92
+ * product can have 100,000 variants, and core's `variants` would hand back the first 1,000 with
93
+ * no sign of the rest (`catalog.variants.list` pages them).
94
+ */
63
95
  export const PRODUCT_QUERY = /* GraphQL */ `
64
96
  query CatalogProduct($id: ID!) {
65
- product(id: $id) { ${PRODUCT_FIELDS} }
97
+ product(id: $id) {
98
+ ${PRODUCT_FIELDS}
99
+ collections {
100
+ id
101
+ name
102
+ slug
103
+ }
104
+ }
66
105
  }
67
106
  `;
68
107
  export const CREATE_PRODUCT_MUTATION = /* GraphQL */ `
@@ -196,15 +235,28 @@ export const SAVE_PRODUCT_MUTATION = /* GraphQL */ `
196
235
  * outright, so the defaults below only cover a NULL value, never an absent one.
197
236
  */
198
237
  export function toProduct(wire) {
199
- const { variantList, customFields, ...rest } = wire;
238
+ const { variantList, customFields, featuredAsset, assets, optionGroups, ...rest } = wire;
200
239
  return {
201
240
  ...rest,
241
+ featuredAsset: featuredAsset ? toAssetRef(featuredAsset) : null,
242
+ assets: assets.map(toAssetRef),
243
+ optionGroups: optionGroups.map(({ customFields: groupFields, ...group }) => ({
244
+ ...group,
245
+ isShared: groupFields?.isShared === true,
246
+ })),
202
247
  variantCount: variantList.totalItems,
203
248
  availabilityState: customFields?.availabilityState ?? 'none',
204
249
  availableFrom: customFields?.availableFrom ?? null,
205
250
  preorderLimit: customFields?.preorderLimit ?? null,
251
+ brand: customFields?.brand ?? null,
252
+ condition: customFields?.condition ?? null,
206
253
  };
207
254
  }
255
+ /** {@link toProduct}, plus the collections. */
256
+ function toProductDetail(wire) {
257
+ const { collections, ...rest } = wire;
258
+ return { ...toProduct(rest), collections };
259
+ }
208
260
  function toWireInput(input) {
209
261
  const { availabilityState, availableFrom, preorderLimit, brand, condition, ...rest } = input;
210
262
  const customFields = availabilityCustomFields({
@@ -237,6 +289,16 @@ export function productFilter(filter) {
237
289
  }
238
290
  return out;
239
291
  }
292
+ /** The engine's `ProductListOptions` for one page of {@link ProductListOptions}. */
293
+ export function productListOptions(options, skip, take) {
294
+ const filter = productFilter(options?.filter);
295
+ return {
296
+ skip,
297
+ take,
298
+ ...(Object.keys(filter).length > 0 ? { filter, filterOperator: 'AND' } : {}),
299
+ ...(options?.sort ? { sort: { [options.sort.field]: options.sort.direction } } : {}),
300
+ };
301
+ }
240
302
  function refuse(code, message) {
241
303
  return new ValidationError({ code, message, status: 400, service: 'vendure' });
242
304
  }
@@ -290,19 +352,11 @@ export function createProductsModule(transport) {
290
352
  };
291
353
  return {
292
354
  async list(options) {
293
- const filter = productFilter(options?.filter);
294
- return vendureListPage(transport, PRODUCTS_QUERY, 'products', (skip, take) => ({
295
- options: {
296
- skip,
297
- take,
298
- ...(Object.keys(filter).length > 0 ? { filter, filterOperator: 'AND' } : {}),
299
- ...(options?.sort ? { sort: { [options.sort.field]: options.sort.direction } } : {}),
300
- },
301
- }), options, toProduct);
355
+ return vendureListPage(transport, PRODUCTS_QUERY, 'products', (skip, take) => ({ options: productListOptions(options, skip, take) }), options, toProduct);
302
356
  },
303
357
  async get(id, options) {
304
358
  const product = await fieldOf(transport, PRODUCT_QUERY, 'product', { id }, options);
305
- return product ? toProduct(product) : null;
359
+ return product ? toProductDetail(product) : null;
306
360
  },
307
361
  // `async` so every refusal below — including `toWireInput`'s datetime
308
362
  // check — arrives as a rejection, never as a synchronous throw a caller's
@@ -362,6 +416,27 @@ export function createProductsModule(transport) {
362
416
  assertAvailabilityInput(input, 'read');
363
417
  return fieldOf(transport, ORGANIZATION_PRODUCT_AVAILABILITY_QUERY, 'organizationProductAvailability', { productIds: input.productIds, channelIds: input.channelIds }, options);
364
418
  },
419
+ async storePriceRanges(productIds, options) {
420
+ // The engine stores a uuid lower-case, so an upper-case repeat is the same product.
421
+ const named = new Map();
422
+ for (const id of productIds) {
423
+ const key = String(id).toLowerCase();
424
+ if (!named.has(key))
425
+ named.set(key, id);
426
+ }
427
+ if (named.size > MAX_STORE_PRICE_RANGE_PRODUCTS) {
428
+ throw refuse('PRODUCT_STORE_PRICE_RANGE_INPUT_INVALID', `Ask for at most ${String(MAX_STORE_PRICE_RANGE_PRODUCTS)} products per call; this one named ${String(named.size)}. Nothing was sent.`);
429
+ }
430
+ if (named.size === 0)
431
+ return [];
432
+ const ids = [...named.values()];
433
+ const page = await fieldOf(transport, PRODUCT_STORE_PRICE_RANGES_QUERY, 'products', { options: { filter: { id: { in: ids } }, take: ids.length } }, options);
434
+ const answered = new Map(page.items.map((item) => [item.id.toLowerCase(), item]));
435
+ return [...named.keys()].flatMap((key) => {
436
+ const item = answered.get(key);
437
+ return item ? [{ productId: item.id, range: item.storePriceRange }] : [];
438
+ });
439
+ },
365
440
  async makeLocalCopy(productId, options) {
366
441
  const { skus, ...call } = options ?? {};
367
442
  const result = await fieldOf(transport, MAKE_LOCAL_COPY_MUTATION, 'makeLocalCopy', {