@endora-commerce/mod-catalog 0.100.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +63 -0
- package/dist/admin/components/PackagingUnitsEditor.d.ts +12 -0
- package/dist/admin/components/PackagingUnitsEditor.d.ts.map +1 -0
- package/dist/admin/components/PackagingUnitsEditor.js +99 -0
- package/dist/admin/components/PackagingUnitsEditor.js.map +1 -0
- package/dist/admin/components/ProductAttributesTab.d.ts +13 -0
- package/dist/admin/components/ProductAttributesTab.d.ts.map +1 -0
- package/dist/admin/components/ProductAttributesTab.js +140 -0
- package/dist/admin/components/ProductAttributesTab.js.map +1 -0
- package/dist/admin/components/ProductInventoryTab.d.ts +14 -0
- package/dist/admin/components/ProductInventoryTab.d.ts.map +1 -0
- package/dist/admin/components/ProductInventoryTab.js +284 -0
- package/dist/admin/components/ProductInventoryTab.js.map +1 -0
- package/dist/admin/components/ProductScopeEditor.d.ts +94 -0
- package/dist/admin/components/ProductScopeEditor.d.ts.map +1 -0
- package/dist/admin/components/ProductScopeEditor.js +395 -0
- package/dist/admin/components/ProductScopeEditor.js.map +1 -0
- package/dist/admin/components/ProductsBulkEditDialog.d.ts +11 -0
- package/dist/admin/components/ProductsBulkEditDialog.d.ts.map +1 -0
- package/dist/admin/components/ProductsBulkEditDialog.js +304 -0
- package/dist/admin/components/ProductsBulkEditDialog.js.map +1 -0
- package/dist/admin/index.d.ts +45 -0
- package/dist/admin/index.d.ts.map +1 -0
- package/dist/admin/index.js +184 -0
- package/dist/admin/index.js.map +1 -0
- package/dist/admin/lib/resolve-product-selection.d.ts +21 -0
- package/dist/admin/lib/resolve-product-selection.d.ts.map +1 -0
- package/dist/admin/lib/resolve-product-selection.js +25 -0
- package/dist/admin/lib/resolve-product-selection.js.map +1 -0
- package/dist/admin/pages/AttachmentTypesPage.d.ts +18 -0
- package/dist/admin/pages/AttachmentTypesPage.d.ts.map +1 -0
- package/dist/admin/pages/AttachmentTypesPage.js +92 -0
- package/dist/admin/pages/AttachmentTypesPage.js.map +1 -0
- package/dist/admin/pages/AttributeSetsPage.d.ts +21 -0
- package/dist/admin/pages/AttributeSetsPage.d.ts.map +1 -0
- package/dist/admin/pages/AttributeSetsPage.js +158 -0
- package/dist/admin/pages/AttributeSetsPage.js.map +1 -0
- package/dist/admin/pages/AttributesManager.d.ts +9 -0
- package/dist/admin/pages/AttributesManager.d.ts.map +1 -0
- package/dist/admin/pages/AttributesManager.js +305 -0
- package/dist/admin/pages/AttributesManager.js.map +1 -0
- package/dist/admin/pages/BulkOperationDetailPage.d.ts +9 -0
- package/dist/admin/pages/BulkOperationDetailPage.d.ts.map +1 -0
- package/dist/admin/pages/BulkOperationDetailPage.js +187 -0
- package/dist/admin/pages/BulkOperationDetailPage.js.map +1 -0
- package/dist/admin/pages/BulkOperationsPage.d.ts +9 -0
- package/dist/admin/pages/BulkOperationsPage.d.ts.map +1 -0
- package/dist/admin/pages/BulkOperationsPage.js +98 -0
- package/dist/admin/pages/BulkOperationsPage.js.map +1 -0
- package/dist/admin/pages/CategoriesTree.d.ts +9 -0
- package/dist/admin/pages/CategoriesTree.d.ts.map +1 -0
- package/dist/admin/pages/CategoriesTree.js +176 -0
- package/dist/admin/pages/CategoriesTree.js.map +1 -0
- package/dist/admin/pages/ProductEditor.d.ts +13 -0
- package/dist/admin/pages/ProductEditor.d.ts.map +1 -0
- package/dist/admin/pages/ProductEditor.js +1050 -0
- package/dist/admin/pages/ProductEditor.js.map +1 -0
- package/dist/admin/pages/ProductsList.d.ts +9 -0
- package/dist/admin/pages/ProductsList.d.ts.map +1 -0
- package/dist/admin/pages/ProductsList.js +399 -0
- package/dist/admin/pages/ProductsList.js.map +1 -0
- package/dist/backend/commands/attribute-commands.d.ts +111 -0
- package/dist/backend/commands/attribute-commands.d.ts.map +1 -0
- package/dist/backend/commands/attribute-commands.js +482 -0
- package/dist/backend/commands/attribute-commands.js.map +1 -0
- package/dist/backend/demo/reset.d.ts +23 -0
- package/dist/backend/demo/reset.d.ts.map +1 -0
- package/dist/backend/demo/reset.js +41 -0
- package/dist/backend/demo/reset.js.map +1 -0
- package/dist/backend/demo/rows.d.ts +103 -0
- package/dist/backend/demo/rows.d.ts.map +1 -0
- package/dist/backend/demo/rows.js +162 -0
- package/dist/backend/demo/rows.js.map +1 -0
- package/dist/backend/demo/seed.d.ts +35 -0
- package/dist/backend/demo/seed.d.ts.map +1 -0
- package/dist/backend/demo/seed.js +177 -0
- package/dist/backend/demo/seed.js.map +1 -0
- package/dist/backend/entities/attachment-type.entity.d.ts +16 -0
- package/dist/backend/entities/attachment-type.entity.d.ts.map +1 -0
- package/dist/backend/entities/attachment-type.entity.js +57 -0
- package/dist/backend/entities/attachment-type.entity.js.map +1 -0
- package/dist/backend/entities/attribute-set-attribute.entity.d.ts +26 -0
- package/dist/backend/entities/attribute-set-attribute.entity.d.ts.map +1 -0
- package/dist/backend/entities/attribute-set-attribute.entity.js +55 -0
- package/dist/backend/entities/attribute-set-attribute.entity.js.map +1 -0
- package/dist/backend/entities/attribute-set.entity.d.ts +22 -0
- package/dist/backend/entities/attribute-set.entity.d.ts.map +1 -0
- package/dist/backend/entities/attribute-set.entity.js +67 -0
- package/dist/backend/entities/attribute-set.entity.js.map +1 -0
- package/dist/backend/entities/bulk-operation.entity.d.ts +78 -0
- package/dist/backend/entities/bulk-operation.entity.d.ts.map +1 -0
- package/dist/backend/entities/bulk-operation.entity.js +138 -0
- package/dist/backend/entities/bulk-operation.entity.js.map +1 -0
- package/dist/backend/entities/bundle-slot-option.entity.d.ts +23 -0
- package/dist/backend/entities/bundle-slot-option.entity.d.ts.map +1 -0
- package/dist/backend/entities/bundle-slot-option.entity.js +68 -0
- package/dist/backend/entities/bundle-slot-option.entity.js.map +1 -0
- package/dist/backend/entities/bundle-slot.entity.d.ts +25 -0
- package/dist/backend/entities/bundle-slot.entity.d.ts.map +1 -0
- package/dist/backend/entities/bundle-slot.entity.js +74 -0
- package/dist/backend/entities/bundle-slot.entity.js.map +1 -0
- package/dist/backend/entities/category.entity.d.ts +26 -0
- package/dist/backend/entities/category.entity.d.ts.map +1 -0
- package/dist/backend/entities/category.entity.js +119 -0
- package/dist/backend/entities/category.entity.js.map +1 -0
- package/dist/backend/entities/gallery-item-label.entity.d.ts +22 -0
- package/dist/backend/entities/gallery-item-label.entity.d.ts.map +1 -0
- package/dist/backend/entities/gallery-item-label.entity.js +50 -0
- package/dist/backend/entities/gallery-item-label.entity.js.map +1 -0
- package/dist/backend/entities/gallery-item.entity.d.ts +17 -0
- package/dist/backend/entities/gallery-item.entity.d.ts.map +1 -0
- package/dist/backend/entities/gallery-item.entity.js +58 -0
- package/dist/backend/entities/gallery-item.entity.js.map +1 -0
- package/dist/backend/entities/grouped-item.entity.d.ts +23 -0
- package/dist/backend/entities/grouped-item.entity.d.ts.map +1 -0
- package/dist/backend/entities/grouped-item.entity.js +68 -0
- package/dist/backend/entities/grouped-item.entity.js.map +1 -0
- package/dist/backend/entities/product-attachment.entity.d.ts +23 -0
- package/dist/backend/entities/product-attachment.entity.d.ts.map +1 -0
- package/dist/backend/entities/product-attachment.entity.js +77 -0
- package/dist/backend/entities/product-attachment.entity.js.map +1 -0
- package/dist/backend/entities/product-attribute.entity.d.ts +72 -0
- package/dist/backend/entities/product-attribute.entity.d.ts.map +1 -0
- package/dist/backend/entities/product-attribute.entity.js +161 -0
- package/dist/backend/entities/product-attribute.entity.js.map +1 -0
- package/dist/backend/entities/product-editor-preference.entity.d.ts +28 -0
- package/dist/backend/entities/product-editor-preference.entity.d.ts.map +1 -0
- package/dist/backend/entities/product-editor-preference.entity.js +63 -0
- package/dist/backend/entities/product-editor-preference.entity.js.map +1 -0
- package/dist/backend/entities/product-link.entity.d.ts +25 -0
- package/dist/backend/entities/product-link.entity.d.ts.map +1 -0
- package/dist/backend/entities/product-link.entity.js +70 -0
- package/dist/backend/entities/product-link.entity.js.map +1 -0
- package/dist/backend/entities/product-packaging-unit.entity.d.ts +26 -0
- package/dist/backend/entities/product-packaging-unit.entity.d.ts.map +1 -0
- package/dist/backend/entities/product-packaging-unit.entity.js +76 -0
- package/dist/backend/entities/product-packaging-unit.entity.js.map +1 -0
- package/dist/backend/entities/product-value-override.entity.d.ts +43 -0
- package/dist/backend/entities/product-value-override.entity.d.ts.map +1 -0
- package/dist/backend/entities/product-value-override.entity.js +90 -0
- package/dist/backend/entities/product-value-override.entity.js.map +1 -0
- package/dist/backend/entities/product-variant.entity.d.ts +18 -0
- package/dist/backend/entities/product-variant.entity.d.ts.map +1 -0
- package/dist/backend/entities/product-variant.entity.js +68 -0
- package/dist/backend/entities/product-variant.entity.js.map +1 -0
- package/dist/backend/entities/product.entity.d.ts +108 -0
- package/dist/backend/entities/product.entity.d.ts.map +1 -0
- package/dist/backend/entities/product.entity.js +230 -0
- package/dist/backend/entities/product.entity.js.map +1 -0
- package/dist/backend/index.d.ts +262 -0
- package/dist/backend/index.d.ts.map +1 -0
- package/dist/backend/index.js +642 -0
- package/dist/backend/index.js.map +1 -0
- package/dist/backend/plugin.d.ts +216 -0
- package/dist/backend/plugin.d.ts.map +1 -0
- package/dist/backend/plugin.js +223 -0
- package/dist/backend/plugin.js.map +1 -0
- package/dist/backend/prompt-tools.d.ts +47 -0
- package/dist/backend/prompt-tools.d.ts.map +1 -0
- package/dist/backend/prompt-tools.js +284 -0
- package/dist/backend/prompt-tools.js.map +1 -0
- package/dist/backend/routes.admin.d.ts +105 -0
- package/dist/backend/routes.admin.d.ts.map +1 -0
- package/dist/backend/routes.admin.js +1162 -0
- package/dist/backend/routes.admin.js.map +1 -0
- package/dist/backend/routes.api-key.d.ts +33 -0
- package/dist/backend/routes.api-key.d.ts.map +1 -0
- package/dist/backend/routes.api-key.js +43 -0
- package/dist/backend/routes.api-key.js.map +1 -0
- package/dist/backend/routes.external.d.ts +32 -0
- package/dist/backend/routes.external.d.ts.map +1 -0
- package/dist/backend/routes.external.js +115 -0
- package/dist/backend/routes.external.js.map +1 -0
- package/dist/backend/routes.public.d.ts +46 -0
- package/dist/backend/routes.public.d.ts.map +1 -0
- package/dist/backend/routes.public.js +318 -0
- package/dist/backend/routes.public.js.map +1 -0
- package/dist/backend/services/asset-references.d.ts +4 -0
- package/dist/backend/services/asset-references.d.ts.map +1 -0
- package/dist/backend/services/asset-references.js +104 -0
- package/dist/backend/services/asset-references.js.map +1 -0
- package/dist/backend/services/attachment.service.d.ts +45 -0
- package/dist/backend/services/attachment.service.d.ts.map +1 -0
- package/dist/backend/services/attachment.service.js +268 -0
- package/dist/backend/services/attachment.service.js.map +1 -0
- package/dist/backend/services/attribute-option-validator.d.ts +47 -0
- package/dist/backend/services/attribute-option-validator.d.ts.map +1 -0
- package/dist/backend/services/attribute-option-validator.js +69 -0
- package/dist/backend/services/attribute-option-validator.js.map +1 -0
- package/dist/backend/services/attribute-set-validations.d.ts +65 -0
- package/dist/backend/services/attribute-set-validations.d.ts.map +1 -0
- package/dist/backend/services/attribute-set-validations.js +89 -0
- package/dist/backend/services/attribute-set-validations.js.map +1 -0
- package/dist/backend/services/attribute-set.service.d.ts +50 -0
- package/dist/backend/services/attribute-set.service.d.ts.map +1 -0
- package/dist/backend/services/attribute-set.service.js +401 -0
- package/dist/backend/services/attribute-set.service.js.map +1 -0
- package/dist/backend/services/attribute-type-mapping.d.ts +66 -0
- package/dist/backend/services/attribute-type-mapping.d.ts.map +1 -0
- package/dist/backend/services/attribute-type-mapping.js +121 -0
- package/dist/backend/services/attribute-type-mapping.js.map +1 -0
- package/dist/backend/services/attribute-value-key.service.d.ts +48 -0
- package/dist/backend/services/attribute-value-key.service.d.ts.map +1 -0
- package/dist/backend/services/attribute-value-key.service.js +118 -0
- package/dist/backend/services/attribute-value-key.service.js.map +1 -0
- package/dist/backend/services/audit-references.d.ts +13 -0
- package/dist/backend/services/audit-references.d.ts.map +1 -0
- package/dist/backend/services/audit-references.js +51 -0
- package/dist/backend/services/audit-references.js.map +1 -0
- package/dist/backend/services/bulk-operation-queue.d.ts +26 -0
- package/dist/backend/services/bulk-operation-queue.d.ts.map +1 -0
- package/dist/backend/services/bulk-operation-queue.js +34 -0
- package/dist/backend/services/bulk-operation-queue.js.map +1 -0
- package/dist/backend/services/bulk-operation.service.d.ts +195 -0
- package/dist/backend/services/bulk-operation.service.d.ts.map +1 -0
- package/dist/backend/services/bulk-operation.service.js +510 -0
- package/dist/backend/services/bulk-operation.service.js.map +1 -0
- package/dist/backend/services/bundle.service.d.ts +87 -0
- package/dist/backend/services/bundle.service.d.ts.map +1 -0
- package/dist/backend/services/bundle.service.js +286 -0
- package/dist/backend/services/bundle.service.js.map +1 -0
- package/dist/backend/services/catalog-admin.service.d.ts +398 -0
- package/dist/backend/services/catalog-admin.service.d.ts.map +1 -0
- package/dist/backend/services/catalog-admin.service.js +1516 -0
- package/dist/backend/services/catalog-admin.service.js.map +1 -0
- package/dist/backend/services/catalog-attribute-read.service.d.ts +78 -0
- package/dist/backend/services/catalog-attribute-read.service.d.ts.map +1 -0
- package/dist/backend/services/catalog-attribute-read.service.js +216 -0
- package/dist/backend/services/catalog-attribute-read.service.js.map +1 -0
- package/dist/backend/services/catalog-bulk-import.service.d.ts +30 -0
- package/dist/backend/services/catalog-bulk-import.service.d.ts.map +1 -0
- package/dist/backend/services/catalog-bulk-import.service.js +136 -0
- package/dist/backend/services/catalog-bulk-import.service.js.map +1 -0
- package/dist/backend/services/catalog-bulk-update.service.d.ts +91 -0
- package/dist/backend/services/catalog-bulk-update.service.d.ts.map +1 -0
- package/dist/backend/services/catalog-bulk-update.service.js +330 -0
- package/dist/backend/services/catalog-bulk-update.service.js.map +1 -0
- package/dist/backend/services/catalog-category-read.service.d.ts +66 -0
- package/dist/backend/services/catalog-category-read.service.d.ts.map +1 -0
- package/dist/backend/services/catalog-category-read.service.js +248 -0
- package/dist/backend/services/catalog-category-read.service.js.map +1 -0
- package/dist/backend/services/catalog-org-price-decorator.d.ts +90 -0
- package/dist/backend/services/catalog-org-price-decorator.d.ts.map +1 -0
- package/dist/backend/services/catalog-org-price-decorator.js +184 -0
- package/dist/backend/services/catalog-org-price-decorator.js.map +1 -0
- package/dist/backend/services/catalog-product-filter.service.d.ts +82 -0
- package/dist/backend/services/catalog-product-filter.service.d.ts.map +1 -0
- package/dist/backend/services/catalog-product-filter.service.js +275 -0
- package/dist/backend/services/catalog-product-filter.service.js.map +1 -0
- package/dist/backend/services/catalog-product-read.service.d.ts +46 -0
- package/dist/backend/services/catalog-product-read.service.d.ts.map +1 -0
- package/dist/backend/services/catalog-product-read.service.js +197 -0
- package/dist/backend/services/catalog-product-read.service.js.map +1 -0
- package/dist/backend/services/catalog-query.service.d.ts +444 -0
- package/dist/backend/services/catalog-query.service.d.ts.map +1 -0
- package/dist/backend/services/catalog-query.service.js +1633 -0
- package/dist/backend/services/catalog-query.service.js.map +1 -0
- package/dist/backend/services/catalog-quick-search.service.d.ts +78 -0
- package/dist/backend/services/catalog-quick-search.service.d.ts.map +1 -0
- package/dist/backend/services/catalog-quick-search.service.js +159 -0
- package/dist/backend/services/catalog-quick-search.service.js.map +1 -0
- package/dist/backend/services/catalog-write-ports.d.ts +25 -0
- package/dist/backend/services/catalog-write-ports.d.ts.map +1 -0
- package/dist/backend/services/catalog-write-ports.js +63 -0
- package/dist/backend/services/catalog-write-ports.js.map +1 -0
- package/dist/backend/services/category-admin.service.d.ts +102 -0
- package/dist/backend/services/category-admin.service.d.ts.map +1 -0
- package/dist/backend/services/category-admin.service.js +271 -0
- package/dist/backend/services/category-admin.service.js.map +1 -0
- package/dist/backend/services/gallery.service.d.ts +85 -0
- package/dist/backend/services/gallery.service.d.ts.map +1 -0
- package/dist/backend/services/gallery.service.js +326 -0
- package/dist/backend/services/gallery.service.js.map +1 -0
- package/dist/backend/services/grouped.service.d.ts +39 -0
- package/dist/backend/services/grouped.service.d.ts.map +1 -0
- package/dist/backend/services/grouped.service.js +136 -0
- package/dist/backend/services/grouped.service.js.map +1 -0
- package/dist/backend/services/label-resolver.d.ts +16 -0
- package/dist/backend/services/label-resolver.d.ts.map +1 -0
- package/dist/backend/services/label-resolver.js +43 -0
- package/dist/backend/services/label-resolver.js.map +1 -0
- package/dist/backend/services/packaging-unit.service.d.ts +28 -0
- package/dist/backend/services/packaging-unit.service.d.ts.map +1 -0
- package/dist/backend/services/packaging-unit.service.js +197 -0
- package/dist/backend/services/packaging-unit.service.js.map +1 -0
- package/dist/backend/services/primary-asset-url.d.ts +4 -0
- package/dist/backend/services/primary-asset-url.d.ts.map +1 -0
- package/dist/backend/services/primary-asset-url.js +55 -0
- package/dist/backend/services/primary-asset-url.js.map +1 -0
- package/dist/backend/services/product-editor-preferences.service.d.ts +20 -0
- package/dist/backend/services/product-editor-preferences.service.d.ts.map +1 -0
- package/dist/backend/services/product-editor-preferences.service.js +44 -0
- package/dist/backend/services/product-editor-preferences.service.js.map +1 -0
- package/dist/backend/services/product-link.service.d.ts +169 -0
- package/dist/backend/services/product-link.service.d.ts.map +1 -0
- package/dist/backend/services/product-link.service.js +297 -0
- package/dist/backend/services/product-link.service.js.map +1 -0
- package/dist/backend/services/product-overrides.service.d.ts +77 -0
- package/dist/backend/services/product-overrides.service.d.ts.map +1 -0
- package/dist/backend/services/product-overrides.service.js +204 -0
- package/dist/backend/services/product-overrides.service.js.map +1 -0
- package/dist/backend/services/product-scope-context.service.d.ts +36 -0
- package/dist/backend/services/product-scope-context.service.d.ts.map +1 -0
- package/dist/backend/services/product-scope-context.service.js +106 -0
- package/dist/backend/services/product-scope-context.service.js.map +1 -0
- package/dist/backend/services/product-type-validations.d.ts +42 -0
- package/dist/backend/services/product-type-validations.d.ts.map +1 -0
- package/dist/backend/services/product-type-validations.js +55 -0
- package/dist/backend/services/product-type-validations.js.map +1 -0
- package/dist/backend/services/product-value-resolver.service.d.ts +59 -0
- package/dist/backend/services/product-value-resolver.service.d.ts.map +1 -0
- package/dist/backend/services/product-value-resolver.service.js +111 -0
- package/dist/backend/services/product-value-resolver.service.js.map +1 -0
- package/dist/backend/services/system-attribute-scopes.d.ts +18 -0
- package/dist/backend/services/system-attribute-scopes.d.ts.map +1 -0
- package/dist/backend/services/system-attribute-scopes.js +18 -0
- package/dist/backend/services/system-attribute-scopes.js.map +1 -0
- package/dist/backend/services/viewer-organization.d.ts +25 -0
- package/dist/backend/services/viewer-organization.d.ts.map +1 -0
- package/dist/backend/services/viewer-organization.js +31 -0
- package/dist/backend/services/viewer-organization.js.map +1 -0
- package/dist/manifest.d.ts +204 -0
- package/dist/manifest.d.ts.map +1 -0
- package/dist/manifest.js +686 -0
- package/dist/manifest.js.map +1 -0
- package/dist/migrations/20260429T064146_catalog_attribute_sets_init.d.ts +33 -0
- package/dist/migrations/20260429T064146_catalog_attribute_sets_init.d.ts.map +1 -0
- package/dist/migrations/20260429T064146_catalog_attribute_sets_init.js +118 -0
- package/dist/migrations/20260429T064146_catalog_attribute_sets_init.js.map +1 -0
- package/dist/migrations/20260429T070004_catalog_product_attribute_extensions.d.ts +24 -0
- package/dist/migrations/20260429T070004_catalog_product_attribute_extensions.d.ts.map +1 -0
- package/dist/migrations/20260429T070004_catalog_product_attribute_extensions.js +31 -0
- package/dist/migrations/20260429T070004_catalog_product_attribute_extensions.js.map +1 -0
- package/dist/migrations/20260429T102322_catalog_product_type_and_virtual_fields.d.ts +32 -0
- package/dist/migrations/20260429T102322_catalog_product_type_and_virtual_fields.d.ts.map +1 -0
- package/dist/migrations/20260429T102322_catalog_product_type_and_virtual_fields.js +58 -0
- package/dist/migrations/20260429T102322_catalog_product_type_and_virtual_fields.js.map +1 -0
- package/dist/migrations/20260429T111839_catalog_gallery_items_and_labels.d.ts +22 -0
- package/dist/migrations/20260429T111839_catalog_gallery_items_and_labels.d.ts.map +1 -0
- package/dist/migrations/20260429T111839_catalog_gallery_items_and_labels.js +66 -0
- package/dist/migrations/20260429T111839_catalog_gallery_items_and_labels.js.map +1 -0
- package/dist/migrations/20260429T112543_catalog_product_attachments.d.ts +18 -0
- package/dist/migrations/20260429T112543_catalog_product_attachments.d.ts.map +1 -0
- package/dist/migrations/20260429T112543_catalog_product_attachments.js +73 -0
- package/dist/migrations/20260429T112543_catalog_product_attachments.js.map +1 -0
- package/dist/migrations/20260429T123726_catalog_product_links.d.ts +21 -0
- package/dist/migrations/20260429T123726_catalog_product_links.d.ts.map +1 -0
- package/dist/migrations/20260429T123726_catalog_product_links.js +48 -0
- package/dist/migrations/20260429T123726_catalog_product_links.js.map +1 -0
- package/dist/migrations/20260429T130803_catalog_grouped_and_bundle.d.ts +23 -0
- package/dist/migrations/20260429T130803_catalog_grouped_and_bundle.d.ts.map +1 -0
- package/dist/migrations/20260429T130803_catalog_grouped_and_bundle.js +94 -0
- package/dist/migrations/20260429T130803_catalog_grouped_and_bundle.js.map +1 -0
- package/dist/migrations/20260501T185835_catalog_product_attribute_is_comparable.d.ts +24 -0
- package/dist/migrations/20260501T185835_catalog_product_attribute_is_comparable.d.ts.map +1 -0
- package/dist/migrations/20260501T185835_catalog_product_attribute_is_comparable.js +31 -0
- package/dist/migrations/20260501T185835_catalog_product_attribute_is_comparable.js.map +1 -0
- package/dist/migrations/20260505T060113_catalog_attribute_options_and_flags.d.ts +31 -0
- package/dist/migrations/20260505T060113_catalog_attribute_options_and_flags.d.ts.map +1 -0
- package/dist/migrations/20260505T060113_catalog_attribute_options_and_flags.js +133 -0
- package/dist/migrations/20260505T060113_catalog_attribute_options_and_flags.js.map +1 -0
- package/dist/migrations/20260515T082629_catalog_attribute_mass_editable.d.ts +16 -0
- package/dist/migrations/20260515T082629_catalog_attribute_mass_editable.d.ts.map +1 -0
- package/dist/migrations/20260515T082629_catalog_attribute_mass_editable.js +23 -0
- package/dist/migrations/20260515T082629_catalog_attribute_mass_editable.js.map +1 -0
- package/dist/migrations/20260526T124736_catalog_product_status_inactive.d.ts +10 -0
- package/dist/migrations/20260526T124736_catalog_product_status_inactive.d.ts.map +1 -0
- package/dist/migrations/20260526T124736_catalog_product_status_inactive.js +22 -0
- package/dist/migrations/20260526T124736_catalog_product_status_inactive.js.map +1 -0
- package/dist/migrations/20260611T140346_catalog_product_value_overrides_init.d.ts +38 -0
- package/dist/migrations/20260611T140346_catalog_product_value_overrides_init.d.ts.map +1 -0
- package/dist/migrations/20260611T140346_catalog_product_value_overrides_init.js +98 -0
- package/dist/migrations/20260611T140346_catalog_product_value_overrides_init.js.map +1 -0
- package/dist/migrations/20260611T140400_catalog_attribute_quick_searchable.d.ts +13 -0
- package/dist/migrations/20260611T140400_catalog_attribute_quick_searchable.d.ts.map +1 -0
- package/dist/migrations/20260611T140400_catalog_attribute_quick_searchable.js +17 -0
- package/dist/migrations/20260611T140400_catalog_attribute_quick_searchable.js.map +1 -0
- package/dist/migrations/20260611T140407_catalog_bulk_operations.d.ts +16 -0
- package/dist/migrations/20260611T140407_catalog_bulk_operations.d.ts.map +1 -0
- package/dist/migrations/20260611T140407_catalog_bulk_operations.js +42 -0
- package/dist/migrations/20260611T140407_catalog_bulk_operations.js.map +1 -0
- package/dist/migrations/20260611T140408_catalog_bulk_operation_logs.d.ts +14 -0
- package/dist/migrations/20260611T140408_catalog_bulk_operation_logs.d.ts.map +1 -0
- package/dist/migrations/20260611T140408_catalog_bulk_operation_logs.js +18 -0
- package/dist/migrations/20260611T140408_catalog_bulk_operation_logs.js.map +1 -0
- package/dist/migrations/20260611T140412_catalog_product_packaging_units.d.ts +11 -0
- package/dist/migrations/20260611T140412_catalog_product_packaging_units.d.ts.map +1 -0
- package/dist/migrations/20260611T140412_catalog_product_packaging_units.js +29 -0
- package/dist/migrations/20260611T140412_catalog_product_packaging_units.js.map +1 -0
- package/dist/migrations/20260718T060659_catalog_bulk_operation_revert_state.d.ts +23 -0
- package/dist/migrations/20260718T060659_catalog_bulk_operation_revert_state.d.ts.map +1 -0
- package/dist/migrations/20260718T060659_catalog_bulk_operation_revert_state.js +35 -0
- package/dist/migrations/20260718T060659_catalog_bulk_operation_revert_state.js.map +1 -0
- package/dist/migrations/20260718T200343_catalog_category_custom_field_values.d.ts +12 -0
- package/dist/migrations/20260718T200343_catalog_category_custom_field_values.d.ts.map +1 -0
- package/dist/migrations/20260718T200343_catalog_category_custom_field_values.js +16 -0
- package/dist/migrations/20260718T200343_catalog_category_custom_field_values.js.map +1 -0
- package/dist/migrations/20260723T230401_catalog_attributes_on_custom_fields.d.ts +32 -0
- package/dist/migrations/20260723T230401_catalog_attributes_on_custom_fields.d.ts.map +1 -0
- package/dist/migrations/20260723T230401_catalog_attributes_on_custom_fields.js +286 -0
- package/dist/migrations/20260723T230401_catalog_attributes_on_custom_fields.js.map +1 -0
- package/dist/migrations/20260804T152604_catalog_widen_product_sku.d.ts +36 -0
- package/dist/migrations/20260804T152604_catalog_widen_product_sku.d.ts.map +1 -0
- package/dist/migrations/20260804T152604_catalog_widen_product_sku.js +63 -0
- package/dist/migrations/20260804T152604_catalog_widen_product_sku.js.map +1 -0
- package/dist/migrations/20260804T160244_catalog_category_activation.d.ts +18 -0
- package/dist/migrations/20260804T160244_catalog_category_activation.d.ts.map +1 -0
- package/dist/migrations/20260804T160244_catalog_category_activation.js +22 -0
- package/dist/migrations/20260804T160244_catalog_category_activation.js.map +1 -0
- package/dist/migrations/20260912T094557_catalog_sales_channel_products.d.ts +27 -0
- package/dist/migrations/20260912T094557_catalog_sales_channel_products.d.ts.map +1 -0
- package/dist/migrations/20260912T094557_catalog_sales_channel_products.js +44 -0
- package/dist/migrations/20260912T094557_catalog_sales_channel_products.js.map +1 -0
- package/dist/migrations/20260912T094623_catalog_sales_channel_categories.d.ts +27 -0
- package/dist/migrations/20260912T094623_catalog_sales_channel_categories.d.ts.map +1 -0
- package/dist/migrations/20260912T094623_catalog_sales_channel_categories.js +44 -0
- package/dist/migrations/20260912T094623_catalog_sales_channel_categories.js.map +1 -0
- package/dist/migrations/20260925T125527_catalog_inventory_columns.d.ts +36 -0
- package/dist/migrations/20260925T125527_catalog_inventory_columns.d.ts.map +1 -0
- package/dist/migrations/20260925T125527_catalog_inventory_columns.js +87 -0
- package/dist/migrations/20260925T125527_catalog_inventory_columns.js.map +1 -0
- package/dist/migrations/index.d.ts +55 -0
- package/dist/migrations/index.d.ts.map +1 -0
- package/dist/migrations/index.js +80 -0
- package/dist/migrations/index.js.map +1 -0
- package/dist/ports/index.d.ts +96 -0
- package/dist/ports/index.d.ts.map +1 -0
- package/dist/ports/index.js +2 -0
- package/dist/ports/index.js.map +1 -0
- package/docs/catalog/attachments.md +69 -0
- package/docs/catalog/attribute-sets.md +63 -0
- package/docs/catalog/attributes.md +244 -0
- package/docs/catalog/composite-products.md +115 -0
- package/docs/catalog/gallery-and-labels.md +73 -0
- package/docs/catalog/packaging-units.md +67 -0
- package/docs/catalog/per-channel-per-language-overrides.md +234 -0
- package/docs/catalog/product-links.md +79 -0
- package/docs/catalog.md +207 -0
- package/i18n/en.json +649 -0
- package/i18n/pl.json +649 -0
- package/package.json +109 -0
- package/tailwind.css +14 -0
|
@@ -0,0 +1,268 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AttachmentService — admin-only CRUD for AttachmentTypes (global
|
|
3
|
+
* dictionary) and ProductAttachments (per-product wrappers around an
|
|
4
|
+
* Asset). Feature 002 US3, data-model.md §2.5, §2.6.
|
|
5
|
+
*
|
|
6
|
+
* Foundation has no public AssetsService — Asset is imported as an
|
|
7
|
+
* entity directly (research.md R-9 + foundation pattern), and the
|
|
8
|
+
* service layer guards `kind ∈ {pdf, certificate, other}` for
|
|
9
|
+
* attachments (image / video are reserved for the gallery).
|
|
10
|
+
*/
|
|
11
|
+
import { randomUUID } from 'node:crypto';
|
|
12
|
+
import { UniqueConstraintViolationException } from '@mikro-orm/core';
|
|
13
|
+
import { ERROR_CODES, } from '@endora-commerce/contracts';
|
|
14
|
+
import { HttpError } from '@endora-commerce/platform/http';
|
|
15
|
+
import { Product } from '../entities/product.entity.js';
|
|
16
|
+
import { AttachmentType } from '../entities/attachment-type.entity.js';
|
|
17
|
+
import { ProductAttachment } from '../entities/product-attachment.entity.js';
|
|
18
|
+
const ASSET_KINDS_ATTACHMENT = new Set(['pdf', 'certificate', 'other']);
|
|
19
|
+
export class AttachmentService {
|
|
20
|
+
emFactory;
|
|
21
|
+
commandBus;
|
|
22
|
+
assets;
|
|
23
|
+
constructor(emFactory,
|
|
24
|
+
/** Feature 054 — audits attachment writes co-transactionally when provided. */
|
|
25
|
+
commandBus,
|
|
26
|
+
/**
|
|
27
|
+
* Feature 075 — `assets_library`'s read port, where `em.findOne(Asset, …)`
|
|
28
|
+
* used to be. The check below is the reason this read exists: an attach
|
|
29
|
+
* that cannot verify the asset would store a dangling id, so with
|
|
30
|
+
* `assets_library` off the port fails closed and the attach is refused.
|
|
31
|
+
*/
|
|
32
|
+
assets) {
|
|
33
|
+
this.emFactory = emFactory;
|
|
34
|
+
this.commandBus = commandBus;
|
|
35
|
+
this.assets = assets;
|
|
36
|
+
}
|
|
37
|
+
#requireAssets() {
|
|
38
|
+
if (!this.assets) {
|
|
39
|
+
throw new Error('AttachmentService: the asset read port is not wired — an attachment cannot be verified.');
|
|
40
|
+
}
|
|
41
|
+
return this.assets;
|
|
42
|
+
}
|
|
43
|
+
/** Feature 054 — run an attachment write through the Command Bus. */
|
|
44
|
+
async #audited(action, objectType, objectId, write) {
|
|
45
|
+
if (this.commandBus) {
|
|
46
|
+
return this.commandBus.run({ action, objectType, objectId, run: ({ em }) => write(em) });
|
|
47
|
+
}
|
|
48
|
+
const em = this.emFactory();
|
|
49
|
+
const w = await write(em);
|
|
50
|
+
await em.flush();
|
|
51
|
+
return w.result;
|
|
52
|
+
}
|
|
53
|
+
// -- Attachment Types -----------------------------------------------------
|
|
54
|
+
async listTypes() {
|
|
55
|
+
const em = this.emFactory();
|
|
56
|
+
const rows = (await em.execute(`select t.id, t.code, t.name, t.position, t.created_at, t.updated_at,
|
|
57
|
+
(select count(*)::int from product_attachments pa where pa.attachment_type_id = t.id) as usage_count
|
|
58
|
+
from attachment_types t
|
|
59
|
+
order by t.position asc, t.code asc`));
|
|
60
|
+
return rows.map((r) => ({
|
|
61
|
+
id: r.id,
|
|
62
|
+
code: r.code,
|
|
63
|
+
name: r.name,
|
|
64
|
+
position: r.position,
|
|
65
|
+
usageCount: r.usage_count,
|
|
66
|
+
createdAt: new Date(r.created_at).toISOString(),
|
|
67
|
+
updatedAt: new Date(r.updated_at).toISOString(),
|
|
68
|
+
}));
|
|
69
|
+
}
|
|
70
|
+
async createType(req) {
|
|
71
|
+
const id = randomUUID();
|
|
72
|
+
const t = await this.#audited('attachment_type.create', 'attachment_type', id, async (em) => {
|
|
73
|
+
const created = em.create(AttachmentType, {
|
|
74
|
+
id,
|
|
75
|
+
code: req.code,
|
|
76
|
+
name: req.name,
|
|
77
|
+
...(req.position !== undefined ? { position: req.position } : {}),
|
|
78
|
+
});
|
|
79
|
+
try {
|
|
80
|
+
await em.flush();
|
|
81
|
+
}
|
|
82
|
+
catch (err) {
|
|
83
|
+
if (err instanceof UniqueConstraintViolationException) {
|
|
84
|
+
throw new HttpError(409, ERROR_CODES.ATTACHMENT_TYPE_CODE_TAKEN, `AttachmentType "${req.code}" already exists.`);
|
|
85
|
+
}
|
|
86
|
+
throw err;
|
|
87
|
+
}
|
|
88
|
+
return { result: created, before: null, after: { code: created.code, name: created.name, position: created.position } };
|
|
89
|
+
});
|
|
90
|
+
return {
|
|
91
|
+
id: t.id,
|
|
92
|
+
code: t.code,
|
|
93
|
+
name: t.name,
|
|
94
|
+
position: t.position,
|
|
95
|
+
usageCount: 0,
|
|
96
|
+
createdAt: t.createdAt.toISOString(),
|
|
97
|
+
updatedAt: t.updatedAt.toISOString(),
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
async updateType(id, req) {
|
|
101
|
+
const t = await this.#audited('attachment_type.update', 'attachment_type', id, async (em) => {
|
|
102
|
+
const row = await em.findOne(AttachmentType, { id });
|
|
103
|
+
if (!row) {
|
|
104
|
+
throw new HttpError(404, ERROR_CODES.ATTACHMENT_TYPE_NOT_FOUND, `AttachmentType ${id} not found.`);
|
|
105
|
+
}
|
|
106
|
+
const before = { code: row.code, name: row.name, position: row.position };
|
|
107
|
+
if (req.code !== undefined)
|
|
108
|
+
row.code = req.code;
|
|
109
|
+
if (req.name !== undefined)
|
|
110
|
+
row.name = req.name;
|
|
111
|
+
if (req.position !== undefined)
|
|
112
|
+
row.position = req.position;
|
|
113
|
+
try {
|
|
114
|
+
await em.flush();
|
|
115
|
+
}
|
|
116
|
+
catch (err) {
|
|
117
|
+
if (err instanceof UniqueConstraintViolationException) {
|
|
118
|
+
throw new HttpError(409, ERROR_CODES.ATTACHMENT_TYPE_CODE_TAKEN, `AttachmentType "${req.code}" already exists.`);
|
|
119
|
+
}
|
|
120
|
+
throw err;
|
|
121
|
+
}
|
|
122
|
+
return { result: row, before, after: { code: row.code, name: row.name, position: row.position } };
|
|
123
|
+
});
|
|
124
|
+
const usageCount = await this.#computeTypeUsage(this.emFactory(), id);
|
|
125
|
+
return {
|
|
126
|
+
id: t.id,
|
|
127
|
+
code: t.code,
|
|
128
|
+
name: t.name,
|
|
129
|
+
position: t.position,
|
|
130
|
+
usageCount,
|
|
131
|
+
createdAt: t.createdAt.toISOString(),
|
|
132
|
+
updatedAt: t.updatedAt.toISOString(),
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
async deleteType(id) {
|
|
136
|
+
await this.#audited('attachment_type.delete', 'attachment_type', id, async (em) => {
|
|
137
|
+
const t = await em.findOne(AttachmentType, { id });
|
|
138
|
+
if (!t) {
|
|
139
|
+
throw new HttpError(404, ERROR_CODES.ATTACHMENT_TYPE_NOT_FOUND, `AttachmentType ${id} not found.`);
|
|
140
|
+
}
|
|
141
|
+
const usageCount = await this.#computeTypeUsage(em, id);
|
|
142
|
+
if (usageCount > 0) {
|
|
143
|
+
throw new HttpError(409, ERROR_CODES.ATTACHMENT_TYPE_IN_USE, `AttachmentType "${t.code}" is referenced by ${usageCount} attachment(s); reassign them first.`, [{ path: 'usageCount', issue: String(usageCount) }]);
|
|
144
|
+
}
|
|
145
|
+
const before = { code: t.code, name: t.name };
|
|
146
|
+
em.remove(t);
|
|
147
|
+
return { result: undefined, before, after: null };
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
// -- Product Attachments --------------------------------------------------
|
|
151
|
+
async listAttachments(productId) {
|
|
152
|
+
const em = this.emFactory();
|
|
153
|
+
await this.#assertProductExists(em, productId);
|
|
154
|
+
const items = await em.find(ProductAttachment, { productId }, { orderBy: { position: 'asc', id: 'asc' } });
|
|
155
|
+
return items.map((i) => this.#attachmentDto(i));
|
|
156
|
+
}
|
|
157
|
+
async createAttachment(productId, req) {
|
|
158
|
+
const em = this.emFactory();
|
|
159
|
+
await this.#assertProductExists(em, productId);
|
|
160
|
+
const asset = await this.#requireAssets().findById(req.assetId);
|
|
161
|
+
if (!asset) {
|
|
162
|
+
throw new HttpError(404, ERROR_CODES.NOT_FOUND, `Asset ${req.assetId} not found.`);
|
|
163
|
+
}
|
|
164
|
+
if (!ASSET_KINDS_ATTACHMENT.has(asset.kind)) {
|
|
165
|
+
throw new HttpError(400, ERROR_CODES.ASSET_KIND_NOT_SUPPORTED, `Attachments require asset.kind ∈ {pdf, certificate, other}; got "${asset.kind}".`);
|
|
166
|
+
}
|
|
167
|
+
const type = await em.findOne(AttachmentType, { id: req.attachmentTypeId });
|
|
168
|
+
if (!type) {
|
|
169
|
+
throw new HttpError(404, ERROR_CODES.ATTACHMENT_TYPE_NOT_FOUND, `AttachmentType ${req.attachmentTypeId} not found.`);
|
|
170
|
+
}
|
|
171
|
+
const position = req.position ?? (await this.#nextPosition(em, productId));
|
|
172
|
+
const id = randomUUID();
|
|
173
|
+
const attachment = await this.#audited('product_attachment.create', 'product_attachment', id, async (cem) => {
|
|
174
|
+
const created = cem.create(ProductAttachment, {
|
|
175
|
+
id,
|
|
176
|
+
productId,
|
|
177
|
+
assetId: req.assetId,
|
|
178
|
+
attachmentTypeId: req.attachmentTypeId,
|
|
179
|
+
name: req.name,
|
|
180
|
+
description: req.description ?? null,
|
|
181
|
+
position,
|
|
182
|
+
});
|
|
183
|
+
await cem.flush();
|
|
184
|
+
return {
|
|
185
|
+
result: created,
|
|
186
|
+
before: null,
|
|
187
|
+
after: { productId, assetId: req.assetId, attachmentTypeId: req.attachmentTypeId, name: req.name, position },
|
|
188
|
+
};
|
|
189
|
+
});
|
|
190
|
+
return this.#attachmentDto(attachment);
|
|
191
|
+
}
|
|
192
|
+
async updateAttachment(productId, attachmentId, req) {
|
|
193
|
+
const a = await this.#audited('product_attachment.update', 'product_attachment', attachmentId, async (em) => {
|
|
194
|
+
const row = await em.findOne(ProductAttachment, { id: attachmentId, productId });
|
|
195
|
+
if (!row) {
|
|
196
|
+
throw new HttpError(404, ERROR_CODES.ATTACHMENT_NOT_FOUND, `Attachment ${attachmentId} not found under Product ${productId}.`);
|
|
197
|
+
}
|
|
198
|
+
const before = { attachmentTypeId: row.attachmentTypeId, name: row.name, position: row.position };
|
|
199
|
+
if (req.attachmentTypeId !== undefined) {
|
|
200
|
+
const type = await em.findOne(AttachmentType, { id: req.attachmentTypeId });
|
|
201
|
+
if (!type) {
|
|
202
|
+
throw new HttpError(404, ERROR_CODES.ATTACHMENT_TYPE_NOT_FOUND, `AttachmentType ${req.attachmentTypeId} not found.`);
|
|
203
|
+
}
|
|
204
|
+
row.attachmentTypeId = req.attachmentTypeId;
|
|
205
|
+
}
|
|
206
|
+
if (req.name !== undefined)
|
|
207
|
+
row.name = req.name;
|
|
208
|
+
if (req.description !== undefined)
|
|
209
|
+
row.description = req.description;
|
|
210
|
+
if (req.position !== undefined)
|
|
211
|
+
row.position = req.position;
|
|
212
|
+
return {
|
|
213
|
+
result: row,
|
|
214
|
+
before,
|
|
215
|
+
after: { attachmentTypeId: row.attachmentTypeId, name: row.name, position: row.position },
|
|
216
|
+
};
|
|
217
|
+
});
|
|
218
|
+
return this.#attachmentDto(a);
|
|
219
|
+
}
|
|
220
|
+
async deleteAttachment(productId, attachmentId) {
|
|
221
|
+
await this.#audited('product_attachment.delete', 'product_attachment', attachmentId, async (em) => {
|
|
222
|
+
const a = await em.findOne(ProductAttachment, { id: attachmentId, productId });
|
|
223
|
+
if (!a) {
|
|
224
|
+
throw new HttpError(404, ERROR_CODES.ATTACHMENT_NOT_FOUND, `Attachment ${attachmentId} not found under Product ${productId}.`);
|
|
225
|
+
}
|
|
226
|
+
const before = { productId, assetId: a.assetId };
|
|
227
|
+
// Asset is FK RESTRICT; the row stays. Whoever uploaded it owns the
|
|
228
|
+
// asset's lifecycle (research.md R-9).
|
|
229
|
+
em.remove(a);
|
|
230
|
+
return { result: undefined, before, after: null };
|
|
231
|
+
});
|
|
232
|
+
}
|
|
233
|
+
// -- INTERNALS ------------------------------------------------------------
|
|
234
|
+
async #assertProductExists(em, productId) {
|
|
235
|
+
const product = await em.findOne(Product, { id: productId });
|
|
236
|
+
if (!product) {
|
|
237
|
+
throw new HttpError(404, ERROR_CODES.PRODUCT_NOT_FOUND, `Product ${productId} not found.`);
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
/**
|
|
241
|
+
* `em.execute`, not `em.getConnection().execute`: the delete path calls this
|
|
242
|
+
* on the Command's `em` to refuse a type that is still referenced, so read on
|
|
243
|
+
* a pooled connection the guard answered from outside the transaction it is
|
|
244
|
+
* guarding (issue #207).
|
|
245
|
+
*/
|
|
246
|
+
async #computeTypeUsage(em, typeId) {
|
|
247
|
+
const rows = (await em.execute(`select count(*)::int as n from product_attachments where attachment_type_id = ?`, [typeId]));
|
|
248
|
+
return rows[0]?.n ?? 0;
|
|
249
|
+
}
|
|
250
|
+
async #nextPosition(em, productId) {
|
|
251
|
+
const rows = (await em.execute(`select coalesce(max(position), -1) + 1 as next_position from product_attachments where product_id = ?`, [productId]));
|
|
252
|
+
return rows[0]?.next_position ?? 0;
|
|
253
|
+
}
|
|
254
|
+
#attachmentDto(a) {
|
|
255
|
+
return {
|
|
256
|
+
id: a.id,
|
|
257
|
+
productId: a.productId,
|
|
258
|
+
assetId: a.assetId,
|
|
259
|
+
attachmentTypeId: a.attachmentTypeId,
|
|
260
|
+
name: a.name,
|
|
261
|
+
description: a.description ?? null,
|
|
262
|
+
position: a.position,
|
|
263
|
+
createdAt: a.createdAt.toISOString(),
|
|
264
|
+
updatedAt: a.updatedAt.toISOString(),
|
|
265
|
+
};
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
//# sourceMappingURL=attachment.service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"attachment.service.js","sourceRoot":"","sources":["../../../src/backend/services/attachment.service.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Attribute / option-list validator (feature 012, retained by feature 061).
|
|
3
|
+
*
|
|
4
|
+
* Pure functions used by the attribute Commands
|
|
5
|
+
* (`catalog/commands/attribute-commands.ts`) to refuse bad input before it
|
|
6
|
+
* reaches the DB. Attribute-key format is enforced at the API boundary by
|
|
7
|
+
* the Zod schemas in `@endora-commerce/contracts`.
|
|
8
|
+
*/
|
|
9
|
+
/**
|
|
10
|
+
* Value types whose options live in `custom_field_options` (feature 061;
|
|
11
|
+
* previously the catalog-owned `attribute_options` table, FR-021 of 012).
|
|
12
|
+
*/
|
|
13
|
+
export declare const SELECT_STYLE_VALUE_TYPES: readonly ["select", "enum", "multiselect"];
|
|
14
|
+
export type SelectStyleValueType = (typeof SELECT_STYLE_VALUE_TYPES)[number];
|
|
15
|
+
export declare function isValidOptionValue(value: string): boolean;
|
|
16
|
+
export interface OptionInput {
|
|
17
|
+
value: string;
|
|
18
|
+
label?: Record<string, string>;
|
|
19
|
+
labelDefault: string;
|
|
20
|
+
isDefault?: boolean;
|
|
21
|
+
sortOrder?: number;
|
|
22
|
+
}
|
|
23
|
+
export interface ValidationError {
|
|
24
|
+
code: 'duplicate_value' | 'default_option_ambiguous' | 'invalid_option_value' | 'attribute_type_unsupported';
|
|
25
|
+
/** The offending value (when applicable). */
|
|
26
|
+
value?: string;
|
|
27
|
+
message: string;
|
|
28
|
+
}
|
|
29
|
+
export type ValidationResult = {
|
|
30
|
+
ok: true;
|
|
31
|
+
} | {
|
|
32
|
+
ok: false;
|
|
33
|
+
errors: ValidationError[];
|
|
34
|
+
};
|
|
35
|
+
/**
|
|
36
|
+
* Validate an option list against the parent attribute's value type.
|
|
37
|
+
*
|
|
38
|
+
* - The parent type MUST be one of `select` / `enum` / `multiselect`,
|
|
39
|
+
* otherwise the call returns `attribute_type_unsupported`.
|
|
40
|
+
* - Every option `value` MUST match `OPTION_VALUE_REGEX`.
|
|
41
|
+
* - Values MUST be unique within the list.
|
|
42
|
+
* - For `select` / `enum` types: at most one option MAY carry
|
|
43
|
+
* `isDefault = true` (FR-023). `multiselect` allows multiple
|
|
44
|
+
* defaults (FR-024).
|
|
45
|
+
*/
|
|
46
|
+
export declare function validateOptionList(options: readonly OptionInput[], parentValueType: string): ValidationResult;
|
|
47
|
+
//# sourceMappingURL=attribute-option-validator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"attribute-option-validator.d.ts","sourceRoot":"","sources":["../../../src/backend/services/attribute-option-validator.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH;;;GAGG;AACH,eAAO,MAAM,wBAAwB,4CAA6C,CAAC;AACnF,MAAM,MAAM,oBAAoB,GAAG,CAAC,OAAO,wBAAwB,CAAC,CAAC,MAAM,CAAC,CAAC;AAE7E,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAEzD;AAED,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC/B,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,eAAe;IAC9B,IAAI,EACA,iBAAiB,GACjB,0BAA0B,GAC1B,sBAAsB,GACtB,4BAA4B,CAAC;IACjC,6CAA6C;IAC7C,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,MAAM,gBAAgB,GACxB;IAAE,EAAE,EAAE,IAAI,CAAA;CAAE,GACZ;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,eAAe,EAAE,CAAA;CAAE,CAAC;AAE7C;;;;;;;;;;GAUG;AACH,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,SAAS,WAAW,EAAE,EAC/B,eAAe,EAAE,MAAM,GACtB,gBAAgB,CA0ClB"}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Attribute / option-list validator (feature 012, retained by feature 061).
|
|
3
|
+
*
|
|
4
|
+
* Pure functions used by the attribute Commands
|
|
5
|
+
* (`catalog/commands/attribute-commands.ts`) to refuse bad input before it
|
|
6
|
+
* reaches the DB. Attribute-key format is enforced at the API boundary by
|
|
7
|
+
* the Zod schemas in `@endora-commerce/contracts`.
|
|
8
|
+
*/
|
|
9
|
+
const OPTION_VALUE_REGEX = /^[a-z0-9_-]{1,200}$/;
|
|
10
|
+
/**
|
|
11
|
+
* Value types whose options live in `custom_field_options` (feature 061;
|
|
12
|
+
* previously the catalog-owned `attribute_options` table, FR-021 of 012).
|
|
13
|
+
*/
|
|
14
|
+
export const SELECT_STYLE_VALUE_TYPES = ['select', 'enum', 'multiselect'];
|
|
15
|
+
export function isValidOptionValue(value) {
|
|
16
|
+
return OPTION_VALUE_REGEX.test(value);
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Validate an option list against the parent attribute's value type.
|
|
20
|
+
*
|
|
21
|
+
* - The parent type MUST be one of `select` / `enum` / `multiselect`,
|
|
22
|
+
* otherwise the call returns `attribute_type_unsupported`.
|
|
23
|
+
* - Every option `value` MUST match `OPTION_VALUE_REGEX`.
|
|
24
|
+
* - Values MUST be unique within the list.
|
|
25
|
+
* - For `select` / `enum` types: at most one option MAY carry
|
|
26
|
+
* `isDefault = true` (FR-023). `multiselect` allows multiple
|
|
27
|
+
* defaults (FR-024).
|
|
28
|
+
*/
|
|
29
|
+
export function validateOptionList(options, parentValueType) {
|
|
30
|
+
const errors = [];
|
|
31
|
+
if (!SELECT_STYLE_VALUE_TYPES.includes(parentValueType)) {
|
|
32
|
+
errors.push({
|
|
33
|
+
code: 'attribute_type_unsupported',
|
|
34
|
+
message: `Options are only supported for ${SELECT_STYLE_VALUE_TYPES.join(' / ')} attributes (got '${parentValueType}').`,
|
|
35
|
+
});
|
|
36
|
+
return { ok: false, errors };
|
|
37
|
+
}
|
|
38
|
+
const seen = new Set();
|
|
39
|
+
let defaultCount = 0;
|
|
40
|
+
for (const opt of options) {
|
|
41
|
+
if (!isValidOptionValue(opt.value)) {
|
|
42
|
+
errors.push({
|
|
43
|
+
code: 'invalid_option_value',
|
|
44
|
+
value: opt.value,
|
|
45
|
+
message: `Option value '${opt.value}' must match /^[a-z0-9_-]{1,200}$/.`,
|
|
46
|
+
});
|
|
47
|
+
continue;
|
|
48
|
+
}
|
|
49
|
+
if (seen.has(opt.value)) {
|
|
50
|
+
errors.push({
|
|
51
|
+
code: 'duplicate_value',
|
|
52
|
+
value: opt.value,
|
|
53
|
+
message: `Duplicate option value '${opt.value}' within the attribute's option list.`,
|
|
54
|
+
});
|
|
55
|
+
continue;
|
|
56
|
+
}
|
|
57
|
+
seen.add(opt.value);
|
|
58
|
+
if (opt.isDefault)
|
|
59
|
+
defaultCount += 1;
|
|
60
|
+
}
|
|
61
|
+
if (defaultCount > 1 && parentValueType !== 'multiselect') {
|
|
62
|
+
errors.push({
|
|
63
|
+
code: 'default_option_ambiguous',
|
|
64
|
+
message: `Attribute of type '${parentValueType}' allows at most one default option.`,
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
return errors.length === 0 ? { ok: true } : { ok: false, errors };
|
|
68
|
+
}
|
|
69
|
+
//# sourceMappingURL=attribute-option-validator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"attribute-option-validator.js","sourceRoot":"","sources":["../../../src/backend/services/attribute-option-validator.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,MAAM,kBAAkB,GAAG,qBAAqB,CAAC;AAEjD;;;GAGG;AACH,MAAM,CAAC,MAAM,wBAAwB,GAAG,CAAC,QAAQ,EAAE,MAAM,EAAE,aAAa,CAAU,CAAC;AAGnF,MAAM,UAAU,kBAAkB,CAAC,KAAa;IAC9C,OAAO,kBAAkB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;AACxC,CAAC;AAyBD;;;;;;;;;;GAUG;AACH,MAAM,UAAU,kBAAkB,CAChC,OAA+B,EAC/B,eAAuB;IAEvB,MAAM,MAAM,GAAsB,EAAE,CAAC;IAErC,IAAI,CAAC,wBAAwB,CAAC,QAAQ,CAAC,eAAuC,CAAC,EAAE,CAAC;QAChF,MAAM,CAAC,IAAI,CAAC;YACV,IAAI,EAAE,4BAA4B;YAClC,OAAO,EAAE,kCAAkC,wBAAwB,CAAC,IAAI,CAAC,KAAK,CAAC,qBAAqB,eAAe,KAAK;SACzH,CAAC,CAAC;QACH,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC;IAC/B,CAAC;IAED,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;IAC/B,IAAI,YAAY,GAAG,CAAC,CAAC;IACrB,KAAK,MAAM,GAAG,IAAI,OAAO,EAAE,CAAC;QAC1B,IAAI,CAAC,kBAAkB,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC;YACnC,MAAM,CAAC,IAAI,CAAC;gBACV,IAAI,EAAE,sBAAsB;gBAC5B,KAAK,EAAE,GAAG,CAAC,KAAK;gBAChB,OAAO,EAAE,iBAAiB,GAAG,CAAC,KAAK,qCAAqC;aACzE,CAAC,CAAC;YACH,SAAS;QACX,CAAC;QACD,IAAI,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC;YACxB,MAAM,CAAC,IAAI,CAAC;gBACV,IAAI,EAAE,iBAAiB;gBACvB,KAAK,EAAE,GAAG,CAAC,KAAK;gBAChB,OAAO,EAAE,2BAA2B,GAAG,CAAC,KAAK,uCAAuC;aACrF,CAAC,CAAC;YACH,SAAS;QACX,CAAC;QACD,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QACpB,IAAI,GAAG,CAAC,SAAS;YAAE,YAAY,IAAI,CAAC,CAAC;IACvC,CAAC;IAED,IAAI,YAAY,GAAG,CAAC,IAAI,eAAe,KAAK,aAAa,EAAE,CAAC;QAC1D,MAAM,CAAC,IAAI,CAAC;YACV,IAAI,EAAE,0BAA0B;YAChC,OAAO,EAAE,sBAAsB,eAAe,sCAAsC;SACrF,CAAC,CAAC;IACL,CAAC;IAED,OAAO,MAAM,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC;AACpE,CAAC"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pure validation helpers for the AttributeSet domain.
|
|
3
|
+
*
|
|
4
|
+
* Extracted so the rules can be unit-tested without spinning up Postgres
|
|
5
|
+
* (Constitution Principle III: integration tests hit the real DB; unit
|
|
6
|
+
* tests stay deterministic and fast).
|
|
7
|
+
*
|
|
8
|
+
* Implementation lands in T022; this file currently exposes the type
|
|
9
|
+
* surface and stubs that throw `not implemented` so the failing unit
|
|
10
|
+
* test (T010) compiles.
|
|
11
|
+
*/
|
|
12
|
+
export type AttributeSetValidationCode = 'SYSTEM_ATTRIBUTE_SET_IMMUTABLE' | 'ATTRIBUTE_SET_IN_USE';
|
|
13
|
+
export declare class AttributeSetValidationError extends Error {
|
|
14
|
+
readonly code: AttributeSetValidationCode;
|
|
15
|
+
readonly details?: Record<string, unknown> | undefined;
|
|
16
|
+
constructor(message: string, code: AttributeSetValidationCode, details?: Record<string, unknown> | undefined);
|
|
17
|
+
}
|
|
18
|
+
export interface SystemSetMarker {
|
|
19
|
+
isSystem: boolean;
|
|
20
|
+
code: string;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Reject any attempt to change the `code` of a system Attribute Set.
|
|
24
|
+
* Renaming the localized `name` of the Default set is permitted; only
|
|
25
|
+
* the `code` (a stable integration key) is immutable.
|
|
26
|
+
*
|
|
27
|
+
* Throws AttributeSetValidationError with code SYSTEM_ATTRIBUTE_SET_IMMUTABLE.
|
|
28
|
+
*/
|
|
29
|
+
export declare function assertCodeNotImmutable(currentSet: SystemSetMarker, newCode: string | undefined): void;
|
|
30
|
+
/**
|
|
31
|
+
* Reject deletion of an Attribute Set that has at least one Product
|
|
32
|
+
* pointing to it. Caller passes `productCount` aggregated from a count
|
|
33
|
+
* query against `products.attribute_set_id`.
|
|
34
|
+
*
|
|
35
|
+
* Throws AttributeSetValidationError with code ATTRIBUTE_SET_IN_USE
|
|
36
|
+
* (and `details: { productCount }`) when productCount > 0.
|
|
37
|
+
*
|
|
38
|
+
* Defensive on negative or fractional inputs: anything other than
|
|
39
|
+
* exactly `0` is treated as "in use". A negative count is nonsense from
|
|
40
|
+
* the caller's side, but we'd rather refuse the delete than silently
|
|
41
|
+
* allow it.
|
|
42
|
+
*/
|
|
43
|
+
export declare function assertNotInUse(productCount: number): void;
|
|
44
|
+
export interface AttributePartition {
|
|
45
|
+
/** Attribute keys preserved as live values (still in the new Set). */
|
|
46
|
+
preservedKeys: string[];
|
|
47
|
+
/** Attribute keys whose values are kept as archival (no longer editable). */
|
|
48
|
+
archivedKeys: string[];
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Decide which attribute values on a Product survive a Set swap and which
|
|
52
|
+
* become archival. Spec §"Edge Cases" / §1.1 Assumptions:
|
|
53
|
+
*
|
|
54
|
+
* - Keys present in BOTH old and new Set → preserved (still editable).
|
|
55
|
+
* - Keys present ONLY in old Set → archived (not editable, not displayed,
|
|
56
|
+
* but kept in `attribute_values` JSONB until either re-added or
|
|
57
|
+
* explicitly cleared by the admin).
|
|
58
|
+
* - Keys present ONLY in new Set → not in current values; product is
|
|
59
|
+
* marked as needing backfill (out of scope for this helper — caller
|
|
60
|
+
* handles).
|
|
61
|
+
*
|
|
62
|
+
* Returns the partition of currently-set keys into preserved vs archived.
|
|
63
|
+
*/
|
|
64
|
+
export declare function partitionAttributesForSetChange(currentValueKeys: string[], oldSetAttributeKeys: string[], newSetAttributeKeys: string[]): AttributePartition;
|
|
65
|
+
//# sourceMappingURL=attribute-set-validations.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"attribute-set-validations.d.ts","sourceRoot":"","sources":["../../../src/backend/services/attribute-set-validations.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,MAAM,MAAM,0BAA0B,GAClC,gCAAgC,GAChC,sBAAsB,CAAC;AAE3B,qBAAa,2BAA4B,SAAQ,KAAK;aAGlC,IAAI,EAAE,0BAA0B;aAChC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;gBAFjD,OAAO,EAAE,MAAM,EACC,IAAI,EAAE,0BAA0B,EAChC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,YAAA;CAKpD;AAED,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,OAAO,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;CACd;AAED;;;;;;GAMG;AACH,wBAAgB,sBAAsB,CACpC,UAAU,EAAE,eAAe,EAC3B,OAAO,EAAE,MAAM,GAAG,SAAS,GAC1B,IAAI,CAQN;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,cAAc,CAAC,YAAY,EAAE,MAAM,GAAG,IAAI,CAOzD;AAED,MAAM,WAAW,kBAAkB;IACjC,sEAAsE;IACtE,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,6EAA6E;IAC7E,YAAY,EAAE,MAAM,EAAE,CAAC;CACxB;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,+BAA+B,CAC7C,gBAAgB,EAAE,MAAM,EAAE,EAC1B,mBAAmB,EAAE,MAAM,EAAE,EAC7B,mBAAmB,EAAE,MAAM,EAAE,GAC5B,kBAAkB,CAiBpB"}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pure validation helpers for the AttributeSet domain.
|
|
3
|
+
*
|
|
4
|
+
* Extracted so the rules can be unit-tested without spinning up Postgres
|
|
5
|
+
* (Constitution Principle III: integration tests hit the real DB; unit
|
|
6
|
+
* tests stay deterministic and fast).
|
|
7
|
+
*
|
|
8
|
+
* Implementation lands in T022; this file currently exposes the type
|
|
9
|
+
* surface and stubs that throw `not implemented` so the failing unit
|
|
10
|
+
* test (T010) compiles.
|
|
11
|
+
*/
|
|
12
|
+
export class AttributeSetValidationError extends Error {
|
|
13
|
+
code;
|
|
14
|
+
details;
|
|
15
|
+
constructor(message, code, details) {
|
|
16
|
+
super(message);
|
|
17
|
+
this.code = code;
|
|
18
|
+
this.details = details;
|
|
19
|
+
this.name = 'AttributeSetValidationError';
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Reject any attempt to change the `code` of a system Attribute Set.
|
|
24
|
+
* Renaming the localized `name` of the Default set is permitted; only
|
|
25
|
+
* the `code` (a stable integration key) is immutable.
|
|
26
|
+
*
|
|
27
|
+
* Throws AttributeSetValidationError with code SYSTEM_ATTRIBUTE_SET_IMMUTABLE.
|
|
28
|
+
*/
|
|
29
|
+
export function assertCodeNotImmutable(currentSet, newCode) {
|
|
30
|
+
if (!currentSet.isSystem)
|
|
31
|
+
return;
|
|
32
|
+
if (newCode === undefined)
|
|
33
|
+
return;
|
|
34
|
+
if (newCode === currentSet.code)
|
|
35
|
+
return;
|
|
36
|
+
throw new AttributeSetValidationError(`Cannot change code of the system Attribute Set "${currentSet.code}".`, 'SYSTEM_ATTRIBUTE_SET_IMMUTABLE');
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Reject deletion of an Attribute Set that has at least one Product
|
|
40
|
+
* pointing to it. Caller passes `productCount` aggregated from a count
|
|
41
|
+
* query against `products.attribute_set_id`.
|
|
42
|
+
*
|
|
43
|
+
* Throws AttributeSetValidationError with code ATTRIBUTE_SET_IN_USE
|
|
44
|
+
* (and `details: { productCount }`) when productCount > 0.
|
|
45
|
+
*
|
|
46
|
+
* Defensive on negative or fractional inputs: anything other than
|
|
47
|
+
* exactly `0` is treated as "in use". A negative count is nonsense from
|
|
48
|
+
* the caller's side, but we'd rather refuse the delete than silently
|
|
49
|
+
* allow it.
|
|
50
|
+
*/
|
|
51
|
+
export function assertNotInUse(productCount) {
|
|
52
|
+
if (productCount === 0)
|
|
53
|
+
return;
|
|
54
|
+
throw new AttributeSetValidationError(`Attribute Set is referenced by ${productCount} Product(s).`, 'ATTRIBUTE_SET_IN_USE', { productCount });
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Decide which attribute values on a Product survive a Set swap and which
|
|
58
|
+
* become archival. Spec §"Edge Cases" / §1.1 Assumptions:
|
|
59
|
+
*
|
|
60
|
+
* - Keys present in BOTH old and new Set → preserved (still editable).
|
|
61
|
+
* - Keys present ONLY in old Set → archived (not editable, not displayed,
|
|
62
|
+
* but kept in `attribute_values` JSONB until either re-added or
|
|
63
|
+
* explicitly cleared by the admin).
|
|
64
|
+
* - Keys present ONLY in new Set → not in current values; product is
|
|
65
|
+
* marked as needing backfill (out of scope for this helper — caller
|
|
66
|
+
* handles).
|
|
67
|
+
*
|
|
68
|
+
* Returns the partition of currently-set keys into preserved vs archived.
|
|
69
|
+
*/
|
|
70
|
+
export function partitionAttributesForSetChange(currentValueKeys, oldSetAttributeKeys, newSetAttributeKeys) {
|
|
71
|
+
const oldSet = new Set(oldSetAttributeKeys);
|
|
72
|
+
const newSet = new Set(newSetAttributeKeys);
|
|
73
|
+
const preservedKeys = [];
|
|
74
|
+
const archivedKeys = [];
|
|
75
|
+
for (const key of currentValueKeys) {
|
|
76
|
+
if (!oldSet.has(key)) {
|
|
77
|
+
// Orphan — wasn't in the old Set either; partition does not move it.
|
|
78
|
+
continue;
|
|
79
|
+
}
|
|
80
|
+
if (newSet.has(key)) {
|
|
81
|
+
preservedKeys.push(key);
|
|
82
|
+
}
|
|
83
|
+
else {
|
|
84
|
+
archivedKeys.push(key);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
return { preservedKeys, archivedKeys };
|
|
88
|
+
}
|
|
89
|
+
//# sourceMappingURL=attribute-set-validations.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"attribute-set-validations.js","sourceRoot":"","sources":["../../../src/backend/services/attribute-set-validations.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAMH,MAAM,OAAO,2BAA4B,SAAQ,KAAK;IAGlC;IACA;IAHlB,YACE,OAAe,EACC,IAAgC,EAChC,OAAiC;QAEjD,KAAK,CAAC,OAAO,CAAC,CAAC;QAHC,SAAI,GAAJ,IAAI,CAA4B;QAChC,YAAO,GAAP,OAAO,CAA0B;QAGjD,IAAI,CAAC,IAAI,GAAG,6BAA6B,CAAC;IAC5C,CAAC;CACF;AAOD;;;;;;GAMG;AACH,MAAM,UAAU,sBAAsB,CACpC,UAA2B,EAC3B,OAA2B;IAE3B,IAAI,CAAC,UAAU,CAAC,QAAQ;QAAE,OAAO;IACjC,IAAI,OAAO,KAAK,SAAS;QAAE,OAAO;IAClC,IAAI,OAAO,KAAK,UAAU,CAAC,IAAI;QAAE,OAAO;IACxC,MAAM,IAAI,2BAA2B,CACnC,mDAAmD,UAAU,CAAC,IAAI,IAAI,EACtE,gCAAgC,CACjC,CAAC;AACJ,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,cAAc,CAAC,YAAoB;IACjD,IAAI,YAAY,KAAK,CAAC;QAAE,OAAO;IAC/B,MAAM,IAAI,2BAA2B,CACnC,kCAAkC,YAAY,cAAc,EAC5D,sBAAsB,EACtB,EAAE,YAAY,EAAE,CACjB,CAAC;AACJ,CAAC;AASD;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,+BAA+B,CAC7C,gBAA0B,EAC1B,mBAA6B,EAC7B,mBAA6B;IAE7B,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,mBAAmB,CAAC,CAAC;IAC5C,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,mBAAmB,CAAC,CAAC;IAC5C,MAAM,aAAa,GAAa,EAAE,CAAC;IACnC,MAAM,YAAY,GAAa,EAAE,CAAC;IAClC,KAAK,MAAM,GAAG,IAAI,gBAAgB,EAAE,CAAC;QACnC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;YACrB,qEAAqE;YACrE,SAAS;QACX,CAAC;QACD,IAAI,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;YACpB,aAAa,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAC1B,CAAC;aAAM,CAAC;YACN,YAAY,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACzB,CAAC;IACH,CAAC;IACD,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,CAAC;AACzC,CAAC"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AttributeSetService — admin-only CRUD for Attribute Sets and their
|
|
3
|
+
* relationship with Product Attributes (feature 002,
|
|
4
|
+
* data-model.md §2.1, §2.2; contracts/catalog-002.contract.md).
|
|
5
|
+
*
|
|
6
|
+
* Composition pattern matches `category-admin.service.ts`:
|
|
7
|
+
* - constructor takes `emFactory: () => EntityManager`,
|
|
8
|
+
* - each call forks a fresh EM,
|
|
9
|
+
* - returns DTOs (matching the published Zod schemas) so route handlers
|
|
10
|
+
* are a thin wrapper.
|
|
11
|
+
*/
|
|
12
|
+
import type { EntityManager } from '@mikro-orm/postgresql';
|
|
13
|
+
import { type AttributeSet as AttributeSetDto, type AttributeSetDetail as AttributeSetDetailDto, type CreateAttributeSetRequest, type UpdateAttributeSetRequest, type AssignAttributesRequest } from '@endora-commerce/contracts';
|
|
14
|
+
import type { CommandBus } from '@endora-commerce/platform/commands';
|
|
15
|
+
import type { CatalogAttributeReadService } from './catalog-attribute-read.service.js';
|
|
16
|
+
import { assertCodeNotImmutable, assertNotInUse, AttributeSetValidationError } from './attribute-set-validations.js';
|
|
17
|
+
export declare class AttributeSetService {
|
|
18
|
+
#private;
|
|
19
|
+
private readonly emFactory;
|
|
20
|
+
/** Feature 054 — audits attribute-set writes co-transactionally when provided. */
|
|
21
|
+
private readonly commandBus?;
|
|
22
|
+
/**
|
|
23
|
+
* Feature 061 — composed attribute read model. Set membership is stored by
|
|
24
|
+
* definition id, but the API keeps accepting/returning attribute
|
|
25
|
+
* (extension) ids — this service maps between the two at the boundary.
|
|
26
|
+
*/
|
|
27
|
+
private readonly attributeRead?;
|
|
28
|
+
constructor(emFactory: () => EntityManager,
|
|
29
|
+
/** Feature 054 — audits attribute-set writes co-transactionally when provided. */
|
|
30
|
+
commandBus?: CommandBus | undefined,
|
|
31
|
+
/**
|
|
32
|
+
* Feature 061 — composed attribute read model. Set membership is stored by
|
|
33
|
+
* definition id, but the API keeps accepting/returning attribute
|
|
34
|
+
* (extension) ids — this service maps between the two at the boundary.
|
|
35
|
+
*/
|
|
36
|
+
attributeRead?: CatalogAttributeReadService | undefined);
|
|
37
|
+
listSets(): Promise<AttributeSetDto[]>;
|
|
38
|
+
getSetDetail(id: string): Promise<AttributeSetDetailDto>;
|
|
39
|
+
createSet(input: CreateAttributeSetRequest): Promise<AttributeSetDetailDto>;
|
|
40
|
+
updateSet(id: string, input: UpdateAttributeSetRequest): Promise<AttributeSetDto>;
|
|
41
|
+
deleteSet(id: string): Promise<void>;
|
|
42
|
+
assignAttributes(id: string, input: AssignAttributesRequest): Promise<AttributeSetDetailDto>;
|
|
43
|
+
unassignAttribute(id: string, attributeId: string): Promise<void>;
|
|
44
|
+
static readonly validations: {
|
|
45
|
+
assertCodeNotImmutable: typeof assertCodeNotImmutable;
|
|
46
|
+
assertNotInUse: typeof assertNotInUse;
|
|
47
|
+
isValidationError: (err: unknown) => err is AttributeSetValidationError;
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
//# sourceMappingURL=attribute-set.service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"attribute-set.service.d.ts","sourceRoot":"","sources":["../../../src/backend/services/attribute-set.service.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAGH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAG3D,OAAO,EAEL,KAAK,YAAY,IAAI,eAAe,EACpC,KAAK,kBAAkB,IAAI,qBAAqB,EAEhD,KAAK,yBAAyB,EAC9B,KAAK,yBAAyB,EAC9B,KAAK,uBAAuB,EAC7B,MAAM,4BAA4B,CAAC;AAGpC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oCAAoC,CAAC;AAErE,OAAO,KAAK,EACV,2BAA2B,EAE5B,MAAM,qCAAqC,CAAC;AAC7C,OAAO,EACL,sBAAsB,EACtB,cAAc,EACd,2BAA2B,EAC5B,MAAM,gCAAgC,CAAC;AAUxC,qBAAa,mBAAmB;;IAE5B,OAAO,CAAC,QAAQ,CAAC,SAAS;IAC1B,kFAAkF;IAClF,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAC;IAC5B;;;;OAIG;IACH,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAC;gBARd,SAAS,EAAE,MAAM,aAAa;IAC/C,kFAAkF;IACjE,UAAU,CAAC,EAAE,UAAU,YAAA;IACxC;;;;OAIG;IACc,aAAa,CAAC,EAAE,2BAA2B,YAAA;IA+CxD,QAAQ,IAAI,OAAO,CAAC,eAAe,EAAE,CAAC;IAwCtC,YAAY,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,qBAAqB,CAAC;IAmBxD,SAAS,CAAC,KAAK,EAAE,yBAAyB,GAAG,OAAO,CAAC,qBAAqB,CAAC;IAwE3E,SAAS,CACb,EAAE,EAAE,MAAM,EACV,KAAK,EAAE,yBAAyB,GAC/B,OAAO,CAAC,eAAe,CAAC;IAyDrB,SAAS,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAqCpC,gBAAgB,CACpB,EAAE,EAAE,MAAM,EACV,KAAK,EAAE,uBAAuB,GAC7B,OAAO,CAAC,qBAAqB,CAAC;IAqE3B,iBAAiB,CAAC,EAAE,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAuIvE,MAAM,CAAC,QAAQ,CAAC,WAAW;;;iCAGA,OAAO,KAAG,GAAG,IAAI,2BAA2B;MAErE;CACH"}
|