@open-mercato/core 0.9.1-develop.7473.1.de5b22888f → 0.9.1-develop.7475.1.28ca93ed97

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 (597) hide show
  1. package/.turbo/turbo-build.log +2 -2
  2. package/dist/generated/entities/catalog_price_history_entry/index.js +53 -0
  3. package/dist/generated/entities/catalog_price_history_entry/index.js.map +7 -0
  4. package/dist/generated/entities/customer_group_terms/index.js +2 -0
  5. package/dist/generated/entities/customer_group_terms/index.js.map +2 -2
  6. package/dist/generated/entities/ecommerce_store/index.js +33 -0
  7. package/dist/generated/entities/ecommerce_store/index.js.map +7 -0
  8. package/dist/generated/entities/ecommerce_store_channel_binding/index.js +29 -0
  9. package/dist/generated/entities/ecommerce_store_channel_binding/index.js.map +7 -0
  10. package/dist/generated/entities/ecommerce_store_domain_binding/index.js +23 -0
  11. package/dist/generated/entities/ecommerce_store_domain_binding/index.js.map +7 -0
  12. package/dist/generated/entities.ids.generated.js +8 -1
  13. package/dist/generated/entities.ids.generated.js.map +2 -2
  14. package/dist/generated/entity-fields-registry.js +72 -0
  15. package/dist/generated/entity-fields-registry.js.map +2 -2
  16. package/dist/helpers/integration/customerGroupsFixtures.js.map +2 -2
  17. package/dist/modules/catalog/acl.js +8 -1
  18. package/dist/modules/catalog/acl.js.map +2 -2
  19. package/dist/modules/catalog/api/config/omnibus/route.js +184 -0
  20. package/dist/modules/catalog/api/config/omnibus/route.js.map +7 -0
  21. package/dist/modules/catalog/api/prices/history/route.js +131 -0
  22. package/dist/modules/catalog/api/prices/history/route.js.map +7 -0
  23. package/dist/modules/catalog/api/prices/omnibus-preview/route.js +184 -0
  24. package/dist/modules/catalog/api/prices/omnibus-preview/route.js.map +7 -0
  25. package/dist/modules/catalog/api/products/route.js +54 -245
  26. package/dist/modules/catalog/api/products/route.js.map +3 -3
  27. package/dist/modules/catalog/api/tags/route.js +6 -0
  28. package/dist/modules/catalog/api/tags/route.js.map +2 -2
  29. package/dist/modules/catalog/backend/config/catalog/page.js +3 -1
  30. package/dist/modules/catalog/backend/config/catalog/page.js.map +2 -2
  31. package/dist/modules/catalog/cli.js +80 -2
  32. package/dist/modules/catalog/cli.js.map +2 -2
  33. package/dist/modules/catalog/commands/categories.js +51 -2
  34. package/dist/modules/catalog/commands/categories.js.map +2 -2
  35. package/dist/modules/catalog/commands/prices.js +43 -1
  36. package/dist/modules/catalog/commands/prices.js.map +2 -2
  37. package/dist/modules/catalog/commands/products.js +71 -0
  38. package/dist/modules/catalog/commands/products.js.map +2 -2
  39. package/dist/modules/catalog/commands/variants.js +7 -0
  40. package/dist/modules/catalog/commands/variants.js.map +2 -2
  41. package/dist/modules/catalog/components/OmnibusSettings.js +703 -0
  42. package/dist/modules/catalog/components/OmnibusSettings.js.map +7 -0
  43. package/dist/modules/catalog/components/PriceEditorOmnibusRow.js +152 -0
  44. package/dist/modules/catalog/components/PriceEditorOmnibusRow.js.map +7 -0
  45. package/dist/modules/catalog/components/lookupSources.js +31 -0
  46. package/dist/modules/catalog/components/lookupSources.js.map +7 -0
  47. package/dist/modules/catalog/components/prices/PriceScopeSelectors.js +8 -2
  48. package/dist/modules/catalog/components/prices/PriceScopeSelectors.js.map +2 -2
  49. package/dist/modules/catalog/components/products/VariantBuilder.js +11 -1
  50. package/dist/modules/catalog/components/products/VariantBuilder.js.map +2 -2
  51. package/dist/modules/catalog/data/entities.js +122 -1
  52. package/dist/modules/catalog/data/entities.js.map +2 -2
  53. package/dist/modules/catalog/data/validators.js +78 -0
  54. package/dist/modules/catalog/data/validators.js.map +2 -2
  55. package/dist/modules/catalog/di.js +18 -0
  56. package/dist/modules/catalog/di.js.map +2 -2
  57. package/dist/modules/catalog/lib/omnibus.js +285 -0
  58. package/dist/modules/catalog/lib/omnibus.js.map +7 -0
  59. package/dist/modules/catalog/lib/omnibusBackfill.js +146 -0
  60. package/dist/modules/catalog/lib/omnibusBackfill.js.map +7 -0
  61. package/dist/modules/catalog/lib/omnibusCache.js +89 -0
  62. package/dist/modules/catalog/lib/omnibusCache.js.map +7 -0
  63. package/dist/modules/catalog/lib/omnibusConfig.js +64 -0
  64. package/dist/modules/catalog/lib/omnibusConfig.js.map +7 -0
  65. package/dist/modules/catalog/lib/omnibusHistoryQueries.js +191 -0
  66. package/dist/modules/catalog/lib/omnibusHistoryQueries.js.map +7 -0
  67. package/dist/modules/catalog/lib/omnibusPresentedEntry.js +73 -0
  68. package/dist/modules/catalog/lib/omnibusPresentedEntry.js.map +7 -0
  69. package/dist/modules/catalog/lib/omnibusProductListEnrichment.js +94 -0
  70. package/dist/modules/catalog/lib/omnibusProductListEnrichment.js.map +7 -0
  71. package/dist/modules/catalog/lib/omnibusTypes.js +115 -0
  72. package/dist/modules/catalog/lib/omnibusTypes.js.map +7 -0
  73. package/dist/modules/catalog/lib/optionSchemaTranslations.js +55 -0
  74. package/dist/modules/catalog/lib/optionSchemaTranslations.js.map +7 -0
  75. package/dist/modules/catalog/lib/priceHistoryQuery.js +103 -0
  76. package/dist/modules/catalog/lib/priceHistoryQuery.js.map +7 -0
  77. package/dist/modules/catalog/lib/pricing.js +26 -2
  78. package/dist/modules/catalog/lib/pricing.js.map +2 -2
  79. package/dist/modules/catalog/lib/productFilters.js +273 -0
  80. package/dist/modules/catalog/lib/productFilters.js.map +7 -0
  81. package/dist/modules/catalog/lib/productScopeKeys.js +105 -0
  82. package/dist/modules/catalog/lib/productScopeKeys.js.map +7 -0
  83. package/dist/modules/catalog/lib/productScopeReindex.js +73 -0
  84. package/dist/modules/catalog/lib/productScopeReindex.js.map +7 -0
  85. package/dist/modules/catalog/migrations/Migration20261005105352_catalog.js +39 -0
  86. package/dist/modules/catalog/migrations/Migration20261005105352_catalog.js.map +7 -0
  87. package/dist/modules/catalog/migrations/Migration20261005150824_catalog.js +39 -0
  88. package/dist/modules/catalog/migrations/Migration20261005150824_catalog.js.map +7 -0
  89. package/dist/modules/catalog/services/catalogOmnibusService.js +480 -0
  90. package/dist/modules/catalog/services/catalogOmnibusService.js.map +7 -0
  91. package/dist/modules/catalog/setup.js +3 -1
  92. package/dist/modules/catalog/setup.js.map +2 -2
  93. package/dist/modules/catalog/subscribers/product-scope-keys-category-deleted.js +16 -0
  94. package/dist/modules/catalog/subscribers/product-scope-keys-category-deleted.js.map +7 -0
  95. package/dist/modules/catalog/subscribers/product-scope-keys-category-updated.js +17 -0
  96. package/dist/modules/catalog/subscribers/product-scope-keys-category-updated.js.map +7 -0
  97. package/dist/modules/catalog/translations.js +10 -0
  98. package/dist/modules/catalog/translations.js.map +2 -2
  99. package/dist/modules/configs/lib/upgrade-actions.js +28 -0
  100. package/dist/modules/configs/lib/upgrade-actions.js.map +2 -2
  101. package/dist/modules/customer_groups/api/customer-groups/[id]/terms/route.js +5 -0
  102. package/dist/modules/customer_groups/api/customer-groups/[id]/terms/route.js.map +2 -2
  103. package/dist/modules/customer_groups/components/CustomerGroupTermsSection.js +111 -3
  104. package/dist/modules/customer_groups/components/CustomerGroupTermsSection.js.map +2 -2
  105. package/dist/modules/customer_groups/components/customerGroupAssortmentScope.js +43 -0
  106. package/dist/modules/customer_groups/components/customerGroupAssortmentScope.js.map +7 -0
  107. package/dist/modules/customer_groups/data/entities.js +3 -0
  108. package/dist/modules/customer_groups/data/entities.js.map +2 -2
  109. package/dist/modules/customer_groups/data/validators.js +9 -0
  110. package/dist/modules/customer_groups/data/validators.js.map +2 -2
  111. package/dist/modules/customer_groups/migrations/Migration20261005110250_customer_groups.js +17 -0
  112. package/dist/modules/customer_groups/migrations/Migration20261005110250_customer_groups.js.map +7 -0
  113. package/dist/modules/customer_groups/services/customerGroupsService.js +62 -15
  114. package/dist/modules/customer_groups/services/customerGroupsService.js.map +2 -2
  115. package/dist/modules/ecommerce/acl.js +13 -0
  116. package/dist/modules/ecommerce/acl.js.map +7 -0
  117. package/dist/modules/ecommerce/api/domain-mappings/route.js +72 -0
  118. package/dist/modules/ecommerce/api/domain-mappings/route.js.map +7 -0
  119. package/dist/modules/ecommerce/api/openapi.js +27 -0
  120. package/dist/modules/ecommerce/api/openapi.js.map +7 -0
  121. package/dist/modules/ecommerce/api/store-channel-bindings/[id]/assortment-count/route.js +109 -0
  122. package/dist/modules/ecommerce/api/store-channel-bindings/[id]/assortment-count/route.js.map +7 -0
  123. package/dist/modules/ecommerce/api/store-channel-bindings/crud.js +265 -0
  124. package/dist/modules/ecommerce/api/store-channel-bindings/crud.js.map +7 -0
  125. package/dist/modules/ecommerce/api/store-channel-bindings/route.js +67 -0
  126. package/dist/modules/ecommerce/api/store-channel-bindings/route.js.map +7 -0
  127. package/dist/modules/ecommerce/api/store-domain-bindings/crud.js +296 -0
  128. package/dist/modules/ecommerce/api/store-domain-bindings/crud.js.map +7 -0
  129. package/dist/modules/ecommerce/api/store-domain-bindings/route.js +73 -0
  130. package/dist/modules/ecommerce/api/store-domain-bindings/route.js.map +7 -0
  131. package/dist/modules/ecommerce/api/storefront/categories/[slug]/route.js +87 -0
  132. package/dist/modules/ecommerce/api/storefront/categories/[slug]/route.js.map +7 -0
  133. package/dist/modules/ecommerce/api/storefront/categories/openapiSchemas.js +50 -0
  134. package/dist/modules/ecommerce/api/storefront/categories/openapiSchemas.js.map +7 -0
  135. package/dist/modules/ecommerce/api/storefront/categories/route.js +75 -0
  136. package/dist/modules/ecommerce/api/storefront/categories/route.js.map +7 -0
  137. package/dist/modules/ecommerce/api/storefront/context/route.js +163 -0
  138. package/dist/modules/ecommerce/api/storefront/context/route.js.map +7 -0
  139. package/dist/modules/ecommerce/api/storefront/products/[idOrHandle]/route.js +87 -0
  140. package/dist/modules/ecommerce/api/storefront/products/[idOrHandle]/route.js.map +7 -0
  141. package/dist/modules/ecommerce/api/storefront/products/openapiSchemas.js +177 -0
  142. package/dist/modules/ecommerce/api/storefront/products/openapiSchemas.js.map +7 -0
  143. package/dist/modules/ecommerce/api/storefront/products/route.js +78 -0
  144. package/dist/modules/ecommerce/api/storefront/products/route.js.map +7 -0
  145. package/dist/modules/ecommerce/api/storefront/search/suggest/openapiSchemas.js +25 -0
  146. package/dist/modules/ecommerce/api/storefront/search/suggest/openapiSchemas.js.map +7 -0
  147. package/dist/modules/ecommerce/api/storefront/search/suggest/route.js +75 -0
  148. package/dist/modules/ecommerce/api/storefront/search/suggest/route.js.map +7 -0
  149. package/dist/modules/ecommerce/api/storefront/storefrontRouteSupport.js +58 -0
  150. package/dist/modules/ecommerce/api/storefront/storefrontRouteSupport.js.map +7 -0
  151. package/dist/modules/ecommerce/api/stores/[id]/branding/route.js +183 -0
  152. package/dist/modules/ecommerce/api/stores/[id]/branding/route.js.map +7 -0
  153. package/dist/modules/ecommerce/api/stores/[id]/preview-branding/route.js +92 -0
  154. package/dist/modules/ecommerce/api/stores/[id]/preview-branding/route.js.map +7 -0
  155. package/dist/modules/ecommerce/api/stores/crud.js +401 -0
  156. package/dist/modules/ecommerce/api/stores/crud.js.map +7 -0
  157. package/dist/modules/ecommerce/api/stores/route.js +64 -0
  158. package/dist/modules/ecommerce/api/stores/route.js.map +7 -0
  159. package/dist/modules/ecommerce/backend/config/ecommerce/[id]/page.js +9 -0
  160. package/dist/modules/ecommerce/backend/config/ecommerce/[id]/page.js.map +7 -0
  161. package/dist/modules/ecommerce/backend/config/ecommerce/[id]/page.meta.js +16 -0
  162. package/dist/modules/ecommerce/backend/config/ecommerce/[id]/page.meta.js.map +7 -0
  163. package/dist/modules/ecommerce/backend/config/ecommerce/page.js +9 -0
  164. package/dist/modules/ecommerce/backend/config/ecommerce/page.js.map +7 -0
  165. package/dist/modules/ecommerce/backend/config/ecommerce/page.meta.js +16 -0
  166. package/dist/modules/ecommerce/backend/config/ecommerce/page.meta.js.map +7 -0
  167. package/dist/modules/ecommerce/commands/stores.js +110 -0
  168. package/dist/modules/ecommerce/commands/stores.js.map +7 -0
  169. package/dist/modules/ecommerce/components/ChannelAssortmentCount.js +90 -0
  170. package/dist/modules/ecommerce/components/ChannelAssortmentCount.js.map +7 -0
  171. package/dist/modules/ecommerce/components/ChannelBindingFormSections.js +33 -0
  172. package/dist/modules/ecommerce/components/ChannelBindingFormSections.js.map +7 -0
  173. package/dist/modules/ecommerce/components/ChannelLookupPicker.js +11 -0
  174. package/dist/modules/ecommerce/components/ChannelLookupPicker.js.map +7 -0
  175. package/dist/modules/ecommerce/components/DomainStatusWarning.js +24 -0
  176. package/dist/modules/ecommerce/components/DomainStatusWarning.js.map +7 -0
  177. package/dist/modules/ecommerce/components/StoreAvailabilityDefaultsSection.js +190 -0
  178. package/dist/modules/ecommerce/components/StoreAvailabilityDefaultsSection.js.map +7 -0
  179. package/dist/modules/ecommerce/components/StoreBrandingControls.js +67 -0
  180. package/dist/modules/ecommerce/components/StoreBrandingControls.js.map +7 -0
  181. package/dist/modules/ecommerce/components/StoreBrandingPreview.js +69 -0
  182. package/dist/modules/ecommerce/components/StoreBrandingPreview.js.map +7 -0
  183. package/dist/modules/ecommerce/components/StoreBrandingTab.js +218 -0
  184. package/dist/modules/ecommerce/components/StoreBrandingTab.js.map +7 -0
  185. package/dist/modules/ecommerce/components/StoreChannelBindingDialog.js +270 -0
  186. package/dist/modules/ecommerce/components/StoreChannelBindingDialog.js.map +7 -0
  187. package/dist/modules/ecommerce/components/StoreChannelsTab.js +313 -0
  188. package/dist/modules/ecommerce/components/StoreChannelsTab.js.map +7 -0
  189. package/dist/modules/ecommerce/components/StoreCreateDialog.js +164 -0
  190. package/dist/modules/ecommerce/components/StoreCreateDialog.js.map +7 -0
  191. package/dist/modules/ecommerce/components/StoreDomainBindingDialog.js +162 -0
  192. package/dist/modules/ecommerce/components/StoreDomainBindingDialog.js.map +7 -0
  193. package/dist/modules/ecommerce/components/StoreDomainsTab.js +357 -0
  194. package/dist/modules/ecommerce/components/StoreDomainsTab.js.map +7 -0
  195. package/dist/modules/ecommerce/components/StoreEditPage.js +155 -0
  196. package/dist/modules/ecommerce/components/StoreEditPage.js.map +7 -0
  197. package/dist/modules/ecommerce/components/StoreGeneralTab.js +167 -0
  198. package/dist/modules/ecommerce/components/StoreGeneralTab.js.map +7 -0
  199. package/dist/modules/ecommerce/components/StoreListPage.js +290 -0
  200. package/dist/modules/ecommerce/components/StoreListPage.js.map +7 -0
  201. package/dist/modules/ecommerce/components/StoreSeoTab.js +132 -0
  202. package/dist/modules/ecommerce/components/StoreSeoTab.js.map +7 -0
  203. package/dist/modules/ecommerce/components/StoreStatusBadge.js +20 -0
  204. package/dist/modules/ecommerce/components/StoreStatusBadge.js.map +7 -0
  205. package/dist/modules/ecommerce/components/channelLookups.js +28 -0
  206. package/dist/modules/ecommerce/components/channelLookups.js.map +7 -0
  207. package/dist/modules/ecommerce/components/storeAdmin.js +41 -0
  208. package/dist/modules/ecommerce/components/storeAdmin.js.map +7 -0
  209. package/dist/modules/ecommerce/components/storeBrandingForm.js +197 -0
  210. package/dist/modules/ecommerce/components/storeBrandingForm.js.map +7 -0
  211. package/dist/modules/ecommerce/components/storeChannels.js +140 -0
  212. package/dist/modules/ecommerce/components/storeChannels.js.map +7 -0
  213. package/dist/modules/ecommerce/components/storeDomains.js +167 -0
  214. package/dist/modules/ecommerce/components/storeDomains.js.map +7 -0
  215. package/dist/modules/ecommerce/components/storeEditTabs.js +62 -0
  216. package/dist/modules/ecommerce/components/storeEditTabs.js.map +7 -0
  217. package/dist/modules/ecommerce/components/storeGeneral.js +95 -0
  218. package/dist/modules/ecommerce/components/storeGeneral.js.map +7 -0
  219. package/dist/modules/ecommerce/components/storeSeo.js +69 -0
  220. package/dist/modules/ecommerce/components/storeSeo.js.map +7 -0
  221. package/dist/modules/ecommerce/components/useChannelAssortmentCount.js +45 -0
  222. package/dist/modules/ecommerce/components/useChannelAssortmentCount.js.map +7 -0
  223. package/dist/modules/ecommerce/components/useStoreAccess.js +28 -0
  224. package/dist/modules/ecommerce/components/useStoreAccess.js.map +7 -0
  225. package/dist/modules/ecommerce/data/enrichers.js +157 -0
  226. package/dist/modules/ecommerce/data/enrichers.js.map +7 -0
  227. package/dist/modules/ecommerce/data/entities.js +197 -0
  228. package/dist/modules/ecommerce/data/entities.js.map +7 -0
  229. package/dist/modules/ecommerce/data/validators.js +406 -0
  230. package/dist/modules/ecommerce/data/validators.js.map +7 -0
  231. package/dist/modules/ecommerce/di.js +11 -0
  232. package/dist/modules/ecommerce/di.js.map +7 -0
  233. package/dist/modules/ecommerce/events.js +27 -0
  234. package/dist/modules/ecommerce/events.js.map +7 -0
  235. package/dist/modules/ecommerce/index.js +16 -0
  236. package/dist/modules/ecommerce/index.js.map +7 -0
  237. package/dist/modules/ecommerce/lib/assortmentCount.js +112 -0
  238. package/dist/modules/ecommerce/lib/assortmentCount.js.map +7 -0
  239. package/dist/modules/ecommerce/lib/brandingStyles.js +184 -0
  240. package/dist/modules/ecommerce/lib/brandingStyles.js.map +7 -0
  241. package/dist/modules/ecommerce/lib/buyerContext.js +284 -0
  242. package/dist/modules/ecommerce/lib/buyerContext.js.map +7 -0
  243. package/dist/modules/ecommerce/lib/cacheInvalidation.js +186 -0
  244. package/dist/modules/ecommerce/lib/cacheInvalidation.js.map +7 -0
  245. package/dist/modules/ecommerce/lib/cacheKeys.js +236 -0
  246. package/dist/modules/ecommerce/lib/cacheKeys.js.map +7 -0
  247. package/dist/modules/ecommerce/lib/createConflictRecheck.js +29 -0
  248. package/dist/modules/ecommerce/lib/createConflictRecheck.js.map +7 -0
  249. package/dist/modules/ecommerce/lib/crudEvents.js +94 -0
  250. package/dist/modules/ecommerce/lib/crudEvents.js.map +7 -0
  251. package/dist/modules/ecommerce/lib/crudSupport.js +64 -0
  252. package/dist/modules/ecommerce/lib/crudSupport.js.map +7 -0
  253. package/dist/modules/ecommerce/lib/domainBindingRebind.js +99 -0
  254. package/dist/modules/ecommerce/lib/domainBindingRebind.js.map +7 -0
  255. package/dist/modules/ecommerce/lib/domainMappingSummaries.js +39 -0
  256. package/dist/modules/ecommerce/lib/domainMappingSummaries.js.map +7 -0
  257. package/dist/modules/ecommerce/lib/exclusiveFlag.js +57 -0
  258. package/dist/modules/ecommerce/lib/exclusiveFlag.js.map +7 -0
  259. package/dist/modules/ecommerce/lib/references.js +70 -0
  260. package/dist/modules/ecommerce/lib/references.js.map +7 -0
  261. package/dist/modules/ecommerce/lib/seedDraftStore.js +99 -0
  262. package/dist/modules/ecommerce/lib/seedDraftStore.js.map +7 -0
  263. package/dist/modules/ecommerce/lib/storeBindingCascade.js +109 -0
  264. package/dist/modules/ecommerce/lib/storeBindingCascade.js.map +7 -0
  265. package/dist/modules/ecommerce/lib/storeBranding.js +40 -0
  266. package/dist/modules/ecommerce/lib/storeBranding.js.map +7 -0
  267. package/dist/modules/ecommerce/lib/storeBrandingRoute.js +76 -0
  268. package/dist/modules/ecommerce/lib/storeBrandingRoute.js.map +7 -0
  269. package/dist/modules/ecommerce/lib/storeContext.js +393 -0
  270. package/dist/modules/ecommerce/lib/storeContext.js.map +7 -0
  271. package/dist/modules/ecommerce/lib/storeContextService.js +43 -0
  272. package/dist/modules/ecommerce/lib/storeContextService.js.map +7 -0
  273. package/dist/modules/ecommerce/lib/storeLocale.js +60 -0
  274. package/dist/modules/ecommerce/lib/storeLocale.js.map +7 -0
  275. package/dist/modules/ecommerce/lib/storeNotifications.js +41 -0
  276. package/dist/modules/ecommerce/lib/storeNotifications.js.map +7 -0
  277. package/dist/modules/ecommerce/lib/storefrontCatalogSupport.js +248 -0
  278. package/dist/modules/ecommerce/lib/storefrontCatalogSupport.js.map +7 -0
  279. package/dist/modules/ecommerce/lib/storefrontCategories.js +241 -0
  280. package/dist/modules/ecommerce/lib/storefrontCategories.js.map +7 -0
  281. package/dist/modules/ecommerce/lib/storefrontCategoryCache.js +71 -0
  282. package/dist/modules/ecommerce/lib/storefrontCategoryCache.js.map +7 -0
  283. package/dist/modules/ecommerce/lib/storefrontDetail.js +447 -0
  284. package/dist/modules/ecommerce/lib/storefrontDetail.js.map +7 -0
  285. package/dist/modules/ecommerce/lib/storefrontFacets.js +441 -0
  286. package/dist/modules/ecommerce/lib/storefrontFacets.js.map +7 -0
  287. package/dist/modules/ecommerce/lib/storefrontOptionFilter.js +15 -0
  288. package/dist/modules/ecommerce/lib/storefrontOptionFilter.js.map +7 -0
  289. package/dist/modules/ecommerce/lib/storefrontPricing.js +393 -0
  290. package/dist/modules/ecommerce/lib/storefrontPricing.js.map +7 -0
  291. package/dist/modules/ecommerce/lib/storefrontProductCache.js +90 -0
  292. package/dist/modules/ecommerce/lib/storefrontProductCache.js.map +7 -0
  293. package/dist/modules/ecommerce/lib/storefrontProductScope.js +107 -0
  294. package/dist/modules/ecommerce/lib/storefrontProductScope.js.map +7 -0
  295. package/dist/modules/ecommerce/lib/storefrontProducts.js +670 -0
  296. package/dist/modules/ecommerce/lib/storefrontProducts.js.map +7 -0
  297. package/dist/modules/ecommerce/lib/storefrontQuery.js +156 -0
  298. package/dist/modules/ecommerce/lib/storefrontQuery.js.map +7 -0
  299. package/dist/modules/ecommerce/lib/storefrontRateLimit.js +99 -0
  300. package/dist/modules/ecommerce/lib/storefrontRateLimit.js.map +7 -0
  301. package/dist/modules/ecommerce/lib/storefrontSearch.js +303 -0
  302. package/dist/modules/ecommerce/lib/storefrontSearch.js.map +7 -0
  303. package/dist/modules/ecommerce/lib/storefrontSearchCache.js +35 -0
  304. package/dist/modules/ecommerce/lib/storefrontSearchCache.js.map +7 -0
  305. package/dist/modules/ecommerce/lib/subscriberSupport.js +33 -0
  306. package/dist/modules/ecommerce/lib/subscriberSupport.js.map +7 -0
  307. package/dist/modules/ecommerce/lib/types.js +1 -0
  308. package/dist/modules/ecommerce/lib/types.js.map +7 -0
  309. package/dist/modules/ecommerce/migrations/Migration20261005113233_ecommerce.js +32 -0
  310. package/dist/modules/ecommerce/migrations/Migration20261005113233_ecommerce.js.map +7 -0
  311. package/dist/modules/ecommerce/migrations/Migration20261006112733_ecommerce.js +17 -0
  312. package/dist/modules/ecommerce/migrations/Migration20261006112733_ecommerce.js.map +7 -0
  313. package/dist/modules/ecommerce/notifications.client.js +47 -0
  314. package/dist/modules/ecommerce/notifications.client.js.map +7 -0
  315. package/dist/modules/ecommerce/notifications.js +48 -0
  316. package/dist/modules/ecommerce/notifications.js.map +7 -0
  317. package/dist/modules/ecommerce/search.js +83 -0
  318. package/dist/modules/ecommerce/search.js.map +7 -0
  319. package/dist/modules/ecommerce/setup.js +17 -0
  320. package/dist/modules/ecommerce/setup.js.map +7 -0
  321. package/dist/modules/ecommerce/subscribers/assortment-empty-notifications.js +14 -0
  322. package/dist/modules/ecommerce/subscribers/assortment-empty-notifications.js.map +7 -0
  323. package/dist/modules/ecommerce/subscribers/availability-policy-cache-invalidation.js +14 -0
  324. package/dist/modules/ecommerce/subscribers/availability-policy-cache-invalidation.js.map +7 -0
  325. package/dist/modules/ecommerce/subscribers/catalog-category-cache-invalidation.js +14 -0
  326. package/dist/modules/ecommerce/subscribers/catalog-category-cache-invalidation.js.map +7 -0
  327. package/dist/modules/ecommerce/subscribers/catalog-price-cache-invalidation.js +14 -0
  328. package/dist/modules/ecommerce/subscribers/catalog-price-cache-invalidation.js.map +7 -0
  329. package/dist/modules/ecommerce/subscribers/catalog-product-cache-invalidation.js +14 -0
  330. package/dist/modules/ecommerce/subscribers/catalog-product-cache-invalidation.js.map +7 -0
  331. package/dist/modules/ecommerce/subscribers/catalog-variant-cache-invalidation.js +14 -0
  332. package/dist/modules/ecommerce/subscribers/catalog-variant-cache-invalidation.js.map +7 -0
  333. package/dist/modules/ecommerce/subscribers/customer-group-cache-invalidation.js +14 -0
  334. package/dist/modules/ecommerce/subscribers/customer-group-cache-invalidation.js.map +7 -0
  335. package/dist/modules/ecommerce/subscribers/customer-group-membership-cache-invalidation.js +14 -0
  336. package/dist/modules/ecommerce/subscribers/customer-group-membership-cache-invalidation.js.map +7 -0
  337. package/dist/modules/ecommerce/subscribers/customer-group-terms-cache-invalidation.js +14 -0
  338. package/dist/modules/ecommerce/subscribers/customer-group-terms-cache-invalidation.js.map +7 -0
  339. package/dist/modules/ecommerce/subscribers/customer-user-deleted-cache-invalidation.js +14 -0
  340. package/dist/modules/ecommerce/subscribers/customer-user-deleted-cache-invalidation.js.map +7 -0
  341. package/dist/modules/ecommerce/subscribers/customer-user-updated-cache-invalidation.js +14 -0
  342. package/dist/modules/ecommerce/subscribers/customer-user-updated-cache-invalidation.js.map +7 -0
  343. package/dist/modules/ecommerce/subscribers/domain-binding-rebind.js +16 -0
  344. package/dist/modules/ecommerce/subscribers/domain-binding-rebind.js.map +7 -0
  345. package/dist/modules/ecommerce/subscribers/domain-mapping-cache-invalidation.js +14 -0
  346. package/dist/modules/ecommerce/subscribers/domain-mapping-cache-invalidation.js.map +7 -0
  347. package/dist/modules/ecommerce/subscribers/store-cache-invalidation.js +14 -0
  348. package/dist/modules/ecommerce/subscribers/store-cache-invalidation.js.map +7 -0
  349. package/dist/modules/ecommerce/subscribers/store-channel-binding-cache-invalidation.js +14 -0
  350. package/dist/modules/ecommerce/subscribers/store-channel-binding-cache-invalidation.js.map +7 -0
  351. package/dist/modules/ecommerce/subscribers/store-domain-binding-cache-invalidation.js +14 -0
  352. package/dist/modules/ecommerce/subscribers/store-domain-binding-cache-invalidation.js.map +7 -0
  353. package/dist/modules/ecommerce/subscribers/store-notifications.js +14 -0
  354. package/dist/modules/ecommerce/subscribers/store-notifications.js.map +7 -0
  355. package/dist/modules/query_index/lib/batch.js +23 -9
  356. package/dist/modules/query_index/lib/batch.js.map +2 -2
  357. package/dist/modules/query_index/lib/doc-enrichers.js +212 -0
  358. package/dist/modules/query_index/lib/doc-enrichers.js.map +7 -0
  359. package/dist/modules/query_index/lib/document.js +2 -0
  360. package/dist/modules/query_index/lib/document.js.map +2 -2
  361. package/dist/modules/query_index/lib/engine.js +68 -1
  362. package/dist/modules/query_index/lib/engine.js.map +2 -2
  363. package/dist/modules/query_index/lib/indexer.js +7 -0
  364. package/dist/modules/query_index/lib/indexer.js.map +2 -2
  365. package/dist/modules/query_index/lib/search-tokens.js +2 -0
  366. package/dist/modules/query_index/lib/search-tokens.js.map +2 -2
  367. package/dist/modules/query_index/migrations/Migration20261005201500_query_index.js +17 -0
  368. package/dist/modules/query_index/migrations/Migration20261005201500_query_index.js.map +7 -0
  369. package/dist/modules/translations/components/TranslationManager.js +3 -3
  370. package/dist/modules/translations/components/TranslationManager.js.map +2 -2
  371. package/dist/modules/translations/data/validators.js +1 -1
  372. package/dist/modules/translations/data/validators.js.map +1 -1
  373. package/dist/modules/translations/lib/batch.js +21 -1
  374. package/dist/modules/translations/lib/batch.js.map +2 -2
  375. package/dist/modules/translations/lib/helpers.js +3 -0
  376. package/dist/modules/translations/lib/helpers.js.map +2 -2
  377. package/dist/modules/translations/lib/resolve-field-list.js +14 -2
  378. package/dist/modules/translations/lib/resolve-field-list.js.map +2 -2
  379. package/generated/entities/catalog_price_history_entry/index.ts +25 -0
  380. package/generated/entities/customer_group_terms/index.ts +1 -0
  381. package/generated/entities/ecommerce_store/index.ts +15 -0
  382. package/generated/entities/ecommerce_store_channel_binding/index.ts +13 -0
  383. package/generated/entities/ecommerce_store_domain_binding/index.ts +10 -0
  384. package/generated/entities.ids.generated.ts +8 -1
  385. package/generated/entity-fields-registry.ts +72 -0
  386. package/package.json +7 -7
  387. package/src/helpers/integration/customerGroupsFixtures.ts +2 -0
  388. package/src/modules/auth/i18n/de.json +8 -0
  389. package/src/modules/auth/i18n/en.json +8 -0
  390. package/src/modules/auth/i18n/es.json +8 -0
  391. package/src/modules/auth/i18n/ko.json +8 -0
  392. package/src/modules/auth/i18n/pl.json +8 -0
  393. package/src/modules/catalog/AGENTS.md +5 -2
  394. package/src/modules/catalog/acl.ts +7 -0
  395. package/src/modules/catalog/api/config/omnibus/route.ts +204 -0
  396. package/src/modules/catalog/api/prices/history/route.ts +139 -0
  397. package/src/modules/catalog/api/prices/omnibus-preview/route.ts +202 -0
  398. package/src/modules/catalog/api/products/route.ts +53 -308
  399. package/src/modules/catalog/api/tags/route.ts +6 -0
  400. package/src/modules/catalog/backend/config/catalog/page.tsx +2 -0
  401. package/src/modules/catalog/cli.ts +84 -1
  402. package/src/modules/catalog/commands/categories.ts +54 -2
  403. package/src/modules/catalog/commands/prices.ts +43 -1
  404. package/src/modules/catalog/commands/products.ts +84 -1
  405. package/src/modules/catalog/commands/variants.ts +7 -0
  406. package/src/modules/catalog/components/OmnibusSettings.tsx +832 -0
  407. package/src/modules/catalog/components/PriceEditorOmnibusRow.tsx +219 -0
  408. package/src/modules/catalog/components/lookupSources.ts +29 -0
  409. package/src/modules/catalog/components/prices/PriceScopeSelectors.tsx +9 -0
  410. package/src/modules/catalog/components/products/VariantBuilder.tsx +9 -0
  411. package/src/modules/catalog/data/entities.ts +123 -1
  412. package/src/modules/catalog/data/validators.ts +118 -0
  413. package/src/modules/catalog/di.ts +23 -0
  414. package/src/modules/catalog/i18n/de.json +77 -0
  415. package/src/modules/catalog/i18n/en.json +77 -0
  416. package/src/modules/catalog/i18n/es.json +77 -0
  417. package/src/modules/catalog/i18n/ko.json +77 -0
  418. package/src/modules/catalog/i18n/pl.json +77 -0
  419. package/src/modules/catalog/lib/omnibus.ts +406 -0
  420. package/src/modules/catalog/lib/omnibusBackfill.ts +198 -0
  421. package/src/modules/catalog/lib/omnibusCache.ts +111 -0
  422. package/src/modules/catalog/lib/omnibusConfig.ts +73 -0
  423. package/src/modules/catalog/lib/omnibusHistoryQueries.ts +248 -0
  424. package/src/modules/catalog/lib/omnibusPresentedEntry.ts +76 -0
  425. package/src/modules/catalog/lib/omnibusProductListEnrichment.ts +125 -0
  426. package/src/modules/catalog/lib/omnibusTypes.ts +202 -0
  427. package/src/modules/catalog/lib/optionSchemaTranslations.ts +55 -0
  428. package/src/modules/catalog/lib/priceHistoryQuery.ts +155 -0
  429. package/src/modules/catalog/lib/pricing.ts +42 -4
  430. package/src/modules/catalog/lib/productFilters.ts +349 -0
  431. package/src/modules/catalog/lib/productScopeKeys.ts +162 -0
  432. package/src/modules/catalog/lib/productScopeReindex.ts +139 -0
  433. package/src/modules/catalog/migrations/.snapshot-open-mercato.json +572 -0
  434. package/src/modules/catalog/migrations/Migration20261005105352_catalog.ts +39 -0
  435. package/src/modules/catalog/migrations/Migration20261005150824_catalog.ts +39 -0
  436. package/src/modules/catalog/services/catalogOmnibusService.ts +642 -0
  437. package/src/modules/catalog/setup.ts +2 -0
  438. package/src/modules/catalog/subscribers/product-scope-keys-category-deleted.ts +18 -0
  439. package/src/modules/catalog/subscribers/product-scope-keys-category-updated.ts +19 -0
  440. package/src/modules/catalog/translations.ts +12 -0
  441. package/src/modules/configs/i18n/de.json +5 -1
  442. package/src/modules/configs/i18n/en.json +5 -1
  443. package/src/modules/configs/i18n/es.json +5 -1
  444. package/src/modules/configs/i18n/ko.json +5 -1
  445. package/src/modules/configs/i18n/pl.json +5 -1
  446. package/src/modules/configs/lib/upgrade-actions.ts +35 -0
  447. package/src/modules/customer_groups/api/customer-groups/[id]/terms/route.ts +7 -0
  448. package/src/modules/customer_groups/components/CustomerGroupTermsSection.tsx +124 -2
  449. package/src/modules/customer_groups/components/customerGroupAssortmentScope.ts +46 -0
  450. package/src/modules/customer_groups/data/entities.ts +4 -0
  451. package/src/modules/customer_groups/data/validators.ts +14 -0
  452. package/src/modules/customer_groups/i18n/de.json +12 -0
  453. package/src/modules/customer_groups/i18n/en.json +12 -0
  454. package/src/modules/customer_groups/i18n/es.json +12 -0
  455. package/src/modules/customer_groups/i18n/ko.json +12 -0
  456. package/src/modules/customer_groups/i18n/pl.json +12 -0
  457. package/src/modules/customer_groups/migrations/.snapshot-open-mercato.json +17 -0
  458. package/src/modules/customer_groups/migrations/Migration20261005110250_customer_groups.ts +15 -0
  459. package/src/modules/customer_groups/services/customerGroupsService.ts +74 -23
  460. package/src/modules/ecommerce/acl.ts +9 -0
  461. package/src/modules/ecommerce/api/domain-mappings/route.ts +76 -0
  462. package/src/modules/ecommerce/api/openapi.ts +28 -0
  463. package/src/modules/ecommerce/api/store-channel-bindings/[id]/assortment-count/route.ts +141 -0
  464. package/src/modules/ecommerce/api/store-channel-bindings/crud.ts +283 -0
  465. package/src/modules/ecommerce/api/store-channel-bindings/route.ts +67 -0
  466. package/src/modules/ecommerce/api/store-domain-bindings/crud.ts +324 -0
  467. package/src/modules/ecommerce/api/store-domain-bindings/route.ts +73 -0
  468. package/src/modules/ecommerce/api/storefront/categories/[slug]/route.ts +94 -0
  469. package/src/modules/ecommerce/api/storefront/categories/openapiSchemas.ts +63 -0
  470. package/src/modules/ecommerce/api/storefront/categories/route.ts +78 -0
  471. package/src/modules/ecommerce/api/storefront/context/route.ts +203 -0
  472. package/src/modules/ecommerce/api/storefront/products/[idOrHandle]/route.ts +94 -0
  473. package/src/modules/ecommerce/api/storefront/products/openapiSchemas.ts +193 -0
  474. package/src/modules/ecommerce/api/storefront/products/route.ts +81 -0
  475. package/src/modules/ecommerce/api/storefront/search/suggest/openapiSchemas.ts +25 -0
  476. package/src/modules/ecommerce/api/storefront/search/suggest/route.ts +78 -0
  477. package/src/modules/ecommerce/api/storefront/storefrontRouteSupport.ts +68 -0
  478. package/src/modules/ecommerce/api/stores/[id]/branding/route.ts +205 -0
  479. package/src/modules/ecommerce/api/stores/[id]/preview-branding/route.ts +99 -0
  480. package/src/modules/ecommerce/api/stores/crud.ts +457 -0
  481. package/src/modules/ecommerce/api/stores/route.ts +66 -0
  482. package/src/modules/ecommerce/backend/config/ecommerce/[id]/page.meta.ts +12 -0
  483. package/src/modules/ecommerce/backend/config/ecommerce/[id]/page.tsx +5 -0
  484. package/src/modules/ecommerce/backend/config/ecommerce/page.meta.ts +12 -0
  485. package/src/modules/ecommerce/backend/config/ecommerce/page.tsx +5 -0
  486. package/src/modules/ecommerce/commands/stores.ts +154 -0
  487. package/src/modules/ecommerce/components/ChannelAssortmentCount.tsx +138 -0
  488. package/src/modules/ecommerce/components/ChannelBindingFormSections.tsx +40 -0
  489. package/src/modules/ecommerce/components/ChannelLookupPicker.tsx +5 -0
  490. package/src/modules/ecommerce/components/DomainStatusWarning.tsx +32 -0
  491. package/src/modules/ecommerce/components/StoreAvailabilityDefaultsSection.tsx +219 -0
  492. package/src/modules/ecommerce/components/StoreBrandingControls.tsx +73 -0
  493. package/src/modules/ecommerce/components/StoreBrandingPreview.tsx +77 -0
  494. package/src/modules/ecommerce/components/StoreBrandingTab.tsx +242 -0
  495. package/src/modules/ecommerce/components/StoreChannelBindingDialog.tsx +306 -0
  496. package/src/modules/ecommerce/components/StoreChannelsTab.tsx +375 -0
  497. package/src/modules/ecommerce/components/StoreCreateDialog.tsx +204 -0
  498. package/src/modules/ecommerce/components/StoreDomainBindingDialog.tsx +198 -0
  499. package/src/modules/ecommerce/components/StoreDomainsTab.tsx +426 -0
  500. package/src/modules/ecommerce/components/StoreEditPage.tsx +193 -0
  501. package/src/modules/ecommerce/components/StoreGeneralTab.tsx +189 -0
  502. package/src/modules/ecommerce/components/StoreListPage.tsx +326 -0
  503. package/src/modules/ecommerce/components/StoreSeoTab.tsx +152 -0
  504. package/src/modules/ecommerce/components/StoreStatusBadge.tsx +22 -0
  505. package/src/modules/ecommerce/components/channelLookups.ts +24 -0
  506. package/src/modules/ecommerce/components/storeAdmin.ts +56 -0
  507. package/src/modules/ecommerce/components/storeBrandingForm.ts +230 -0
  508. package/src/modules/ecommerce/components/storeChannels.ts +210 -0
  509. package/src/modules/ecommerce/components/storeDomains.ts +221 -0
  510. package/src/modules/ecommerce/components/storeEditTabs.tsx +76 -0
  511. package/src/modules/ecommerce/components/storeGeneral.ts +155 -0
  512. package/src/modules/ecommerce/components/storeSeo.ts +78 -0
  513. package/src/modules/ecommerce/components/useChannelAssortmentCount.ts +67 -0
  514. package/src/modules/ecommerce/components/useStoreAccess.ts +36 -0
  515. package/src/modules/ecommerce/data/enrichers.ts +213 -0
  516. package/src/modules/ecommerce/data/entities.ts +168 -0
  517. package/src/modules/ecommerce/data/validators.ts +587 -0
  518. package/src/modules/ecommerce/di.ts +9 -0
  519. package/src/modules/ecommerce/events.ts +27 -0
  520. package/src/modules/ecommerce/i18n/de.json +341 -0
  521. package/src/modules/ecommerce/i18n/en.json +341 -0
  522. package/src/modules/ecommerce/i18n/es.json +341 -0
  523. package/src/modules/ecommerce/i18n/ko.json +341 -0
  524. package/src/modules/ecommerce/i18n/pl.json +341 -0
  525. package/src/modules/ecommerce/index.ts +14 -0
  526. package/src/modules/ecommerce/lib/assortmentCount.ts +175 -0
  527. package/src/modules/ecommerce/lib/brandingStyles.ts +215 -0
  528. package/src/modules/ecommerce/lib/buyerContext.ts +401 -0
  529. package/src/modules/ecommerce/lib/cacheInvalidation.ts +302 -0
  530. package/src/modules/ecommerce/lib/cacheKeys.ts +340 -0
  531. package/src/modules/ecommerce/lib/createConflictRecheck.ts +31 -0
  532. package/src/modules/ecommerce/lib/crudEvents.ts +128 -0
  533. package/src/modules/ecommerce/lib/crudSupport.ts +85 -0
  534. package/src/modules/ecommerce/lib/domainBindingRebind.ts +138 -0
  535. package/src/modules/ecommerce/lib/domainMappingSummaries.ts +71 -0
  536. package/src/modules/ecommerce/lib/exclusiveFlag.ts +90 -0
  537. package/src/modules/ecommerce/lib/references.ts +93 -0
  538. package/src/modules/ecommerce/lib/seedDraftStore.ts +125 -0
  539. package/src/modules/ecommerce/lib/storeBindingCascade.ts +138 -0
  540. package/src/modules/ecommerce/lib/storeBranding.ts +48 -0
  541. package/src/modules/ecommerce/lib/storeBrandingRoute.ts +91 -0
  542. package/src/modules/ecommerce/lib/storeContext.ts +669 -0
  543. package/src/modules/ecommerce/lib/storeContextService.ts +71 -0
  544. package/src/modules/ecommerce/lib/storeLocale.ts +88 -0
  545. package/src/modules/ecommerce/lib/storeNotifications.ts +55 -0
  546. package/src/modules/ecommerce/lib/storefrontCatalogSupport.ts +427 -0
  547. package/src/modules/ecommerce/lib/storefrontCategories.ts +419 -0
  548. package/src/modules/ecommerce/lib/storefrontCategoryCache.ts +113 -0
  549. package/src/modules/ecommerce/lib/storefrontDetail.ts +654 -0
  550. package/src/modules/ecommerce/lib/storefrontFacets.ts +697 -0
  551. package/src/modules/ecommerce/lib/storefrontOptionFilter.ts +44 -0
  552. package/src/modules/ecommerce/lib/storefrontPricing.ts +583 -0
  553. package/src/modules/ecommerce/lib/storefrontProductCache.ts +126 -0
  554. package/src/modules/ecommerce/lib/storefrontProductScope.ts +181 -0
  555. package/src/modules/ecommerce/lib/storefrontProducts.ts +963 -0
  556. package/src/modules/ecommerce/lib/storefrontQuery.ts +215 -0
  557. package/src/modules/ecommerce/lib/storefrontRateLimit.ts +126 -0
  558. package/src/modules/ecommerce/lib/storefrontSearch.ts +454 -0
  559. package/src/modules/ecommerce/lib/storefrontSearchCache.ts +49 -0
  560. package/src/modules/ecommerce/lib/subscriberSupport.ts +41 -0
  561. package/src/modules/ecommerce/lib/types.ts +69 -0
  562. package/src/modules/ecommerce/migrations/.snapshot-open-mercato.json +829 -0
  563. package/src/modules/ecommerce/migrations/Migration20261005113233_ecommerce.ts +32 -0
  564. package/src/modules/ecommerce/migrations/Migration20261006112733_ecommerce.ts +15 -0
  565. package/src/modules/ecommerce/notifications.client.ts +46 -0
  566. package/src/modules/ecommerce/notifications.ts +46 -0
  567. package/src/modules/ecommerce/search.ts +93 -0
  568. package/src/modules/ecommerce/setup.ts +15 -0
  569. package/src/modules/ecommerce/subscribers/assortment-empty-notifications.ts +12 -0
  570. package/src/modules/ecommerce/subscribers/availability-policy-cache-invalidation.ts +12 -0
  571. package/src/modules/ecommerce/subscribers/catalog-category-cache-invalidation.ts +12 -0
  572. package/src/modules/ecommerce/subscribers/catalog-price-cache-invalidation.ts +12 -0
  573. package/src/modules/ecommerce/subscribers/catalog-product-cache-invalidation.ts +12 -0
  574. package/src/modules/ecommerce/subscribers/catalog-variant-cache-invalidation.ts +12 -0
  575. package/src/modules/ecommerce/subscribers/customer-group-cache-invalidation.ts +12 -0
  576. package/src/modules/ecommerce/subscribers/customer-group-membership-cache-invalidation.ts +12 -0
  577. package/src/modules/ecommerce/subscribers/customer-group-terms-cache-invalidation.ts +12 -0
  578. package/src/modules/ecommerce/subscribers/customer-user-deleted-cache-invalidation.ts +12 -0
  579. package/src/modules/ecommerce/subscribers/customer-user-updated-cache-invalidation.ts +12 -0
  580. package/src/modules/ecommerce/subscribers/domain-binding-rebind.ts +14 -0
  581. package/src/modules/ecommerce/subscribers/domain-mapping-cache-invalidation.ts +12 -0
  582. package/src/modules/ecommerce/subscribers/store-cache-invalidation.ts +12 -0
  583. package/src/modules/ecommerce/subscribers/store-channel-binding-cache-invalidation.ts +12 -0
  584. package/src/modules/ecommerce/subscribers/store-domain-binding-cache-invalidation.ts +12 -0
  585. package/src/modules/ecommerce/subscribers/store-notifications.ts +12 -0
  586. package/src/modules/query_index/lib/batch.ts +25 -9
  587. package/src/modules/query_index/lib/doc-enrichers.ts +306 -0
  588. package/src/modules/query_index/lib/document.ts +2 -0
  589. package/src/modules/query_index/lib/engine.ts +58 -1
  590. package/src/modules/query_index/lib/indexer.ts +8 -0
  591. package/src/modules/query_index/lib/search-tokens.ts +2 -0
  592. package/src/modules/query_index/migrations/Migration20261005201500_query_index.ts +42 -0
  593. package/src/modules/translations/components/TranslationManager.tsx +3 -3
  594. package/src/modules/translations/data/validators.ts +1 -1
  595. package/src/modules/translations/lib/batch.ts +47 -0
  596. package/src/modules/translations/lib/helpers.ts +4 -0
  597. package/src/modules/translations/lib/resolve-field-list.ts +16 -2
@@ -0,0 +1,16 @@
1
+ const metadata = {
2
+ requireAuth: true,
3
+ requireFeatures: ["ecommerce.stores.view"],
4
+ pageTitle: "Stores",
5
+ pageTitleKey: "ecommerce.module.title",
6
+ pageGroup: "Module Configs",
7
+ pageGroupKey: "settings.sections.moduleConfigs",
8
+ pageOrder: 25,
9
+ pageContext: "settings",
10
+ icon: "store",
11
+ breadcrumb: [{ label: "Stores", labelKey: "ecommerce.module.title" }]
12
+ };
13
+ export {
14
+ metadata
15
+ };
16
+ //# sourceMappingURL=page.meta.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../../../src/modules/ecommerce/backend/config/ecommerce/page.meta.ts"],
4
+ "sourcesContent": ["export const metadata = {\n requireAuth: true,\n requireFeatures: ['ecommerce.stores.view'],\n pageTitle: 'Stores',\n pageTitleKey: 'ecommerce.module.title',\n pageGroup: 'Module Configs',\n pageGroupKey: 'settings.sections.moduleConfigs',\n pageOrder: 25,\n pageContext: 'settings' as const,\n icon: 'store',\n breadcrumb: [{ label: 'Stores', labelKey: 'ecommerce.module.title' }],\n} as const\n"],
5
+ "mappings": "AAAO,MAAM,WAAW;AAAA,EACtB,aAAa;AAAA,EACb,iBAAiB,CAAC,uBAAuB;AAAA,EACzC,WAAW;AAAA,EACX,cAAc;AAAA,EACd,WAAW;AAAA,EACX,cAAc;AAAA,EACd,WAAW;AAAA,EACX,aAAa;AAAA,EACb,MAAM;AAAA,EACN,YAAY,CAAC,EAAE,OAAO,UAAU,UAAU,yBAAyB,CAAC;AACtE;",
6
+ "names": []
7
+ }
@@ -0,0 +1,110 @@
1
+ import { registerCommand } from "@open-mercato/shared/lib/commands";
2
+ import { buildChanges } from "@open-mercato/shared/lib/commands/helpers";
3
+ import { ensureOrganizationScope, ensureTenantScope } from "@open-mercato/shared/lib/commands/scope";
4
+ import { extractUndoPayload } from "@open-mercato/shared/lib/commands/undo";
5
+ import { CrudHttpError } from "@open-mercato/shared/lib/crud/errors";
6
+ import { enforceCommandOptimisticLockWithGuards } from "@open-mercato/shared/lib/crud/optimistic-lock-command";
7
+ import { findOneWithDecryption } from "@open-mercato/shared/lib/encryption/find";
8
+ import { resolveTranslations } from "@open-mercato/shared/lib/i18n/server";
9
+ import { EcommerceStore } from "../data/entities.js";
10
+ import { ecommerceStoreBrandingSchema } from "../data/validators.js";
11
+ import { announceStoreBrandingUpdated } from "../lib/crudEvents.js";
12
+ import {
13
+ compactBranding,
14
+ mergeBrandingIntoSettings,
15
+ STORE_BRANDING_RESOURCE_KIND,
16
+ STORE_BRANDING_UPDATE_COMMAND_ID
17
+ } from "../lib/storeBranding.js";
18
+ const BRANDING_CHANGE_KEYS = ["branding"];
19
+ async function loadStore(em, scope) {
20
+ return findOneWithDecryption(
21
+ em,
22
+ EcommerceStore,
23
+ { id: scope.id, tenantId: scope.tenantId, organizationId: scope.organizationId, deletedAt: null },
24
+ void 0,
25
+ { tenantId: scope.tenantId, organizationId: scope.organizationId }
26
+ );
27
+ }
28
+ function toSnapshot(store) {
29
+ return {
30
+ id: store.id,
31
+ tenantId: store.tenantId,
32
+ organizationId: store.organizationId,
33
+ branding: compactBranding(store.settings?.branding ?? {}),
34
+ updatedAt: store.updatedAt.toISOString()
35
+ };
36
+ }
37
+ async function loadSnapshot(ctx, scope) {
38
+ const em = ctx.container.resolve("em").fork();
39
+ const store = await loadStore(em, scope);
40
+ return store ? toSnapshot(store) : null;
41
+ }
42
+ const updateStoreBrandingCommand = {
43
+ id: STORE_BRANDING_UPDATE_COMMAND_ID,
44
+ async prepare(input, ctx) {
45
+ ensureTenantScope(ctx, input.tenantId);
46
+ ensureOrganizationScope(ctx, input.organizationId);
47
+ const snapshot = await loadSnapshot(ctx, input);
48
+ return snapshot ? { before: snapshot } : {};
49
+ },
50
+ async execute(input, ctx) {
51
+ ensureTenantScope(ctx, input.tenantId);
52
+ ensureOrganizationScope(ctx, input.organizationId);
53
+ const branding = compactBranding(ecommerceStoreBrandingSchema.parse(input.branding));
54
+ const em = ctx.container.resolve("em").fork();
55
+ const store = await loadStore(em, input);
56
+ if (!store) {
57
+ const { translate } = await resolveTranslations();
58
+ throw new CrudHttpError(404, {
59
+ error: translate("ecommerce.errors.storeNotFound", "The selected store does not exist in this organization.")
60
+ });
61
+ }
62
+ await enforceCommandOptimisticLockWithGuards(ctx.container, {
63
+ resourceKind: STORE_BRANDING_RESOURCE_KIND,
64
+ resourceId: store.id,
65
+ current: store.updatedAt,
66
+ request: ctx.request
67
+ });
68
+ store.settings = mergeBrandingIntoSettings(store.settings, branding);
69
+ await em.flush();
70
+ await announceStoreBrandingUpdated(ctx.container, store);
71
+ return { id: store.id, updatedAt: store.updatedAt.toISOString(), branding };
72
+ },
73
+ async captureAfter(input, _result, ctx) {
74
+ return loadSnapshot(ctx, input);
75
+ },
76
+ async buildLog({ snapshots, input }) {
77
+ const before = snapshots.before;
78
+ const after = snapshots.after;
79
+ if (!before || !after) return null;
80
+ const { translate } = await resolveTranslations();
81
+ return {
82
+ actionLabel: translate("ecommerce.audit.stores.branding.update", "Update store branding"),
83
+ resourceKind: STORE_BRANDING_RESOURCE_KIND,
84
+ resourceId: before.id,
85
+ tenantId: input.tenantId,
86
+ organizationId: input.organizationId,
87
+ snapshotBefore: before,
88
+ snapshotAfter: after,
89
+ changes: buildChanges(before, after, BRANDING_CHANGE_KEYS),
90
+ payload: {
91
+ undo: { before, after }
92
+ }
93
+ };
94
+ },
95
+ async undo({ logEntry, ctx }) {
96
+ const payload = extractUndoPayload(logEntry);
97
+ const before = payload?.before;
98
+ if (!before) return;
99
+ ensureTenantScope(ctx, before.tenantId);
100
+ ensureOrganizationScope(ctx, before.organizationId);
101
+ const em = ctx.container.resolve("em").fork();
102
+ const store = await loadStore(em, before);
103
+ if (!store) return;
104
+ store.settings = mergeBrandingIntoSettings(store.settings, before.branding);
105
+ await em.flush();
106
+ await announceStoreBrandingUpdated(ctx.container, store);
107
+ }
108
+ };
109
+ registerCommand(updateStoreBrandingCommand);
110
+ //# sourceMappingURL=stores.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../src/modules/ecommerce/commands/stores.ts"],
4
+ "sourcesContent": ["import type { EntityManager } from '@mikro-orm/postgresql'\nimport { registerCommand } from '@open-mercato/shared/lib/commands'\nimport type { CommandHandler } from '@open-mercato/shared/lib/commands'\nimport { buildChanges } from '@open-mercato/shared/lib/commands/helpers'\nimport { ensureOrganizationScope, ensureTenantScope } from '@open-mercato/shared/lib/commands/scope'\nimport { extractUndoPayload } from '@open-mercato/shared/lib/commands/undo'\nimport { CrudHttpError } from '@open-mercato/shared/lib/crud/errors'\nimport { enforceCommandOptimisticLockWithGuards } from '@open-mercato/shared/lib/crud/optimistic-lock-command'\nimport { findOneWithDecryption } from '@open-mercato/shared/lib/encryption/find'\nimport { resolveTranslations } from '@open-mercato/shared/lib/i18n/server'\nimport { EcommerceStore } from '../data/entities'\nimport { ecommerceStoreBrandingSchema, type EcommerceStoreBranding } from '../data/validators'\nimport { announceStoreBrandingUpdated } from '../lib/crudEvents'\nimport {\n compactBranding,\n mergeBrandingIntoSettings,\n STORE_BRANDING_RESOURCE_KIND,\n STORE_BRANDING_UPDATE_COMMAND_ID,\n} from '../lib/storeBranding'\n\nexport type StoreBrandingUpdateInput = {\n id: string\n tenantId: string\n organizationId: string\n branding: EcommerceStoreBranding\n}\n\nexport type StoreBrandingUpdateResult = {\n id: string\n updatedAt: string\n branding: EcommerceStoreBranding\n}\n\ntype StoreBrandingSnapshot = {\n id: string\n tenantId: string\n organizationId: string\n branding: EcommerceStoreBranding\n updatedAt: string\n}\n\ntype StoreBrandingUndoPayload = {\n before?: StoreBrandingSnapshot | null\n after?: StoreBrandingSnapshot | null\n}\n\nconst BRANDING_CHANGE_KEYS = ['branding'] as const\n\nasync function loadStore(\n em: EntityManager,\n scope: { id: string; tenantId: string; organizationId: string },\n): Promise<EcommerceStore | null> {\n return findOneWithDecryption(\n em,\n EcommerceStore,\n { id: scope.id, tenantId: scope.tenantId, organizationId: scope.organizationId, deletedAt: null },\n undefined,\n { tenantId: scope.tenantId, organizationId: scope.organizationId },\n )\n}\n\nfunction toSnapshot(store: EcommerceStore): StoreBrandingSnapshot {\n return {\n id: store.id,\n tenantId: store.tenantId,\n organizationId: store.organizationId,\n branding: compactBranding(store.settings?.branding ?? {}),\n updatedAt: store.updatedAt.toISOString(),\n }\n}\n\nasync function loadSnapshot(\n ctx: { container: { resolve: (name: string) => unknown } },\n scope: { id: string; tenantId: string; organizationId: string },\n): Promise<StoreBrandingSnapshot | null> {\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n const store = await loadStore(em, scope)\n return store ? toSnapshot(store) : null\n}\n\nconst updateStoreBrandingCommand: CommandHandler<StoreBrandingUpdateInput, StoreBrandingUpdateResult> = {\n id: STORE_BRANDING_UPDATE_COMMAND_ID,\n\n async prepare(input, ctx) {\n ensureTenantScope(ctx, input.tenantId)\n ensureOrganizationScope(ctx, input.organizationId)\n const snapshot = await loadSnapshot(ctx, input)\n return snapshot ? { before: snapshot } : {}\n },\n\n async execute(input, ctx) {\n ensureTenantScope(ctx, input.tenantId)\n ensureOrganizationScope(ctx, input.organizationId)\n const branding = compactBranding(ecommerceStoreBrandingSchema.parse(input.branding))\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n const store = await loadStore(em, input)\n if (!store) {\n const { translate } = await resolveTranslations()\n throw new CrudHttpError(404, {\n error: translate('ecommerce.errors.storeNotFound', 'The selected store does not exist in this organization.'),\n })\n }\n await enforceCommandOptimisticLockWithGuards(ctx.container, {\n resourceKind: STORE_BRANDING_RESOURCE_KIND,\n resourceId: store.id,\n current: store.updatedAt,\n request: ctx.request,\n })\n store.settings = mergeBrandingIntoSettings(store.settings, branding)\n await em.flush()\n await announceStoreBrandingUpdated(ctx.container, store)\n return { id: store.id, updatedAt: store.updatedAt.toISOString(), branding }\n },\n\n async captureAfter(input, _result, ctx) {\n return loadSnapshot(ctx, input)\n },\n\n async buildLog({ snapshots, input }) {\n const before = snapshots.before as StoreBrandingSnapshot | undefined\n const after = snapshots.after as StoreBrandingSnapshot | undefined\n if (!before || !after) return null\n const { translate } = await resolveTranslations()\n return {\n actionLabel: translate('ecommerce.audit.stores.branding.update', 'Update store branding'),\n resourceKind: STORE_BRANDING_RESOURCE_KIND,\n resourceId: before.id,\n tenantId: input.tenantId,\n organizationId: input.organizationId,\n snapshotBefore: before,\n snapshotAfter: after,\n changes: buildChanges(before, after, BRANDING_CHANGE_KEYS),\n payload: {\n undo: { before, after } satisfies StoreBrandingUndoPayload,\n },\n }\n },\n\n async undo({ logEntry, ctx }) {\n const payload = extractUndoPayload<StoreBrandingUndoPayload>(logEntry)\n const before = payload?.before\n if (!before) return\n ensureTenantScope(ctx, before.tenantId)\n ensureOrganizationScope(ctx, before.organizationId)\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n const store = await loadStore(em, before)\n if (!store) return\n store.settings = mergeBrandingIntoSettings(store.settings, before.branding)\n await em.flush()\n await announceStoreBrandingUpdated(ctx.container, store)\n },\n}\n\nregisterCommand(updateStoreBrandingCommand)\n"],
5
+ "mappings": "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",
6
+ "names": []
7
+ }
@@ -0,0 +1,90 @@
1
+ "use client";
2
+ import { jsx, jsxs } from "react/jsx-runtime";
3
+ import * as React from "react";
4
+ import { Alert, AlertDescription, AlertTitle } from "@open-mercato/ui/primitives/alert";
5
+ import { Spinner } from "@open-mercato/ui/primitives/spinner";
6
+ import { useLocale, useT } from "@open-mercato/shared/lib/i18n/context";
7
+ import { useChannelAssortmentCount } from "./useChannelAssortmentCount.js";
8
+ function useCountFormatter() {
9
+ const locale = useLocale();
10
+ const formatter = React.useMemo(() => new Intl.NumberFormat(locale), [locale]);
11
+ return React.useCallback((value) => formatter.format(value), [formatter]);
12
+ }
13
+ function describeAuthenticationGate(result, t, format) {
14
+ if (result.reducedByAuthentication) {
15
+ return t(
16
+ "ecommerce.backend.store.channels.count.reducedByAuthentication",
17
+ "0 products for anonymous visitors because sign-in is required; {count} without that requirement.",
18
+ { count: format(result.countWithoutAuthentication) }
19
+ );
20
+ }
21
+ return t(
22
+ "ecommerce.backend.store.channels.count.authenticationEmpty",
23
+ "0 products visible to anonymous visitors: sign-in is required, and the scope matches no products even without that requirement."
24
+ );
25
+ }
26
+ function ChannelAssortmentCountPanel({ state, unrestricted }) {
27
+ const t = useT();
28
+ const format = useCountFormatter();
29
+ if (state.status === "idle") {
30
+ return /* @__PURE__ */ jsx(Alert, { status: "information", children: /* @__PURE__ */ jsx(AlertDescription, { children: t(
31
+ "ecommerce.backend.store.channels.count.saveFirst",
32
+ "Save the binding to see how many products it shows. After that, the count updates as you change the scope."
33
+ ) }) });
34
+ }
35
+ if (state.status === "error") {
36
+ return /* @__PURE__ */ jsx(Alert, { status: "warning", children: /* @__PURE__ */ jsx(AlertDescription, { children: t("ecommerce.backend.store.channels.count.error", "The product count is unavailable right now.") }) });
37
+ }
38
+ if (state.status === "loading") {
39
+ return /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 rounded-md border border-border p-3 text-sm text-muted-foreground", "aria-live": "polite", children: [
40
+ /* @__PURE__ */ jsx(Spinner, { size: "sm" }),
41
+ t("ecommerce.backend.store.channels.count.loading", "Counting products\u2026")
42
+ ] });
43
+ }
44
+ const { result } = state;
45
+ const headline = result.requireAuthentication ? describeAuthenticationGate(result, t, format) : unrestricted ? t("ecommerce.backend.store.channels.count.unrestricted", "All products in this channel's catalog: {count}.", {
46
+ count: format(result.count)
47
+ }) : t("ecommerce.backend.store.channels.count.restricted", "Products matching this scope: {count}.", {
48
+ count: format(result.count)
49
+ });
50
+ return /* @__PURE__ */ jsxs("div", { className: "space-y-2", "aria-live": "polite", "data-testid": "channel-assortment-count", children: [
51
+ result.requireAuthentication ? /* @__PURE__ */ jsxs(Alert, { status: "warning", children: [
52
+ /* @__PURE__ */ jsx(AlertTitle, { children: t("ecommerce.backend.store.channels.count.title", "Live product count") }),
53
+ /* @__PURE__ */ jsx(AlertDescription, { children: headline })
54
+ ] }) : /* @__PURE__ */ jsxs("div", { className: "space-y-1 rounded-md border border-border p-3", children: [
55
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 text-sm font-medium", children: [
56
+ t("ecommerce.backend.store.channels.count.title", "Live product count"),
57
+ state.refreshing ? /* @__PURE__ */ jsx(Spinner, { size: "sm" }) : null
58
+ ] }),
59
+ /* @__PURE__ */ jsx("p", { className: "text-sm", children: headline })
60
+ ] }),
61
+ /* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground", children: t(
62
+ "ecommerce.backend.store.channels.count.basis",
63
+ "Counted for an anonymous visitor, including the default customer group's own restrictions. Unsaved changes are counted too."
64
+ ) }),
65
+ result.unindexedCount > 0 ? /* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground", children: t(
66
+ "ecommerce.backend.store.channels.count.unindexed",
67
+ "{count} active products are not indexed for visibility yet. Under a restricted scope they stay hidden and are not counted until indexing catches up.",
68
+ { count: format(result.unindexedCount) }
69
+ ) }) : null
70
+ ] });
71
+ }
72
+ function ChannelAssortmentCountCell({ bindingId, updatedAt }) {
73
+ const t = useT();
74
+ const format = useCountFormatter();
75
+ const state = useChannelAssortmentCount(bindingId, null, 0, updatedAt ?? null);
76
+ if (state.status === "loading" || state.status === "idle") return /* @__PURE__ */ jsx(Spinner, { size: "sm" });
77
+ if (state.status === "error") return /* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: "\u2014" });
78
+ const { result } = state;
79
+ if (result.requireAuthentication) {
80
+ return /* @__PURE__ */ jsx("span", { children: result.reducedByAuthentication ? t("ecommerce.backend.store.channels.count.cellReduced", "0 ({count} without the sign-in requirement)", {
81
+ count: format(result.countWithoutAuthentication)
82
+ }) : format(0) });
83
+ }
84
+ return /* @__PURE__ */ jsx("span", { children: format(result.count) });
85
+ }
86
+ export {
87
+ ChannelAssortmentCountCell,
88
+ ChannelAssortmentCountPanel
89
+ };
90
+ //# sourceMappingURL=ChannelAssortmentCount.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../src/modules/ecommerce/components/ChannelAssortmentCount.tsx"],
4
+ "sourcesContent": ["'use client'\n\nimport * as React from 'react'\nimport { Alert, AlertDescription, AlertTitle } from '@open-mercato/ui/primitives/alert'\nimport { Spinner } from '@open-mercato/ui/primitives/spinner'\nimport { useLocale, useT } from '@open-mercato/shared/lib/i18n/context'\nimport { useChannelAssortmentCount, type AssortmentCountState } from './useChannelAssortmentCount'\nimport type { AssortmentCountResult } from './storeChannels'\n\ntype Translate = ReturnType<typeof useT>\n\nfunction useCountFormatter(): (value: number) => string {\n const locale = useLocale()\n const formatter = React.useMemo(() => new Intl.NumberFormat(locale), [locale])\n return React.useCallback((value: number) => formatter.format(value), [formatter])\n}\n\nfunction describeAuthenticationGate(result: AssortmentCountResult, t: Translate, format: (value: number) => string): string {\n if (result.reducedByAuthentication) {\n return t(\n 'ecommerce.backend.store.channels.count.reducedByAuthentication',\n '0 products for anonymous visitors because sign-in is required; {count} without that requirement.',\n { count: format(result.countWithoutAuthentication) },\n )\n }\n return t(\n 'ecommerce.backend.store.channels.count.authenticationEmpty',\n '0 products visible to anonymous visitors: sign-in is required, and the scope matches no products even without that requirement.',\n )\n}\n\ntype ChannelAssortmentCountPanelProps = {\n state: AssortmentCountState\n unrestricted: boolean\n}\n\nexport function ChannelAssortmentCountPanel({ state, unrestricted }: ChannelAssortmentCountPanelProps) {\n const t = useT()\n const format = useCountFormatter()\n\n if (state.status === 'idle') {\n return (\n <Alert status=\"information\">\n <AlertDescription>\n {t(\n 'ecommerce.backend.store.channels.count.saveFirst',\n 'Save the binding to see how many products it shows. After that, the count updates as you change the scope.',\n )}\n </AlertDescription>\n </Alert>\n )\n }\n\n if (state.status === 'error') {\n return (\n <Alert status=\"warning\">\n <AlertDescription>\n {t('ecommerce.backend.store.channels.count.error', 'The product count is unavailable right now.')}\n </AlertDescription>\n </Alert>\n )\n }\n\n if (state.status === 'loading') {\n return (\n <div className=\"flex items-center gap-2 rounded-md border border-border p-3 text-sm text-muted-foreground\" aria-live=\"polite\">\n <Spinner size=\"sm\" />\n {t('ecommerce.backend.store.channels.count.loading', 'Counting products\u2026')}\n </div>\n )\n }\n\n const { result } = state\n const headline = result.requireAuthentication\n ? describeAuthenticationGate(result, t, format)\n : unrestricted\n ? t('ecommerce.backend.store.channels.count.unrestricted', \"All products in this channel's catalog: {count}.\", {\n count: format(result.count),\n })\n : t('ecommerce.backend.store.channels.count.restricted', 'Products matching this scope: {count}.', {\n count: format(result.count),\n })\n\n return (\n <div className=\"space-y-2\" aria-live=\"polite\" data-testid=\"channel-assortment-count\">\n {result.requireAuthentication ? (\n <Alert status=\"warning\">\n <AlertTitle>{t('ecommerce.backend.store.channels.count.title', 'Live product count')}</AlertTitle>\n <AlertDescription>{headline}</AlertDescription>\n </Alert>\n ) : (\n <div className=\"space-y-1 rounded-md border border-border p-3\">\n <div className=\"flex items-center gap-2 text-sm font-medium\">\n {t('ecommerce.backend.store.channels.count.title', 'Live product count')}\n {state.refreshing ? <Spinner size=\"sm\" /> : null}\n </div>\n <p className=\"text-sm\">{headline}</p>\n </div>\n )}\n <p className=\"text-xs text-muted-foreground\">\n {t(\n 'ecommerce.backend.store.channels.count.basis',\n \"Counted for an anonymous visitor, including the default customer group's own restrictions. Unsaved changes are counted too.\",\n )}\n </p>\n {result.unindexedCount > 0 ? (\n <p className=\"text-xs text-muted-foreground\">\n {t(\n 'ecommerce.backend.store.channels.count.unindexed',\n '{count} active products are not indexed for visibility yet. Under a restricted scope they stay hidden and are not counted until indexing catches up.',\n { count: format(result.unindexedCount) },\n )}\n </p>\n ) : null}\n </div>\n )\n}\n\nexport function ChannelAssortmentCountCell({ bindingId, updatedAt }: { bindingId: string; updatedAt?: string | null }) {\n const t = useT()\n const format = useCountFormatter()\n const state = useChannelAssortmentCount(bindingId, null, 0, updatedAt ?? null)\n if (state.status === 'loading' || state.status === 'idle') return <Spinner size=\"sm\" />\n if (state.status === 'error') return <span className=\"text-muted-foreground\">\u2014</span>\n const { result } = state\n if (result.requireAuthentication) {\n return (\n <span>\n {result.reducedByAuthentication\n ? t('ecommerce.backend.store.channels.count.cellReduced', '0 ({count} without the sign-in requirement)', {\n count: format(result.countWithoutAuthentication),\n })\n : format(0)}\n </span>\n )\n }\n return <span>{format(result.count)}</span>\n}\n"],
5
+ "mappings": "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",
6
+ "names": []
7
+ }
@@ -0,0 +1,33 @@
1
+ "use client";
2
+ import { jsx } from "react/jsx-runtime";
3
+ import { Alert, AlertDescription } from "@open-mercato/ui/primitives/alert";
4
+ import { useLocale, useT } from "@open-mercato/shared/lib/i18n/context";
5
+ import { ChannelAssortmentCountPanel } from "./ChannelAssortmentCount.js";
6
+ import { buildAssortmentCountDraft, isPriceSortFallback, PRICE_SORT_CAP } from "./storeChannels.js";
7
+ import { useChannelAssortmentCount } from "./useChannelAssortmentCount.js";
8
+ function ChannelBindingLiveCount({ bindingId, values }) {
9
+ const draft = buildAssortmentCountDraft(values);
10
+ const state = useChannelAssortmentCount(bindingId, draft);
11
+ return /* @__PURE__ */ jsx(ChannelAssortmentCountPanel, { state, unrestricted: draft.scope === null });
12
+ }
13
+ function PriceSortFallbackConsequence({ values }) {
14
+ const t = useT();
15
+ const locale = useLocale();
16
+ const cap = new Intl.NumberFormat(locale).format(PRICE_SORT_CAP);
17
+ const fallback = isPriceSortFallback(values.priceSortFallback) ? values.priceSortFallback : "approximate";
18
+ const text = fallback === "unavailable" ? t(
19
+ "ecommerce.backend.store.channels.priceSortFallback.unavailableConsequence",
20
+ "When more than {cap} products match, price sorting is withdrawn on this channel: price ascending and descending are no longer offered, and a buyer arriving on a shared price-sorted link gets the catalogue in the default order rather than an error.",
21
+ { cap }
22
+ ) : t(
23
+ "ecommerce.backend.store.channels.priceSortFallback.approximateConsequence",
24
+ "When more than {cap} products match, the price order is computed from the default price kind, not from the buyer's own prices. The only signal is a response header no shopper sees, so contract-priced buyers may see an order that does not match what they pay.",
25
+ { cap }
26
+ );
27
+ return /* @__PURE__ */ jsx(Alert, { status: "information", "data-testid": "price-sort-fallback-consequence", children: /* @__PURE__ */ jsx(AlertDescription, { children: text }) });
28
+ }
29
+ export {
30
+ ChannelBindingLiveCount,
31
+ PriceSortFallbackConsequence
32
+ };
33
+ //# sourceMappingURL=ChannelBindingFormSections.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../src/modules/ecommerce/components/ChannelBindingFormSections.tsx"],
4
+ "sourcesContent": ["'use client'\n\nimport * as React from 'react'\nimport { Alert, AlertDescription } from '@open-mercato/ui/primitives/alert'\nimport { useLocale, useT } from '@open-mercato/shared/lib/i18n/context'\nimport { ChannelAssortmentCountPanel } from './ChannelAssortmentCount'\nimport { buildAssortmentCountDraft, isPriceSortFallback, PRICE_SORT_CAP } from './storeChannels'\nimport { useChannelAssortmentCount } from './useChannelAssortmentCount'\n\ntype FormValuesProps = { values: Record<string, unknown> }\n\nexport function ChannelBindingLiveCount({ bindingId, values }: FormValuesProps & { bindingId: string | null }) {\n const draft = buildAssortmentCountDraft(values)\n const state = useChannelAssortmentCount(bindingId, draft)\n return <ChannelAssortmentCountPanel state={state} unrestricted={draft.scope === null} />\n}\n\nexport function PriceSortFallbackConsequence({ values }: FormValuesProps) {\n const t = useT()\n const locale = useLocale()\n const cap = new Intl.NumberFormat(locale).format(PRICE_SORT_CAP)\n const fallback = isPriceSortFallback(values.priceSortFallback) ? values.priceSortFallback : 'approximate'\n const text =\n fallback === 'unavailable'\n ? t(\n 'ecommerce.backend.store.channels.priceSortFallback.unavailableConsequence',\n 'When more than {cap} products match, price sorting is withdrawn on this channel: price ascending and descending are no longer offered, and a buyer arriving on a shared price-sorted link gets the catalogue in the default order rather than an error.',\n { cap },\n )\n : t(\n 'ecommerce.backend.store.channels.priceSortFallback.approximateConsequence',\n \"When more than {cap} products match, the price order is computed from the default price kind, not from the buyer's own prices. The only signal is a response header no shopper sees, so contract-priced buyers may see an order that does not match what they pay.\",\n { cap },\n )\n return (\n <Alert status=\"information\" data-testid=\"price-sort-fallback-consequence\">\n <AlertDescription>{text}</AlertDescription>\n </Alert>\n )\n}\n"],
5
+ "mappings": ";AAcS;AAXT,SAAS,OAAO,wBAAwB;AACxC,SAAS,WAAW,YAAY;AAChC,SAAS,mCAAmC;AAC5C,SAAS,2BAA2B,qBAAqB,sBAAsB;AAC/E,SAAS,iCAAiC;AAInC,SAAS,wBAAwB,EAAE,WAAW,OAAO,GAAmD;AAC7G,QAAM,QAAQ,0BAA0B,MAAM;AAC9C,QAAM,QAAQ,0BAA0B,WAAW,KAAK;AACxD,SAAO,oBAAC,+BAA4B,OAAc,cAAc,MAAM,UAAU,MAAM;AACxF;AAEO,SAAS,6BAA6B,EAAE,OAAO,GAAoB;AACxE,QAAM,IAAI,KAAK;AACf,QAAM,SAAS,UAAU;AACzB,QAAM,MAAM,IAAI,KAAK,aAAa,MAAM,EAAE,OAAO,cAAc;AAC/D,QAAM,WAAW,oBAAoB,OAAO,iBAAiB,IAAI,OAAO,oBAAoB;AAC5F,QAAM,OACJ,aAAa,gBACT;AAAA,IACE;AAAA,IACA;AAAA,IACA,EAAE,IAAI;AAAA,EACR,IACA;AAAA,IACE;AAAA,IACA;AAAA,IACA,EAAE,IAAI;AAAA,EACR;AACN,SACE,oBAAC,SAAM,QAAO,eAAc,eAAY,mCACtC,8BAAC,oBAAkB,gBAAK,GAC1B;AAEJ;",
6
+ "names": []
7
+ }
@@ -0,0 +1,11 @@
1
+ import {
2
+ LookupMultiPicker,
3
+ LookupSinglePicker,
4
+ useLookupLabelMap
5
+ } from "@open-mercato/ui/backend/inputs/LookupPickers";
6
+ export {
7
+ LookupMultiPicker as ChannelLookupMultiPicker,
8
+ LookupSinglePicker as ChannelLookupSinglePicker,
9
+ useLookupLabelMap
10
+ };
11
+ //# sourceMappingURL=ChannelLookupPicker.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../src/modules/ecommerce/components/ChannelLookupPicker.tsx"],
4
+ "sourcesContent": ["export {\n LookupMultiPicker as ChannelLookupMultiPicker,\n LookupSinglePicker as ChannelLookupSinglePicker,\n useLookupLabelMap,\n} from '@open-mercato/ui/backend/inputs/LookupPickers'\n"],
5
+ "mappings": "AAAA;AAAA,EACuB;AAAA,EACC;AAAA,EACtB;AAAA,OACK;",
6
+ "names": []
7
+ }
@@ -0,0 +1,24 @@
1
+ "use client";
2
+ import { jsx } from "react/jsx-runtime";
3
+ import { useT } from "@open-mercato/shared/lib/i18n/context";
4
+ import { Alert, AlertDescription } from "@open-mercato/ui/primitives/alert";
5
+ import { describeDomainStatus, isServingStatus } from "./storeDomains.js";
6
+ function DomainStatusWarning({ status, hostname, appearance = "inline" }) {
7
+ const t = useT();
8
+ if (isServingStatus(status)) return null;
9
+ const described = describeDomainStatus(status);
10
+ const statusLabel = described.key ? t(described.key, described.fallback) : described.fallback;
11
+ const message = t(
12
+ "ecommerce.backend.store.domains.warning.notServing",
13
+ "This domain is {status}. Only an active domain serves, so the store does not answer at {hostname} yet.",
14
+ { status: statusLabel, hostname }
15
+ );
16
+ if (appearance === "alert") {
17
+ return /* @__PURE__ */ jsx(Alert, { status: "warning", children: /* @__PURE__ */ jsx(AlertDescription, { children: message }) });
18
+ }
19
+ return /* @__PURE__ */ jsx("p", { className: "text-xs text-status-warning-text", children: message });
20
+ }
21
+ export {
22
+ DomainStatusWarning
23
+ };
24
+ //# sourceMappingURL=DomainStatusWarning.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../src/modules/ecommerce/components/DomainStatusWarning.tsx"],
4
+ "sourcesContent": ["'use client'\n\nimport * as React from 'react'\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\nimport { Alert, AlertDescription } from '@open-mercato/ui/primitives/alert'\nimport { describeDomainStatus, isServingStatus } from './storeDomains'\n\ntype DomainStatusWarningProps = {\n status: string\n hostname: string\n appearance?: 'alert' | 'inline'\n}\n\nexport function DomainStatusWarning({ status, hostname, appearance = 'inline' }: DomainStatusWarningProps) {\n const t = useT()\n if (isServingStatus(status)) return null\n const described = describeDomainStatus(status)\n const statusLabel = described.key ? t(described.key, described.fallback) : described.fallback\n const message = t(\n 'ecommerce.backend.store.domains.warning.notServing',\n 'This domain is {status}. Only an active domain serves, so the store does not answer at {hostname} yet.',\n { status: statusLabel, hostname },\n )\n if (appearance === 'alert') {\n return (\n <Alert status=\"warning\">\n <AlertDescription>{message}</AlertDescription>\n </Alert>\n )\n }\n return <p className=\"text-xs text-status-warning-text\">{message}</p>\n}\n"],
5
+ "mappings": ";AA0BQ;AAvBR,SAAS,YAAY;AACrB,SAAS,OAAO,wBAAwB;AACxC,SAAS,sBAAsB,uBAAuB;AAQ/C,SAAS,oBAAoB,EAAE,QAAQ,UAAU,aAAa,SAAS,GAA6B;AACzG,QAAM,IAAI,KAAK;AACf,MAAI,gBAAgB,MAAM,EAAG,QAAO;AACpC,QAAM,YAAY,qBAAqB,MAAM;AAC7C,QAAM,cAAc,UAAU,MAAM,EAAE,UAAU,KAAK,UAAU,QAAQ,IAAI,UAAU;AACrF,QAAM,UAAU;AAAA,IACd;AAAA,IACA;AAAA,IACA,EAAE,QAAQ,aAAa,SAAS;AAAA,EAClC;AACA,MAAI,eAAe,SAAS;AAC1B,WACE,oBAAC,SAAM,QAAO,WACZ,8BAAC,oBAAkB,mBAAQ,GAC7B;AAAA,EAEJ;AACA,SAAO,oBAAC,OAAE,WAAU,oCAAoC,mBAAQ;AAClE;",
6
+ "names": []
7
+ }
@@ -0,0 +1,190 @@
1
+ "use client";
2
+ import { jsx, jsxs } from "react/jsx-runtime";
3
+ import * as React from "react";
4
+ import { useQuery, useQueryClient } from "@tanstack/react-query";
5
+ import { CrudForm } from "@open-mercato/ui/backend/CrudForm";
6
+ import { ErrorMessage, LoadingMessage } from "@open-mercato/ui/backend/detail";
7
+ import { flash } from "@open-mercato/ui/backend/FlashMessages";
8
+ import { apiCall } from "@open-mercato/ui/backend/utils/apiCall";
9
+ import { createCrud, updateCrud } from "@open-mercato/ui/backend/utils/crud";
10
+ import { createCrudFormError, raiseCrudError } from "@open-mercato/ui/backend/utils/serverErrors";
11
+ import { Alert, AlertDescription } from "@open-mercato/ui/primitives/alert";
12
+ import { Button } from "@open-mercato/ui/primitives/button";
13
+ import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@open-mercato/ui/primitives/card";
14
+ import { useT } from "@open-mercato/shared/lib/i18n/context";
15
+ import { AVAILABILITY_POLICIES_API_PATH, AVAILABILITY_POLICIES_API_URL } from "./storeAdmin.js";
16
+ import {
17
+ availabilityDefaultsFormSchema,
18
+ buildAvailabilityCreatePayload,
19
+ buildAvailabilityInitialValues,
20
+ buildAvailabilityUpdatePayload,
21
+ isStoreDefaultPolicy
22
+ } from "./storeGeneral.js";
23
+ import { useStoreAccess } from "./useStoreAccess.js";
24
+ const POLICY_PAGE_SIZE = 100;
25
+ async function fetchStoreDefaultPolicy(storeId, translate) {
26
+ for (let page = 1; ; page += 1) {
27
+ const params = new URLSearchParams({
28
+ storeId,
29
+ page: String(page),
30
+ pageSize: String(POLICY_PAGE_SIZE),
31
+ sortField: "createdAt",
32
+ sortDir: "asc"
33
+ });
34
+ const call = await apiCall(`${AVAILABILITY_POLICIES_API_URL}?${params.toString()}`, {
35
+ cache: "no-store"
36
+ });
37
+ if (!call.ok) {
38
+ await raiseCrudError(
39
+ call.response,
40
+ translate("ecommerce.backend.store.availability.errors.load", "Failed to load the availability defaults.")
41
+ );
42
+ }
43
+ const match = (call.result?.items ?? []).find((item) => isStoreDefaultPolicy(item, storeId));
44
+ if (match) return match;
45
+ if (page >= (call.result?.totalPages ?? 1)) return null;
46
+ }
47
+ }
48
+ function StoreAvailabilityDefaultsSection({ store }) {
49
+ const t = useT();
50
+ const queryClient = useQueryClient();
51
+ const { canManage, canViewAvailability, canManageAvailability } = useStoreAccess();
52
+ const queryKey = React.useMemo(() => ["ecommerce", "stores", "availability-default", store.id], [store.id]);
53
+ const [formKey, setFormKey] = React.useState(0);
54
+ const policyQuery = useQuery({
55
+ queryKey,
56
+ enabled: canViewAvailability,
57
+ queryFn: async () => ({ policy: await fetchStoreDefaultPolicy(store.id, t) })
58
+ });
59
+ const editable = canManage && canManageAvailability;
60
+ const policy = policyQuery.data?.policy ?? null;
61
+ const readOnlyReason = React.useMemo(() => {
62
+ if (!canViewAvailability) {
63
+ return t(
64
+ "ecommerce.backend.store.availability.readOnly.noView",
65
+ "You do not have access to availability policies, so the store defaults cannot be shown."
66
+ );
67
+ }
68
+ if (!canManage) {
69
+ return t(
70
+ "ecommerce.backend.store.availability.readOnly.noStoreManage",
71
+ "You can view these defaults but not change them. Changing them requires permission to manage stores."
72
+ );
73
+ }
74
+ if (!canManageAvailability) {
75
+ return t(
76
+ "ecommerce.backend.store.availability.readOnly.noAvailabilityManage",
77
+ "You can view these defaults but not change them. Saving them requires permission to manage availability policies."
78
+ );
79
+ }
80
+ return null;
81
+ }, [canManage, canManageAvailability, canViewAvailability, t]);
82
+ const fields = React.useMemo(
83
+ () => [
84
+ {
85
+ id: "hideWhenOutOfStock",
86
+ type: "checkbox",
87
+ label: t("ecommerce.backend.store.availability.hideWhenOutOfStock", "Hide out-of-stock products"),
88
+ description: t(
89
+ "ecommerce.backend.store.availability.hideWhenOutOfStockHint",
90
+ "Products with no stock left are not shown in this store."
91
+ ),
92
+ disabled: !editable
93
+ },
94
+ {
95
+ id: "allowBackorder",
96
+ type: "checkbox",
97
+ label: t("ecommerce.backend.store.availability.allowBackorder", "Allow backorders"),
98
+ description: t(
99
+ "ecommerce.backend.store.availability.allowBackorderHint",
100
+ "Shoppers can order products that are out of stock."
101
+ ),
102
+ disabled: !editable
103
+ },
104
+ {
105
+ id: "backorderLeadTimeDays",
106
+ type: "number",
107
+ label: t("ecommerce.backend.store.availability.leadTime", "Backorder lead time (days)"),
108
+ description: t(
109
+ "ecommerce.backend.store.availability.leadTimeHint",
110
+ "How many days a backordered product takes to ship. Required while backorders are allowed."
111
+ ),
112
+ visibleWhen: { field: "allowBackorder", equals: true },
113
+ disabled: !editable,
114
+ layout: "half"
115
+ }
116
+ ],
117
+ [editable, t]
118
+ );
119
+ const initialValues = React.useMemo(() => buildAvailabilityInitialValues(policy), [policy]);
120
+ const refresh = React.useCallback(async () => {
121
+ await queryClient.invalidateQueries({ queryKey });
122
+ setFormKey((current) => current + 1);
123
+ }, [queryClient, queryKey]);
124
+ const handleSubmit = React.useCallback(
125
+ async (values) => {
126
+ const errorMessage = t("ecommerce.backend.store.availability.errors.save", "Failed to save the availability defaults.");
127
+ if (policy) {
128
+ await updateCrud(AVAILABILITY_POLICIES_API_PATH, buildAvailabilityUpdatePayload(policy.id, values), { errorMessage });
129
+ } else {
130
+ const payload = buildAvailabilityCreatePayload(store, values);
131
+ if (!payload) throw createCrudFormError(errorMessage);
132
+ await createCrud(AVAILABILITY_POLICIES_API_PATH, payload, { errorMessage });
133
+ }
134
+ flash(t("ecommerce.backend.store.availability.flash.saved", "Availability defaults saved"), "success");
135
+ await refresh();
136
+ },
137
+ [policy, refresh, store, t]
138
+ );
139
+ const handleKeyDown = React.useCallback((event) => {
140
+ if (event.key !== "Escape" || event.defaultPrevented) return;
141
+ setFormKey((current) => current + 1);
142
+ }, []);
143
+ const renderBody = () => {
144
+ if (!canViewAvailability) return null;
145
+ if (policyQuery.isLoading) {
146
+ return /* @__PURE__ */ jsx(LoadingMessage, { label: t("ecommerce.backend.store.availability.loading", "Loading availability defaults...") });
147
+ }
148
+ if (policyQuery.isError) {
149
+ return /* @__PURE__ */ jsx(
150
+ ErrorMessage,
151
+ {
152
+ label: t("ecommerce.backend.store.availability.errors.load", "Failed to load the availability defaults."),
153
+ action: /* @__PURE__ */ jsx(Button, { type: "button", variant: "outline", size: "sm", onClick: () => void policyQuery.refetch(), children: t("ecommerce.backend.store.actions.retry", "Retry") })
154
+ }
155
+ );
156
+ }
157
+ return /* @__PURE__ */ jsx("div", { onKeyDown: handleKeyDown, children: /* @__PURE__ */ jsx(
158
+ CrudForm,
159
+ {
160
+ schema: availabilityDefaultsFormSchema,
161
+ fields,
162
+ initialValues,
163
+ optimisticLockUpdatedAt: policy?.updatedAt ?? null,
164
+ submitLabel: t("ecommerce.backend.store.availability.save", "Save availability defaults"),
165
+ onSubmit: handleSubmit,
166
+ hideFooterActions: !editable,
167
+ embedded: true
168
+ },
169
+ `${formKey}:${policy?.updatedAt ?? "new"}`
170
+ ) });
171
+ };
172
+ return /* @__PURE__ */ jsxs(Card, { children: [
173
+ /* @__PURE__ */ jsxs(CardHeader, { children: [
174
+ /* @__PURE__ */ jsx(CardTitle, { children: t("ecommerce.backend.store.availability.title", "Availability defaults") }),
175
+ /* @__PURE__ */ jsx(CardDescription, { children: t(
176
+ "ecommerce.backend.store.availability.description",
177
+ "Default stock rules for every product in this store. A policy set on a product or variant overrides these defaults, so those policies only need to describe exceptions."
178
+ ) })
179
+ ] }),
180
+ /* @__PURE__ */ jsxs(CardContent, { className: "space-y-4", children: [
181
+ readOnlyReason ? /* @__PURE__ */ jsx(Alert, { status: "information", children: /* @__PURE__ */ jsx(AlertDescription, { children: readOnlyReason }) }) : null,
182
+ renderBody()
183
+ ] })
184
+ ] });
185
+ }
186
+ export {
187
+ StoreAvailabilityDefaultsSection,
188
+ fetchStoreDefaultPolicy
189
+ };
190
+ //# sourceMappingURL=StoreAvailabilityDefaultsSection.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../src/modules/ecommerce/components/StoreAvailabilityDefaultsSection.tsx"],
4
+ "sourcesContent": ["'use client'\n\nimport * as React from 'react'\nimport { useQuery, useQueryClient } from '@tanstack/react-query'\nimport { CrudForm, type CrudField } from '@open-mercato/ui/backend/CrudForm'\nimport { ErrorMessage, LoadingMessage } from '@open-mercato/ui/backend/detail'\nimport { flash } from '@open-mercato/ui/backend/FlashMessages'\nimport { apiCall } from '@open-mercato/ui/backend/utils/apiCall'\nimport { createCrud, updateCrud } from '@open-mercato/ui/backend/utils/crud'\nimport { createCrudFormError, raiseCrudError } from '@open-mercato/ui/backend/utils/serverErrors'\nimport { Alert, AlertDescription } from '@open-mercato/ui/primitives/alert'\nimport { Button } from '@open-mercato/ui/primitives/button'\nimport { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@open-mercato/ui/primitives/card'\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\nimport { AVAILABILITY_POLICIES_API_PATH, AVAILABILITY_POLICIES_API_URL, type StoreAdminRecord } from './storeAdmin'\nimport {\n availabilityDefaultsFormSchema,\n buildAvailabilityCreatePayload,\n buildAvailabilityInitialValues,\n buildAvailabilityUpdatePayload,\n isStoreDefaultPolicy,\n type AvailabilityDefaultsFormValues,\n type PolicyListResponse,\n type StoreDefaultPolicy,\n} from './storeGeneral'\nimport { useStoreAccess } from './useStoreAccess'\n\nconst POLICY_PAGE_SIZE = 100\n\ntype Translate = (key: string, fallback?: string) => string\n\nexport async function fetchStoreDefaultPolicy(storeId: string, translate: Translate): Promise<StoreDefaultPolicy | null> {\n for (let page = 1; ; page += 1) {\n const params = new URLSearchParams({\n storeId,\n page: String(page),\n pageSize: String(POLICY_PAGE_SIZE),\n sortField: 'createdAt',\n sortDir: 'asc',\n })\n const call = await apiCall<PolicyListResponse>(`${AVAILABILITY_POLICIES_API_URL}?${params.toString()}`, {\n cache: 'no-store',\n })\n if (!call.ok) {\n await raiseCrudError(\n call.response,\n translate('ecommerce.backend.store.availability.errors.load', 'Failed to load the availability defaults.'),\n )\n }\n const match = (call.result?.items ?? []).find((item) => isStoreDefaultPolicy(item, storeId))\n if (match) return match\n if (page >= (call.result?.totalPages ?? 1)) return null\n }\n}\n\ntype StoreAvailabilityDefaultsSectionProps = {\n store: StoreAdminRecord\n}\n\nexport function StoreAvailabilityDefaultsSection({ store }: StoreAvailabilityDefaultsSectionProps) {\n const t = useT()\n const queryClient = useQueryClient()\n const { canManage, canViewAvailability, canManageAvailability } = useStoreAccess()\n const queryKey = React.useMemo(() => ['ecommerce', 'stores', 'availability-default', store.id], [store.id])\n const [formKey, setFormKey] = React.useState(0)\n\n const policyQuery = useQuery({\n queryKey,\n enabled: canViewAvailability,\n queryFn: async () => ({ policy: await fetchStoreDefaultPolicy(store.id, t) }),\n })\n\n const editable = canManage && canManageAvailability\n const policy = policyQuery.data?.policy ?? null\n\n const readOnlyReason = React.useMemo(() => {\n if (!canViewAvailability) {\n return t(\n 'ecommerce.backend.store.availability.readOnly.noView',\n 'You do not have access to availability policies, so the store defaults cannot be shown.',\n )\n }\n if (!canManage) {\n return t(\n 'ecommerce.backend.store.availability.readOnly.noStoreManage',\n 'You can view these defaults but not change them. Changing them requires permission to manage stores.',\n )\n }\n if (!canManageAvailability) {\n return t(\n 'ecommerce.backend.store.availability.readOnly.noAvailabilityManage',\n 'You can view these defaults but not change them. Saving them requires permission to manage availability policies.',\n )\n }\n return null\n }, [canManage, canManageAvailability, canViewAvailability, t])\n\n const fields = React.useMemo<CrudField[]>(\n () => [\n {\n id: 'hideWhenOutOfStock',\n type: 'checkbox',\n label: t('ecommerce.backend.store.availability.hideWhenOutOfStock', 'Hide out-of-stock products'),\n description: t(\n 'ecommerce.backend.store.availability.hideWhenOutOfStockHint',\n 'Products with no stock left are not shown in this store.',\n ),\n disabled: !editable,\n },\n {\n id: 'allowBackorder',\n type: 'checkbox',\n label: t('ecommerce.backend.store.availability.allowBackorder', 'Allow backorders'),\n description: t(\n 'ecommerce.backend.store.availability.allowBackorderHint',\n 'Shoppers can order products that are out of stock.',\n ),\n disabled: !editable,\n },\n {\n id: 'backorderLeadTimeDays',\n type: 'number',\n label: t('ecommerce.backend.store.availability.leadTime', 'Backorder lead time (days)'),\n description: t(\n 'ecommerce.backend.store.availability.leadTimeHint',\n 'How many days a backordered product takes to ship. Required while backorders are allowed.',\n ),\n visibleWhen: { field: 'allowBackorder', equals: true },\n disabled: !editable,\n layout: 'half',\n },\n ],\n [editable, t],\n )\n\n const initialValues = React.useMemo(() => buildAvailabilityInitialValues(policy), [policy])\n\n const refresh = React.useCallback(async () => {\n await queryClient.invalidateQueries({ queryKey })\n setFormKey((current) => current + 1)\n }, [queryClient, queryKey])\n\n const handleSubmit = React.useCallback(\n async (values: AvailabilityDefaultsFormValues) => {\n const errorMessage = t('ecommerce.backend.store.availability.errors.save', 'Failed to save the availability defaults.')\n if (policy) {\n await updateCrud(AVAILABILITY_POLICIES_API_PATH, buildAvailabilityUpdatePayload(policy.id, values), { errorMessage })\n } else {\n const payload = buildAvailabilityCreatePayload(store, values)\n if (!payload) throw createCrudFormError(errorMessage)\n await createCrud(AVAILABILITY_POLICIES_API_PATH, payload, { errorMessage })\n }\n flash(t('ecommerce.backend.store.availability.flash.saved', 'Availability defaults saved'), 'success')\n await refresh()\n },\n [policy, refresh, store, t],\n )\n\n const handleKeyDown = React.useCallback((event: React.KeyboardEvent<HTMLDivElement>) => {\n if (event.key !== 'Escape' || event.defaultPrevented) return\n setFormKey((current) => current + 1)\n }, [])\n\n const renderBody = () => {\n if (!canViewAvailability) return null\n if (policyQuery.isLoading) {\n return <LoadingMessage label={t('ecommerce.backend.store.availability.loading', 'Loading availability defaults...')} />\n }\n if (policyQuery.isError) {\n return (\n <ErrorMessage\n label={t('ecommerce.backend.store.availability.errors.load', 'Failed to load the availability defaults.')}\n action={\n <Button type=\"button\" variant=\"outline\" size=\"sm\" onClick={() => void policyQuery.refetch()}>\n {t('ecommerce.backend.store.actions.retry', 'Retry')}\n </Button>\n }\n />\n )\n }\n return (\n <div onKeyDown={handleKeyDown}>\n <CrudForm<AvailabilityDefaultsFormValues>\n key={`${formKey}:${policy?.updatedAt ?? 'new'}`}\n schema={availabilityDefaultsFormSchema}\n fields={fields}\n initialValues={initialValues}\n optimisticLockUpdatedAt={policy?.updatedAt ?? null}\n submitLabel={t('ecommerce.backend.store.availability.save', 'Save availability defaults')}\n onSubmit={handleSubmit}\n hideFooterActions={!editable}\n embedded\n />\n </div>\n )\n }\n\n return (\n <Card>\n <CardHeader>\n <CardTitle>{t('ecommerce.backend.store.availability.title', 'Availability defaults')}</CardTitle>\n <CardDescription>\n {t(\n 'ecommerce.backend.store.availability.description',\n 'Default stock rules for every product in this store. A policy set on a product or variant overrides these defaults, so those policies only need to describe exceptions.',\n )}\n </CardDescription>\n </CardHeader>\n <CardContent className=\"space-y-4\">\n {readOnlyReason ? (\n <Alert status=\"information\">\n <AlertDescription>{readOnlyReason}</AlertDescription>\n </Alert>\n ) : null}\n {renderBody()}\n </CardContent>\n </Card>\n )\n}\n"],
5
+ "mappings": "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",
6
+ "names": []
7
+ }