@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
@@ -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
  }
@@ -0,0 +1,142 @@
1
+ /**
2
+ * A product's documents (headless spec §9.2 `catalog`: "documents"; W10-10): the downloads the
3
+ * storefront lists on a product page (a data sheet, a manual, a certificate), each pointing at a
4
+ * file in the asset library.
5
+ *
6
+ * - **Universal or localized.** A universal document (`isLocalized: false`) has exactly ONE
7
+ * translation, with no language code, and it names the file. A localized one has one
8
+ * translation per language (each language once), and at least one of them names a file; the
9
+ * storefront shows the request's language, else the store's default, else one with a file.
10
+ * - **Who sees it** on the storefront: everyone (`PUBLIC`), signed-in customers
11
+ * (`AUTHENTICATED`), or customers in the listed groups (`CUSTOMER_GROUP`, which needs at least
12
+ * one group). The Admin API always lists every document.
13
+ * - **Order.** A new document goes after the product's last; `reorder` sets the order.
14
+ *
15
+ * Every document is the store's own: a product, document or customer group of another store is
16
+ * never answered and never written.
17
+ *
18
+ * Permissions: `list` needs `ReadCatalog`, the writes `UpdateCatalog`.
19
+ *
20
+ * Refusals, GraphQL errors mapped by `core`:
21
+ * - `USER_INPUT_ERROR` → `ValidationError` (400), in the engine's words: a product of another
22
+ * store or none ("Product … not found"), a document of another store or none
23
+ * ("ProductDocument … not found"), a translation set that breaks the rules above, a
24
+ * `CUSTOMER_GROUP` document with no group, a `reorder` naming a document that is not one of the
25
+ * product's.
26
+ * - `ENTITY_NOT_FOUND` → `NotFoundError` (404): a customer group the store does not hold.
27
+ * - `TRANSLATION_LANGUAGE_NOT_OFFERED` → `ValidationError` (400): a translation in a language the
28
+ * store does not offer (a language the document already has stays editable).
29
+ * - `FORBIDDEN` → `PermissionDeniedError` (403) without the permission.
30
+ *
31
+ * No release gate: every operation here is served by every platform release this SDK supports.
32
+ * No method deduplicates on `idempotencyKey`: repeating a `create` adds a second document.
33
+ */
34
+ import { type Transport } from '@sixtyninecommerce/core';
35
+ import type { Call } from '../types.js';
36
+ import { type LanguageCode } from './types.js';
37
+ export type ProductDocumentVisibility = 'PUBLIC' | 'AUTHENTICATED' | 'CUSTOMER_GROUP';
38
+ /** The file a document translation points at: an asset of the library. */
39
+ export interface ProductDocumentFile {
40
+ id: string;
41
+ name: string;
42
+ /** A string on the wire: a newer engine may add a type. */
43
+ type: 'IMAGE' | 'VIDEO' | 'BINARY' | (string & {});
44
+ mimeType: string;
45
+ /** Bytes. */
46
+ fileSize: number;
47
+ /** The asset's own URL (absolute or relative to the engine). */
48
+ source: string;
49
+ preview: string;
50
+ }
51
+ export interface ProductDocumentTranslation {
52
+ id: string;
53
+ /** Null on a universal document's one translation. */
54
+ languageCode: LanguageCode | null;
55
+ title: string;
56
+ description: string | null;
57
+ assetId: string | null;
58
+ /** Null when the translation names no file, or its file is gone. */
59
+ asset: ProductDocumentFile | null;
60
+ }
61
+ export interface ProductDocument {
62
+ id: string;
63
+ productId: string;
64
+ /** 0 first. */
65
+ position: number;
66
+ visibility: ProductDocumentVisibility | (string & {});
67
+ isLocalized: boolean;
68
+ translations: ProductDocumentTranslation[];
69
+ /** The groups a `CUSTOMER_GROUP` document is shown to; empty under the other two. */
70
+ customerGroups: Array<{
71
+ id: string;
72
+ name: string;
73
+ }>;
74
+ /** ISO-8601 UTC. */
75
+ createdAt: string;
76
+ /** ISO-8601 UTC. */
77
+ updatedAt: string;
78
+ }
79
+ export interface ProductDocumentTranslationInput {
80
+ /** Null (or omitted) on a universal document; required, once per language, on a localized one. */
81
+ languageCode?: LanguageCode | null;
82
+ title: string;
83
+ description?: string | null;
84
+ /** The asset (`catalog.assets`) the translation points at. */
85
+ assetId?: string | null;
86
+ }
87
+ export interface CreateProductDocumentInput {
88
+ productId: string;
89
+ visibility: ProductDocumentVisibility;
90
+ isLocalized: boolean;
91
+ /** Required (one or more) under `CUSTOMER_GROUP`; ignored under the other two. */
92
+ customerGroupIds?: string[];
93
+ translations: ProductDocumentTranslationInput[];
94
+ }
95
+ /**
96
+ * Only the fields named change. `translations`, when sent, REPLACES the document's translations;
97
+ * `customerGroupIds`, when sent, replaces its groups. Leaving `CUSTOMER_GROUP` drops its groups.
98
+ */
99
+ export interface UpdateProductDocumentInput {
100
+ visibility?: ProductDocumentVisibility;
101
+ isLocalized?: boolean;
102
+ customerGroupIds?: string[];
103
+ translations?: ProductDocumentTranslationInput[];
104
+ }
105
+ export interface ProductDocumentsModule {
106
+ /**
107
+ * The product's documents, in their order (ties: the older first). A product of another store,
108
+ * or none, answers `[]`.
109
+ *
110
+ * @effect read
111
+ */
112
+ list(productId: string, options?: Call): Promise<ProductDocument[]>;
113
+ /**
114
+ * Adds a document after the product's last.
115
+ *
116
+ * @effect write
117
+ */
118
+ create(input: CreateProductDocumentInput, options?: Call): Promise<ProductDocument>;
119
+ /** @effect write */
120
+ update(id: string, input: UpdateProductDocumentInput, options?: Call): Promise<ProductDocument>;
121
+ /**
122
+ * Deletes the document; its file stays in the asset library. A document the store does not
123
+ * have (another store's, or already deleted) is refused `PRODUCT_DOCUMENT_NOT_FOUND`
124
+ * (`NotFoundError`, 404, raised by this SDK: the engine answers it as `false`).
125
+ *
126
+ * @effect destructive
127
+ */
128
+ delete(id: string, options?: Call): Promise<void>;
129
+ /**
130
+ * Puts the named documents in this order (`0, 1, 2…`). Name the product's documents: one that
131
+ * is not the product's refuses the whole call and nothing moves; one left out keeps its position.
132
+ *
133
+ * @effect write
134
+ */
135
+ reorder(productId: string, orderedIds: string[], options?: Call): Promise<void>;
136
+ }
137
+ export declare const PRODUCT_DOCUMENTS_QUERY = "\n query CatalogProductDocuments($productId: ID!) {\n productDocuments(productId: $productId) { \n id\n productId\n position\n visibility\n isLocalized\n createdAt\n updatedAt\n translations {\n id\n languageCode\n title\n description\n assetId\n asset {\n id\n name\n type\n mimeType\n fileSize\n source\n preview\n }\n }\n customerGroups {\n id\n name\n }\n }\n }\n";
138
+ export declare const CREATE_PRODUCT_DOCUMENT_MUTATION = "\n mutation CatalogCreateProductDocument($input: CreateProductDocumentInput!) {\n createProductDocument(input: $input) { \n id\n productId\n position\n visibility\n isLocalized\n createdAt\n updatedAt\n translations {\n id\n languageCode\n title\n description\n assetId\n asset {\n id\n name\n type\n mimeType\n fileSize\n source\n preview\n }\n }\n customerGroups {\n id\n name\n }\n }\n }\n";
139
+ export declare const UPDATE_PRODUCT_DOCUMENT_MUTATION = "\n mutation CatalogUpdateProductDocument($input: UpdateProductDocumentInput!) {\n updateProductDocument(input: $input) { \n id\n productId\n position\n visibility\n isLocalized\n createdAt\n updatedAt\n translations {\n id\n languageCode\n title\n description\n assetId\n asset {\n id\n name\n type\n mimeType\n fileSize\n source\n preview\n }\n }\n customerGroups {\n id\n name\n }\n }\n }\n";
140
+ export declare const DELETE_PRODUCT_DOCUMENT_MUTATION = "\n mutation CatalogDeleteProductDocument($id: ID!) {\n deleteProductDocument(id: $id)\n }\n";
141
+ export declare const REORDER_PRODUCT_DOCUMENTS_MUTATION = "\n mutation CatalogReorderProductDocuments($productId: ID!, $orderedIds: [ID!]!) {\n reorderProductDocuments(productId: $productId, orderedIds: $orderedIds)\n }\n";
142
+ export declare function createProductDocumentsModule(transport: Transport): ProductDocumentsModule;
@@ -0,0 +1,114 @@
1
+ /**
2
+ * A product's documents (headless spec §9.2 `catalog`: "documents"; W10-10): the downloads the
3
+ * storefront lists on a product page (a data sheet, a manual, a certificate), each pointing at a
4
+ * file in the asset library.
5
+ *
6
+ * - **Universal or localized.** A universal document (`isLocalized: false`) has exactly ONE
7
+ * translation, with no language code, and it names the file. A localized one has one
8
+ * translation per language (each language once), and at least one of them names a file; the
9
+ * storefront shows the request's language, else the store's default, else one with a file.
10
+ * - **Who sees it** on the storefront: everyone (`PUBLIC`), signed-in customers
11
+ * (`AUTHENTICATED`), or customers in the listed groups (`CUSTOMER_GROUP`, which needs at least
12
+ * one group). The Admin API always lists every document.
13
+ * - **Order.** A new document goes after the product's last; `reorder` sets the order.
14
+ *
15
+ * Every document is the store's own: a product, document or customer group of another store is
16
+ * never answered and never written.
17
+ *
18
+ * Permissions: `list` needs `ReadCatalog`, the writes `UpdateCatalog`.
19
+ *
20
+ * Refusals, GraphQL errors mapped by `core`:
21
+ * - `USER_INPUT_ERROR` → `ValidationError` (400), in the engine's words: a product of another
22
+ * store or none ("Product … not found"), a document of another store or none
23
+ * ("ProductDocument … not found"), a translation set that breaks the rules above, a
24
+ * `CUSTOMER_GROUP` document with no group, a `reorder` naming a document that is not one of the
25
+ * product's.
26
+ * - `ENTITY_NOT_FOUND` → `NotFoundError` (404): a customer group the store does not hold.
27
+ * - `TRANSLATION_LANGUAGE_NOT_OFFERED` → `ValidationError` (400): a translation in a language the
28
+ * store does not offer (a language the document already has stays editable).
29
+ * - `FORBIDDEN` → `PermissionDeniedError` (403) without the permission.
30
+ *
31
+ * No release gate: every operation here is served by every platform release this SDK supports.
32
+ * No method deduplicates on `idempotencyKey`: repeating a `create` adds a second document.
33
+ */
34
+ import { NotFoundError } from '@sixtyninecommerce/core';
35
+ import { fieldOf } from './types.js';
36
+ const DOCUMENT_FIELDS = /* GraphQL */ `
37
+ id
38
+ productId
39
+ position
40
+ visibility
41
+ isLocalized
42
+ createdAt
43
+ updatedAt
44
+ translations {
45
+ id
46
+ languageCode
47
+ title
48
+ description
49
+ assetId
50
+ asset {
51
+ id
52
+ name
53
+ type
54
+ mimeType
55
+ fileSize
56
+ source
57
+ preview
58
+ }
59
+ }
60
+ customerGroups {
61
+ id
62
+ name
63
+ }
64
+ `;
65
+ export const PRODUCT_DOCUMENTS_QUERY = /* GraphQL */ `
66
+ query CatalogProductDocuments($productId: ID!) {
67
+ productDocuments(productId: $productId) { ${DOCUMENT_FIELDS} }
68
+ }
69
+ `;
70
+ export const CREATE_PRODUCT_DOCUMENT_MUTATION = /* GraphQL */ `
71
+ mutation CatalogCreateProductDocument($input: CreateProductDocumentInput!) {
72
+ createProductDocument(input: $input) { ${DOCUMENT_FIELDS} }
73
+ }
74
+ `;
75
+ export const UPDATE_PRODUCT_DOCUMENT_MUTATION = /* GraphQL */ `
76
+ mutation CatalogUpdateProductDocument($input: UpdateProductDocumentInput!) {
77
+ updateProductDocument(input: $input) { ${DOCUMENT_FIELDS} }
78
+ }
79
+ `;
80
+ export const DELETE_PRODUCT_DOCUMENT_MUTATION = /* GraphQL */ `
81
+ mutation CatalogDeleteProductDocument($id: ID!) {
82
+ deleteProductDocument(id: $id)
83
+ }
84
+ `;
85
+ export const REORDER_PRODUCT_DOCUMENTS_MUTATION = /* GraphQL */ `
86
+ mutation CatalogReorderProductDocuments($productId: ID!, $orderedIds: [ID!]!) {
87
+ reorderProductDocuments(productId: $productId, orderedIds: $orderedIds)
88
+ }
89
+ `;
90
+ /** The engine reads the list in `position` order; keep that, with the older first on a tie. */
91
+ function byPosition(documents) {
92
+ return [...documents].sort((a, b) => a.position - b.position || a.createdAt.localeCompare(b.createdAt));
93
+ }
94
+ export function createProductDocumentsModule(transport) {
95
+ return {
96
+ list: async (productId, options) => byPosition(await fieldOf(transport, PRODUCT_DOCUMENTS_QUERY, 'productDocuments', { productId }, options)),
97
+ create: (input, options) => fieldOf(transport, CREATE_PRODUCT_DOCUMENT_MUTATION, 'createProductDocument', { input }, options),
98
+ update: (id, input, options) => fieldOf(transport, UPDATE_PRODUCT_DOCUMENT_MUTATION, 'updateProductDocument', { input: { ...input, id } }, options),
99
+ async delete(id, options) {
100
+ const deleted = await fieldOf(transport, DELETE_PRODUCT_DOCUMENT_MUTATION, 'deleteProductDocument', { id }, options);
101
+ if (!deleted) {
102
+ throw new NotFoundError({
103
+ code: 'PRODUCT_DOCUMENT_NOT_FOUND',
104
+ message: `This store has no product document ${id}.`,
105
+ status: 404,
106
+ service: 'vendure',
107
+ });
108
+ }
109
+ },
110
+ async reorder(productId, orderedIds, options) {
111
+ await fieldOf(transport, REORDER_PRODUCT_DOCUMENTS_MUTATION, 'reorderProductDocuments', { productId, orderedIds }, options);
112
+ },
113
+ };
114
+ }
@@ -2,16 +2,21 @@ import type { Transport } from '@sixtyninecommerce/core';
2
2
  import type { Call } from '../types.js';
3
3
  import { type AssetsModule } from './assets.js';
4
4
  import { type CollectionsModule } from './collections.js';
5
+ import { type ProductDocumentsModule } from './documents.js';
5
6
  import { type FacetsModule } from './facets.js';
7
+ import { type ProductMetadataModule } from './metadata.js';
6
8
  import { type OptionsModule } from './options.js';
7
9
  import { type ProductsModule } from './products.js';
8
- import { type ContentFacetSyncResult, type PropertiesModule } from './properties.js';
10
+ import { type ContentFacetSyncResult, type ContentItemFacetSyncResult, type PropertiesModule } from './properties.js';
11
+ import { type RecommendationsModule } from './recommendations.js';
12
+ import { type ReviewsModule } from './reviews.js';
9
13
  import { type VariantsModule } from './variants.js';
10
14
  import { type VisibilityModule } from './visibility.js';
11
15
  /**
12
16
  * 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.
17
+ * collections, assets, storefront visibility, product documents, product SEO metadata, product
18
+ * properties, product recommendations and product reviews — one resource per namespace, over the
19
+ * Admin API the dashboard itself uses.
15
20
  *
16
21
  * **Per-resource, not per-intent.** Saving a product form is several calls
17
22
  * here (the product, its variants, its properties, its collections), and they
@@ -69,7 +74,15 @@ export interface CatalogModule {
69
74
  collections: CollectionsModule;
70
75
  assets: AssetsModule;
71
76
  visibility: VisibilityModule;
77
+ /** A product's downloads: data sheets, manuals, certificates (W10-10). */
78
+ documents: ProductDocumentsModule;
79
+ /** A product's SEO, social and AI-agent metadata, and the SEO coverage list (W10-10). */
80
+ metadata: ProductMetadataModule;
72
81
  properties: PropertiesModule;
82
+ /** Recommendation groups, their rules and the products picked per product (W10-13). */
83
+ recommendations: RecommendationsModule;
84
+ /** Product reviews: moderation, the store's replies, statistics, review attributes (W10-117). */
85
+ reviews: ReviewsModule;
73
86
  /**
74
87
  * "Sync filter values" for one filterable `content_item` or `product` property, done by the
75
88
  * engine (headless spec §7 `catalog.syncContentFacets`, by property, the unit the merchant syncs).
@@ -86,9 +99,11 @@ export interface CatalogModule {
86
99
  * anything changes. Repeating the call is safe: a label that did not change is not written
87
100
  * again, so a repeat answers the same counts and changes nothing.
88
101
  *
89
- * Nothing runs it automatically in this release: rename a content item or a product, then call
90
- * it (or press "Sync filter values") to update the filter label (ruling G17; an event-driven
91
- * update is a later phase).
102
+ * Automatic for PUBLISHED content items (headless W10-19, ruling G115): when a published item
103
+ * is edited, published or unpublished, the platform syncs the properties naming it by itself
104
+ * within about a minute ({@link CatalogModule.syncContentItemFacets}). Call this after renaming
105
+ * a DRAFT or archived item (the content system announces nothing for one until it is
106
+ * published), after renaming a product, or to sync one property at once.
92
107
  *
93
108
  * Needs `UpdateCatalog`. Platform releases before this method do not have the mutation and refuse
94
109
  * it as `ValidationError` `GRAPHQL_VALIDATION_FAILED` (400).
@@ -109,7 +124,40 @@ export interface CatalogModule {
109
124
  * - `PROPERTY_SYNC_SOURCE_UNAVAILABLE` → `BusinessRuleError` (422): a `content_item` property on
110
125
  * a platform with no content system wired.
111
126
  * - `FORBIDDEN` → `PermissionDeniedError` (403): no `UpdateCatalog`.
127
+ *
128
+ * @effect write
112
129
  */
113
130
  syncContentFacets(propertyId: string, options?: Call): Promise<ContentFacetSyncResult>;
131
+ /**
132
+ * "Sync filter values" for every filterable `content_item` property of the store whose values
133
+ * name one of `contentItemIds` (headless W10-19): each is synced as
134
+ * {@link CatalogModule.syncContentFacets} syncs it, so a renamed content item's filter label
135
+ * follows its title. The platform calls it by itself, within about a minute, for the items a
136
+ * change to a PUBLISHED item touched (published, edited while published, unpublished); call it
137
+ * yourself for items you know changed otherwise (an app importing content, a draft renamed).
138
+ *
139
+ * Per property: a property its own sync refuses is reported in `skipped` with that refusal
140
+ * (`MANAGED_BY_ORGANIZATION` for the organization workspace's property, synced in the
141
+ * workspace) and nothing of it is written; the others are synced. `changed` says whether
142
+ * anything was written. Every label is read before anything is written, and the writes are
143
+ * one transaction: a content system that cannot be read, or any failure other than a
144
+ * property's refusal, refuses the whole call and writes nothing. Repeating it is safe.
145
+ *
146
+ * At most {@link MAX_CONTENT_ITEM_FACET_SYNC_IDS} different ids per call (repeats count once);
147
+ * an id no property names syncs nothing. Needs `UpdateCatalog`. Platform releases before this
148
+ * method do not have the mutation and refuse it as `ValidationError`
149
+ * `GRAPHQL_VALIDATION_FAILED` (400).
150
+ *
151
+ * Refusals of the whole call (nothing is written):
152
+ * - `CONTENT_ITEM_IDS_INVALID` → `ValidationError` (400): a blank id, or more than 500
153
+ * different ids; checked before sending as well.
154
+ * - `ENTITY_NOT_FOUND` → `NotFoundError` (404): an id that is not a uuid.
155
+ * - `CMS_REQUEST_FAILED` → `BusinessRuleError` (422): the content system could not be read;
156
+ * try again.
157
+ * - `FORBIDDEN` → `PermissionDeniedError` (403): no `UpdateCatalog`.
158
+ *
159
+ * @effect write
160
+ */
161
+ syncContentItemFacets(contentItemIds: readonly string[], options?: Call): Promise<ContentItemFacetSyncResult>;
114
162
  }
115
163
  export declare function createCatalogModule(transport: Transport): CatalogModule;