@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.
- package/.turbo/turbo-build.log +2 -2
- package/dist/generated/entities/catalog_price_history_entry/index.js +53 -0
- package/dist/generated/entities/catalog_price_history_entry/index.js.map +7 -0
- package/dist/generated/entities/customer_group_terms/index.js +2 -0
- package/dist/generated/entities/customer_group_terms/index.js.map +2 -2
- package/dist/generated/entities/ecommerce_store/index.js +33 -0
- package/dist/generated/entities/ecommerce_store/index.js.map +7 -0
- package/dist/generated/entities/ecommerce_store_channel_binding/index.js +29 -0
- package/dist/generated/entities/ecommerce_store_channel_binding/index.js.map +7 -0
- package/dist/generated/entities/ecommerce_store_domain_binding/index.js +23 -0
- package/dist/generated/entities/ecommerce_store_domain_binding/index.js.map +7 -0
- package/dist/generated/entities.ids.generated.js +8 -1
- package/dist/generated/entities.ids.generated.js.map +2 -2
- package/dist/generated/entity-fields-registry.js +72 -0
- package/dist/generated/entity-fields-registry.js.map +2 -2
- package/dist/helpers/integration/customerGroupsFixtures.js.map +2 -2
- package/dist/modules/catalog/acl.js +8 -1
- package/dist/modules/catalog/acl.js.map +2 -2
- package/dist/modules/catalog/api/config/omnibus/route.js +184 -0
- package/dist/modules/catalog/api/config/omnibus/route.js.map +7 -0
- package/dist/modules/catalog/api/prices/history/route.js +131 -0
- package/dist/modules/catalog/api/prices/history/route.js.map +7 -0
- package/dist/modules/catalog/api/prices/omnibus-preview/route.js +184 -0
- package/dist/modules/catalog/api/prices/omnibus-preview/route.js.map +7 -0
- package/dist/modules/catalog/api/products/route.js +54 -245
- package/dist/modules/catalog/api/products/route.js.map +3 -3
- package/dist/modules/catalog/api/tags/route.js +6 -0
- package/dist/modules/catalog/api/tags/route.js.map +2 -2
- package/dist/modules/catalog/backend/config/catalog/page.js +3 -1
- package/dist/modules/catalog/backend/config/catalog/page.js.map +2 -2
- package/dist/modules/catalog/cli.js +80 -2
- package/dist/modules/catalog/cli.js.map +2 -2
- package/dist/modules/catalog/commands/categories.js +51 -2
- package/dist/modules/catalog/commands/categories.js.map +2 -2
- package/dist/modules/catalog/commands/prices.js +43 -1
- package/dist/modules/catalog/commands/prices.js.map +2 -2
- package/dist/modules/catalog/commands/products.js +71 -0
- package/dist/modules/catalog/commands/products.js.map +2 -2
- package/dist/modules/catalog/commands/variants.js +7 -0
- package/dist/modules/catalog/commands/variants.js.map +2 -2
- package/dist/modules/catalog/components/OmnibusSettings.js +703 -0
- package/dist/modules/catalog/components/OmnibusSettings.js.map +7 -0
- package/dist/modules/catalog/components/PriceEditorOmnibusRow.js +152 -0
- package/dist/modules/catalog/components/PriceEditorOmnibusRow.js.map +7 -0
- package/dist/modules/catalog/components/lookupSources.js +31 -0
- package/dist/modules/catalog/components/lookupSources.js.map +7 -0
- package/dist/modules/catalog/components/prices/PriceScopeSelectors.js +8 -2
- package/dist/modules/catalog/components/prices/PriceScopeSelectors.js.map +2 -2
- package/dist/modules/catalog/components/products/VariantBuilder.js +11 -1
- package/dist/modules/catalog/components/products/VariantBuilder.js.map +2 -2
- package/dist/modules/catalog/data/entities.js +122 -1
- package/dist/modules/catalog/data/entities.js.map +2 -2
- package/dist/modules/catalog/data/validators.js +78 -0
- package/dist/modules/catalog/data/validators.js.map +2 -2
- package/dist/modules/catalog/di.js +18 -0
- package/dist/modules/catalog/di.js.map +2 -2
- package/dist/modules/catalog/lib/omnibus.js +285 -0
- package/dist/modules/catalog/lib/omnibus.js.map +7 -0
- package/dist/modules/catalog/lib/omnibusBackfill.js +146 -0
- package/dist/modules/catalog/lib/omnibusBackfill.js.map +7 -0
- package/dist/modules/catalog/lib/omnibusCache.js +89 -0
- package/dist/modules/catalog/lib/omnibusCache.js.map +7 -0
- package/dist/modules/catalog/lib/omnibusConfig.js +64 -0
- package/dist/modules/catalog/lib/omnibusConfig.js.map +7 -0
- package/dist/modules/catalog/lib/omnibusHistoryQueries.js +191 -0
- package/dist/modules/catalog/lib/omnibusHistoryQueries.js.map +7 -0
- package/dist/modules/catalog/lib/omnibusPresentedEntry.js +73 -0
- package/dist/modules/catalog/lib/omnibusPresentedEntry.js.map +7 -0
- package/dist/modules/catalog/lib/omnibusProductListEnrichment.js +94 -0
- package/dist/modules/catalog/lib/omnibusProductListEnrichment.js.map +7 -0
- package/dist/modules/catalog/lib/omnibusTypes.js +115 -0
- package/dist/modules/catalog/lib/omnibusTypes.js.map +7 -0
- package/dist/modules/catalog/lib/optionSchemaTranslations.js +55 -0
- package/dist/modules/catalog/lib/optionSchemaTranslations.js.map +7 -0
- package/dist/modules/catalog/lib/priceHistoryQuery.js +103 -0
- package/dist/modules/catalog/lib/priceHistoryQuery.js.map +7 -0
- package/dist/modules/catalog/lib/pricing.js +26 -2
- package/dist/modules/catalog/lib/pricing.js.map +2 -2
- package/dist/modules/catalog/lib/productFilters.js +273 -0
- package/dist/modules/catalog/lib/productFilters.js.map +7 -0
- package/dist/modules/catalog/lib/productScopeKeys.js +105 -0
- package/dist/modules/catalog/lib/productScopeKeys.js.map +7 -0
- package/dist/modules/catalog/lib/productScopeReindex.js +73 -0
- package/dist/modules/catalog/lib/productScopeReindex.js.map +7 -0
- package/dist/modules/catalog/migrations/Migration20261005105352_catalog.js +39 -0
- package/dist/modules/catalog/migrations/Migration20261005105352_catalog.js.map +7 -0
- package/dist/modules/catalog/migrations/Migration20261005150824_catalog.js +39 -0
- package/dist/modules/catalog/migrations/Migration20261005150824_catalog.js.map +7 -0
- package/dist/modules/catalog/services/catalogOmnibusService.js +480 -0
- package/dist/modules/catalog/services/catalogOmnibusService.js.map +7 -0
- package/dist/modules/catalog/setup.js +3 -1
- package/dist/modules/catalog/setup.js.map +2 -2
- package/dist/modules/catalog/subscribers/product-scope-keys-category-deleted.js +16 -0
- package/dist/modules/catalog/subscribers/product-scope-keys-category-deleted.js.map +7 -0
- package/dist/modules/catalog/subscribers/product-scope-keys-category-updated.js +17 -0
- package/dist/modules/catalog/subscribers/product-scope-keys-category-updated.js.map +7 -0
- package/dist/modules/catalog/translations.js +10 -0
- package/dist/modules/catalog/translations.js.map +2 -2
- package/dist/modules/configs/lib/upgrade-actions.js +28 -0
- package/dist/modules/configs/lib/upgrade-actions.js.map +2 -2
- package/dist/modules/customer_groups/api/customer-groups/[id]/terms/route.js +5 -0
- package/dist/modules/customer_groups/api/customer-groups/[id]/terms/route.js.map +2 -2
- package/dist/modules/customer_groups/components/CustomerGroupTermsSection.js +111 -3
- package/dist/modules/customer_groups/components/CustomerGroupTermsSection.js.map +2 -2
- package/dist/modules/customer_groups/components/customerGroupAssortmentScope.js +43 -0
- package/dist/modules/customer_groups/components/customerGroupAssortmentScope.js.map +7 -0
- package/dist/modules/customer_groups/data/entities.js +3 -0
- package/dist/modules/customer_groups/data/entities.js.map +2 -2
- package/dist/modules/customer_groups/data/validators.js +9 -0
- package/dist/modules/customer_groups/data/validators.js.map +2 -2
- package/dist/modules/customer_groups/migrations/Migration20261005110250_customer_groups.js +17 -0
- package/dist/modules/customer_groups/migrations/Migration20261005110250_customer_groups.js.map +7 -0
- package/dist/modules/customer_groups/services/customerGroupsService.js +62 -15
- package/dist/modules/customer_groups/services/customerGroupsService.js.map +2 -2
- package/dist/modules/ecommerce/acl.js +13 -0
- package/dist/modules/ecommerce/acl.js.map +7 -0
- package/dist/modules/ecommerce/api/domain-mappings/route.js +72 -0
- package/dist/modules/ecommerce/api/domain-mappings/route.js.map +7 -0
- package/dist/modules/ecommerce/api/openapi.js +27 -0
- package/dist/modules/ecommerce/api/openapi.js.map +7 -0
- package/dist/modules/ecommerce/api/store-channel-bindings/[id]/assortment-count/route.js +109 -0
- package/dist/modules/ecommerce/api/store-channel-bindings/[id]/assortment-count/route.js.map +7 -0
- package/dist/modules/ecommerce/api/store-channel-bindings/crud.js +265 -0
- package/dist/modules/ecommerce/api/store-channel-bindings/crud.js.map +7 -0
- package/dist/modules/ecommerce/api/store-channel-bindings/route.js +67 -0
- package/dist/modules/ecommerce/api/store-channel-bindings/route.js.map +7 -0
- package/dist/modules/ecommerce/api/store-domain-bindings/crud.js +296 -0
- package/dist/modules/ecommerce/api/store-domain-bindings/crud.js.map +7 -0
- package/dist/modules/ecommerce/api/store-domain-bindings/route.js +73 -0
- package/dist/modules/ecommerce/api/store-domain-bindings/route.js.map +7 -0
- package/dist/modules/ecommerce/api/storefront/categories/[slug]/route.js +87 -0
- package/dist/modules/ecommerce/api/storefront/categories/[slug]/route.js.map +7 -0
- package/dist/modules/ecommerce/api/storefront/categories/openapiSchemas.js +50 -0
- package/dist/modules/ecommerce/api/storefront/categories/openapiSchemas.js.map +7 -0
- package/dist/modules/ecommerce/api/storefront/categories/route.js +75 -0
- package/dist/modules/ecommerce/api/storefront/categories/route.js.map +7 -0
- package/dist/modules/ecommerce/api/storefront/context/route.js +163 -0
- package/dist/modules/ecommerce/api/storefront/context/route.js.map +7 -0
- package/dist/modules/ecommerce/api/storefront/products/[idOrHandle]/route.js +87 -0
- package/dist/modules/ecommerce/api/storefront/products/[idOrHandle]/route.js.map +7 -0
- package/dist/modules/ecommerce/api/storefront/products/openapiSchemas.js +177 -0
- package/dist/modules/ecommerce/api/storefront/products/openapiSchemas.js.map +7 -0
- package/dist/modules/ecommerce/api/storefront/products/route.js +78 -0
- package/dist/modules/ecommerce/api/storefront/products/route.js.map +7 -0
- package/dist/modules/ecommerce/api/storefront/search/suggest/openapiSchemas.js +25 -0
- package/dist/modules/ecommerce/api/storefront/search/suggest/openapiSchemas.js.map +7 -0
- package/dist/modules/ecommerce/api/storefront/search/suggest/route.js +75 -0
- package/dist/modules/ecommerce/api/storefront/search/suggest/route.js.map +7 -0
- package/dist/modules/ecommerce/api/storefront/storefrontRouteSupport.js +58 -0
- package/dist/modules/ecommerce/api/storefront/storefrontRouteSupport.js.map +7 -0
- package/dist/modules/ecommerce/api/stores/[id]/branding/route.js +183 -0
- package/dist/modules/ecommerce/api/stores/[id]/branding/route.js.map +7 -0
- package/dist/modules/ecommerce/api/stores/[id]/preview-branding/route.js +92 -0
- package/dist/modules/ecommerce/api/stores/[id]/preview-branding/route.js.map +7 -0
- package/dist/modules/ecommerce/api/stores/crud.js +401 -0
- package/dist/modules/ecommerce/api/stores/crud.js.map +7 -0
- package/dist/modules/ecommerce/api/stores/route.js +64 -0
- package/dist/modules/ecommerce/api/stores/route.js.map +7 -0
- package/dist/modules/ecommerce/backend/config/ecommerce/[id]/page.js +9 -0
- package/dist/modules/ecommerce/backend/config/ecommerce/[id]/page.js.map +7 -0
- package/dist/modules/ecommerce/backend/config/ecommerce/[id]/page.meta.js +16 -0
- package/dist/modules/ecommerce/backend/config/ecommerce/[id]/page.meta.js.map +7 -0
- package/dist/modules/ecommerce/backend/config/ecommerce/page.js +9 -0
- package/dist/modules/ecommerce/backend/config/ecommerce/page.js.map +7 -0
- package/dist/modules/ecommerce/backend/config/ecommerce/page.meta.js +16 -0
- package/dist/modules/ecommerce/backend/config/ecommerce/page.meta.js.map +7 -0
- package/dist/modules/ecommerce/commands/stores.js +110 -0
- package/dist/modules/ecommerce/commands/stores.js.map +7 -0
- package/dist/modules/ecommerce/components/ChannelAssortmentCount.js +90 -0
- package/dist/modules/ecommerce/components/ChannelAssortmentCount.js.map +7 -0
- package/dist/modules/ecommerce/components/ChannelBindingFormSections.js +33 -0
- package/dist/modules/ecommerce/components/ChannelBindingFormSections.js.map +7 -0
- package/dist/modules/ecommerce/components/ChannelLookupPicker.js +11 -0
- package/dist/modules/ecommerce/components/ChannelLookupPicker.js.map +7 -0
- package/dist/modules/ecommerce/components/DomainStatusWarning.js +24 -0
- package/dist/modules/ecommerce/components/DomainStatusWarning.js.map +7 -0
- package/dist/modules/ecommerce/components/StoreAvailabilityDefaultsSection.js +190 -0
- package/dist/modules/ecommerce/components/StoreAvailabilityDefaultsSection.js.map +7 -0
- package/dist/modules/ecommerce/components/StoreBrandingControls.js +67 -0
- package/dist/modules/ecommerce/components/StoreBrandingControls.js.map +7 -0
- package/dist/modules/ecommerce/components/StoreBrandingPreview.js +69 -0
- package/dist/modules/ecommerce/components/StoreBrandingPreview.js.map +7 -0
- package/dist/modules/ecommerce/components/StoreBrandingTab.js +218 -0
- package/dist/modules/ecommerce/components/StoreBrandingTab.js.map +7 -0
- package/dist/modules/ecommerce/components/StoreChannelBindingDialog.js +270 -0
- package/dist/modules/ecommerce/components/StoreChannelBindingDialog.js.map +7 -0
- package/dist/modules/ecommerce/components/StoreChannelsTab.js +313 -0
- package/dist/modules/ecommerce/components/StoreChannelsTab.js.map +7 -0
- package/dist/modules/ecommerce/components/StoreCreateDialog.js +164 -0
- package/dist/modules/ecommerce/components/StoreCreateDialog.js.map +7 -0
- package/dist/modules/ecommerce/components/StoreDomainBindingDialog.js +162 -0
- package/dist/modules/ecommerce/components/StoreDomainBindingDialog.js.map +7 -0
- package/dist/modules/ecommerce/components/StoreDomainsTab.js +357 -0
- package/dist/modules/ecommerce/components/StoreDomainsTab.js.map +7 -0
- package/dist/modules/ecommerce/components/StoreEditPage.js +155 -0
- package/dist/modules/ecommerce/components/StoreEditPage.js.map +7 -0
- package/dist/modules/ecommerce/components/StoreGeneralTab.js +167 -0
- package/dist/modules/ecommerce/components/StoreGeneralTab.js.map +7 -0
- package/dist/modules/ecommerce/components/StoreListPage.js +290 -0
- package/dist/modules/ecommerce/components/StoreListPage.js.map +7 -0
- package/dist/modules/ecommerce/components/StoreSeoTab.js +132 -0
- package/dist/modules/ecommerce/components/StoreSeoTab.js.map +7 -0
- package/dist/modules/ecommerce/components/StoreStatusBadge.js +20 -0
- package/dist/modules/ecommerce/components/StoreStatusBadge.js.map +7 -0
- package/dist/modules/ecommerce/components/channelLookups.js +28 -0
- package/dist/modules/ecommerce/components/channelLookups.js.map +7 -0
- package/dist/modules/ecommerce/components/storeAdmin.js +41 -0
- package/dist/modules/ecommerce/components/storeAdmin.js.map +7 -0
- package/dist/modules/ecommerce/components/storeBrandingForm.js +197 -0
- package/dist/modules/ecommerce/components/storeBrandingForm.js.map +7 -0
- package/dist/modules/ecommerce/components/storeChannels.js +140 -0
- package/dist/modules/ecommerce/components/storeChannels.js.map +7 -0
- package/dist/modules/ecommerce/components/storeDomains.js +167 -0
- package/dist/modules/ecommerce/components/storeDomains.js.map +7 -0
- package/dist/modules/ecommerce/components/storeEditTabs.js +62 -0
- package/dist/modules/ecommerce/components/storeEditTabs.js.map +7 -0
- package/dist/modules/ecommerce/components/storeGeneral.js +95 -0
- package/dist/modules/ecommerce/components/storeGeneral.js.map +7 -0
- package/dist/modules/ecommerce/components/storeSeo.js +69 -0
- package/dist/modules/ecommerce/components/storeSeo.js.map +7 -0
- package/dist/modules/ecommerce/components/useChannelAssortmentCount.js +45 -0
- package/dist/modules/ecommerce/components/useChannelAssortmentCount.js.map +7 -0
- package/dist/modules/ecommerce/components/useStoreAccess.js +28 -0
- package/dist/modules/ecommerce/components/useStoreAccess.js.map +7 -0
- package/dist/modules/ecommerce/data/enrichers.js +157 -0
- package/dist/modules/ecommerce/data/enrichers.js.map +7 -0
- package/dist/modules/ecommerce/data/entities.js +197 -0
- package/dist/modules/ecommerce/data/entities.js.map +7 -0
- package/dist/modules/ecommerce/data/validators.js +406 -0
- package/dist/modules/ecommerce/data/validators.js.map +7 -0
- package/dist/modules/ecommerce/di.js +11 -0
- package/dist/modules/ecommerce/di.js.map +7 -0
- package/dist/modules/ecommerce/events.js +27 -0
- package/dist/modules/ecommerce/events.js.map +7 -0
- package/dist/modules/ecommerce/index.js +16 -0
- package/dist/modules/ecommerce/index.js.map +7 -0
- package/dist/modules/ecommerce/lib/assortmentCount.js +112 -0
- package/dist/modules/ecommerce/lib/assortmentCount.js.map +7 -0
- package/dist/modules/ecommerce/lib/brandingStyles.js +184 -0
- package/dist/modules/ecommerce/lib/brandingStyles.js.map +7 -0
- package/dist/modules/ecommerce/lib/buyerContext.js +284 -0
- package/dist/modules/ecommerce/lib/buyerContext.js.map +7 -0
- package/dist/modules/ecommerce/lib/cacheInvalidation.js +186 -0
- package/dist/modules/ecommerce/lib/cacheInvalidation.js.map +7 -0
- package/dist/modules/ecommerce/lib/cacheKeys.js +236 -0
- package/dist/modules/ecommerce/lib/cacheKeys.js.map +7 -0
- package/dist/modules/ecommerce/lib/createConflictRecheck.js +29 -0
- package/dist/modules/ecommerce/lib/createConflictRecheck.js.map +7 -0
- package/dist/modules/ecommerce/lib/crudEvents.js +94 -0
- package/dist/modules/ecommerce/lib/crudEvents.js.map +7 -0
- package/dist/modules/ecommerce/lib/crudSupport.js +64 -0
- package/dist/modules/ecommerce/lib/crudSupport.js.map +7 -0
- package/dist/modules/ecommerce/lib/domainBindingRebind.js +99 -0
- package/dist/modules/ecommerce/lib/domainBindingRebind.js.map +7 -0
- package/dist/modules/ecommerce/lib/domainMappingSummaries.js +39 -0
- package/dist/modules/ecommerce/lib/domainMappingSummaries.js.map +7 -0
- package/dist/modules/ecommerce/lib/exclusiveFlag.js +57 -0
- package/dist/modules/ecommerce/lib/exclusiveFlag.js.map +7 -0
- package/dist/modules/ecommerce/lib/references.js +70 -0
- package/dist/modules/ecommerce/lib/references.js.map +7 -0
- package/dist/modules/ecommerce/lib/seedDraftStore.js +99 -0
- package/dist/modules/ecommerce/lib/seedDraftStore.js.map +7 -0
- package/dist/modules/ecommerce/lib/storeBindingCascade.js +109 -0
- package/dist/modules/ecommerce/lib/storeBindingCascade.js.map +7 -0
- package/dist/modules/ecommerce/lib/storeBranding.js +40 -0
- package/dist/modules/ecommerce/lib/storeBranding.js.map +7 -0
- package/dist/modules/ecommerce/lib/storeBrandingRoute.js +76 -0
- package/dist/modules/ecommerce/lib/storeBrandingRoute.js.map +7 -0
- package/dist/modules/ecommerce/lib/storeContext.js +393 -0
- package/dist/modules/ecommerce/lib/storeContext.js.map +7 -0
- package/dist/modules/ecommerce/lib/storeContextService.js +43 -0
- package/dist/modules/ecommerce/lib/storeContextService.js.map +7 -0
- package/dist/modules/ecommerce/lib/storeLocale.js +60 -0
- package/dist/modules/ecommerce/lib/storeLocale.js.map +7 -0
- package/dist/modules/ecommerce/lib/storeNotifications.js +41 -0
- package/dist/modules/ecommerce/lib/storeNotifications.js.map +7 -0
- package/dist/modules/ecommerce/lib/storefrontCatalogSupport.js +248 -0
- package/dist/modules/ecommerce/lib/storefrontCatalogSupport.js.map +7 -0
- package/dist/modules/ecommerce/lib/storefrontCategories.js +241 -0
- package/dist/modules/ecommerce/lib/storefrontCategories.js.map +7 -0
- package/dist/modules/ecommerce/lib/storefrontCategoryCache.js +71 -0
- package/dist/modules/ecommerce/lib/storefrontCategoryCache.js.map +7 -0
- package/dist/modules/ecommerce/lib/storefrontDetail.js +447 -0
- package/dist/modules/ecommerce/lib/storefrontDetail.js.map +7 -0
- package/dist/modules/ecommerce/lib/storefrontFacets.js +441 -0
- package/dist/modules/ecommerce/lib/storefrontFacets.js.map +7 -0
- package/dist/modules/ecommerce/lib/storefrontOptionFilter.js +15 -0
- package/dist/modules/ecommerce/lib/storefrontOptionFilter.js.map +7 -0
- package/dist/modules/ecommerce/lib/storefrontPricing.js +393 -0
- package/dist/modules/ecommerce/lib/storefrontPricing.js.map +7 -0
- package/dist/modules/ecommerce/lib/storefrontProductCache.js +90 -0
- package/dist/modules/ecommerce/lib/storefrontProductCache.js.map +7 -0
- package/dist/modules/ecommerce/lib/storefrontProductScope.js +107 -0
- package/dist/modules/ecommerce/lib/storefrontProductScope.js.map +7 -0
- package/dist/modules/ecommerce/lib/storefrontProducts.js +670 -0
- package/dist/modules/ecommerce/lib/storefrontProducts.js.map +7 -0
- package/dist/modules/ecommerce/lib/storefrontQuery.js +156 -0
- package/dist/modules/ecommerce/lib/storefrontQuery.js.map +7 -0
- package/dist/modules/ecommerce/lib/storefrontRateLimit.js +99 -0
- package/dist/modules/ecommerce/lib/storefrontRateLimit.js.map +7 -0
- package/dist/modules/ecommerce/lib/storefrontSearch.js +303 -0
- package/dist/modules/ecommerce/lib/storefrontSearch.js.map +7 -0
- package/dist/modules/ecommerce/lib/storefrontSearchCache.js +35 -0
- package/dist/modules/ecommerce/lib/storefrontSearchCache.js.map +7 -0
- package/dist/modules/ecommerce/lib/subscriberSupport.js +33 -0
- package/dist/modules/ecommerce/lib/subscriberSupport.js.map +7 -0
- package/dist/modules/ecommerce/lib/types.js +1 -0
- package/dist/modules/ecommerce/lib/types.js.map +7 -0
- package/dist/modules/ecommerce/migrations/Migration20261005113233_ecommerce.js +32 -0
- package/dist/modules/ecommerce/migrations/Migration20261005113233_ecommerce.js.map +7 -0
- package/dist/modules/ecommerce/migrations/Migration20261006112733_ecommerce.js +17 -0
- package/dist/modules/ecommerce/migrations/Migration20261006112733_ecommerce.js.map +7 -0
- package/dist/modules/ecommerce/notifications.client.js +47 -0
- package/dist/modules/ecommerce/notifications.client.js.map +7 -0
- package/dist/modules/ecommerce/notifications.js +48 -0
- package/dist/modules/ecommerce/notifications.js.map +7 -0
- package/dist/modules/ecommerce/search.js +83 -0
- package/dist/modules/ecommerce/search.js.map +7 -0
- package/dist/modules/ecommerce/setup.js +17 -0
- package/dist/modules/ecommerce/setup.js.map +7 -0
- package/dist/modules/ecommerce/subscribers/assortment-empty-notifications.js +14 -0
- package/dist/modules/ecommerce/subscribers/assortment-empty-notifications.js.map +7 -0
- package/dist/modules/ecommerce/subscribers/availability-policy-cache-invalidation.js +14 -0
- package/dist/modules/ecommerce/subscribers/availability-policy-cache-invalidation.js.map +7 -0
- package/dist/modules/ecommerce/subscribers/catalog-category-cache-invalidation.js +14 -0
- package/dist/modules/ecommerce/subscribers/catalog-category-cache-invalidation.js.map +7 -0
- package/dist/modules/ecommerce/subscribers/catalog-price-cache-invalidation.js +14 -0
- package/dist/modules/ecommerce/subscribers/catalog-price-cache-invalidation.js.map +7 -0
- package/dist/modules/ecommerce/subscribers/catalog-product-cache-invalidation.js +14 -0
- package/dist/modules/ecommerce/subscribers/catalog-product-cache-invalidation.js.map +7 -0
- package/dist/modules/ecommerce/subscribers/catalog-variant-cache-invalidation.js +14 -0
- package/dist/modules/ecommerce/subscribers/catalog-variant-cache-invalidation.js.map +7 -0
- package/dist/modules/ecommerce/subscribers/customer-group-cache-invalidation.js +14 -0
- package/dist/modules/ecommerce/subscribers/customer-group-cache-invalidation.js.map +7 -0
- package/dist/modules/ecommerce/subscribers/customer-group-membership-cache-invalidation.js +14 -0
- package/dist/modules/ecommerce/subscribers/customer-group-membership-cache-invalidation.js.map +7 -0
- package/dist/modules/ecommerce/subscribers/customer-group-terms-cache-invalidation.js +14 -0
- package/dist/modules/ecommerce/subscribers/customer-group-terms-cache-invalidation.js.map +7 -0
- package/dist/modules/ecommerce/subscribers/customer-user-deleted-cache-invalidation.js +14 -0
- package/dist/modules/ecommerce/subscribers/customer-user-deleted-cache-invalidation.js.map +7 -0
- package/dist/modules/ecommerce/subscribers/customer-user-updated-cache-invalidation.js +14 -0
- package/dist/modules/ecommerce/subscribers/customer-user-updated-cache-invalidation.js.map +7 -0
- package/dist/modules/ecommerce/subscribers/domain-binding-rebind.js +16 -0
- package/dist/modules/ecommerce/subscribers/domain-binding-rebind.js.map +7 -0
- package/dist/modules/ecommerce/subscribers/domain-mapping-cache-invalidation.js +14 -0
- package/dist/modules/ecommerce/subscribers/domain-mapping-cache-invalidation.js.map +7 -0
- package/dist/modules/ecommerce/subscribers/store-cache-invalidation.js +14 -0
- package/dist/modules/ecommerce/subscribers/store-cache-invalidation.js.map +7 -0
- package/dist/modules/ecommerce/subscribers/store-channel-binding-cache-invalidation.js +14 -0
- package/dist/modules/ecommerce/subscribers/store-channel-binding-cache-invalidation.js.map +7 -0
- package/dist/modules/ecommerce/subscribers/store-domain-binding-cache-invalidation.js +14 -0
- package/dist/modules/ecommerce/subscribers/store-domain-binding-cache-invalidation.js.map +7 -0
- package/dist/modules/ecommerce/subscribers/store-notifications.js +14 -0
- package/dist/modules/ecommerce/subscribers/store-notifications.js.map +7 -0
- package/dist/modules/query_index/lib/batch.js +23 -9
- package/dist/modules/query_index/lib/batch.js.map +2 -2
- package/dist/modules/query_index/lib/doc-enrichers.js +212 -0
- package/dist/modules/query_index/lib/doc-enrichers.js.map +7 -0
- package/dist/modules/query_index/lib/document.js +2 -0
- package/dist/modules/query_index/lib/document.js.map +2 -2
- package/dist/modules/query_index/lib/engine.js +68 -1
- package/dist/modules/query_index/lib/engine.js.map +2 -2
- package/dist/modules/query_index/lib/indexer.js +7 -0
- package/dist/modules/query_index/lib/indexer.js.map +2 -2
- package/dist/modules/query_index/lib/search-tokens.js +2 -0
- package/dist/modules/query_index/lib/search-tokens.js.map +2 -2
- package/dist/modules/query_index/migrations/Migration20261005201500_query_index.js +17 -0
- package/dist/modules/query_index/migrations/Migration20261005201500_query_index.js.map +7 -0
- package/dist/modules/translations/components/TranslationManager.js +3 -3
- package/dist/modules/translations/components/TranslationManager.js.map +2 -2
- package/dist/modules/translations/data/validators.js +1 -1
- package/dist/modules/translations/data/validators.js.map +1 -1
- package/dist/modules/translations/lib/batch.js +21 -1
- package/dist/modules/translations/lib/batch.js.map +2 -2
- package/dist/modules/translations/lib/helpers.js +3 -0
- package/dist/modules/translations/lib/helpers.js.map +2 -2
- package/dist/modules/translations/lib/resolve-field-list.js +14 -2
- package/dist/modules/translations/lib/resolve-field-list.js.map +2 -2
- package/generated/entities/catalog_price_history_entry/index.ts +25 -0
- package/generated/entities/customer_group_terms/index.ts +1 -0
- package/generated/entities/ecommerce_store/index.ts +15 -0
- package/generated/entities/ecommerce_store_channel_binding/index.ts +13 -0
- package/generated/entities/ecommerce_store_domain_binding/index.ts +10 -0
- package/generated/entities.ids.generated.ts +8 -1
- package/generated/entity-fields-registry.ts +72 -0
- package/package.json +7 -7
- package/src/helpers/integration/customerGroupsFixtures.ts +2 -0
- package/src/modules/auth/i18n/de.json +8 -0
- package/src/modules/auth/i18n/en.json +8 -0
- package/src/modules/auth/i18n/es.json +8 -0
- package/src/modules/auth/i18n/ko.json +8 -0
- package/src/modules/auth/i18n/pl.json +8 -0
- package/src/modules/catalog/AGENTS.md +5 -2
- package/src/modules/catalog/acl.ts +7 -0
- package/src/modules/catalog/api/config/omnibus/route.ts +204 -0
- package/src/modules/catalog/api/prices/history/route.ts +139 -0
- package/src/modules/catalog/api/prices/omnibus-preview/route.ts +202 -0
- package/src/modules/catalog/api/products/route.ts +53 -308
- package/src/modules/catalog/api/tags/route.ts +6 -0
- package/src/modules/catalog/backend/config/catalog/page.tsx +2 -0
- package/src/modules/catalog/cli.ts +84 -1
- package/src/modules/catalog/commands/categories.ts +54 -2
- package/src/modules/catalog/commands/prices.ts +43 -1
- package/src/modules/catalog/commands/products.ts +84 -1
- package/src/modules/catalog/commands/variants.ts +7 -0
- package/src/modules/catalog/components/OmnibusSettings.tsx +832 -0
- package/src/modules/catalog/components/PriceEditorOmnibusRow.tsx +219 -0
- package/src/modules/catalog/components/lookupSources.ts +29 -0
- package/src/modules/catalog/components/prices/PriceScopeSelectors.tsx +9 -0
- package/src/modules/catalog/components/products/VariantBuilder.tsx +9 -0
- package/src/modules/catalog/data/entities.ts +123 -1
- package/src/modules/catalog/data/validators.ts +118 -0
- package/src/modules/catalog/di.ts +23 -0
- package/src/modules/catalog/i18n/de.json +77 -0
- package/src/modules/catalog/i18n/en.json +77 -0
- package/src/modules/catalog/i18n/es.json +77 -0
- package/src/modules/catalog/i18n/ko.json +77 -0
- package/src/modules/catalog/i18n/pl.json +77 -0
- package/src/modules/catalog/lib/omnibus.ts +406 -0
- package/src/modules/catalog/lib/omnibusBackfill.ts +198 -0
- package/src/modules/catalog/lib/omnibusCache.ts +111 -0
- package/src/modules/catalog/lib/omnibusConfig.ts +73 -0
- package/src/modules/catalog/lib/omnibusHistoryQueries.ts +248 -0
- package/src/modules/catalog/lib/omnibusPresentedEntry.ts +76 -0
- package/src/modules/catalog/lib/omnibusProductListEnrichment.ts +125 -0
- package/src/modules/catalog/lib/omnibusTypes.ts +202 -0
- package/src/modules/catalog/lib/optionSchemaTranslations.ts +55 -0
- package/src/modules/catalog/lib/priceHistoryQuery.ts +155 -0
- package/src/modules/catalog/lib/pricing.ts +42 -4
- package/src/modules/catalog/lib/productFilters.ts +349 -0
- package/src/modules/catalog/lib/productScopeKeys.ts +162 -0
- package/src/modules/catalog/lib/productScopeReindex.ts +139 -0
- package/src/modules/catalog/migrations/.snapshot-open-mercato.json +572 -0
- package/src/modules/catalog/migrations/Migration20261005105352_catalog.ts +39 -0
- package/src/modules/catalog/migrations/Migration20261005150824_catalog.ts +39 -0
- package/src/modules/catalog/services/catalogOmnibusService.ts +642 -0
- package/src/modules/catalog/setup.ts +2 -0
- package/src/modules/catalog/subscribers/product-scope-keys-category-deleted.ts +18 -0
- package/src/modules/catalog/subscribers/product-scope-keys-category-updated.ts +19 -0
- package/src/modules/catalog/translations.ts +12 -0
- package/src/modules/configs/i18n/de.json +5 -1
- package/src/modules/configs/i18n/en.json +5 -1
- package/src/modules/configs/i18n/es.json +5 -1
- package/src/modules/configs/i18n/ko.json +5 -1
- package/src/modules/configs/i18n/pl.json +5 -1
- package/src/modules/configs/lib/upgrade-actions.ts +35 -0
- package/src/modules/customer_groups/api/customer-groups/[id]/terms/route.ts +7 -0
- package/src/modules/customer_groups/components/CustomerGroupTermsSection.tsx +124 -2
- package/src/modules/customer_groups/components/customerGroupAssortmentScope.ts +46 -0
- package/src/modules/customer_groups/data/entities.ts +4 -0
- package/src/modules/customer_groups/data/validators.ts +14 -0
- package/src/modules/customer_groups/i18n/de.json +12 -0
- package/src/modules/customer_groups/i18n/en.json +12 -0
- package/src/modules/customer_groups/i18n/es.json +12 -0
- package/src/modules/customer_groups/i18n/ko.json +12 -0
- package/src/modules/customer_groups/i18n/pl.json +12 -0
- package/src/modules/customer_groups/migrations/.snapshot-open-mercato.json +17 -0
- package/src/modules/customer_groups/migrations/Migration20261005110250_customer_groups.ts +15 -0
- package/src/modules/customer_groups/services/customerGroupsService.ts +74 -23
- package/src/modules/ecommerce/acl.ts +9 -0
- package/src/modules/ecommerce/api/domain-mappings/route.ts +76 -0
- package/src/modules/ecommerce/api/openapi.ts +28 -0
- package/src/modules/ecommerce/api/store-channel-bindings/[id]/assortment-count/route.ts +141 -0
- package/src/modules/ecommerce/api/store-channel-bindings/crud.ts +283 -0
- package/src/modules/ecommerce/api/store-channel-bindings/route.ts +67 -0
- package/src/modules/ecommerce/api/store-domain-bindings/crud.ts +324 -0
- package/src/modules/ecommerce/api/store-domain-bindings/route.ts +73 -0
- package/src/modules/ecommerce/api/storefront/categories/[slug]/route.ts +94 -0
- package/src/modules/ecommerce/api/storefront/categories/openapiSchemas.ts +63 -0
- package/src/modules/ecommerce/api/storefront/categories/route.ts +78 -0
- package/src/modules/ecommerce/api/storefront/context/route.ts +203 -0
- package/src/modules/ecommerce/api/storefront/products/[idOrHandle]/route.ts +94 -0
- package/src/modules/ecommerce/api/storefront/products/openapiSchemas.ts +193 -0
- package/src/modules/ecommerce/api/storefront/products/route.ts +81 -0
- package/src/modules/ecommerce/api/storefront/search/suggest/openapiSchemas.ts +25 -0
- package/src/modules/ecommerce/api/storefront/search/suggest/route.ts +78 -0
- package/src/modules/ecommerce/api/storefront/storefrontRouteSupport.ts +68 -0
- package/src/modules/ecommerce/api/stores/[id]/branding/route.ts +205 -0
- package/src/modules/ecommerce/api/stores/[id]/preview-branding/route.ts +99 -0
- package/src/modules/ecommerce/api/stores/crud.ts +457 -0
- package/src/modules/ecommerce/api/stores/route.ts +66 -0
- package/src/modules/ecommerce/backend/config/ecommerce/[id]/page.meta.ts +12 -0
- package/src/modules/ecommerce/backend/config/ecommerce/[id]/page.tsx +5 -0
- package/src/modules/ecommerce/backend/config/ecommerce/page.meta.ts +12 -0
- package/src/modules/ecommerce/backend/config/ecommerce/page.tsx +5 -0
- package/src/modules/ecommerce/commands/stores.ts +154 -0
- package/src/modules/ecommerce/components/ChannelAssortmentCount.tsx +138 -0
- package/src/modules/ecommerce/components/ChannelBindingFormSections.tsx +40 -0
- package/src/modules/ecommerce/components/ChannelLookupPicker.tsx +5 -0
- package/src/modules/ecommerce/components/DomainStatusWarning.tsx +32 -0
- package/src/modules/ecommerce/components/StoreAvailabilityDefaultsSection.tsx +219 -0
- package/src/modules/ecommerce/components/StoreBrandingControls.tsx +73 -0
- package/src/modules/ecommerce/components/StoreBrandingPreview.tsx +77 -0
- package/src/modules/ecommerce/components/StoreBrandingTab.tsx +242 -0
- package/src/modules/ecommerce/components/StoreChannelBindingDialog.tsx +306 -0
- package/src/modules/ecommerce/components/StoreChannelsTab.tsx +375 -0
- package/src/modules/ecommerce/components/StoreCreateDialog.tsx +204 -0
- package/src/modules/ecommerce/components/StoreDomainBindingDialog.tsx +198 -0
- package/src/modules/ecommerce/components/StoreDomainsTab.tsx +426 -0
- package/src/modules/ecommerce/components/StoreEditPage.tsx +193 -0
- package/src/modules/ecommerce/components/StoreGeneralTab.tsx +189 -0
- package/src/modules/ecommerce/components/StoreListPage.tsx +326 -0
- package/src/modules/ecommerce/components/StoreSeoTab.tsx +152 -0
- package/src/modules/ecommerce/components/StoreStatusBadge.tsx +22 -0
- package/src/modules/ecommerce/components/channelLookups.ts +24 -0
- package/src/modules/ecommerce/components/storeAdmin.ts +56 -0
- package/src/modules/ecommerce/components/storeBrandingForm.ts +230 -0
- package/src/modules/ecommerce/components/storeChannels.ts +210 -0
- package/src/modules/ecommerce/components/storeDomains.ts +221 -0
- package/src/modules/ecommerce/components/storeEditTabs.tsx +76 -0
- package/src/modules/ecommerce/components/storeGeneral.ts +155 -0
- package/src/modules/ecommerce/components/storeSeo.ts +78 -0
- package/src/modules/ecommerce/components/useChannelAssortmentCount.ts +67 -0
- package/src/modules/ecommerce/components/useStoreAccess.ts +36 -0
- package/src/modules/ecommerce/data/enrichers.ts +213 -0
- package/src/modules/ecommerce/data/entities.ts +168 -0
- package/src/modules/ecommerce/data/validators.ts +587 -0
- package/src/modules/ecommerce/di.ts +9 -0
- package/src/modules/ecommerce/events.ts +27 -0
- package/src/modules/ecommerce/i18n/de.json +341 -0
- package/src/modules/ecommerce/i18n/en.json +341 -0
- package/src/modules/ecommerce/i18n/es.json +341 -0
- package/src/modules/ecommerce/i18n/ko.json +341 -0
- package/src/modules/ecommerce/i18n/pl.json +341 -0
- package/src/modules/ecommerce/index.ts +14 -0
- package/src/modules/ecommerce/lib/assortmentCount.ts +175 -0
- package/src/modules/ecommerce/lib/brandingStyles.ts +215 -0
- package/src/modules/ecommerce/lib/buyerContext.ts +401 -0
- package/src/modules/ecommerce/lib/cacheInvalidation.ts +302 -0
- package/src/modules/ecommerce/lib/cacheKeys.ts +340 -0
- package/src/modules/ecommerce/lib/createConflictRecheck.ts +31 -0
- package/src/modules/ecommerce/lib/crudEvents.ts +128 -0
- package/src/modules/ecommerce/lib/crudSupport.ts +85 -0
- package/src/modules/ecommerce/lib/domainBindingRebind.ts +138 -0
- package/src/modules/ecommerce/lib/domainMappingSummaries.ts +71 -0
- package/src/modules/ecommerce/lib/exclusiveFlag.ts +90 -0
- package/src/modules/ecommerce/lib/references.ts +93 -0
- package/src/modules/ecommerce/lib/seedDraftStore.ts +125 -0
- package/src/modules/ecommerce/lib/storeBindingCascade.ts +138 -0
- package/src/modules/ecommerce/lib/storeBranding.ts +48 -0
- package/src/modules/ecommerce/lib/storeBrandingRoute.ts +91 -0
- package/src/modules/ecommerce/lib/storeContext.ts +669 -0
- package/src/modules/ecommerce/lib/storeContextService.ts +71 -0
- package/src/modules/ecommerce/lib/storeLocale.ts +88 -0
- package/src/modules/ecommerce/lib/storeNotifications.ts +55 -0
- package/src/modules/ecommerce/lib/storefrontCatalogSupport.ts +427 -0
- package/src/modules/ecommerce/lib/storefrontCategories.ts +419 -0
- package/src/modules/ecommerce/lib/storefrontCategoryCache.ts +113 -0
- package/src/modules/ecommerce/lib/storefrontDetail.ts +654 -0
- package/src/modules/ecommerce/lib/storefrontFacets.ts +697 -0
- package/src/modules/ecommerce/lib/storefrontOptionFilter.ts +44 -0
- package/src/modules/ecommerce/lib/storefrontPricing.ts +583 -0
- package/src/modules/ecommerce/lib/storefrontProductCache.ts +126 -0
- package/src/modules/ecommerce/lib/storefrontProductScope.ts +181 -0
- package/src/modules/ecommerce/lib/storefrontProducts.ts +963 -0
- package/src/modules/ecommerce/lib/storefrontQuery.ts +215 -0
- package/src/modules/ecommerce/lib/storefrontRateLimit.ts +126 -0
- package/src/modules/ecommerce/lib/storefrontSearch.ts +454 -0
- package/src/modules/ecommerce/lib/storefrontSearchCache.ts +49 -0
- package/src/modules/ecommerce/lib/subscriberSupport.ts +41 -0
- package/src/modules/ecommerce/lib/types.ts +69 -0
- package/src/modules/ecommerce/migrations/.snapshot-open-mercato.json +829 -0
- package/src/modules/ecommerce/migrations/Migration20261005113233_ecommerce.ts +32 -0
- package/src/modules/ecommerce/migrations/Migration20261006112733_ecommerce.ts +15 -0
- package/src/modules/ecommerce/notifications.client.ts +46 -0
- package/src/modules/ecommerce/notifications.ts +46 -0
- package/src/modules/ecommerce/search.ts +93 -0
- package/src/modules/ecommerce/setup.ts +15 -0
- package/src/modules/ecommerce/subscribers/assortment-empty-notifications.ts +12 -0
- package/src/modules/ecommerce/subscribers/availability-policy-cache-invalidation.ts +12 -0
- package/src/modules/ecommerce/subscribers/catalog-category-cache-invalidation.ts +12 -0
- package/src/modules/ecommerce/subscribers/catalog-price-cache-invalidation.ts +12 -0
- package/src/modules/ecommerce/subscribers/catalog-product-cache-invalidation.ts +12 -0
- package/src/modules/ecommerce/subscribers/catalog-variant-cache-invalidation.ts +12 -0
- package/src/modules/ecommerce/subscribers/customer-group-cache-invalidation.ts +12 -0
- package/src/modules/ecommerce/subscribers/customer-group-membership-cache-invalidation.ts +12 -0
- package/src/modules/ecommerce/subscribers/customer-group-terms-cache-invalidation.ts +12 -0
- package/src/modules/ecommerce/subscribers/customer-user-deleted-cache-invalidation.ts +12 -0
- package/src/modules/ecommerce/subscribers/customer-user-updated-cache-invalidation.ts +12 -0
- package/src/modules/ecommerce/subscribers/domain-binding-rebind.ts +14 -0
- package/src/modules/ecommerce/subscribers/domain-mapping-cache-invalidation.ts +12 -0
- package/src/modules/ecommerce/subscribers/store-cache-invalidation.ts +12 -0
- package/src/modules/ecommerce/subscribers/store-channel-binding-cache-invalidation.ts +12 -0
- package/src/modules/ecommerce/subscribers/store-domain-binding-cache-invalidation.ts +12 -0
- package/src/modules/ecommerce/subscribers/store-notifications.ts +12 -0
- package/src/modules/query_index/lib/batch.ts +25 -9
- package/src/modules/query_index/lib/doc-enrichers.ts +306 -0
- package/src/modules/query_index/lib/document.ts +2 -0
- package/src/modules/query_index/lib/engine.ts +58 -1
- package/src/modules/query_index/lib/indexer.ts +8 -0
- package/src/modules/query_index/lib/search-tokens.ts +2 -0
- package/src/modules/query_index/migrations/Migration20261005201500_query_index.ts +42 -0
- package/src/modules/translations/components/TranslationManager.tsx +3 -3
- package/src/modules/translations/data/validators.ts +1 -1
- package/src/modules/translations/lib/batch.ts +47 -0
- package/src/modules/translations/lib/helpers.ts +4 -0
- package/src/modules/translations/lib/resolve-field-list.ts +16 -2
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../src/modules/catalog/lib/omnibusTypes.ts"],
|
|
4
|
+
"sourcesContent": ["import { z } from 'zod'\n\nexport const PRICE_HISTORY_CHANGE_TYPES = ['create', 'update', 'delete', 'undo'] as const\n\nexport const priceHistoryChangeTypeSchema = z.enum(PRICE_HISTORY_CHANGE_TYPES)\n\nexport type PriceHistoryChangeType = z.infer<typeof priceHistoryChangeTypeSchema>\n\nexport const PRICE_HISTORY_SOURCES = ['api', 'system'] as const\n\nexport const priceHistorySourceSchema = z.enum(PRICE_HISTORY_SOURCES)\n\nexport type PriceHistorySource = z.infer<typeof priceHistorySourceSchema>\n\nconst numericString = z.string().regex(/^-?\\d+(\\.\\d+)?$/)\n\nexport const priceHistoryEntrySchema = z.object({\n tenantId: z.string().uuid(),\n organizationId: z.string().uuid(),\n priceId: z.string().uuid(),\n productId: z.string().uuid(),\n variantId: z.string().uuid().nullable(),\n offerId: z.string().uuid().nullable(),\n channelId: z.string().uuid().nullable(),\n priceKindId: z.string().uuid(),\n priceKindCode: z.string().min(1),\n currencyCode: z.string().length(3),\n unitPriceNet: numericString.nullable(),\n unitPriceGross: numericString.nullable(),\n taxRate: numericString.nullable(),\n taxAmount: numericString.nullable(),\n minQuantity: z.number().int().nullable(),\n maxQuantity: z.number().int().nullable(),\n startsAt: z.date().nullable(),\n endsAt: z.date().nullable(),\n recordedAt: z.date(),\n changeType: priceHistoryChangeTypeSchema,\n source: priceHistorySourceSchema,\n isAnnounced: z.boolean().nullable(),\n idempotencyKey: z.string().min(1).nullable(),\n metadata: z.record(z.string(), z.unknown()).nullable(),\n})\n\nexport type PriceHistoryEntryInput = z.infer<typeof priceHistoryEntrySchema>\n\nexport const OMNIBUS_CONFIG_MODULE_ID = 'catalog'\n\nexport const OMNIBUS_CONFIG_NAME = 'omnibus'\n\nexport const OMNIBUS_DEFAULT_LOOKBACK_DAYS = 30\n\nexport const OMNIBUS_NO_CHANNEL_MODES = ['best_effort', 'require_channel'] as const\n\nexport const omnibusNoChannelModeSchema = z.enum(OMNIBUS_NO_CHANNEL_MODES)\n\nexport type OmnibusNoChannelMode = z.infer<typeof omnibusNoChannelModeSchema>\n\nexport const OMNIBUS_MINIMIZATION_AXES = ['gross', 'net'] as const\n\nexport const omnibusMinimizationAxisSchema = z.enum(OMNIBUS_MINIMIZATION_AXES)\n\nexport type OmnibusMinimizationAxis = z.infer<typeof omnibusMinimizationAxisSchema>\n\nexport const OMNIBUS_APPLICABILITY_REASONS = [\n 'no_history',\n 'not_in_eu_market',\n 'missing_channel_context',\n 'insufficient_history',\n 'announced_promotion',\n 'not_announced',\n 'progressive_reduction_frozen',\n 'perishable_exempt',\n 'perishable_last_price',\n 'new_arrival_reduced_window',\n] as const\n\nexport const omnibusApplicabilityReasonSchema = z.enum(OMNIBUS_APPLICABILITY_REASONS)\n\nexport type OmnibusApplicabilityReason = z.infer<typeof omnibusApplicabilityReasonSchema>\n\nexport const omnibusCountryCodeSchema = z\n .string()\n .regex(/^[A-Z]{2}$/)\n .refine((value) => value !== 'EU')\n\nexport const omnibusLookbackDaysSchema = z.number().int().min(1).max(365)\n\nexport const omnibusChannelConfigSchema = z.object({\n presentedPriceKindId: z.string().uuid(),\n countryCode: omnibusCountryCodeSchema.optional(),\n lookbackDays: omnibusLookbackDaysSchema.optional(),\n minimizationAxis: omnibusMinimizationAxisSchema.optional(),\n})\n\nexport type OmnibusChannelConfig = z.infer<typeof omnibusChannelConfigSchema>\n\nexport const omnibusBackfillCoverageSchema = z.object({\n completedAt: z.string().datetime({ offset: true }),\n lookbackDays: omnibusLookbackDaysSchema,\n})\n\nexport const omnibusConfigSchema = z.object({\n enabled: z.boolean().default(false),\n enabledCountryCodes: z.array(omnibusCountryCodeSchema).default([]),\n noChannelMode: omnibusNoChannelModeSchema.default('best_effort'),\n lookbackDays: omnibusLookbackDaysSchema.default(OMNIBUS_DEFAULT_LOOKBACK_DAYS),\n minimizationAxis: omnibusMinimizationAxisSchema.default('gross'),\n defaultPresentedPriceKindId: z.string().uuid().optional(),\n backfillCoverage: z.record(z.string(), omnibusBackfillCoverageSchema).default({}),\n channels: z.record(z.string().uuid(), omnibusChannelConfigSchema).default({}),\n})\n\nexport type OmnibusConfig = z.infer<typeof omnibusConfigSchema>\n\nexport type OmnibusResolutionContext = {\n tenantId: string\n organizationId: string\n productId?: string | null\n variantId?: string | null\n offerId?: string | null\n channelId?: string | null\n priceKindId?: string | null\n currencyCode: string\n isStorefront?: boolean\n now?: Date\n}\n\nexport type OmnibusPresentedEntry = {\n priceId: string\n changeType: PriceHistoryChangeType\n recordedAt: Date | string\n startsAt?: Date | string | null\n offerId?: string | null\n isAnnounced?: boolean | null\n}\n\nexport type OmnibusResolutionRequest = {\n context: OmnibusResolutionContext\n presentedEntry?: OmnibusPresentedEntry | null\n priceKindIsPromotion?: boolean\n}\n\n/** Undo of this command removes the price, so its history row is a tombstone, not a price observation. */\nexport const OMNIBUS_PRICE_REMOVING_UNDO_COMMAND = 'catalog.prices.create'\n\nexport type OmnibusHistoryRow = {\n id: string\n priceId: string\n changeType: PriceHistoryChangeType\n recordedAt: string\n unitPriceNet: string | null\n unitPriceGross: string | null\n undoneCommand?: string | null\n}\n\nexport type OmnibusLowestPriceResult = {\n reason: OmnibusApplicabilityReason | null\n presentedPriceKindId: string | null\n lowestRow: OmnibusHistoryRow | null\n previousRow: OmnibusHistoryRow | null\n insufficientHistory: boolean\n promotionAnchorAt: string | null\n coverageStartAt: string | null\n windowStart: string | null\n windowEnd: string | null\n lookbackDays: number\n minimizationAxis: OmnibusMinimizationAxis\n}\n\nexport type OmnibusBlock = {\n presentedPriceKindId: string | null\n lookbackDays: number\n minimizationAxis: OmnibusMinimizationAxis\n promotionAnchorAt: string | null\n windowStart: string | null\n windowEnd: string | null\n coverageStartAt: string | null\n lowestPriceNet: string | null\n lowestPriceGross: string | null\n previousPriceNet: string | null\n previousPriceGross: string | null\n currencyCode: string\n applicable: boolean\n applicabilityReason: OmnibusApplicabilityReason\n}\n\nexport const omnibusBlockSchema = z.object({\n presentedPriceKindId: z.string().uuid().nullable(),\n lookbackDays: z.number().int(),\n minimizationAxis: omnibusMinimizationAxisSchema,\n promotionAnchorAt: z.string().nullable(),\n windowStart: z.string().nullable(),\n windowEnd: z.string().nullable(),\n coverageStartAt: z.string().nullable(),\n lowestPriceNet: z.string().nullable(),\n lowestPriceGross: z.string().nullable(),\n previousPriceNet: z.string().nullable(),\n previousPriceGross: z.string().nullable(),\n currencyCode: z.string(),\n applicable: z.boolean(),\n applicabilityReason: omnibusApplicabilityReasonSchema,\n}) satisfies z.ZodType<OmnibusBlock>\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
const OPTION_SCHEMA_TEMPLATE_ENTITY_TYPE = "catalog:catalog_option_schema_template";
|
|
2
|
+
function optionLabelTranslationField(optionCode) {
|
|
3
|
+
return `options.${optionCode}.label`;
|
|
4
|
+
}
|
|
5
|
+
function optionChoiceLabelTranslationField(optionCode, choiceCode) {
|
|
6
|
+
return `options.${optionCode}.choices.${choiceCode}.label`;
|
|
7
|
+
}
|
|
8
|
+
function isRecord(value) {
|
|
9
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
10
|
+
}
|
|
11
|
+
function nonEmptyText(value) {
|
|
12
|
+
return typeof value === "string" && value.trim().length > 0 ? value.trim() : null;
|
|
13
|
+
}
|
|
14
|
+
function expandOptionSchemaTranslationFields(record) {
|
|
15
|
+
const schema = isRecord(record.schema) ? record.schema : null;
|
|
16
|
+
const options = schema && Array.isArray(schema.options) ? schema.options : [];
|
|
17
|
+
const expansions = [];
|
|
18
|
+
const seen = /* @__PURE__ */ new Set();
|
|
19
|
+
const push = (expansion) => {
|
|
20
|
+
if (seen.has(expansion.key)) return;
|
|
21
|
+
seen.add(expansion.key);
|
|
22
|
+
expansions.push(expansion);
|
|
23
|
+
};
|
|
24
|
+
for (const option of options) {
|
|
25
|
+
if (!isRecord(option)) continue;
|
|
26
|
+
const optionCode = nonEmptyText(option.code);
|
|
27
|
+
if (!optionCode) continue;
|
|
28
|
+
const optionLabel = nonEmptyText(option.label) ?? optionCode;
|
|
29
|
+
push({
|
|
30
|
+
key: optionLabelTranslationField(optionCode),
|
|
31
|
+
label: optionLabel,
|
|
32
|
+
baseValue: nonEmptyText(option.label) ?? ""
|
|
33
|
+
});
|
|
34
|
+
const choices = Array.isArray(option.choices) ? option.choices : [];
|
|
35
|
+
for (const choice of choices) {
|
|
36
|
+
if (!isRecord(choice)) continue;
|
|
37
|
+
const choiceCode = nonEmptyText(choice.code);
|
|
38
|
+
if (!choiceCode) continue;
|
|
39
|
+
const choiceLabel = nonEmptyText(choice.label);
|
|
40
|
+
push({
|
|
41
|
+
key: optionChoiceLabelTranslationField(optionCode, choiceCode),
|
|
42
|
+
label: `${optionLabel} \u203A ${choiceLabel ?? choiceCode}`,
|
|
43
|
+
baseValue: choiceLabel ?? ""
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
return expansions;
|
|
48
|
+
}
|
|
49
|
+
export {
|
|
50
|
+
OPTION_SCHEMA_TEMPLATE_ENTITY_TYPE,
|
|
51
|
+
expandOptionSchemaTranslationFields,
|
|
52
|
+
optionChoiceLabelTranslationField,
|
|
53
|
+
optionLabelTranslationField
|
|
54
|
+
};
|
|
55
|
+
//# sourceMappingURL=optionSchemaTranslations.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../src/modules/catalog/lib/optionSchemaTranslations.ts"],
|
|
4
|
+
"sourcesContent": ["import type { TranslatableFieldExpansion } from '@open-mercato/shared/lib/localization/translatable-fields'\n\nexport const OPTION_SCHEMA_TEMPLATE_ENTITY_TYPE = 'catalog:catalog_option_schema_template'\n\nexport function optionLabelTranslationField(optionCode: string): string {\n return `options.${optionCode}.label`\n}\n\nexport function optionChoiceLabelTranslationField(optionCode: string, choiceCode: string): string {\n return `options.${optionCode}.choices.${choiceCode}.label`\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value)\n}\n\nfunction nonEmptyText(value: unknown): string | null {\n return typeof value === 'string' && value.trim().length > 0 ? value.trim() : null\n}\n\nexport function expandOptionSchemaTranslationFields(record: Record<string, unknown>): TranslatableFieldExpansion[] {\n const schema = isRecord(record.schema) ? record.schema : null\n const options = schema && Array.isArray(schema.options) ? schema.options : []\n const expansions: TranslatableFieldExpansion[] = []\n const seen = new Set<string>()\n const push = (expansion: TranslatableFieldExpansion) => {\n if (seen.has(expansion.key)) return\n seen.add(expansion.key)\n expansions.push(expansion)\n }\n for (const option of options) {\n if (!isRecord(option)) continue\n const optionCode = nonEmptyText(option.code)\n if (!optionCode) continue\n const optionLabel = nonEmptyText(option.label) ?? optionCode\n push({\n key: optionLabelTranslationField(optionCode),\n label: optionLabel,\n baseValue: nonEmptyText(option.label) ?? '',\n })\n const choices = Array.isArray(option.choices) ? option.choices : []\n for (const choice of choices) {\n if (!isRecord(choice)) continue\n const choiceCode = nonEmptyText(choice.code)\n if (!choiceCode) continue\n const choiceLabel = nonEmptyText(choice.label)\n push({\n key: optionChoiceLabelTranslationField(optionCode, choiceCode),\n label: `${optionLabel} \u203A ${choiceLabel ?? choiceCode}`,\n baseValue: choiceLabel ?? '',\n })\n }\n }\n return expansions\n}\n"],
|
|
5
|
+
"mappings": "AAEO,MAAM,qCAAqC;AAE3C,SAAS,4BAA4B,YAA4B;AACtE,SAAO,WAAW,UAAU;AAC9B;AAEO,SAAS,kCAAkC,YAAoB,YAA4B;AAChG,SAAO,WAAW,UAAU,YAAY,UAAU;AACpD;AAEA,SAAS,SAAS,OAAkD;AAClE,SAAO,OAAO,UAAU,YAAY,UAAU,QAAQ,CAAC,MAAM,QAAQ,KAAK;AAC5E;AAEA,SAAS,aAAa,OAA+B;AACnD,SAAO,OAAO,UAAU,YAAY,MAAM,KAAK,EAAE,SAAS,IAAI,MAAM,KAAK,IAAI;AAC/E;AAEO,SAAS,oCAAoC,QAA+D;AACjH,QAAM,SAAS,SAAS,OAAO,MAAM,IAAI,OAAO,SAAS;AACzD,QAAM,UAAU,UAAU,MAAM,QAAQ,OAAO,OAAO,IAAI,OAAO,UAAU,CAAC;AAC5E,QAAM,aAA2C,CAAC;AAClD,QAAM,OAAO,oBAAI,IAAY;AAC7B,QAAM,OAAO,CAAC,cAA0C;AACtD,QAAI,KAAK,IAAI,UAAU,GAAG,EAAG;AAC7B,SAAK,IAAI,UAAU,GAAG;AACtB,eAAW,KAAK,SAAS;AAAA,EAC3B;AACA,aAAW,UAAU,SAAS;AAC5B,QAAI,CAAC,SAAS,MAAM,EAAG;AACvB,UAAM,aAAa,aAAa,OAAO,IAAI;AAC3C,QAAI,CAAC,WAAY;AACjB,UAAM,cAAc,aAAa,OAAO,KAAK,KAAK;AAClD,SAAK;AAAA,MACH,KAAK,4BAA4B,UAAU;AAAA,MAC3C,OAAO;AAAA,MACP,WAAW,aAAa,OAAO,KAAK,KAAK;AAAA,IAC3C,CAAC;AACD,UAAM,UAAU,MAAM,QAAQ,OAAO,OAAO,IAAI,OAAO,UAAU,CAAC;AAClE,eAAW,UAAU,SAAS;AAC5B,UAAI,CAAC,SAAS,MAAM,EAAG;AACvB,YAAM,aAAa,aAAa,OAAO,IAAI;AAC3C,UAAI,CAAC,WAAY;AACjB,YAAM,cAAc,aAAa,OAAO,KAAK;AAC7C,WAAK;AAAA,QACH,KAAK,kCAAkC,YAAY,UAAU;AAAA,QAC7D,OAAO,GAAG,WAAW,WAAM,eAAe,UAAU;AAAA,QACpD,WAAW,eAAe;AAAA,MAC5B,CAAC;AAAA,IACH;AAAA,EACF;AACA,SAAO;AACT;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
const cursorSchema = z.object({
|
|
3
|
+
recordedAt: z.string().datetime({ offset: true }),
|
|
4
|
+
id: z.string().uuid()
|
|
5
|
+
});
|
|
6
|
+
function encodePriceHistoryCursor(cursor) {
|
|
7
|
+
return Buffer.from(JSON.stringify(cursor), "utf8").toString("base64");
|
|
8
|
+
}
|
|
9
|
+
function decodePriceHistoryCursor(value) {
|
|
10
|
+
if (typeof value !== "string" || value.trim().length === 0) return null;
|
|
11
|
+
try {
|
|
12
|
+
const decoded = Buffer.from(value.trim(), "base64").toString("utf8");
|
|
13
|
+
const parsed = cursorSchema.safeParse(JSON.parse(decoded));
|
|
14
|
+
if (!parsed.success) return null;
|
|
15
|
+
return { recordedAt: new Date(parsed.data.recordedAt).toISOString(), id: parsed.data.id };
|
|
16
|
+
} catch {
|
|
17
|
+
return null;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
function resolvePriceHistoryOrganizationIds(scope, authOrganizationId) {
|
|
21
|
+
if (scope.selectedId) return [scope.selectedId];
|
|
22
|
+
if (Array.isArray(scope.filterIds) && scope.filterIds.length > 0) return Array.from(new Set(scope.filterIds));
|
|
23
|
+
if (scope.filterIds === null && scope.allowedIds === null) return null;
|
|
24
|
+
return authOrganizationId ? [authOrganizationId] : [];
|
|
25
|
+
}
|
|
26
|
+
function buildPriceHistoryWhere(scope, query) {
|
|
27
|
+
const where = { tenantId: scope.tenantId };
|
|
28
|
+
if (scope.organizationIds) where.organizationId = { $in: scope.organizationIds };
|
|
29
|
+
if (query.productId) where.productId = query.productId;
|
|
30
|
+
if (query.variantId) where.variantId = query.variantId;
|
|
31
|
+
if (query.priceKindId) where.priceKindId = query.priceKindId;
|
|
32
|
+
if (query.channelId) where.channelId = query.channelId;
|
|
33
|
+
if (query.currencyCode) where.currencyCode = query.currencyCode;
|
|
34
|
+
const recordedAt = {};
|
|
35
|
+
if (query.from) recordedAt.$gte = new Date(query.from);
|
|
36
|
+
if (query.to) recordedAt.$lte = new Date(query.to);
|
|
37
|
+
if (Object.keys(recordedAt).length > 0) where.recordedAt = recordedAt;
|
|
38
|
+
return where;
|
|
39
|
+
}
|
|
40
|
+
function applyPriceHistoryCursor(where, cursor) {
|
|
41
|
+
if (!cursor) return where;
|
|
42
|
+
const recordedAt = new Date(cursor.recordedAt);
|
|
43
|
+
return {
|
|
44
|
+
$and: [
|
|
45
|
+
where,
|
|
46
|
+
{
|
|
47
|
+
$or: [
|
|
48
|
+
{ recordedAt: { $lt: recordedAt } },
|
|
49
|
+
{ recordedAt, id: { $lt: cursor.id } }
|
|
50
|
+
]
|
|
51
|
+
}
|
|
52
|
+
]
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
function formatFixedDecimal4(value) {
|
|
56
|
+
if (value === null || value === void 0) return null;
|
|
57
|
+
const raw = typeof value === "number" ? value.toFixed(4) : value.trim();
|
|
58
|
+
const match = /^(-?)(\d+)(?:\.(\d*))?$/.exec(raw);
|
|
59
|
+
if (!match) return raw;
|
|
60
|
+
const [, sign, whole, fraction = ""] = match;
|
|
61
|
+
const normalizedFraction = fraction.length >= 4 ? fraction.slice(0, 4) : fraction.padEnd(4, "0");
|
|
62
|
+
return `${sign}${whole}.${normalizedFraction}`;
|
|
63
|
+
}
|
|
64
|
+
function toIsoOrNull(value) {
|
|
65
|
+
if (!value) return null;
|
|
66
|
+
const date = value instanceof Date ? value : new Date(value);
|
|
67
|
+
return Number.isNaN(date.getTime()) ? null : date.toISOString();
|
|
68
|
+
}
|
|
69
|
+
function serializePriceHistoryEntry(entry) {
|
|
70
|
+
return {
|
|
71
|
+
id: entry.id,
|
|
72
|
+
priceId: entry.priceId,
|
|
73
|
+
productId: entry.productId,
|
|
74
|
+
variantId: entry.variantId ?? null,
|
|
75
|
+
offerId: entry.offerId ?? null,
|
|
76
|
+
channelId: entry.channelId ?? null,
|
|
77
|
+
priceKindId: entry.priceKindId,
|
|
78
|
+
priceKindCode: entry.priceKindCode,
|
|
79
|
+
currencyCode: entry.currencyCode,
|
|
80
|
+
unitPriceNet: formatFixedDecimal4(entry.unitPriceNet),
|
|
81
|
+
unitPriceGross: formatFixedDecimal4(entry.unitPriceGross),
|
|
82
|
+
taxRate: formatFixedDecimal4(entry.taxRate),
|
|
83
|
+
taxAmount: formatFixedDecimal4(entry.taxAmount),
|
|
84
|
+
minQuantity: entry.minQuantity ?? null,
|
|
85
|
+
maxQuantity: entry.maxQuantity ?? null,
|
|
86
|
+
startsAt: toIsoOrNull(entry.startsAt),
|
|
87
|
+
endsAt: toIsoOrNull(entry.endsAt),
|
|
88
|
+
recordedAt: toIsoOrNull(entry.recordedAt) ?? (/* @__PURE__ */ new Date(0)).toISOString(),
|
|
89
|
+
changeType: entry.changeType,
|
|
90
|
+
source: entry.source,
|
|
91
|
+
isAnnounced: entry.isAnnounced === true
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
export {
|
|
95
|
+
applyPriceHistoryCursor,
|
|
96
|
+
buildPriceHistoryWhere,
|
|
97
|
+
decodePriceHistoryCursor,
|
|
98
|
+
encodePriceHistoryCursor,
|
|
99
|
+
formatFixedDecimal4,
|
|
100
|
+
resolvePriceHistoryOrganizationIds,
|
|
101
|
+
serializePriceHistoryEntry
|
|
102
|
+
};
|
|
103
|
+
//# sourceMappingURL=priceHistoryQuery.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../src/modules/catalog/lib/priceHistoryQuery.ts"],
|
|
4
|
+
"sourcesContent": ["import { z } from 'zod'\nimport type { FilterQuery } from '@mikro-orm/postgresql'\nimport type { CatalogPriceHistoryEntry } from '../data/entities'\nimport type { PriceHistoryQuery } from '../data/validators'\nimport type { PriceHistoryChangeType, PriceHistorySource } from './omnibusTypes'\n\nexport type PriceHistoryCursor = {\n recordedAt: string\n id: string\n}\n\nconst cursorSchema = z.object({\n recordedAt: z.string().datetime({ offset: true }),\n id: z.string().uuid(),\n})\n\nexport function encodePriceHistoryCursor(cursor: PriceHistoryCursor): string {\n return Buffer.from(JSON.stringify(cursor), 'utf8').toString('base64')\n}\n\nexport function decodePriceHistoryCursor(value: string | null | undefined): PriceHistoryCursor | null {\n if (typeof value !== 'string' || value.trim().length === 0) return null\n try {\n const decoded = Buffer.from(value.trim(), 'base64').toString('utf8')\n const parsed = cursorSchema.safeParse(JSON.parse(decoded))\n if (!parsed.success) return null\n return { recordedAt: new Date(parsed.data.recordedAt).toISOString(), id: parsed.data.id }\n } catch {\n return null\n }\n}\n\nexport type PriceHistoryScope = {\n tenantId: string\n organizationIds: string[] | null\n}\n\nexport type PriceHistoryOrganizationScopeInput = {\n selectedId: string | null\n filterIds: string[] | null\n allowedIds: string[] | null\n}\n\nexport function resolvePriceHistoryOrganizationIds(\n scope: PriceHistoryOrganizationScopeInput,\n authOrganizationId: string | null | undefined,\n): string[] | null {\n if (scope.selectedId) return [scope.selectedId]\n if (Array.isArray(scope.filterIds) && scope.filterIds.length > 0) return Array.from(new Set(scope.filterIds))\n if (scope.filterIds === null && scope.allowedIds === null) return null\n return authOrganizationId ? [authOrganizationId] : []\n}\n\nexport function buildPriceHistoryWhere(\n scope: PriceHistoryScope,\n query: PriceHistoryQuery,\n): FilterQuery<CatalogPriceHistoryEntry> {\n const where: Record<string, unknown> = { tenantId: scope.tenantId }\n if (scope.organizationIds) where.organizationId = { $in: scope.organizationIds }\n if (query.productId) where.productId = query.productId\n if (query.variantId) where.variantId = query.variantId\n if (query.priceKindId) where.priceKindId = query.priceKindId\n if (query.channelId) where.channelId = query.channelId\n if (query.currencyCode) where.currencyCode = query.currencyCode\n const recordedAt: Record<string, Date> = {}\n if (query.from) recordedAt.$gte = new Date(query.from)\n if (query.to) recordedAt.$lte = new Date(query.to)\n if (Object.keys(recordedAt).length > 0) where.recordedAt = recordedAt\n return where as FilterQuery<CatalogPriceHistoryEntry>\n}\n\nexport function applyPriceHistoryCursor(\n where: FilterQuery<CatalogPriceHistoryEntry>,\n cursor: PriceHistoryCursor | null,\n): FilterQuery<CatalogPriceHistoryEntry> {\n if (!cursor) return where\n const recordedAt = new Date(cursor.recordedAt)\n return {\n $and: [\n where,\n {\n $or: [\n { recordedAt: { $lt: recordedAt } },\n { recordedAt, id: { $lt: cursor.id } },\n ],\n },\n ],\n } as FilterQuery<CatalogPriceHistoryEntry>\n}\n\nexport function formatFixedDecimal4(value: string | number | null | undefined): string | null {\n if (value === null || value === undefined) return null\n const raw = typeof value === 'number' ? value.toFixed(4) : value.trim()\n const match = /^(-?)(\\d+)(?:\\.(\\d*))?$/.exec(raw)\n if (!match) return raw\n const [, sign, whole, fraction = ''] = match\n const normalizedFraction = fraction.length >= 4 ? fraction.slice(0, 4) : fraction.padEnd(4, '0')\n return `${sign}${whole}.${normalizedFraction}`\n}\n\nfunction toIsoOrNull(value: Date | string | null | undefined): string | null {\n if (!value) return null\n const date = value instanceof Date ? value : new Date(value)\n return Number.isNaN(date.getTime()) ? null : date.toISOString()\n}\n\nexport type PriceHistoryItem = {\n id: string\n priceId: string\n productId: string\n variantId: string | null\n offerId: string | null\n channelId: string | null\n priceKindId: string\n priceKindCode: string\n currencyCode: string\n unitPriceNet: string | null\n unitPriceGross: string | null\n taxRate: string | null\n taxAmount: string | null\n minQuantity: number | null\n maxQuantity: number | null\n startsAt: string | null\n endsAt: string | null\n recordedAt: string\n changeType: PriceHistoryChangeType\n source: PriceHistorySource\n isAnnounced: boolean\n}\n\nexport function serializePriceHistoryEntry(entry: CatalogPriceHistoryEntry): PriceHistoryItem {\n return {\n id: entry.id,\n priceId: entry.priceId,\n productId: entry.productId,\n variantId: entry.variantId ?? null,\n offerId: entry.offerId ?? null,\n channelId: entry.channelId ?? null,\n priceKindId: entry.priceKindId,\n priceKindCode: entry.priceKindCode,\n currencyCode: entry.currencyCode,\n unitPriceNet: formatFixedDecimal4(entry.unitPriceNet),\n unitPriceGross: formatFixedDecimal4(entry.unitPriceGross),\n taxRate: formatFixedDecimal4(entry.taxRate),\n taxAmount: formatFixedDecimal4(entry.taxAmount),\n minQuantity: entry.minQuantity ?? null,\n maxQuantity: entry.maxQuantity ?? null,\n startsAt: toIsoOrNull(entry.startsAt),\n endsAt: toIsoOrNull(entry.endsAt),\n recordedAt: toIsoOrNull(entry.recordedAt) ?? new Date(0).toISOString(),\n changeType: entry.changeType,\n source: entry.source,\n isAnnounced: entry.isAnnounced === true,\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -11,6 +11,19 @@ function resolvePriceChannelId(row) {
|
|
|
11
11
|
if (typeof row.offer === "string") return row.channelId ?? null;
|
|
12
12
|
return row.channelId ?? row.offer.channelId ?? null;
|
|
13
13
|
}
|
|
14
|
+
function resolvePriceKindId(row) {
|
|
15
|
+
if (!row.priceKind) return null;
|
|
16
|
+
return typeof row.priceKind === "string" ? row.priceKind : row.priceKind.id ?? null;
|
|
17
|
+
}
|
|
18
|
+
function resolveContextCustomerIds(ctx) {
|
|
19
|
+
return ctx.customerIds ?? (ctx.customerId ? [ctx.customerId] : []);
|
|
20
|
+
}
|
|
21
|
+
function isPromotionalPriceKindRow(row) {
|
|
22
|
+
return Boolean(row.priceKind && typeof row.priceKind !== "string" && row.priceKind.isPromotion === true);
|
|
23
|
+
}
|
|
24
|
+
function matchesPriceKind(row, priceKindId) {
|
|
25
|
+
return resolvePriceKindId(row) === priceKindId || isPromotionalPriceKindRow(row);
|
|
26
|
+
}
|
|
14
27
|
function resolvePriceKindCode(row) {
|
|
15
28
|
if (row.priceKind) {
|
|
16
29
|
if (typeof row.priceKind === "string") return row.priceKind;
|
|
@@ -31,19 +44,21 @@ function matchesContext(row, ctx) {
|
|
|
31
44
|
}
|
|
32
45
|
if (row.userId && ctx.userId !== row.userId) return false;
|
|
33
46
|
if (row.userGroupId && ctx.userGroupId !== row.userGroupId) return false;
|
|
34
|
-
if (row.customerId && ctx.
|
|
47
|
+
if (row.customerId && !resolveContextCustomerIds(ctx).includes(row.customerId)) return false;
|
|
35
48
|
if (row.customerGroupId) {
|
|
36
49
|
const candidateGroupIds = ctx.customerGroupIds ?? (ctx.customerGroupId ? [ctx.customerGroupId] : []);
|
|
37
50
|
if (!candidateGroupIds.includes(row.customerGroupId)) return false;
|
|
38
51
|
}
|
|
39
52
|
if (ctx.currencyCode && row.currencyCode !== ctx.currencyCode) return false;
|
|
53
|
+
if (ctx.priceKindId && !matchesPriceKind(row, ctx.priceKindId)) return false;
|
|
40
54
|
if (ctx.offerId && resolvePriceOfferId(row) && resolvePriceOfferId(row) !== ctx.offerId) return false;
|
|
41
55
|
return true;
|
|
42
56
|
}
|
|
43
57
|
function buildPriceRowFilter(ctx) {
|
|
44
58
|
const customerGroupIds = ctx.customerGroupIds ?? (ctx.customerGroupId ? [ctx.customerGroupId] : []);
|
|
59
|
+
const customerIds = resolveContextCustomerIds(ctx);
|
|
45
60
|
const clauses = [
|
|
46
|
-
|
|
61
|
+
customerIds.length ? { $or: [{ customerId: null }, { customerId: { $in: customerIds } }] } : { customerId: null },
|
|
47
62
|
customerGroupIds.length ? { $or: [{ customerGroupId: null }, { customerGroupId: { $in: customerGroupIds } }] } : { customerGroupId: null },
|
|
48
63
|
ctx.userId ? { $or: [{ userId: null }, { userId: ctx.userId }] } : { userId: null },
|
|
49
64
|
ctx.userGroupId ? { $or: [{ userGroupId: null }, { userGroupId: ctx.userGroupId }] } : { userGroupId: null },
|
|
@@ -52,6 +67,9 @@ function buildPriceRowFilter(ctx) {
|
|
|
52
67
|
if (ctx.currencyCode) {
|
|
53
68
|
clauses.push({ currencyCode: ctx.currencyCode });
|
|
54
69
|
}
|
|
70
|
+
if (ctx.priceKindId) {
|
|
71
|
+
clauses.push({ $or: [{ priceKind: ctx.priceKindId }, { priceKind: { isPromotion: true } }] });
|
|
72
|
+
}
|
|
55
73
|
return { $and: clauses };
|
|
56
74
|
}
|
|
57
75
|
function scorePrice(row) {
|
|
@@ -74,9 +92,14 @@ function scorePrice(row) {
|
|
|
74
92
|
function selectBestPrice(rows, ctx) {
|
|
75
93
|
const candidates = rows.filter((row) => matchesContext(row, ctx));
|
|
76
94
|
if (!candidates.length) return null;
|
|
95
|
+
const customerIds = resolveContextCustomerIds(ctx);
|
|
96
|
+
const customerRank = (row) => row.customerId ? customerIds.indexOf(row.customerId) : -1;
|
|
77
97
|
candidates.sort((a, b) => {
|
|
78
98
|
const scoreDiff = scorePrice(b) - scorePrice(a);
|
|
79
99
|
if (scoreDiff !== 0) return scoreDiff;
|
|
100
|
+
const rankA = customerRank(a);
|
|
101
|
+
const rankB = customerRank(b);
|
|
102
|
+
if (rankA >= 0 && rankB >= 0 && rankA !== rankB) return rankA - rankB;
|
|
80
103
|
const startA = a.startsAt ? a.startsAt.getTime() : 0;
|
|
81
104
|
const startB = b.startsAt ? b.startsAt.getTime() : 0;
|
|
82
105
|
if (startA !== startB) return startB - startA;
|
|
@@ -164,6 +187,7 @@ export {
|
|
|
164
187
|
resolveCatalogPriceBatch,
|
|
165
188
|
resolvePriceChannelId,
|
|
166
189
|
resolvePriceKindCode,
|
|
190
|
+
resolvePriceKindId,
|
|
167
191
|
resolvePriceOfferId,
|
|
168
192
|
resolvePriceVariantId,
|
|
169
193
|
selectBestPrice
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/modules/catalog/lib/pricing.ts"],
|
|
4
|
-
"sourcesContent": ["import type { EventBus } from '@open-mercato/events'\nimport type { FilterQuery } from '@mikro-orm/postgresql'\nimport type {\n CatalogOffer,\n CatalogPriceKind,\n CatalogProduct,\n CatalogProductPrice,\n CatalogProductVariant,\n} from '../data/entities'\n\nexport type PricingContext = {\n channelId?: string | null\n offerId?: string | null\n userId?: string | null\n userGroupId?: string | null\n customerId?: string | null\n /** @deprecated use `customerGroupIds` \u2014 kept for backward compatibility, read as a one-element set when `customerGroupIds` is absent. */\n customerGroupId?: string | null\n /** Set membership: a row's `customerGroupId` matches when it appears in this list. Falls back to `customerGroupId` (above) when omitted. */\n customerGroupIds?: string[]\n /** When set, only rows in this currency match. Omitted (the default): no currency filtering, unchanged legacy behavior. */\n currencyCode?: string | null\n quantity: number\n date: Date\n}\n\nexport type PriceRow = CatalogProductPrice & {\n product?: CatalogProduct | string | null\n variant?: CatalogProductVariant | string | null\n offer?: CatalogOffer | string | null\n priceKind?: CatalogPriceKind | string | null\n}\n\nexport function resolvePriceVariantId(row: PriceRow): string | null {\n if (!row.variant) return null\n return typeof row.variant === 'string' ? row.variant : row.variant.id\n}\n\nexport function resolvePriceOfferId(row: PriceRow): string | null {\n if (!row.offer) return null\n return typeof row.offer === 'string' ? row.offer : row.offer.id\n}\n\nexport function resolvePriceChannelId(row: PriceRow): string | null {\n if (!row.offer) return row.channelId ?? null\n if (typeof row.offer === 'string') return row.channelId ?? null\n return row.channelId ?? row.offer.channelId ?? null\n}\n\nexport function resolvePriceKindCode(row: PriceRow): string {\n if (row.priceKind) {\n if (typeof row.priceKind === 'string') return row.priceKind\n return row.priceKind.code ?? row.kind ?? ''\n }\n return row.kind ?? ''\n}\n\nfunction matchesContext(row: PriceRow, ctx: PricingContext): boolean {\n const { quantity, date } = ctx\n if (row.minQuantity && quantity < row.minQuantity) return false\n if (row.maxQuantity && quantity > row.maxQuantity) return false\n if (row.startsAt && date < row.startsAt) return false\n if (row.endsAt && date > row.endsAt) return false\n if (row.channelId || (row.offer && resolvePriceChannelId(row))) {\n const channel = resolvePriceChannelId(row)\n if (channel && ctx.channelId && channel !== ctx.channelId) return false\n if (channel && !ctx.channelId) return false\n }\n if (row.userId && ctx.userId !== row.userId) return false\n if (row.userGroupId && ctx.userGroupId !== row.userGroupId) return false\n if (row.customerId && ctx.customerId !== row.customerId) return false\n if (row.customerGroupId) {\n const candidateGroupIds = ctx.customerGroupIds ?? (ctx.customerGroupId ? [ctx.customerGroupId] : [])\n if (!candidateGroupIds.includes(row.customerGroupId)) return false\n }\n if (ctx.currencyCode && row.currencyCode !== ctx.currencyCode) return false\n if (ctx.offerId && resolvePriceOfferId(row) && resolvePriceOfferId(row) !== ctx.offerId) return false\n return true\n}\n\n/**\n * The narrowing half of `matchesContext` expressed as a MikroORM filter, for\n * callers that fetch `CatalogProductPrice` rows by product/variant today and\n * would otherwise load every contracted customer's rows just to discard\n * almost all of them (per-customer pricing at scale \u2014 see\n * `.ai/specs/2026-08-21-pricing-engine.md` \u00A7 Row narrowing).\n *\n * Covers only the dimensions that are plain column comparisons: customer,\n * customer-group, user, user-group, channel, currency. Quantity bounds,\n * validity windows, and offer-derived channel resolution stay in\n * `matchesContext` \u2014 they are cheap over an already-narrowed set and are not\n * expressible as one column predicate (offer's own `channelId` lives on a\n * different table).\n *\n * **Invariant (one-directional, this is the whole point of the helper):**\n * `matchesContext(row, ctx)` implies this filter admits `row`. The filter\n * MAY admit rows `matchesContext` later rejects (a slightly wide fetch) \u2014\n * it MUST NEVER exclude a row `matchesContext` would have accepted, because\n * that is a silently wrong price with no error anywhere. Verified by the\n * property-based test in `lib/__tests__/buildPriceRowFilter.property.test.ts`.\n */\nexport function buildPriceRowFilter(ctx: PricingContext): FilterQuery<CatalogProductPrice> {\n const customerGroupIds = ctx.customerGroupIds ?? (ctx.customerGroupId ? [ctx.customerGroupId] : [])\n\n const clauses: FilterQuery<CatalogProductPrice>[] = [\n ctx.customerId\n ? { $or: [{ customerId: null }, { customerId: ctx.customerId }] }\n : { customerId: null },\n customerGroupIds.length\n ? { $or: [{ customerGroupId: null }, { customerGroupId: { $in: customerGroupIds } }] }\n : { customerGroupId: null },\n ctx.userId\n ? { $or: [{ userId: null }, { userId: ctx.userId }] }\n : { userId: null },\n ctx.userGroupId\n ? { $or: [{ userGroupId: null }, { userGroupId: ctx.userGroupId }] }\n : { userGroupId: null },\n ctx.channelId\n ? { $or: [{ channelId: null }, { channelId: ctx.channelId }] }\n : { channelId: null },\n ]\n\n if (ctx.currencyCode) {\n clauses.push({ currencyCode: ctx.currencyCode })\n }\n\n return { $and: clauses } as FilterQuery<CatalogProductPrice>\n}\n\nfunction scorePrice(row: PriceRow): number {\n const resolvedKind = resolvePriceKindCode(row)\n let score = 0\n if (resolvedKind === 'custom') score += 5\n else if (resolvedKind === 'tier') score += 3\n else if (resolvedKind === 'promotion' || row.priceKind?.isPromotion) score += 4\n else score += 2\n if (row.variant) score += 8\n if (row.offer) score += 6\n if (row.channelId) score += 5\n if (row.userId) score += 5\n if (row.userGroupId) score += 4\n if (row.customerId) score += 4\n if (row.customerGroupId) score += 3\n if (row.minQuantity && row.minQuantity > 1) score += 1\n return score\n}\n\nexport function selectBestPrice(rows: PriceRow[], ctx: PricingContext): PriceRow | null {\n const candidates = rows.filter((row) => matchesContext(row, ctx))\n if (!candidates.length) return null\n candidates.sort((a, b) => {\n const scoreDiff = scorePrice(b) - scorePrice(a)\n if (scoreDiff !== 0) return scoreDiff\n const startA = a.startsAt ? a.startsAt.getTime() : 0\n const startB = b.startsAt ? b.startsAt.getTime() : 0\n if (startA !== startB) return startB - startA\n // minQuantity tie-break is direction-dependent on the resolved kind.\n // Within the same kind we pick the more specific tier (higher minQuantity wins \u2014 issue #1706).\n // Across kinds we keep the pre-#1706 ascending order so a row whose kind has a higher\n // scoreBase still wins when scorePrice's \"+1 for minQuantity > 1\" bonus produces a\n // cross-kind collision (e.g. promotion[minQty=1]=4 vs tier[minQty=3]=4).\n if (resolvePriceKindCode(a) === resolvePriceKindCode(b)) {\n return (b.minQuantity ?? 1) - (a.minQuantity ?? 1)\n }\n return (a.minQuantity ?? 1) - (b.minQuantity ?? 1)\n })\n return candidates[0]\n}\n\nexport type CatalogPricingResolver = (\n rows: PriceRow[],\n ctx: PricingContext\n) => PriceRow | null | undefined | Promise<PriceRow | null | undefined>\n\ntype RegisteredResolver = {\n id?: string\n resolver: CatalogPricingResolver\n priority: number\n}\n\ntype PricingRegistryState = {\n resolvers: RegisteredResolver[]\n}\n\n// `globalThis`-keyed so the registry survives duplicated module instances\n// (a standalone app built from this monorepo, or any dev/build setup that\n// loads `catalog` through more than one chunk) \u2014 the same failure class\n// already fixed once for the ORM entity registry\n// (see `packages/shared/src/modules/integrations/types.ts` for the identical\n// pattern). A module-local array is invisible across instances: a resolver\n// registered from one instance would silently never run for resolution\n// happening in another.\nconst GLOBAL_PRICING_REGISTRY_KEY = '__openMercatoCatalogPricingRegistry__' as const\n\ntype GlobalPricingRegistry = typeof globalThis & {\n [GLOBAL_PRICING_REGISTRY_KEY]?: PricingRegistryState\n}\n\nfunction getPricingRegistryState(): PricingRegistryState {\n const globalRegistry = globalThis as GlobalPricingRegistry\n if (!globalRegistry[GLOBAL_PRICING_REGISTRY_KEY]) {\n globalRegistry[GLOBAL_PRICING_REGISTRY_KEY] = { resolvers: [] }\n }\n return globalRegistry[GLOBAL_PRICING_REGISTRY_KEY]\n}\n\nfunction sortResolvers(state: PricingRegistryState): void {\n // `Array.prototype.sort` is stable (ES2019+): resolvers registered at the\n // same priority keep their registration order. This is the documented,\n // tested same-priority tie-break \u2014 see `catalog/AGENTS.md` \u00A7 Price\n // selection order and the registry test in `lib/__tests__/pricing.test.ts`.\n state.resolvers.sort((a, b) => b.priority - a.priority)\n}\n\nexport function registerCatalogPricingResolver(\n resolver: CatalogPricingResolver,\n options?: { priority?: number; id?: string }\n): void {\n const state = getPricingRegistryState()\n const id = options?.id\n // Dedupe by id so a documented extension point stays HMR-safe for every\n // future registrant, not just one caller: re-registering the same id is a\n // no-op instead of appending a duplicate entry on every module reload.\n if (id && state.resolvers.some((entry) => entry.id === id)) return\n state.resolvers.push({ id, resolver, priority: options?.priority ?? 0 })\n sortResolvers(state)\n}\n\nexport function resetCatalogPricingResolvers(): void {\n getPricingRegistryState().resolvers.splice(0)\n}\n\nexport async function resolveCatalogPrice(\n rows: PriceRow[],\n ctx: PricingContext,\n options?: { eventBus?: EventBus | null }\n): Promise<PriceRow | null> {\n let workingRows = rows\n let workingContext = ctx\n const eventBus = options?.eventBus ?? null\n let resolved: PriceRow | null | undefined\n\n if (eventBus) {\n await eventBus.emitEvent('catalog.pricing.resolve.before', {\n rows: workingRows,\n context: workingContext,\n setRows(next: PriceRow[]) {\n if (Array.isArray(next)) workingRows = next\n },\n setContext(next: PricingContext) {\n if (next) workingContext = next\n },\n setResult(next: PriceRow | null) {\n resolved = next\n },\n })\n if (resolved !== undefined) return resolved\n }\n\n for (const { resolver } of getPricingRegistryState().resolvers) {\n const result = await resolver(workingRows, workingContext)\n if (result !== undefined) {\n resolved = result ?? null\n break\n }\n }\n\n if (resolved === undefined) {\n resolved = selectBestPrice(workingRows, workingContext)\n }\n\n if (eventBus) {\n await eventBus.emitEvent('catalog.pricing.resolve.after', {\n rows: workingRows,\n context: workingContext,\n result: resolved ?? null,\n setResult(next: PriceRow | null) {\n resolved = next\n },\n })\n }\n\n return resolved ?? null\n}\n\nexport async function resolveCatalogPriceBatch(\n entries: Array<{ rows: PriceRow[]; context: PricingContext }>,\n options?: { eventBus?: EventBus | null }\n): Promise<Array<PriceRow | null>> {\n return Promise.all(\n entries.map(({ rows, context }) => resolveCatalogPrice(rows, context, options))\n )\n}\n"],
|
|
5
|
-
"mappings": "
|
|
4
|
+
"sourcesContent": ["import type { EventBus } from '@open-mercato/events'\nimport type { FilterQuery } from '@mikro-orm/postgresql'\nimport type {\n CatalogOffer,\n CatalogPriceKind,\n CatalogProduct,\n CatalogProductPrice,\n CatalogProductVariant,\n} from '../data/entities'\n\nexport type PricingContext = {\n channelId?: string | null\n offerId?: string | null\n userId?: string | null\n userGroupId?: string | null\n customerId?: string | null\n /** @deprecated use `customerGroupIds` \u2014 kept for backward compatibility, read as a one-element set when `customerGroupIds` is absent. */\n customerGroupId?: string | null\n /** Set membership: a row's `customerGroupId` matches when it appears in this list. Falls back to `customerGroupId` (above) when omitted. */\n customerGroupIds?: string[]\n /** When set, only rows in this currency match. Omitted (the default): no currency filtering, unchanged legacy behavior. */\n currencyCode?: string | null\n /**\n * When set, only rows of this price kind (by `CatalogPriceKind` id) match, plus rows of any promotional\n * kind (`CatalogPriceKind.isPromotion === true`) as an overlay (pricing-engine amendment D2a). Promotion\n * status is read from a populated `priceKind`; a row carrying only a kind id string is admitted solely when\n * that id equals this one. Unset or `null`: kind is not filtered, unchanged legacy behavior.\n */\n priceKindId?: string | null\n /** The buyer's customer entities, person first, then company. A row's `customerId` matches when it appears in this list. Falls back to `customerId` (above) when omitted. */\n customerIds?: string[]\n quantity: number\n date: Date\n}\n\nexport type PriceRow = CatalogProductPrice & {\n product?: CatalogProduct | string | null\n variant?: CatalogProductVariant | string | null\n offer?: CatalogOffer | string | null\n priceKind?: CatalogPriceKind | string | null\n}\n\nexport function resolvePriceVariantId(row: PriceRow): string | null {\n if (!row.variant) return null\n return typeof row.variant === 'string' ? row.variant : row.variant.id\n}\n\nexport function resolvePriceOfferId(row: PriceRow): string | null {\n if (!row.offer) return null\n return typeof row.offer === 'string' ? row.offer : row.offer.id\n}\n\nexport function resolvePriceChannelId(row: PriceRow): string | null {\n if (!row.offer) return row.channelId ?? null\n if (typeof row.offer === 'string') return row.channelId ?? null\n return row.channelId ?? row.offer.channelId ?? null\n}\n\nexport function resolvePriceKindId(row: PriceRow): string | null {\n if (!row.priceKind) return null\n return typeof row.priceKind === 'string' ? row.priceKind : row.priceKind.id ?? null\n}\n\nfunction resolveContextCustomerIds(ctx: PricingContext): string[] {\n return ctx.customerIds ?? (ctx.customerId ? [ctx.customerId] : [])\n}\n\nfunction isPromotionalPriceKindRow(row: PriceRow): boolean {\n return Boolean(row.priceKind && typeof row.priceKind !== 'string' && row.priceKind.isPromotion === true)\n}\n\nfunction matchesPriceKind(row: PriceRow, priceKindId: string): boolean {\n return resolvePriceKindId(row) === priceKindId || isPromotionalPriceKindRow(row)\n}\n\nexport function resolvePriceKindCode(row: PriceRow): string {\n if (row.priceKind) {\n if (typeof row.priceKind === 'string') return row.priceKind\n return row.priceKind.code ?? row.kind ?? ''\n }\n return row.kind ?? ''\n}\n\nfunction matchesContext(row: PriceRow, ctx: PricingContext): boolean {\n const { quantity, date } = ctx\n if (row.minQuantity && quantity < row.minQuantity) return false\n if (row.maxQuantity && quantity > row.maxQuantity) return false\n if (row.startsAt && date < row.startsAt) return false\n if (row.endsAt && date > row.endsAt) return false\n if (row.channelId || (row.offer && resolvePriceChannelId(row))) {\n const channel = resolvePriceChannelId(row)\n if (channel && ctx.channelId && channel !== ctx.channelId) return false\n if (channel && !ctx.channelId) return false\n }\n if (row.userId && ctx.userId !== row.userId) return false\n if (row.userGroupId && ctx.userGroupId !== row.userGroupId) return false\n if (row.customerId && !resolveContextCustomerIds(ctx).includes(row.customerId)) return false\n if (row.customerGroupId) {\n const candidateGroupIds = ctx.customerGroupIds ?? (ctx.customerGroupId ? [ctx.customerGroupId] : [])\n if (!candidateGroupIds.includes(row.customerGroupId)) return false\n }\n if (ctx.currencyCode && row.currencyCode !== ctx.currencyCode) return false\n if (ctx.priceKindId && !matchesPriceKind(row, ctx.priceKindId)) return false\n if (ctx.offerId && resolvePriceOfferId(row) && resolvePriceOfferId(row) !== ctx.offerId) return false\n return true\n}\n\n/**\n * The narrowing half of `matchesContext` expressed as a MikroORM filter, for\n * callers that fetch `CatalogProductPrice` rows by product/variant today and\n * would otherwise load every contracted customer's rows just to discard\n * almost all of them (per-customer pricing at scale \u2014 see\n * `.ai/specs/2026-08-21-pricing-engine.md` \u00A7 Row narrowing).\n *\n * Covers only the dimensions that are plain column comparisons: customer,\n * customer-group, user, user-group, channel, currency, price kind (the resolved\n * kind or any promotional kind, via a `priceKind.isPromotion` relation clause). Quantity bounds,\n * validity windows, and offer-derived channel resolution stay in\n * `matchesContext` \u2014 they are cheap over an already-narrowed set and are not\n * expressible as one column predicate (offer's own `channelId` lives on a\n * different table).\n *\n * **Invariant (one-directional, this is the whole point of the helper):**\n * `matchesContext(row, ctx)` implies this filter admits `row`. The filter\n * MAY admit rows `matchesContext` later rejects (a slightly wide fetch) \u2014\n * it MUST NEVER exclude a row `matchesContext` would have accepted, because\n * that is a silently wrong price with no error anywhere. Verified by the\n * property-based test in `lib/__tests__/buildPriceRowFilter.property.test.ts`.\n */\nexport function buildPriceRowFilter(ctx: PricingContext): FilterQuery<CatalogProductPrice> {\n const customerGroupIds = ctx.customerGroupIds ?? (ctx.customerGroupId ? [ctx.customerGroupId] : [])\n const customerIds = resolveContextCustomerIds(ctx)\n\n const clauses: FilterQuery<CatalogProductPrice>[] = [\n customerIds.length\n ? { $or: [{ customerId: null }, { customerId: { $in: customerIds } }] }\n : { customerId: null },\n customerGroupIds.length\n ? { $or: [{ customerGroupId: null }, { customerGroupId: { $in: customerGroupIds } }] }\n : { customerGroupId: null },\n ctx.userId\n ? { $or: [{ userId: null }, { userId: ctx.userId }] }\n : { userId: null },\n ctx.userGroupId\n ? { $or: [{ userGroupId: null }, { userGroupId: ctx.userGroupId }] }\n : { userGroupId: null },\n ctx.channelId\n ? { $or: [{ channelId: null }, { channelId: ctx.channelId }] }\n : { channelId: null },\n ]\n\n if (ctx.currencyCode) {\n clauses.push({ currencyCode: ctx.currencyCode })\n }\n\n if (ctx.priceKindId) {\n clauses.push({ $or: [{ priceKind: ctx.priceKindId }, { priceKind: { isPromotion: true } }] })\n }\n\n return { $and: clauses } as FilterQuery<CatalogProductPrice>\n}\n\nfunction scorePrice(row: PriceRow): number {\n const resolvedKind = resolvePriceKindCode(row)\n let score = 0\n if (resolvedKind === 'custom') score += 5\n else if (resolvedKind === 'tier') score += 3\n else if (resolvedKind === 'promotion' || row.priceKind?.isPromotion) score += 4\n else score += 2\n if (row.variant) score += 8\n if (row.offer) score += 6\n if (row.channelId) score += 5\n if (row.userId) score += 5\n if (row.userGroupId) score += 4\n if (row.customerId) score += 4\n if (row.customerGroupId) score += 3\n if (row.minQuantity && row.minQuantity > 1) score += 1\n return score\n}\n\nexport function selectBestPrice(rows: PriceRow[], ctx: PricingContext): PriceRow | null {\n const candidates = rows.filter((row) => matchesContext(row, ctx))\n if (!candidates.length) return null\n const customerIds = resolveContextCustomerIds(ctx)\n const customerRank = (row: PriceRow): number => (row.customerId ? customerIds.indexOf(row.customerId) : -1)\n candidates.sort((a, b) => {\n const scoreDiff = scorePrice(b) - scorePrice(a)\n if (scoreDiff !== 0) return scoreDiff\n const rankA = customerRank(a)\n const rankB = customerRank(b)\n if (rankA >= 0 && rankB >= 0 && rankA !== rankB) return rankA - rankB\n const startA = a.startsAt ? a.startsAt.getTime() : 0\n const startB = b.startsAt ? b.startsAt.getTime() : 0\n if (startA !== startB) return startB - startA\n // minQuantity tie-break is direction-dependent on the resolved kind.\n // Within the same kind we pick the more specific tier (higher minQuantity wins \u2014 issue #1706).\n // Across kinds we keep the pre-#1706 ascending order so a row whose kind has a higher\n // scoreBase still wins when scorePrice's \"+1 for minQuantity > 1\" bonus produces a\n // cross-kind collision (e.g. promotion[minQty=1]=4 vs tier[minQty=3]=4).\n if (resolvePriceKindCode(a) === resolvePriceKindCode(b)) {\n return (b.minQuantity ?? 1) - (a.minQuantity ?? 1)\n }\n return (a.minQuantity ?? 1) - (b.minQuantity ?? 1)\n })\n return candidates[0]\n}\n\nexport type CatalogPricingResolver = (\n rows: PriceRow[],\n ctx: PricingContext\n) => PriceRow | null | undefined | Promise<PriceRow | null | undefined>\n\ntype RegisteredResolver = {\n id?: string\n resolver: CatalogPricingResolver\n priority: number\n}\n\ntype PricingRegistryState = {\n resolvers: RegisteredResolver[]\n}\n\n// `globalThis`-keyed so the registry survives duplicated module instances\n// (a standalone app built from this monorepo, or any dev/build setup that\n// loads `catalog` through more than one chunk) \u2014 the same failure class\n// already fixed once for the ORM entity registry\n// (see `packages/shared/src/modules/integrations/types.ts` for the identical\n// pattern). A module-local array is invisible across instances: a resolver\n// registered from one instance would silently never run for resolution\n// happening in another.\nconst GLOBAL_PRICING_REGISTRY_KEY = '__openMercatoCatalogPricingRegistry__' as const\n\ntype GlobalPricingRegistry = typeof globalThis & {\n [GLOBAL_PRICING_REGISTRY_KEY]?: PricingRegistryState\n}\n\nfunction getPricingRegistryState(): PricingRegistryState {\n const globalRegistry = globalThis as GlobalPricingRegistry\n if (!globalRegistry[GLOBAL_PRICING_REGISTRY_KEY]) {\n globalRegistry[GLOBAL_PRICING_REGISTRY_KEY] = { resolvers: [] }\n }\n return globalRegistry[GLOBAL_PRICING_REGISTRY_KEY]\n}\n\nfunction sortResolvers(state: PricingRegistryState): void {\n // `Array.prototype.sort` is stable (ES2019+): resolvers registered at the\n // same priority keep their registration order. This is the documented,\n // tested same-priority tie-break \u2014 see `catalog/AGENTS.md` \u00A7 Price\n // selection order and the registry test in `lib/__tests__/pricing.test.ts`.\n state.resolvers.sort((a, b) => b.priority - a.priority)\n}\n\nexport function registerCatalogPricingResolver(\n resolver: CatalogPricingResolver,\n options?: { priority?: number; id?: string }\n): void {\n const state = getPricingRegistryState()\n const id = options?.id\n // Dedupe by id so a documented extension point stays HMR-safe for every\n // future registrant, not just one caller: re-registering the same id is a\n // no-op instead of appending a duplicate entry on every module reload.\n if (id && state.resolvers.some((entry) => entry.id === id)) return\n state.resolvers.push({ id, resolver, priority: options?.priority ?? 0 })\n sortResolvers(state)\n}\n\nexport function resetCatalogPricingResolvers(): void {\n getPricingRegistryState().resolvers.splice(0)\n}\n\nexport async function resolveCatalogPrice(\n rows: PriceRow[],\n ctx: PricingContext,\n options?: { eventBus?: EventBus | null }\n): Promise<PriceRow | null> {\n let workingRows = rows\n let workingContext = ctx\n const eventBus = options?.eventBus ?? null\n let resolved: PriceRow | null | undefined\n\n if (eventBus) {\n await eventBus.emitEvent('catalog.pricing.resolve.before', {\n rows: workingRows,\n context: workingContext,\n setRows(next: PriceRow[]) {\n if (Array.isArray(next)) workingRows = next\n },\n setContext(next: PricingContext) {\n if (next) workingContext = next\n },\n setResult(next: PriceRow | null) {\n resolved = next\n },\n })\n if (resolved !== undefined) return resolved\n }\n\n for (const { resolver } of getPricingRegistryState().resolvers) {\n const result = await resolver(workingRows, workingContext)\n if (result !== undefined) {\n resolved = result ?? null\n break\n }\n }\n\n if (resolved === undefined) {\n resolved = selectBestPrice(workingRows, workingContext)\n }\n\n if (eventBus) {\n await eventBus.emitEvent('catalog.pricing.resolve.after', {\n rows: workingRows,\n context: workingContext,\n result: resolved ?? null,\n setResult(next: PriceRow | null) {\n resolved = next\n },\n })\n }\n\n return resolved ?? null\n}\n\nexport async function resolveCatalogPriceBatch(\n entries: Array<{ rows: PriceRow[]; context: PricingContext }>,\n options?: { eventBus?: EventBus | null }\n): Promise<Array<PriceRow | null>> {\n return Promise.all(\n entries.map(({ rows, context }) => resolveCatalogPrice(rows, context, options))\n )\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|