@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,4 +1,30 @@
1
- import { ASSET_REF_FIELDS, assertDeleted, CATALOGUE_OWNERSHIP_FIELDS, DELETION_FIELDS, fieldOf, vendureListPage, } from './types.js';
1
+ import { pageFromVendureList, ValidationError, } from '@sixtyninecommerce/core';
2
+ import { createSearchModule } from '../search/index.js';
3
+ import { ASSET_REF_FIELDS, assertDeleted, CATALOGUE_OWNERSHIP_FIELDS, DEFAULT_PAGE_SIZE, DELETION_FIELDS, fieldOf, toAssetRef, vendureListPage, } from './types.js';
4
+ /** The most collections one {@link CollectionsModule.search} answers. */
5
+ export const MAX_COLLECTION_SEARCH_TAKE = 100;
6
+ const SEO_FIELDS = /* GraphQL */ `
7
+ customFields {
8
+ isRoutable
9
+ isCanonical
10
+ noindex
11
+ nofollow
12
+ metaRobotsMaxImagePreview
13
+ socialImageId
14
+ socialOgType
15
+ twitterCardType
16
+ }
17
+ `;
18
+ const TRANSLATION_SEO_FIELDS = /* GraphQL */ `
19
+ customFields {
20
+ seoTitle
21
+ seoDescription
22
+ canonicalUrl
23
+ socialTitle
24
+ socialDescription
25
+ socialImageAlt
26
+ }
27
+ `;
2
28
  export const COLLECTION_FIELDS = /* GraphQL */ `
3
29
  id
4
30
  ${CATALOGUE_OWNERSHIP_FIELDS}
@@ -26,12 +52,14 @@ export const COLLECTION_FIELDS = /* GraphQL */ `
26
52
  slug
27
53
  }
28
54
  productVariantCount
55
+ ${SEO_FIELDS}
29
56
  translations {
30
57
  id
31
58
  languageCode
32
59
  name
33
60
  slug
34
61
  description
62
+ ${TRANSLATION_SEO_FIELDS}
35
63
  }
36
64
  `;
37
65
  export const COLLECTIONS_QUERY = /* GraphQL */ `
@@ -44,7 +72,19 @@ export const COLLECTIONS_QUERY = /* GraphQL */ `
44
72
  `;
45
73
  export const COLLECTION_QUERY = /* GraphQL */ `
46
74
  query CatalogCollection($id: ID!) {
47
- collection(id: $id) { ${COLLECTION_FIELDS} }
75
+ collection(id: $id) {
76
+ ${COLLECTION_FIELDS}
77
+ parent {
78
+ id
79
+ name
80
+ }
81
+ children {
82
+ id
83
+ name
84
+ slug
85
+ position
86
+ }
87
+ }
48
88
  }
49
89
  `;
50
90
  export const CREATE_COLLECTION_MUTATION = /* GraphQL */ `
@@ -67,25 +107,216 @@ export const MOVE_COLLECTION_MUTATION = /* GraphQL */ `
67
107
  moveCollection(input: $input) { ${COLLECTION_FIELDS} }
68
108
  }
69
109
  `;
110
+ export const COLLECTION_FILTER_DEFINITIONS_QUERY = /* GraphQL */ `
111
+ query CatalogCollectionFilterDefinitions {
112
+ collectionFilters {
113
+ code
114
+ description
115
+ args {
116
+ name
117
+ type
118
+ list
119
+ required
120
+ defaultValue
121
+ label
122
+ description
123
+ ui
124
+ }
125
+ }
126
+ }
127
+ `;
128
+ /**
129
+ * The preview's price is `storePrice` (null for a variant the store has no price for), never
130
+ * core's `price` / `priceWithTax` / `currencyCode`, which raise "No price information was
131
+ * found…" for such a variant and, being non-null, empty the whole preview (#1504).
132
+ */
133
+ export const PREVIEW_COLLECTION_VARIANTS_QUERY = /* GraphQL */ `
134
+ query CatalogPreviewCollectionVariants(
135
+ $input: PreviewCollectionVariantsInput!
136
+ $options: ProductVariantListOptions
137
+ ) {
138
+ previewCollectionVariants(input: $input, options: $options) {
139
+ items {
140
+ id
141
+ name
142
+ sku
143
+ storePrice {
144
+ price
145
+ priceWithTax
146
+ currencyCode
147
+ }
148
+ product {
149
+ id
150
+ name
151
+ featuredAsset { ${ASSET_REF_FIELDS} }
152
+ }
153
+ }
154
+ totalItems
155
+ }
156
+ }
157
+ `;
158
+ const COLLECTION_SORT_FIELDS = [
159
+ 'position',
160
+ 'name',
161
+ 'createdAt',
162
+ 'updatedAt',
163
+ 'id',
164
+ ];
165
+ function toPreviewVariant(wire) {
166
+ const { featuredAsset, ...product } = wire.product;
167
+ return {
168
+ ...wire,
169
+ product: { ...product, featuredAsset: featuredAsset ? toAssetRef(featuredAsset) : null },
170
+ };
171
+ }
172
+ function toSeo(wire) {
173
+ return {
174
+ isRoutable: wire?.isRoutable ?? null,
175
+ isCanonical: wire?.isCanonical ?? null,
176
+ noindex: wire?.noindex ?? null,
177
+ nofollow: wire?.nofollow ?? null,
178
+ metaRobotsMaxImagePreview: wire?.metaRobotsMaxImagePreview ?? null,
179
+ socialImageId: wire?.socialImageId ?? null,
180
+ socialOgType: wire?.socialOgType ?? null,
181
+ twitterCardType: wire?.twitterCardType ?? null,
182
+ };
183
+ }
184
+ function toTranslationSeo(wire) {
185
+ return {
186
+ seoTitle: wire?.seoTitle ?? null,
187
+ seoDescription: wire?.seoDescription ?? null,
188
+ canonicalUrl: wire?.canonicalUrl ?? null,
189
+ socialTitle: wire?.socialTitle ?? null,
190
+ socialDescription: wire?.socialDescription ?? null,
191
+ socialImageAlt: wire?.socialImageAlt ?? null,
192
+ };
193
+ }
194
+ function toCollection(wire) {
195
+ const { customFields, translations, featuredAsset, assets, ...rest } = wire;
196
+ return {
197
+ ...rest,
198
+ featuredAsset: featuredAsset ? toAssetRef(featuredAsset) : null,
199
+ assets: (assets ?? []).map(toAssetRef),
200
+ seo: toSeo(customFields),
201
+ translations: (translations ?? []).map(({ customFields: seo, ...translation }) => ({
202
+ ...translation,
203
+ seo: toTranslationSeo(seo),
204
+ })),
205
+ };
206
+ }
207
+ /** `seo` goes on the wire as the engine's `customFields`, only the keys the caller named. */
208
+ function toWireTranslation(translation) {
209
+ const { seo, ...rest } = translation;
210
+ return seo === undefined ? rest : { ...rest, customFields: { ...seo } };
211
+ }
212
+ function toWireInput(input) {
213
+ const { seo, translations, ...rest } = input;
214
+ return {
215
+ ...rest,
216
+ ...(translations === undefined ? {} : { translations: translations.map(toWireTranslation) }),
217
+ ...(seo === undefined ? {} : { customFields: { ...seo } }),
218
+ };
219
+ }
220
+ function invalidSort(sort) {
221
+ return new ValidationError({
222
+ code: 'INVALID_COLLECTION_SORT',
223
+ message: `sort must name one of ${COLLECTION_SORT_FIELDS.join(', ')} and the direction ASC or DESC; got ${JSON.stringify(sort)}. Nothing was sent.`,
224
+ status: 400,
225
+ service: 'vendure',
226
+ });
227
+ }
228
+ function listOptionsOf(options) {
229
+ const filter = {};
230
+ if (options?.parentId !== undefined)
231
+ filter.parentId = { eq: options.parentId };
232
+ if (options?.name !== undefined)
233
+ filter.name = { contains: options.name };
234
+ if (options?.ids !== undefined)
235
+ filter.id = { in: [...options.ids] };
236
+ const sort = options?.sort;
237
+ if (sort !== undefined &&
238
+ (!COLLECTION_SORT_FIELDS.includes(sort.field) ||
239
+ (sort.direction !== 'ASC' && sort.direction !== 'DESC'))) {
240
+ throw invalidSort(sort);
241
+ }
242
+ return {
243
+ ...(options?.topLevelOnly === true ? { topLevelOnly: true } : {}),
244
+ ...(Object.keys(filter).length > 0 ? { filter } : {}),
245
+ ...(sort === undefined ? {} : { sort: { [sort.field]: sort.direction } }),
246
+ };
247
+ }
248
+ function invalidSearch(message) {
249
+ return new ValidationError({
250
+ code: 'SEARCH_INPUT_INVALID',
251
+ message: `${message} Nothing was sent.`,
252
+ status: 400,
253
+ service: 'vendure',
254
+ });
255
+ }
70
256
  export function createCollectionsModule(transport) {
257
+ const write = async (document, field, variables, options) => toCollection(await fieldOf(transport, document, field, variables, options));
258
+ const list = async (options) => {
259
+ const listOptions = listOptionsOf(options);
260
+ if (options?.ids !== undefined && options.ids.length === 0) {
261
+ return pageFromVendureList({ items: [], totalItems: 0 }, 0, options.limit ?? DEFAULT_PAGE_SIZE, () => Promise.reject(new Error('an empty page has no next page')));
262
+ }
263
+ return vendureListPage(transport, COLLECTIONS_QUERY, 'collections', (skip, take) => ({ options: { skip, take, ...listOptions } }), options, toCollection);
264
+ };
71
265
  return {
72
- list: (options) => {
73
- const filter = {};
74
- if (options?.parentId !== undefined)
75
- filter.parentId = { eq: options.parentId };
76
- if (options?.name !== undefined)
77
- filter.name = { contains: options.name };
78
- return vendureListPage(transport, COLLECTIONS_QUERY, 'collections', (skip, take) => ({
79
- options: { skip, take, ...(Object.keys(filter).length > 0 ? { filter } : {}) },
80
- }), options);
266
+ list,
267
+ async get(id, options) {
268
+ const collection = await fieldOf(transport, COLLECTION_QUERY, 'collection', { id }, options);
269
+ return collection ? toCollection(collection) : null;
81
270
  },
82
- get: (id, options) => fieldOf(transport, COLLECTION_QUERY, 'collection', { id }, options),
83
- create: (input, options) => fieldOf(transport, CREATE_COLLECTION_MUTATION, 'createCollection', { input }, options),
84
- update: (input, options) => fieldOf(transport, UPDATE_COLLECTION_MUTATION, 'updateCollection', { input }, options),
271
+ async search(term, options = {}) {
272
+ const { take = DEFAULT_PAGE_SIZE, skip = 0, ...call } = options;
273
+ if (!Number.isInteger(take) || take < 1 || take > MAX_COLLECTION_SEARCH_TAKE) {
274
+ throw invalidSearch(`take must be a whole number from 1 to ${String(MAX_COLLECTION_SEARCH_TAKE)}; got ${String(take)}.`);
275
+ }
276
+ if (!Number.isInteger(skip) || skip < 0) {
277
+ throw invalidSearch(`skip must be a whole number from 0; got ${String(skip)}.`);
278
+ }
279
+ const hits = await createSearchModule(transport).index('collections', { term, take, skip }, call);
280
+ const ids = [...new Set(hits.items.map((hit) => hit.id))];
281
+ if (ids.length === 0)
282
+ return { items: [], total: hits.total };
283
+ // The index says which and in what order; the rows are the engine's, read in the store the
284
+ // call acts on, so a collection the store no longer holds is not answered.
285
+ const page = await list({ ...call, ids, limit: ids.length });
286
+ const byId = new Map(page.items.map((collection) => [collection.id, collection]));
287
+ return {
288
+ items: ids.flatMap((id) => {
289
+ const collection = byId.get(id);
290
+ return collection ? [collection] : [];
291
+ }),
292
+ total: hits.total,
293
+ };
294
+ },
295
+ create: (input, options) => write(CREATE_COLLECTION_MUTATION, 'createCollection', { input: toWireInput(input) }, options),
296
+ update: (input, options) => write(UPDATE_COLLECTION_MUTATION, 'updateCollection', { input: toWireInput(input) }, options),
85
297
  async delete(id, options) {
86
298
  const response = await fieldOf(transport, DELETE_COLLECTION_MUTATION, 'deleteCollection', { id }, options);
87
299
  assertDeleted('COLLECTION_NOT_DELETED', [response]);
88
300
  },
89
- move: (collectionId, parentId, index, options) => fieldOf(transport, MOVE_COLLECTION_MUTATION, 'moveCollection', { input: { collectionId, parentId, index } }, options),
301
+ move: (collectionId, parentId, index, options) => write(MOVE_COLLECTION_MUTATION, 'moveCollection', { input: { collectionId, parentId, index } }, options),
302
+ filterDefinitions: (options) => fieldOf(transport, COLLECTION_FILTER_DEFINITIONS_QUERY, 'collectionFilters', {}, options),
303
+ previewVariants(input, options = {}) {
304
+ const { term: rawTerm, ...listOptions } = options;
305
+ const term = rawTerm?.trim() ?? '';
306
+ const filter = term === ''
307
+ ? {}
308
+ : {
309
+ filter: { name: { contains: term }, sku: { contains: term } },
310
+ filterOperator: 'OR',
311
+ };
312
+ return vendureListPage(transport, PREVIEW_COLLECTION_VARIANTS_QUERY, 'previewCollectionVariants', (skip, take) => ({
313
+ input: {
314
+ filters: input.filters,
315
+ inheritFilters: input.inheritFilters,
316
+ ...(input.parentId === undefined ? {} : { parentId: input.parentId }),
317
+ },
318
+ options: { skip, take, ...filter },
319
+ }), listOptions, toPreviewVariant);
320
+ },
90
321
  };
91
322
  }
@@ -6,12 +6,15 @@ import { type FacetsModule } from './facets.js';
6
6
  import { type OptionsModule } from './options.js';
7
7
  import { type ProductsModule } from './products.js';
8
8
  import { type ContentFacetSyncResult, type PropertiesModule } from './properties.js';
9
+ import { type RecommendationsModule } from './recommendations.js';
10
+ import { type ReviewsModule } from './reviews.js';
9
11
  import { type VariantsModule } from './variants.js';
10
12
  import { type VisibilityModule } from './visibility.js';
11
13
  /**
12
14
  * The catalogue (spec §9.2 `catalog`): products, variants, options, facets,
13
- * collections, assets, storefront visibility and product properties — one
14
- * resource per namespace, over the Admin API the dashboard itself uses.
15
+ * collections, assets, storefront visibility, product properties, product
16
+ * recommendations and product reviews — one resource per namespace, over the Admin API the
17
+ * dashboard itself uses.
15
18
  *
16
19
  * **Per-resource, not per-intent.** Saving a product form is several calls
17
20
  * here (the product, its variants, its properties, its collections), and they
@@ -70,6 +73,10 @@ export interface CatalogModule {
70
73
  assets: AssetsModule;
71
74
  visibility: VisibilityModule;
72
75
  properties: PropertiesModule;
76
+ /** Recommendation groups, their rules and the products picked per product (W10-13). */
77
+ recommendations: RecommendationsModule;
78
+ /** Product reviews: moderation, the store's replies, statistics, review attributes (W10-117). */
79
+ reviews: ReviewsModule;
73
80
  /**
74
81
  * "Sync filter values" for one filterable `content_item` or `product` property, done by the
75
82
  * engine (headless spec §7 `catalog.syncContentFacets`, by property, the unit the merchant syncs).
@@ -4,6 +4,8 @@ import { createFacetsModule } from './facets.js';
4
4
  import { createOptionsModule } from './options.js';
5
5
  import { createProductsModule } from './products.js';
6
6
  import { createPropertiesModule, syncContentFacets, } from './properties.js';
7
+ import { createRecommendationsModule } from './recommendations.js';
8
+ import { createReviewsModule } from './reviews.js';
7
9
  import { createVariantsModule } from './variants.js';
8
10
  import { createVisibilityModule } from './visibility.js';
9
11
  export function createCatalogModule(transport) {
@@ -16,6 +18,8 @@ export function createCatalogModule(transport) {
16
18
  assets: createAssetsModule(transport),
17
19
  visibility: createVisibilityModule(transport),
18
20
  properties: createPropertiesModule(transport),
21
+ recommendations: createRecommendationsModule(transport),
22
+ reviews: createReviewsModule(transport),
19
23
  syncContentFacets: (propertyId, options) => syncContentFacets(transport, propertyId, options),
20
24
  };
21
25
  }
@@ -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 {};