@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.
Files changed (443) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +63 -0
  3. package/dist/admin/components/PackagingUnitsEditor.d.ts +12 -0
  4. package/dist/admin/components/PackagingUnitsEditor.d.ts.map +1 -0
  5. package/dist/admin/components/PackagingUnitsEditor.js +99 -0
  6. package/dist/admin/components/PackagingUnitsEditor.js.map +1 -0
  7. package/dist/admin/components/ProductAttributesTab.d.ts +13 -0
  8. package/dist/admin/components/ProductAttributesTab.d.ts.map +1 -0
  9. package/dist/admin/components/ProductAttributesTab.js +140 -0
  10. package/dist/admin/components/ProductAttributesTab.js.map +1 -0
  11. package/dist/admin/components/ProductInventoryTab.d.ts +14 -0
  12. package/dist/admin/components/ProductInventoryTab.d.ts.map +1 -0
  13. package/dist/admin/components/ProductInventoryTab.js +284 -0
  14. package/dist/admin/components/ProductInventoryTab.js.map +1 -0
  15. package/dist/admin/components/ProductScopeEditor.d.ts +94 -0
  16. package/dist/admin/components/ProductScopeEditor.d.ts.map +1 -0
  17. package/dist/admin/components/ProductScopeEditor.js +395 -0
  18. package/dist/admin/components/ProductScopeEditor.js.map +1 -0
  19. package/dist/admin/components/ProductsBulkEditDialog.d.ts +11 -0
  20. package/dist/admin/components/ProductsBulkEditDialog.d.ts.map +1 -0
  21. package/dist/admin/components/ProductsBulkEditDialog.js +304 -0
  22. package/dist/admin/components/ProductsBulkEditDialog.js.map +1 -0
  23. package/dist/admin/index.d.ts +45 -0
  24. package/dist/admin/index.d.ts.map +1 -0
  25. package/dist/admin/index.js +184 -0
  26. package/dist/admin/index.js.map +1 -0
  27. package/dist/admin/lib/resolve-product-selection.d.ts +21 -0
  28. package/dist/admin/lib/resolve-product-selection.d.ts.map +1 -0
  29. package/dist/admin/lib/resolve-product-selection.js +25 -0
  30. package/dist/admin/lib/resolve-product-selection.js.map +1 -0
  31. package/dist/admin/pages/AttachmentTypesPage.d.ts +18 -0
  32. package/dist/admin/pages/AttachmentTypesPage.d.ts.map +1 -0
  33. package/dist/admin/pages/AttachmentTypesPage.js +92 -0
  34. package/dist/admin/pages/AttachmentTypesPage.js.map +1 -0
  35. package/dist/admin/pages/AttributeSetsPage.d.ts +21 -0
  36. package/dist/admin/pages/AttributeSetsPage.d.ts.map +1 -0
  37. package/dist/admin/pages/AttributeSetsPage.js +158 -0
  38. package/dist/admin/pages/AttributeSetsPage.js.map +1 -0
  39. package/dist/admin/pages/AttributesManager.d.ts +9 -0
  40. package/dist/admin/pages/AttributesManager.d.ts.map +1 -0
  41. package/dist/admin/pages/AttributesManager.js +305 -0
  42. package/dist/admin/pages/AttributesManager.js.map +1 -0
  43. package/dist/admin/pages/BulkOperationDetailPage.d.ts +9 -0
  44. package/dist/admin/pages/BulkOperationDetailPage.d.ts.map +1 -0
  45. package/dist/admin/pages/BulkOperationDetailPage.js +187 -0
  46. package/dist/admin/pages/BulkOperationDetailPage.js.map +1 -0
  47. package/dist/admin/pages/BulkOperationsPage.d.ts +9 -0
  48. package/dist/admin/pages/BulkOperationsPage.d.ts.map +1 -0
  49. package/dist/admin/pages/BulkOperationsPage.js +98 -0
  50. package/dist/admin/pages/BulkOperationsPage.js.map +1 -0
  51. package/dist/admin/pages/CategoriesTree.d.ts +9 -0
  52. package/dist/admin/pages/CategoriesTree.d.ts.map +1 -0
  53. package/dist/admin/pages/CategoriesTree.js +176 -0
  54. package/dist/admin/pages/CategoriesTree.js.map +1 -0
  55. package/dist/admin/pages/ProductEditor.d.ts +13 -0
  56. package/dist/admin/pages/ProductEditor.d.ts.map +1 -0
  57. package/dist/admin/pages/ProductEditor.js +1050 -0
  58. package/dist/admin/pages/ProductEditor.js.map +1 -0
  59. package/dist/admin/pages/ProductsList.d.ts +9 -0
  60. package/dist/admin/pages/ProductsList.d.ts.map +1 -0
  61. package/dist/admin/pages/ProductsList.js +399 -0
  62. package/dist/admin/pages/ProductsList.js.map +1 -0
  63. package/dist/backend/commands/attribute-commands.d.ts +111 -0
  64. package/dist/backend/commands/attribute-commands.d.ts.map +1 -0
  65. package/dist/backend/commands/attribute-commands.js +482 -0
  66. package/dist/backend/commands/attribute-commands.js.map +1 -0
  67. package/dist/backend/demo/reset.d.ts +23 -0
  68. package/dist/backend/demo/reset.d.ts.map +1 -0
  69. package/dist/backend/demo/reset.js +41 -0
  70. package/dist/backend/demo/reset.js.map +1 -0
  71. package/dist/backend/demo/rows.d.ts +103 -0
  72. package/dist/backend/demo/rows.d.ts.map +1 -0
  73. package/dist/backend/demo/rows.js +162 -0
  74. package/dist/backend/demo/rows.js.map +1 -0
  75. package/dist/backend/demo/seed.d.ts +35 -0
  76. package/dist/backend/demo/seed.d.ts.map +1 -0
  77. package/dist/backend/demo/seed.js +177 -0
  78. package/dist/backend/demo/seed.js.map +1 -0
  79. package/dist/backend/entities/attachment-type.entity.d.ts +16 -0
  80. package/dist/backend/entities/attachment-type.entity.d.ts.map +1 -0
  81. package/dist/backend/entities/attachment-type.entity.js +57 -0
  82. package/dist/backend/entities/attachment-type.entity.js.map +1 -0
  83. package/dist/backend/entities/attribute-set-attribute.entity.d.ts +26 -0
  84. package/dist/backend/entities/attribute-set-attribute.entity.d.ts.map +1 -0
  85. package/dist/backend/entities/attribute-set-attribute.entity.js +55 -0
  86. package/dist/backend/entities/attribute-set-attribute.entity.js.map +1 -0
  87. package/dist/backend/entities/attribute-set.entity.d.ts +22 -0
  88. package/dist/backend/entities/attribute-set.entity.d.ts.map +1 -0
  89. package/dist/backend/entities/attribute-set.entity.js +67 -0
  90. package/dist/backend/entities/attribute-set.entity.js.map +1 -0
  91. package/dist/backend/entities/bulk-operation.entity.d.ts +78 -0
  92. package/dist/backend/entities/bulk-operation.entity.d.ts.map +1 -0
  93. package/dist/backend/entities/bulk-operation.entity.js +138 -0
  94. package/dist/backend/entities/bulk-operation.entity.js.map +1 -0
  95. package/dist/backend/entities/bundle-slot-option.entity.d.ts +23 -0
  96. package/dist/backend/entities/bundle-slot-option.entity.d.ts.map +1 -0
  97. package/dist/backend/entities/bundle-slot-option.entity.js +68 -0
  98. package/dist/backend/entities/bundle-slot-option.entity.js.map +1 -0
  99. package/dist/backend/entities/bundle-slot.entity.d.ts +25 -0
  100. package/dist/backend/entities/bundle-slot.entity.d.ts.map +1 -0
  101. package/dist/backend/entities/bundle-slot.entity.js +74 -0
  102. package/dist/backend/entities/bundle-slot.entity.js.map +1 -0
  103. package/dist/backend/entities/category.entity.d.ts +26 -0
  104. package/dist/backend/entities/category.entity.d.ts.map +1 -0
  105. package/dist/backend/entities/category.entity.js +119 -0
  106. package/dist/backend/entities/category.entity.js.map +1 -0
  107. package/dist/backend/entities/gallery-item-label.entity.d.ts +22 -0
  108. package/dist/backend/entities/gallery-item-label.entity.d.ts.map +1 -0
  109. package/dist/backend/entities/gallery-item-label.entity.js +50 -0
  110. package/dist/backend/entities/gallery-item-label.entity.js.map +1 -0
  111. package/dist/backend/entities/gallery-item.entity.d.ts +17 -0
  112. package/dist/backend/entities/gallery-item.entity.d.ts.map +1 -0
  113. package/dist/backend/entities/gallery-item.entity.js +58 -0
  114. package/dist/backend/entities/gallery-item.entity.js.map +1 -0
  115. package/dist/backend/entities/grouped-item.entity.d.ts +23 -0
  116. package/dist/backend/entities/grouped-item.entity.d.ts.map +1 -0
  117. package/dist/backend/entities/grouped-item.entity.js +68 -0
  118. package/dist/backend/entities/grouped-item.entity.js.map +1 -0
  119. package/dist/backend/entities/product-attachment.entity.d.ts +23 -0
  120. package/dist/backend/entities/product-attachment.entity.d.ts.map +1 -0
  121. package/dist/backend/entities/product-attachment.entity.js +77 -0
  122. package/dist/backend/entities/product-attachment.entity.js.map +1 -0
  123. package/dist/backend/entities/product-attribute.entity.d.ts +72 -0
  124. package/dist/backend/entities/product-attribute.entity.d.ts.map +1 -0
  125. package/dist/backend/entities/product-attribute.entity.js +161 -0
  126. package/dist/backend/entities/product-attribute.entity.js.map +1 -0
  127. package/dist/backend/entities/product-editor-preference.entity.d.ts +28 -0
  128. package/dist/backend/entities/product-editor-preference.entity.d.ts.map +1 -0
  129. package/dist/backend/entities/product-editor-preference.entity.js +63 -0
  130. package/dist/backend/entities/product-editor-preference.entity.js.map +1 -0
  131. package/dist/backend/entities/product-link.entity.d.ts +25 -0
  132. package/dist/backend/entities/product-link.entity.d.ts.map +1 -0
  133. package/dist/backend/entities/product-link.entity.js +70 -0
  134. package/dist/backend/entities/product-link.entity.js.map +1 -0
  135. package/dist/backend/entities/product-packaging-unit.entity.d.ts +26 -0
  136. package/dist/backend/entities/product-packaging-unit.entity.d.ts.map +1 -0
  137. package/dist/backend/entities/product-packaging-unit.entity.js +76 -0
  138. package/dist/backend/entities/product-packaging-unit.entity.js.map +1 -0
  139. package/dist/backend/entities/product-value-override.entity.d.ts +43 -0
  140. package/dist/backend/entities/product-value-override.entity.d.ts.map +1 -0
  141. package/dist/backend/entities/product-value-override.entity.js +90 -0
  142. package/dist/backend/entities/product-value-override.entity.js.map +1 -0
  143. package/dist/backend/entities/product-variant.entity.d.ts +18 -0
  144. package/dist/backend/entities/product-variant.entity.d.ts.map +1 -0
  145. package/dist/backend/entities/product-variant.entity.js +68 -0
  146. package/dist/backend/entities/product-variant.entity.js.map +1 -0
  147. package/dist/backend/entities/product.entity.d.ts +108 -0
  148. package/dist/backend/entities/product.entity.d.ts.map +1 -0
  149. package/dist/backend/entities/product.entity.js +230 -0
  150. package/dist/backend/entities/product.entity.js.map +1 -0
  151. package/dist/backend/index.d.ts +262 -0
  152. package/dist/backend/index.d.ts.map +1 -0
  153. package/dist/backend/index.js +642 -0
  154. package/dist/backend/index.js.map +1 -0
  155. package/dist/backend/plugin.d.ts +216 -0
  156. package/dist/backend/plugin.d.ts.map +1 -0
  157. package/dist/backend/plugin.js +223 -0
  158. package/dist/backend/plugin.js.map +1 -0
  159. package/dist/backend/prompt-tools.d.ts +47 -0
  160. package/dist/backend/prompt-tools.d.ts.map +1 -0
  161. package/dist/backend/prompt-tools.js +284 -0
  162. package/dist/backend/prompt-tools.js.map +1 -0
  163. package/dist/backend/routes.admin.d.ts +105 -0
  164. package/dist/backend/routes.admin.d.ts.map +1 -0
  165. package/dist/backend/routes.admin.js +1162 -0
  166. package/dist/backend/routes.admin.js.map +1 -0
  167. package/dist/backend/routes.api-key.d.ts +33 -0
  168. package/dist/backend/routes.api-key.d.ts.map +1 -0
  169. package/dist/backend/routes.api-key.js +43 -0
  170. package/dist/backend/routes.api-key.js.map +1 -0
  171. package/dist/backend/routes.external.d.ts +32 -0
  172. package/dist/backend/routes.external.d.ts.map +1 -0
  173. package/dist/backend/routes.external.js +115 -0
  174. package/dist/backend/routes.external.js.map +1 -0
  175. package/dist/backend/routes.public.d.ts +46 -0
  176. package/dist/backend/routes.public.d.ts.map +1 -0
  177. package/dist/backend/routes.public.js +318 -0
  178. package/dist/backend/routes.public.js.map +1 -0
  179. package/dist/backend/services/asset-references.d.ts +4 -0
  180. package/dist/backend/services/asset-references.d.ts.map +1 -0
  181. package/dist/backend/services/asset-references.js +104 -0
  182. package/dist/backend/services/asset-references.js.map +1 -0
  183. package/dist/backend/services/attachment.service.d.ts +45 -0
  184. package/dist/backend/services/attachment.service.d.ts.map +1 -0
  185. package/dist/backend/services/attachment.service.js +268 -0
  186. package/dist/backend/services/attachment.service.js.map +1 -0
  187. package/dist/backend/services/attribute-option-validator.d.ts +47 -0
  188. package/dist/backend/services/attribute-option-validator.d.ts.map +1 -0
  189. package/dist/backend/services/attribute-option-validator.js +69 -0
  190. package/dist/backend/services/attribute-option-validator.js.map +1 -0
  191. package/dist/backend/services/attribute-set-validations.d.ts +65 -0
  192. package/dist/backend/services/attribute-set-validations.d.ts.map +1 -0
  193. package/dist/backend/services/attribute-set-validations.js +89 -0
  194. package/dist/backend/services/attribute-set-validations.js.map +1 -0
  195. package/dist/backend/services/attribute-set.service.d.ts +50 -0
  196. package/dist/backend/services/attribute-set.service.d.ts.map +1 -0
  197. package/dist/backend/services/attribute-set.service.js +401 -0
  198. package/dist/backend/services/attribute-set.service.js.map +1 -0
  199. package/dist/backend/services/attribute-type-mapping.d.ts +66 -0
  200. package/dist/backend/services/attribute-type-mapping.d.ts.map +1 -0
  201. package/dist/backend/services/attribute-type-mapping.js +121 -0
  202. package/dist/backend/services/attribute-type-mapping.js.map +1 -0
  203. package/dist/backend/services/attribute-value-key.service.d.ts +48 -0
  204. package/dist/backend/services/attribute-value-key.service.d.ts.map +1 -0
  205. package/dist/backend/services/attribute-value-key.service.js +118 -0
  206. package/dist/backend/services/attribute-value-key.service.js.map +1 -0
  207. package/dist/backend/services/audit-references.d.ts +13 -0
  208. package/dist/backend/services/audit-references.d.ts.map +1 -0
  209. package/dist/backend/services/audit-references.js +51 -0
  210. package/dist/backend/services/audit-references.js.map +1 -0
  211. package/dist/backend/services/bulk-operation-queue.d.ts +26 -0
  212. package/dist/backend/services/bulk-operation-queue.d.ts.map +1 -0
  213. package/dist/backend/services/bulk-operation-queue.js +34 -0
  214. package/dist/backend/services/bulk-operation-queue.js.map +1 -0
  215. package/dist/backend/services/bulk-operation.service.d.ts +195 -0
  216. package/dist/backend/services/bulk-operation.service.d.ts.map +1 -0
  217. package/dist/backend/services/bulk-operation.service.js +510 -0
  218. package/dist/backend/services/bulk-operation.service.js.map +1 -0
  219. package/dist/backend/services/bundle.service.d.ts +87 -0
  220. package/dist/backend/services/bundle.service.d.ts.map +1 -0
  221. package/dist/backend/services/bundle.service.js +286 -0
  222. package/dist/backend/services/bundle.service.js.map +1 -0
  223. package/dist/backend/services/catalog-admin.service.d.ts +398 -0
  224. package/dist/backend/services/catalog-admin.service.d.ts.map +1 -0
  225. package/dist/backend/services/catalog-admin.service.js +1516 -0
  226. package/dist/backend/services/catalog-admin.service.js.map +1 -0
  227. package/dist/backend/services/catalog-attribute-read.service.d.ts +78 -0
  228. package/dist/backend/services/catalog-attribute-read.service.d.ts.map +1 -0
  229. package/dist/backend/services/catalog-attribute-read.service.js +216 -0
  230. package/dist/backend/services/catalog-attribute-read.service.js.map +1 -0
  231. package/dist/backend/services/catalog-bulk-import.service.d.ts +30 -0
  232. package/dist/backend/services/catalog-bulk-import.service.d.ts.map +1 -0
  233. package/dist/backend/services/catalog-bulk-import.service.js +136 -0
  234. package/dist/backend/services/catalog-bulk-import.service.js.map +1 -0
  235. package/dist/backend/services/catalog-bulk-update.service.d.ts +91 -0
  236. package/dist/backend/services/catalog-bulk-update.service.d.ts.map +1 -0
  237. package/dist/backend/services/catalog-bulk-update.service.js +330 -0
  238. package/dist/backend/services/catalog-bulk-update.service.js.map +1 -0
  239. package/dist/backend/services/catalog-category-read.service.d.ts +66 -0
  240. package/dist/backend/services/catalog-category-read.service.d.ts.map +1 -0
  241. package/dist/backend/services/catalog-category-read.service.js +248 -0
  242. package/dist/backend/services/catalog-category-read.service.js.map +1 -0
  243. package/dist/backend/services/catalog-org-price-decorator.d.ts +90 -0
  244. package/dist/backend/services/catalog-org-price-decorator.d.ts.map +1 -0
  245. package/dist/backend/services/catalog-org-price-decorator.js +184 -0
  246. package/dist/backend/services/catalog-org-price-decorator.js.map +1 -0
  247. package/dist/backend/services/catalog-product-filter.service.d.ts +82 -0
  248. package/dist/backend/services/catalog-product-filter.service.d.ts.map +1 -0
  249. package/dist/backend/services/catalog-product-filter.service.js +275 -0
  250. package/dist/backend/services/catalog-product-filter.service.js.map +1 -0
  251. package/dist/backend/services/catalog-product-read.service.d.ts +46 -0
  252. package/dist/backend/services/catalog-product-read.service.d.ts.map +1 -0
  253. package/dist/backend/services/catalog-product-read.service.js +197 -0
  254. package/dist/backend/services/catalog-product-read.service.js.map +1 -0
  255. package/dist/backend/services/catalog-query.service.d.ts +444 -0
  256. package/dist/backend/services/catalog-query.service.d.ts.map +1 -0
  257. package/dist/backend/services/catalog-query.service.js +1633 -0
  258. package/dist/backend/services/catalog-query.service.js.map +1 -0
  259. package/dist/backend/services/catalog-quick-search.service.d.ts +78 -0
  260. package/dist/backend/services/catalog-quick-search.service.d.ts.map +1 -0
  261. package/dist/backend/services/catalog-quick-search.service.js +159 -0
  262. package/dist/backend/services/catalog-quick-search.service.js.map +1 -0
  263. package/dist/backend/services/catalog-write-ports.d.ts +25 -0
  264. package/dist/backend/services/catalog-write-ports.d.ts.map +1 -0
  265. package/dist/backend/services/catalog-write-ports.js +63 -0
  266. package/dist/backend/services/catalog-write-ports.js.map +1 -0
  267. package/dist/backend/services/category-admin.service.d.ts +102 -0
  268. package/dist/backend/services/category-admin.service.d.ts.map +1 -0
  269. package/dist/backend/services/category-admin.service.js +271 -0
  270. package/dist/backend/services/category-admin.service.js.map +1 -0
  271. package/dist/backend/services/gallery.service.d.ts +85 -0
  272. package/dist/backend/services/gallery.service.d.ts.map +1 -0
  273. package/dist/backend/services/gallery.service.js +326 -0
  274. package/dist/backend/services/gallery.service.js.map +1 -0
  275. package/dist/backend/services/grouped.service.d.ts +39 -0
  276. package/dist/backend/services/grouped.service.d.ts.map +1 -0
  277. package/dist/backend/services/grouped.service.js +136 -0
  278. package/dist/backend/services/grouped.service.js.map +1 -0
  279. package/dist/backend/services/label-resolver.d.ts +16 -0
  280. package/dist/backend/services/label-resolver.d.ts.map +1 -0
  281. package/dist/backend/services/label-resolver.js +43 -0
  282. package/dist/backend/services/label-resolver.js.map +1 -0
  283. package/dist/backend/services/packaging-unit.service.d.ts +28 -0
  284. package/dist/backend/services/packaging-unit.service.d.ts.map +1 -0
  285. package/dist/backend/services/packaging-unit.service.js +197 -0
  286. package/dist/backend/services/packaging-unit.service.js.map +1 -0
  287. package/dist/backend/services/primary-asset-url.d.ts +4 -0
  288. package/dist/backend/services/primary-asset-url.d.ts.map +1 -0
  289. package/dist/backend/services/primary-asset-url.js +55 -0
  290. package/dist/backend/services/primary-asset-url.js.map +1 -0
  291. package/dist/backend/services/product-editor-preferences.service.d.ts +20 -0
  292. package/dist/backend/services/product-editor-preferences.service.d.ts.map +1 -0
  293. package/dist/backend/services/product-editor-preferences.service.js +44 -0
  294. package/dist/backend/services/product-editor-preferences.service.js.map +1 -0
  295. package/dist/backend/services/product-link.service.d.ts +169 -0
  296. package/dist/backend/services/product-link.service.d.ts.map +1 -0
  297. package/dist/backend/services/product-link.service.js +297 -0
  298. package/dist/backend/services/product-link.service.js.map +1 -0
  299. package/dist/backend/services/product-overrides.service.d.ts +77 -0
  300. package/dist/backend/services/product-overrides.service.d.ts.map +1 -0
  301. package/dist/backend/services/product-overrides.service.js +204 -0
  302. package/dist/backend/services/product-overrides.service.js.map +1 -0
  303. package/dist/backend/services/product-scope-context.service.d.ts +36 -0
  304. package/dist/backend/services/product-scope-context.service.d.ts.map +1 -0
  305. package/dist/backend/services/product-scope-context.service.js +106 -0
  306. package/dist/backend/services/product-scope-context.service.js.map +1 -0
  307. package/dist/backend/services/product-type-validations.d.ts +42 -0
  308. package/dist/backend/services/product-type-validations.d.ts.map +1 -0
  309. package/dist/backend/services/product-type-validations.js +55 -0
  310. package/dist/backend/services/product-type-validations.js.map +1 -0
  311. package/dist/backend/services/product-value-resolver.service.d.ts +59 -0
  312. package/dist/backend/services/product-value-resolver.service.d.ts.map +1 -0
  313. package/dist/backend/services/product-value-resolver.service.js +111 -0
  314. package/dist/backend/services/product-value-resolver.service.js.map +1 -0
  315. package/dist/backend/services/system-attribute-scopes.d.ts +18 -0
  316. package/dist/backend/services/system-attribute-scopes.d.ts.map +1 -0
  317. package/dist/backend/services/system-attribute-scopes.js +18 -0
  318. package/dist/backend/services/system-attribute-scopes.js.map +1 -0
  319. package/dist/backend/services/viewer-organization.d.ts +25 -0
  320. package/dist/backend/services/viewer-organization.d.ts.map +1 -0
  321. package/dist/backend/services/viewer-organization.js +31 -0
  322. package/dist/backend/services/viewer-organization.js.map +1 -0
  323. package/dist/manifest.d.ts +204 -0
  324. package/dist/manifest.d.ts.map +1 -0
  325. package/dist/manifest.js +686 -0
  326. package/dist/manifest.js.map +1 -0
  327. package/dist/migrations/20260429T064146_catalog_attribute_sets_init.d.ts +33 -0
  328. package/dist/migrations/20260429T064146_catalog_attribute_sets_init.d.ts.map +1 -0
  329. package/dist/migrations/20260429T064146_catalog_attribute_sets_init.js +118 -0
  330. package/dist/migrations/20260429T064146_catalog_attribute_sets_init.js.map +1 -0
  331. package/dist/migrations/20260429T070004_catalog_product_attribute_extensions.d.ts +24 -0
  332. package/dist/migrations/20260429T070004_catalog_product_attribute_extensions.d.ts.map +1 -0
  333. package/dist/migrations/20260429T070004_catalog_product_attribute_extensions.js +31 -0
  334. package/dist/migrations/20260429T070004_catalog_product_attribute_extensions.js.map +1 -0
  335. package/dist/migrations/20260429T102322_catalog_product_type_and_virtual_fields.d.ts +32 -0
  336. package/dist/migrations/20260429T102322_catalog_product_type_and_virtual_fields.d.ts.map +1 -0
  337. package/dist/migrations/20260429T102322_catalog_product_type_and_virtual_fields.js +58 -0
  338. package/dist/migrations/20260429T102322_catalog_product_type_and_virtual_fields.js.map +1 -0
  339. package/dist/migrations/20260429T111839_catalog_gallery_items_and_labels.d.ts +22 -0
  340. package/dist/migrations/20260429T111839_catalog_gallery_items_and_labels.d.ts.map +1 -0
  341. package/dist/migrations/20260429T111839_catalog_gallery_items_and_labels.js +66 -0
  342. package/dist/migrations/20260429T111839_catalog_gallery_items_and_labels.js.map +1 -0
  343. package/dist/migrations/20260429T112543_catalog_product_attachments.d.ts +18 -0
  344. package/dist/migrations/20260429T112543_catalog_product_attachments.d.ts.map +1 -0
  345. package/dist/migrations/20260429T112543_catalog_product_attachments.js +73 -0
  346. package/dist/migrations/20260429T112543_catalog_product_attachments.js.map +1 -0
  347. package/dist/migrations/20260429T123726_catalog_product_links.d.ts +21 -0
  348. package/dist/migrations/20260429T123726_catalog_product_links.d.ts.map +1 -0
  349. package/dist/migrations/20260429T123726_catalog_product_links.js +48 -0
  350. package/dist/migrations/20260429T123726_catalog_product_links.js.map +1 -0
  351. package/dist/migrations/20260429T130803_catalog_grouped_and_bundle.d.ts +23 -0
  352. package/dist/migrations/20260429T130803_catalog_grouped_and_bundle.d.ts.map +1 -0
  353. package/dist/migrations/20260429T130803_catalog_grouped_and_bundle.js +94 -0
  354. package/dist/migrations/20260429T130803_catalog_grouped_and_bundle.js.map +1 -0
  355. package/dist/migrations/20260501T185835_catalog_product_attribute_is_comparable.d.ts +24 -0
  356. package/dist/migrations/20260501T185835_catalog_product_attribute_is_comparable.d.ts.map +1 -0
  357. package/dist/migrations/20260501T185835_catalog_product_attribute_is_comparable.js +31 -0
  358. package/dist/migrations/20260501T185835_catalog_product_attribute_is_comparable.js.map +1 -0
  359. package/dist/migrations/20260505T060113_catalog_attribute_options_and_flags.d.ts +31 -0
  360. package/dist/migrations/20260505T060113_catalog_attribute_options_and_flags.d.ts.map +1 -0
  361. package/dist/migrations/20260505T060113_catalog_attribute_options_and_flags.js +133 -0
  362. package/dist/migrations/20260505T060113_catalog_attribute_options_and_flags.js.map +1 -0
  363. package/dist/migrations/20260515T082629_catalog_attribute_mass_editable.d.ts +16 -0
  364. package/dist/migrations/20260515T082629_catalog_attribute_mass_editable.d.ts.map +1 -0
  365. package/dist/migrations/20260515T082629_catalog_attribute_mass_editable.js +23 -0
  366. package/dist/migrations/20260515T082629_catalog_attribute_mass_editable.js.map +1 -0
  367. package/dist/migrations/20260526T124736_catalog_product_status_inactive.d.ts +10 -0
  368. package/dist/migrations/20260526T124736_catalog_product_status_inactive.d.ts.map +1 -0
  369. package/dist/migrations/20260526T124736_catalog_product_status_inactive.js +22 -0
  370. package/dist/migrations/20260526T124736_catalog_product_status_inactive.js.map +1 -0
  371. package/dist/migrations/20260611T140346_catalog_product_value_overrides_init.d.ts +38 -0
  372. package/dist/migrations/20260611T140346_catalog_product_value_overrides_init.d.ts.map +1 -0
  373. package/dist/migrations/20260611T140346_catalog_product_value_overrides_init.js +98 -0
  374. package/dist/migrations/20260611T140346_catalog_product_value_overrides_init.js.map +1 -0
  375. package/dist/migrations/20260611T140400_catalog_attribute_quick_searchable.d.ts +13 -0
  376. package/dist/migrations/20260611T140400_catalog_attribute_quick_searchable.d.ts.map +1 -0
  377. package/dist/migrations/20260611T140400_catalog_attribute_quick_searchable.js +17 -0
  378. package/dist/migrations/20260611T140400_catalog_attribute_quick_searchable.js.map +1 -0
  379. package/dist/migrations/20260611T140407_catalog_bulk_operations.d.ts +16 -0
  380. package/dist/migrations/20260611T140407_catalog_bulk_operations.d.ts.map +1 -0
  381. package/dist/migrations/20260611T140407_catalog_bulk_operations.js +42 -0
  382. package/dist/migrations/20260611T140407_catalog_bulk_operations.js.map +1 -0
  383. package/dist/migrations/20260611T140408_catalog_bulk_operation_logs.d.ts +14 -0
  384. package/dist/migrations/20260611T140408_catalog_bulk_operation_logs.d.ts.map +1 -0
  385. package/dist/migrations/20260611T140408_catalog_bulk_operation_logs.js +18 -0
  386. package/dist/migrations/20260611T140408_catalog_bulk_operation_logs.js.map +1 -0
  387. package/dist/migrations/20260611T140412_catalog_product_packaging_units.d.ts +11 -0
  388. package/dist/migrations/20260611T140412_catalog_product_packaging_units.d.ts.map +1 -0
  389. package/dist/migrations/20260611T140412_catalog_product_packaging_units.js +29 -0
  390. package/dist/migrations/20260611T140412_catalog_product_packaging_units.js.map +1 -0
  391. package/dist/migrations/20260718T060659_catalog_bulk_operation_revert_state.d.ts +23 -0
  392. package/dist/migrations/20260718T060659_catalog_bulk_operation_revert_state.d.ts.map +1 -0
  393. package/dist/migrations/20260718T060659_catalog_bulk_operation_revert_state.js +35 -0
  394. package/dist/migrations/20260718T060659_catalog_bulk_operation_revert_state.js.map +1 -0
  395. package/dist/migrations/20260718T200343_catalog_category_custom_field_values.d.ts +12 -0
  396. package/dist/migrations/20260718T200343_catalog_category_custom_field_values.d.ts.map +1 -0
  397. package/dist/migrations/20260718T200343_catalog_category_custom_field_values.js +16 -0
  398. package/dist/migrations/20260718T200343_catalog_category_custom_field_values.js.map +1 -0
  399. package/dist/migrations/20260723T230401_catalog_attributes_on_custom_fields.d.ts +32 -0
  400. package/dist/migrations/20260723T230401_catalog_attributes_on_custom_fields.d.ts.map +1 -0
  401. package/dist/migrations/20260723T230401_catalog_attributes_on_custom_fields.js +286 -0
  402. package/dist/migrations/20260723T230401_catalog_attributes_on_custom_fields.js.map +1 -0
  403. package/dist/migrations/20260804T152604_catalog_widen_product_sku.d.ts +36 -0
  404. package/dist/migrations/20260804T152604_catalog_widen_product_sku.d.ts.map +1 -0
  405. package/dist/migrations/20260804T152604_catalog_widen_product_sku.js +63 -0
  406. package/dist/migrations/20260804T152604_catalog_widen_product_sku.js.map +1 -0
  407. package/dist/migrations/20260804T160244_catalog_category_activation.d.ts +18 -0
  408. package/dist/migrations/20260804T160244_catalog_category_activation.d.ts.map +1 -0
  409. package/dist/migrations/20260804T160244_catalog_category_activation.js +22 -0
  410. package/dist/migrations/20260804T160244_catalog_category_activation.js.map +1 -0
  411. package/dist/migrations/20260912T094557_catalog_sales_channel_products.d.ts +27 -0
  412. package/dist/migrations/20260912T094557_catalog_sales_channel_products.d.ts.map +1 -0
  413. package/dist/migrations/20260912T094557_catalog_sales_channel_products.js +44 -0
  414. package/dist/migrations/20260912T094557_catalog_sales_channel_products.js.map +1 -0
  415. package/dist/migrations/20260912T094623_catalog_sales_channel_categories.d.ts +27 -0
  416. package/dist/migrations/20260912T094623_catalog_sales_channel_categories.d.ts.map +1 -0
  417. package/dist/migrations/20260912T094623_catalog_sales_channel_categories.js +44 -0
  418. package/dist/migrations/20260912T094623_catalog_sales_channel_categories.js.map +1 -0
  419. package/dist/migrations/20260925T125527_catalog_inventory_columns.d.ts +36 -0
  420. package/dist/migrations/20260925T125527_catalog_inventory_columns.d.ts.map +1 -0
  421. package/dist/migrations/20260925T125527_catalog_inventory_columns.js +87 -0
  422. package/dist/migrations/20260925T125527_catalog_inventory_columns.js.map +1 -0
  423. package/dist/migrations/index.d.ts +55 -0
  424. package/dist/migrations/index.d.ts.map +1 -0
  425. package/dist/migrations/index.js +80 -0
  426. package/dist/migrations/index.js.map +1 -0
  427. package/dist/ports/index.d.ts +96 -0
  428. package/dist/ports/index.d.ts.map +1 -0
  429. package/dist/ports/index.js +2 -0
  430. package/dist/ports/index.js.map +1 -0
  431. package/docs/catalog/attachments.md +69 -0
  432. package/docs/catalog/attribute-sets.md +63 -0
  433. package/docs/catalog/attributes.md +244 -0
  434. package/docs/catalog/composite-products.md +115 -0
  435. package/docs/catalog/gallery-and-labels.md +73 -0
  436. package/docs/catalog/packaging-units.md +67 -0
  437. package/docs/catalog/per-channel-per-language-overrides.md +234 -0
  438. package/docs/catalog/product-links.md +79 -0
  439. package/docs/catalog.md +207 -0
  440. package/i18n/en.json +649 -0
  441. package/i18n/pl.json +649 -0
  442. package/package.json +109 -0
  443. 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"}