@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 @@
1
+ {"version":3,"file":"product-scope-context.service.d.ts","sourceRoot":"","sources":["../../../src/backend/services/product-scope-context.service.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,KAAK,EACV,gBAAgB,EAGhB,2BAA2B,EAC5B,MAAM,4BAA4B,CAAC;AAIpC,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,kCAAkC,CAAC;AAEnF,OAAO,EAAE,uBAAuB,EAAE,MAAM,iDAAiD,CAAC;AAC1F,OAAO,KAAK,EAAE,+BAA+B,EAAE,MAAM,yCAAyC,CAAC;AAE/F;;;;;;;;;;;;;;GAcG;AACH,qBAAa,0BAA0B;IAEnC,OAAO,CAAC,QAAQ,CAAC,SAAS;IAC1B,OAAO,CAAC,QAAQ,CAAC,sBAAsB;IACvC,OAAO,CAAC,QAAQ,CAAC,eAAe;IAChC,OAAO,CAAC,QAAQ,CAAC,iBAAiB;gBAHjB,SAAS,EAAE,MAAM,aAAa,EAC9B,sBAAsB,EAAE,0BAA0B,EAClD,eAAe,EAAE,gBAAgB,EACjC,iBAAiB,EAAE,+BAA+B;IAG/D,UAAU,CACd,SAAS,EAAE,MAAM,EACjB,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,2BAA2B,CAAC;IAqEvC;;;OAGG;IACG,8BAA8B,CAClC,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,IAAI,CAAC;IAehB,oEAAoE;IACpE,qBAAqB,IAAI,OAAO,uBAAuB;CAGxD"}
@@ -0,0 +1,106 @@
1
+ import { ERROR_CODES } from '@endora-commerce/contracts';
2
+ import { HttpError } from '@endora-commerce/platform/http';
3
+ import { Product } from '../entities/product.entity.js';
4
+ import { ProductEditorPreference } from '../entities/product-editor-preference.entity.js';
5
+ /**
6
+ * Feature 022 — assembles the response of
7
+ * `GET /admin/products/:id/scope-context`.
8
+ *
9
+ * Combines:
10
+ * - the product's assigned channels (via SalesChannelMembershipPort),
11
+ * each carrying its language list (`SalesChannel.languages` JSONB),
12
+ * - the union of those languages,
13
+ * - the platform's primary admin language (LanguageService.getDefault()),
14
+ * - the editor's remembered context (ProductEditorPreference).
15
+ *
16
+ * If the product has zero assigned channels, `languagesUnion` falls
17
+ * back to every active platform language so the editor can still
18
+ * translate the global baseline.
19
+ */
20
+ export class ProductScopeContextService {
21
+ emFactory;
22
+ salesChannelMembership;
23
+ languageService;
24
+ editorPreferences;
25
+ constructor(emFactory, salesChannelMembership, languageService, editorPreferences) {
26
+ this.emFactory = emFactory;
27
+ this.salesChannelMembership = salesChannelMembership;
28
+ this.languageService = languageService;
29
+ this.editorPreferences = editorPreferences;
30
+ }
31
+ async getContext(productId, adminUserId) {
32
+ const em = this.emFactory();
33
+ // 1. Ensure the product exists (or surface a clean 404).
34
+ const product = await em.findOne(Product, { id: productId });
35
+ if (!product) {
36
+ throw new HttpError(404, ERROR_CODES.NOT_FOUND, 'Product not found.');
37
+ }
38
+ // 2. Channels the product is assigned to. Each channel carries its
39
+ // language list directly on the entity.
40
+ const channels = await this.salesChannelMembership.listChannelsForEntity('product', productId);
41
+ const channelDtos = channels
42
+ .map((c) => {
43
+ const name = (typeof c.name === 'object' && c.name !== null
44
+ ? Object.values(c.name).find((v) => typeof v === 'string' && v.length > 0)
45
+ : null) ?? c.code;
46
+ return {
47
+ id: c.id,
48
+ code: c.code,
49
+ name,
50
+ languages: [...c.languages].sort(),
51
+ isDefault: c.systemDefault,
52
+ };
53
+ })
54
+ .sort((a, b) => a.code.localeCompare(b.code));
55
+ // 3. Union of channel languages. When the product is in zero
56
+ // channels, fall back to every active platform language so the
57
+ // editor still has a viable language list.
58
+ let languagesUnion;
59
+ if (channelDtos.length === 0) {
60
+ const activeLangs = await this.languageService.listActive();
61
+ languagesUnion = activeLangs.map((l) => l.code).sort();
62
+ }
63
+ else {
64
+ const unionSet = new Set();
65
+ for (const c of channelDtos)
66
+ for (const code of c.languages)
67
+ unionSet.add(code);
68
+ languagesUnion = [...unionSet].sort();
69
+ }
70
+ // 4. Primary admin language — default Language row if present, else
71
+ // the first available active language, else 'en' as a last resort.
72
+ const defaultLang = await this.languageService.getDefault();
73
+ let primaryAdminLanguage = defaultLang?.code;
74
+ if (!primaryAdminLanguage) {
75
+ const actives = await this.languageService.listActive();
76
+ primaryAdminLanguage = actives[0]?.code ?? 'en';
77
+ }
78
+ // 5. Editor preference — null if no prior visit.
79
+ const pref = await this.editorPreferences.find(adminUserId, productId);
80
+ const preference = pref
81
+ ? { lastChannelId: pref.lastChannelId ?? null, lastLanguageCode: pref.lastLanguageCode ?? null }
82
+ : null;
83
+ return {
84
+ productId,
85
+ channels: channelDtos,
86
+ languagesUnion,
87
+ primaryAdminLanguage,
88
+ preference,
89
+ };
90
+ }
91
+ /**
92
+ * Validate that a remembered preference is still applicable for the
93
+ * given product. Used by the PUT editor-preference endpoint.
94
+ */
95
+ async assertChannelAssignedToProduct(productId, channelId) {
96
+ const channels = await this.salesChannelMembership.listChannelsForEntity('product', productId);
97
+ if (!channels.some((c) => c.id === channelId)) {
98
+ throw new HttpError(422, ERROR_CODES.VALIDATION_FAILED, 'channel_not_assigned_to_product', [{ path: 'lastChannelId', issue: channelId }]);
99
+ }
100
+ }
101
+ /** Re-export for tests + consumers needing direct entity access. */
102
+ preferenceEntityClass() {
103
+ return ProductEditorPreference;
104
+ }
105
+ }
106
+ //# sourceMappingURL=product-scope-context.service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"product-scope-context.service.js","sourceRoot":"","sources":["../../../src/backend/services/product-scope-context.service.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,42 @@
1
+ /**
2
+ * Pure validation helpers for the Product type domain (feature 002,
3
+ * data-model.md §1.1).
4
+ *
5
+ * Implementation lands in T047. This module currently exposes only
6
+ * the type surface and stubs that throw `not implemented` so the
7
+ * failing unit test (T040) compiles.
8
+ */
9
+ export type ProductTypeValidationCode = 'CONFIGURABLE_REQUIRES_VARIANT' | 'VIRTUAL_DOWNLOAD_EXACTLY_ONE' | 'NON_VIRTUAL_HAS_DOWNLOAD_FIELDS';
10
+ export declare class ProductTypeValidationError extends Error {
11
+ readonly code: ProductTypeValidationCode;
12
+ constructor(message: string, code: ProductTypeValidationCode);
13
+ }
14
+ export interface ProductTypeForVariantCheck {
15
+ type: 'simple' | 'configurable' | 'grouped' | 'bundle' | 'virtual';
16
+ variantCount: number;
17
+ }
18
+ /**
19
+ * Reject a configurable Product that has zero variants. Other types
20
+ * are accepted regardless of `variantCount`.
21
+ *
22
+ * Throws ProductTypeValidationError with code
23
+ * CONFIGURABLE_REQUIRES_VARIANT.
24
+ */
25
+ export declare function assertConfigurableHasVariants(input: ProductTypeForVariantCheck): void;
26
+ export interface ProductTypeForDownloadCheck {
27
+ type: 'simple' | 'configurable' | 'grouped' | 'bundle' | 'virtual';
28
+ downloadAssetId: string | null;
29
+ downloadUrl: string | null;
30
+ }
31
+ /**
32
+ * Cross-field validation of `downloadAssetId` / `downloadUrl` against
33
+ * the Product type:
34
+ * - virtual: exactly one of the two MUST be set.
35
+ * - non-virtual: BOTH MUST be null.
36
+ *
37
+ * Throws ProductTypeValidationError with one of:
38
+ * - VIRTUAL_DOWNLOAD_EXACTLY_ONE
39
+ * - NON_VIRTUAL_HAS_DOWNLOAD_FIELDS
40
+ */
41
+ export declare function assertVirtualDownloadFields(input: ProductTypeForDownloadCheck): void;
42
+ //# sourceMappingURL=product-type-validations.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"product-type-validations.d.ts","sourceRoot":"","sources":["../../../src/backend/services/product-type-validations.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,MAAM,MAAM,yBAAyB,GACjC,+BAA+B,GAC/B,8BAA8B,GAC9B,iCAAiC,CAAC;AAEtC,qBAAa,0BAA2B,SAAQ,KAAK;aAGjC,IAAI,EAAE,yBAAyB;gBAD/C,OAAO,EAAE,MAAM,EACC,IAAI,EAAE,yBAAyB;CAKlD;AAED,MAAM,WAAW,0BAA0B;IACzC,IAAI,EAAE,QAAQ,GAAG,cAAc,GAAG,SAAS,GAAG,QAAQ,GAAG,SAAS,CAAC;IACnE,YAAY,EAAE,MAAM,CAAC;CACtB;AAED;;;;;;GAMG;AACH,wBAAgB,6BAA6B,CAC3C,KAAK,EAAE,0BAA0B,GAChC,IAAI,CAON;AAED,MAAM,WAAW,2BAA2B;IAC1C,IAAI,EAAE,QAAQ,GAAG,cAAc,GAAG,SAAS,GAAG,QAAQ,GAAG,SAAS,CAAC;IACnE,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;CAC5B;AAED;;;;;;;;;GASG;AACH,wBAAgB,2BAA2B,CACzC,KAAK,EAAE,2BAA2B,GACjC,IAAI,CAoBN"}
@@ -0,0 +1,55 @@
1
+ /**
2
+ * Pure validation helpers for the Product type domain (feature 002,
3
+ * data-model.md §1.1).
4
+ *
5
+ * Implementation lands in T047. This module currently exposes only
6
+ * the type surface and stubs that throw `not implemented` so the
7
+ * failing unit test (T040) compiles.
8
+ */
9
+ export class ProductTypeValidationError extends Error {
10
+ code;
11
+ constructor(message, code) {
12
+ super(message);
13
+ this.code = code;
14
+ this.name = 'ProductTypeValidationError';
15
+ }
16
+ }
17
+ /**
18
+ * Reject a configurable Product that has zero variants. Other types
19
+ * are accepted regardless of `variantCount`.
20
+ *
21
+ * Throws ProductTypeValidationError with code
22
+ * CONFIGURABLE_REQUIRES_VARIANT.
23
+ */
24
+ export function assertConfigurableHasVariants(input) {
25
+ if (input.type !== 'configurable')
26
+ return;
27
+ if (input.variantCount > 0)
28
+ return;
29
+ throw new ProductTypeValidationError('configurable products require at least one Variant.', 'CONFIGURABLE_REQUIRES_VARIANT');
30
+ }
31
+ /**
32
+ * Cross-field validation of `downloadAssetId` / `downloadUrl` against
33
+ * the Product type:
34
+ * - virtual: exactly one of the two MUST be set.
35
+ * - non-virtual: BOTH MUST be null.
36
+ *
37
+ * Throws ProductTypeValidationError with one of:
38
+ * - VIRTUAL_DOWNLOAD_EXACTLY_ONE
39
+ * - NON_VIRTUAL_HAS_DOWNLOAD_FIELDS
40
+ */
41
+ export function assertVirtualDownloadFields(input) {
42
+ const hasAsset = input.downloadAssetId !== null;
43
+ const hasUrl = input.downloadUrl !== null;
44
+ if (input.type === 'virtual') {
45
+ if (hasAsset !== hasUrl)
46
+ return; // exactly one of
47
+ throw new ProductTypeValidationError(hasAsset && hasUrl
48
+ ? 'virtual products MUST set exactly one of downloadAssetId / downloadUrl, not both.'
49
+ : 'virtual products MUST set exactly one of downloadAssetId / downloadUrl.', 'VIRTUAL_DOWNLOAD_EXACTLY_ONE');
50
+ }
51
+ if (hasAsset || hasUrl) {
52
+ throw new ProductTypeValidationError(`non-virtual products (type=${input.type}) MUST have both downloadAssetId and downloadUrl null.`, 'NON_VIRTUAL_HAS_DOWNLOAD_FIELDS');
53
+ }
54
+ }
55
+ //# sourceMappingURL=product-type-validations.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"product-type-validations.js","sourceRoot":"","sources":["../../../src/backend/services/product-type-validations.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAOH,MAAM,OAAO,0BAA2B,SAAQ,KAAK;IAGjC;IAFlB,YACE,OAAe,EACC,IAA+B;QAE/C,KAAK,CAAC,OAAO,CAAC,CAAC;QAFC,SAAI,GAAJ,IAAI,CAA2B;QAG/C,IAAI,CAAC,IAAI,GAAG,4BAA4B,CAAC;IAC3C,CAAC;CACF;AAOD;;;;;;GAMG;AACH,MAAM,UAAU,6BAA6B,CAC3C,KAAiC;IAEjC,IAAI,KAAK,CAAC,IAAI,KAAK,cAAc;QAAE,OAAO;IAC1C,IAAI,KAAK,CAAC,YAAY,GAAG,CAAC;QAAE,OAAO;IACnC,MAAM,IAAI,0BAA0B,CAClC,qDAAqD,EACrD,+BAA+B,CAChC,CAAC;AACJ,CAAC;AAQD;;;;;;;;;GASG;AACH,MAAM,UAAU,2BAA2B,CACzC,KAAkC;IAElC,MAAM,QAAQ,GAAG,KAAK,CAAC,eAAe,KAAK,IAAI,CAAC;IAChD,MAAM,MAAM,GAAG,KAAK,CAAC,WAAW,KAAK,IAAI,CAAC;IAE1C,IAAI,KAAK,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;QAC7B,IAAI,QAAQ,KAAK,MAAM;YAAE,OAAO,CAAC,iBAAiB;QAClD,MAAM,IAAI,0BAA0B,CAClC,QAAQ,IAAI,MAAM;YAChB,CAAC,CAAC,mFAAmF;YACrF,CAAC,CAAC,yEAAyE,EAC7E,8BAA8B,CAC/B,CAAC;IACJ,CAAC;IAED,IAAI,QAAQ,IAAI,MAAM,EAAE,CAAC;QACvB,MAAM,IAAI,0BAA0B,CAClC,8BAA8B,KAAK,CAAC,IAAI,wDAAwD,EAChG,iCAAiC,CAClC,CAAC;IACJ,CAAC;AACH,CAAC"}
@@ -0,0 +1,59 @@
1
+ import type { EntityManager } from '@mikro-orm/postgresql';
2
+ import { type AttributeScope, type OverrideRow, type Resolved, type ResolveAllResult, type LanguageReadPort, type ResolverContext } from '@endora-commerce/contracts';
3
+ import type { Product } from '../entities/product.entity.js';
4
+ import type { CatalogAttributeReadService } from './catalog-attribute-read.service.js';
5
+ /**
6
+ * Feature 022 — backend wrapper around the pure resolver in
7
+ * `@endora-commerce/contracts`. Handles the EM-side concerns:
8
+ * - fetching the override map for a product in a single SELECT,
9
+ * - assembling AttributeDefs for the system + user-defined attrs,
10
+ * - resolving the platform's primary admin language.
11
+ *
12
+ * The actual fallback-chain logic lives in `@endora-commerce/contracts` so the
13
+ * admin SPA imports the same code (guaranteeing server / client
14
+ * agreement — SC-004).
15
+ */
16
+ export declare class ProductValueResolverService {
17
+ private readonly emFactory;
18
+ private readonly languageService;
19
+ /** Feature 061 — composed attribute read model (scope lookups). */
20
+ private readonly attributeRead?;
21
+ constructor(emFactory: () => EntityManager, languageService: LanguageReadPort,
22
+ /** Feature 061 — composed attribute read model (scope lookups). */
23
+ attributeRead?: CatalogAttributeReadService | undefined);
24
+ /** Load every override row for a product in one query. */
25
+ loadOverrides(productId: string): Promise<OverrideRow[]>;
26
+ /** Resolve the platform's primary admin language. */
27
+ getPrimaryAdminLanguage(): Promise<string>;
28
+ /**
29
+ * Build a ResolverContext from a (channelId, languageCode) pair,
30
+ * filling in the primary admin language.
31
+ */
32
+ makeContext(channelId: string | null, languageCode: string | null): Promise<ResolverContext>;
33
+ /**
34
+ * Resolve every attribute for the given product in one pass: system
35
+ * Name + Description plus every user-defined attribute defined in the
36
+ * `product_attributes` table whose value is present in
37
+ * `attribute_values` JSONB (or every row in the assigned set, see
38
+ * below).
39
+ *
40
+ * For simplicity this implementation walks the union of (a) the
41
+ * product's `attributeValues` keys and (b) `SYSTEM_ATTRIBUTE_SCOPES`.
42
+ * Attributes defined in the assigned `AttributeSet` but currently
43
+ * empty are skipped — the admin UI re-introduces them when binding
44
+ * fields. The resolver tolerates empty inputs gracefully.
45
+ */
46
+ resolveForProduct(product: Product, ctx: ResolverContext): Promise<ResolveAllResult>;
47
+ /**
48
+ * Resolve a single attribute. Convenience for handlers that only need
49
+ * Name or Description (e.g., the public PDP route).
50
+ */
51
+ resolveOne(args: {
52
+ baseline: unknown;
53
+ overrides: readonly OverrideRow[];
54
+ attributeKey: string;
55
+ scope: AttributeScope;
56
+ ctx: ResolverContext;
57
+ }): Resolved;
58
+ }
59
+ //# sourceMappingURL=product-value-resolver.service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"product-value-resolver.service.d.ts","sourceRoot":"","sources":["../../../src/backend/services/product-value-resolver.service.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,EAIL,KAAK,cAAc,EACnB,KAAK,WAAW,EAChB,KAAK,QAAQ,EACb,KAAK,gBAAgB,EACrB,KAAK,gBAAgB,EACrB,KAAK,eAAe,EACrB,MAAM,4BAA4B,CAAC;AAEpC,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,+BAA+B,CAAC;AAE7D,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,qCAAqC,CAAC;AAMvF;;;;;;;;;;GAUG;AACH,qBAAa,2BAA2B;IAEpC,OAAO,CAAC,QAAQ,CAAC,SAAS;IAC1B,OAAO,CAAC,QAAQ,CAAC,eAAe;IAChC,mEAAmE;IACnE,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAC;gBAHd,SAAS,EAAE,MAAM,aAAa,EAC9B,eAAe,EAAE,gBAAgB;IAClD,mEAAmE;IAClD,aAAa,CAAC,EAAE,2BAA2B,YAAA;IAG9D,0DAA0D;IACpD,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC;IAW9D,qDAAqD;IAC/C,uBAAuB,IAAI,OAAO,CAAC,MAAM,CAAC;IAOhD;;;OAGG;IACG,WAAW,CACf,SAAS,EAAE,MAAM,GAAG,IAAI,EACxB,YAAY,EAAE,MAAM,GAAG,IAAI,GAC1B,OAAO,CAAC,eAAe,CAAC;IAK3B;;;;;;;;;;;;OAYG;IACG,iBAAiB,CACrB,OAAO,EAAE,OAAO,EAChB,GAAG,EAAE,eAAe,GACnB,OAAO,CAAC,gBAAgB,CAAC;IA+C5B;;;OAGG;IACH,UAAU,CAAC,IAAI,EAAE;QACf,QAAQ,EAAE,OAAO,CAAC;QAClB,SAAS,EAAE,SAAS,WAAW,EAAE,CAAC;QAClC,YAAY,EAAE,MAAM,CAAC;QACrB,KAAK,EAAE,cAAc,CAAC;QACtB,GAAG,EAAE,eAAe,CAAC;KACtB,GAAG,QAAQ;CAGb"}
@@ -0,0 +1,111 @@
1
+ import { resolveAttribute, resolveAll, } from '@endora-commerce/contracts';
2
+ import { ProductValueOverride } from '../entities/product-value-override.entity.js';
3
+ import { SYSTEM_ATTRIBUTE_SCOPES, } from './system-attribute-scopes.js';
4
+ /**
5
+ * Feature 022 — backend wrapper around the pure resolver in
6
+ * `@endora-commerce/contracts`. Handles the EM-side concerns:
7
+ * - fetching the override map for a product in a single SELECT,
8
+ * - assembling AttributeDefs for the system + user-defined attrs,
9
+ * - resolving the platform's primary admin language.
10
+ *
11
+ * The actual fallback-chain logic lives in `@endora-commerce/contracts` so the
12
+ * admin SPA imports the same code (guaranteeing server / client
13
+ * agreement — SC-004).
14
+ */
15
+ export class ProductValueResolverService {
16
+ emFactory;
17
+ languageService;
18
+ attributeRead;
19
+ constructor(emFactory, languageService,
20
+ /** Feature 061 — composed attribute read model (scope lookups). */
21
+ attributeRead) {
22
+ this.emFactory = emFactory;
23
+ this.languageService = languageService;
24
+ this.attributeRead = attributeRead;
25
+ }
26
+ /** Load every override row for a product in one query. */
27
+ async loadOverrides(productId) {
28
+ const em = this.emFactory();
29
+ const rows = await em.find(ProductValueOverride, { productId });
30
+ return rows.map((r) => ({
31
+ attributeKey: r.attributeKey,
32
+ channelId: r.channelId,
33
+ languageCode: r.languageCode ?? null,
34
+ value: r.value,
35
+ }));
36
+ }
37
+ /** Resolve the platform's primary admin language. */
38
+ async getPrimaryAdminLanguage() {
39
+ const def = await this.languageService.getDefault();
40
+ if (def)
41
+ return def.code;
42
+ const actives = await this.languageService.listActive();
43
+ return actives[0]?.code ?? 'en';
44
+ }
45
+ /**
46
+ * Build a ResolverContext from a (channelId, languageCode) pair,
47
+ * filling in the primary admin language.
48
+ */
49
+ async makeContext(channelId, languageCode) {
50
+ const primaryLanguage = await this.getPrimaryAdminLanguage();
51
+ return { channelId, languageCode, primaryLanguage };
52
+ }
53
+ /**
54
+ * Resolve every attribute for the given product in one pass: system
55
+ * Name + Description plus every user-defined attribute defined in the
56
+ * `product_attributes` table whose value is present in
57
+ * `attribute_values` JSONB (or every row in the assigned set, see
58
+ * below).
59
+ *
60
+ * For simplicity this implementation walks the union of (a) the
61
+ * product's `attributeValues` keys and (b) `SYSTEM_ATTRIBUTE_SCOPES`.
62
+ * Attributes defined in the assigned `AttributeSet` but currently
63
+ * empty are skipped — the admin UI re-introduces them when binding
64
+ * fields. The resolver tolerates empty inputs gracefully.
65
+ */
66
+ async resolveForProduct(product, ctx) {
67
+ const overrides = await this.loadOverrides(product.id);
68
+ const userAttrKeys = Object.keys(product.attributeValues ?? {});
69
+ // Look up user-defined attribute metadata through the composed view
70
+ // (feature 061 — the key/scope pair spans definition + extension).
71
+ if (!this.attributeRead) {
72
+ throw new Error('ProductValueResolverService: CatalogAttributeReadService is not wired — attribute reads are unavailable.');
73
+ }
74
+ const wantedKeys = new Set(userAttrKeys);
75
+ const userAttrRows = userAttrKeys.length === 0
76
+ ? []
77
+ : (await this.attributeRead.listAll()).filter((v) => wantedKeys.has(v.key));
78
+ const userAttrByKey = new Map(userAttrRows.map((r) => [r.key, r]));
79
+ const defs = [];
80
+ // System attributes — their baseline lives directly on the product.
81
+ for (const sysKey of Object.keys(SYSTEM_ATTRIBUTE_SCOPES)) {
82
+ const baseline = sysKey === 'name' ? product.name : sysKey === 'description' ? product.description : null;
83
+ defs.push({
84
+ attributeKey: sysKey,
85
+ scope: SYSTEM_ATTRIBUTE_SCOPES[sysKey],
86
+ baseline,
87
+ });
88
+ }
89
+ // User-defined attributes — baseline is product.attributeValues[key].
90
+ for (const key of userAttrKeys) {
91
+ const row = userAttrByKey.get(key);
92
+ const scope = row
93
+ ? { channelScoped: row.channelScoped, languageScoped: row.languageScoped }
94
+ : { channelScoped: false, languageScoped: false };
95
+ defs.push({
96
+ attributeKey: key,
97
+ scope,
98
+ baseline: product.attributeValues[key],
99
+ });
100
+ }
101
+ return resolveAll(defs, overrides, ctx);
102
+ }
103
+ /**
104
+ * Resolve a single attribute. Convenience for handlers that only need
105
+ * Name or Description (e.g., the public PDP route).
106
+ */
107
+ resolveOne(args) {
108
+ return resolveAttribute(args);
109
+ }
110
+ }
111
+ //# sourceMappingURL=product-value-resolver.service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"product-value-resolver.service.js","sourceRoot":"","sources":["../../../src/backend/services/product-value-resolver.service.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Feature 022 — scope flags for the **system** product attributes that are NOT
3
+ * rows in `product_attributes` (and therefore do not carry their own DB-stored
4
+ * scope flags).
5
+ *
6
+ * All four declarations moved to `@endora-commerce/contracts` in feature 075's Phase P
7
+ * (FR-013). `SYSTEM_ATTRIBUTE_SCOPES` is a constant and `getAttributeScope` a
8
+ * pure function over it: `name` and `description` are channel- and
9
+ * language-scoped because the product table stores them as per-locale JSONB,
10
+ * which is a fact about the schema rather than about whether a module is
11
+ * switched on. A gated port answering 503 to "is this key channel-scoped"
12
+ * would be a bug.
13
+ *
14
+ * Re-exported here for the length of Phase P, which cuts no consumer —
15
+ * `search`'s indexer still names this path.
16
+ */
17
+ export { SYSTEM_ATTRIBUTE_SCOPES, type SystemAttributeKey, isSystemAttributeKey, getAttributeScope, } from '@endora-commerce/contracts';
18
+ //# sourceMappingURL=system-attribute-scopes.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"system-attribute-scopes.d.ts","sourceRoot":"","sources":["../../../src/backend/services/system-attribute-scopes.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AACH,OAAO,EACL,uBAAuB,EACvB,KAAK,kBAAkB,EACvB,oBAAoB,EACpB,iBAAiB,GAClB,MAAM,4BAA4B,CAAC"}
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Feature 022 — scope flags for the **system** product attributes that are NOT
3
+ * rows in `product_attributes` (and therefore do not carry their own DB-stored
4
+ * scope flags).
5
+ *
6
+ * All four declarations moved to `@endora-commerce/contracts` in feature 075's Phase P
7
+ * (FR-013). `SYSTEM_ATTRIBUTE_SCOPES` is a constant and `getAttributeScope` a
8
+ * pure function over it: `name` and `description` are channel- and
9
+ * language-scoped because the product table stores them as per-locale JSONB,
10
+ * which is a fact about the schema rather than about whether a module is
11
+ * switched on. A gated port answering 503 to "is this key channel-scoped"
12
+ * would be a bug.
13
+ *
14
+ * Re-exported here for the length of Phase P, which cuts no consumer —
15
+ * `search`'s indexer still names this path.
16
+ */
17
+ export { SYSTEM_ATTRIBUTE_SCOPES, isSystemAttributeKey, getAttributeScope, } from '@endora-commerce/contracts';
18
+ //# sourceMappingURL=system-attribute-scopes.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"system-attribute-scopes.js","sourceRoot":"","sources":["../../../src/backend/services/system-attribute-scopes.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AACH,OAAO,EACL,uBAAuB,EAEvB,oBAAoB,EACpB,iBAAiB,GAClB,MAAM,4BAA4B,CAAC"}
@@ -0,0 +1,25 @@
1
+ import type { OrganizationDetailsPort, PriceOrganization, ProductAudience } from '@endora-commerce/contracts';
2
+ /**
3
+ * The buying organisation the pricing engine should resolve a catalogue price
4
+ * against, for the viewer in front of this page — or `null` when there is none.
5
+ *
6
+ * `null` covers three callers, and they get the channel price for three
7
+ * different reasons that happen to agree:
8
+ *
9
+ * - the **anonymous** visitor and the crawler, who have no identity to price
10
+ * for and whose answer has to stay the canonical, cacheable, indexable one;
11
+ * - the **signed-in buyer with no Organization** — feature 026's guest-style
12
+ * account, and an unbound API key. Authenticated, and with no negotiated
13
+ * list to resolve against, so the channel price is not a fallback but the
14
+ * right answer;
15
+ * - the buyer whose Organization row is **gone**. That one answers with the
16
+ * channel price rather than throwing, for the reason `comparisons` states at
17
+ * the same seam: a missing row is not a reason to refuse a catalogue.
18
+ *
19
+ * Shared by `CatalogQueryService` and `ProductLinkService` because a PDP calls
20
+ * both — the hero price and the cross-sell tiles under it come out of one
21
+ * request, and two derivations of "who is asking" is two chances to answer it
22
+ * differently on one page.
23
+ */
24
+ export declare function viewerOrganizationFor(organizations: OrganizationDetailsPort, audience: ProductAudience): Promise<PriceOrganization | null>;
25
+ //# sourceMappingURL=viewer-organization.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"viewer-organization.d.ts","sourceRoot":"","sources":["../../../src/backend/services/viewer-organization.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,uBAAuB,EACvB,iBAAiB,EACjB,eAAe,EAChB,MAAM,4BAA4B,CAAC;AAEpC;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAsB,qBAAqB,CACzC,aAAa,EAAE,uBAAuB,EACtC,QAAQ,EAAE,eAAe,GACxB,OAAO,CAAC,iBAAiB,GAAG,IAAI,CAAC,CAKnC"}
@@ -0,0 +1,31 @@
1
+ /**
2
+ * The buying organisation the pricing engine should resolve a catalogue price
3
+ * against, for the viewer in front of this page — or `null` when there is none.
4
+ *
5
+ * `null` covers three callers, and they get the channel price for three
6
+ * different reasons that happen to agree:
7
+ *
8
+ * - the **anonymous** visitor and the crawler, who have no identity to price
9
+ * for and whose answer has to stay the canonical, cacheable, indexable one;
10
+ * - the **signed-in buyer with no Organization** — feature 026's guest-style
11
+ * account, and an unbound API key. Authenticated, and with no negotiated
12
+ * list to resolve against, so the channel price is not a fallback but the
13
+ * right answer;
14
+ * - the buyer whose Organization row is **gone**. That one answers with the
15
+ * channel price rather than throwing, for the reason `comparisons` states at
16
+ * the same seam: a missing row is not a reason to refuse a catalogue.
17
+ *
18
+ * Shared by `CatalogQueryService` and `ProductLinkService` because a PDP calls
19
+ * both — the hero price and the cross-sell tiles under it come out of one
20
+ * request, and two derivations of "who is asking" is two chances to answer it
21
+ * differently on one page.
22
+ */
23
+ export async function viewerOrganizationFor(organizations, audience) {
24
+ if (audience.organizationId === null)
25
+ return null;
26
+ const record = await organizations.findById(audience.organizationId);
27
+ if (!record)
28
+ return null;
29
+ return { id: record.id, customerGroupId: record.customerGroupId };
30
+ }
31
+ //# sourceMappingURL=viewer-organization.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"viewer-organization.js","sourceRoot":"","sources":["../../../src/backend/services/viewer-organization.ts"],"names":[],"mappings":"AAMA;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,MAAM,CAAC,KAAK,UAAU,qBAAqB,CACzC,aAAsC,EACtC,QAAyB;IAEzB,IAAI,QAAQ,CAAC,cAAc,KAAK,IAAI;QAAE,OAAO,IAAI,CAAC;IAClD,MAAM,MAAM,GAAG,MAAM,aAAa,CAAC,QAAQ,CAAC,QAAQ,CAAC,cAAc,CAAC,CAAC;IACrE,IAAI,CAAC,MAAM;QAAE,OAAO,IAAI,CAAC;IACzB,OAAO,EAAE,EAAE,EAAE,MAAM,CAAC,EAAE,EAAE,eAAe,EAAE,MAAM,CAAC,eAAe,EAAE,CAAC;AACpE,CAAC"}