@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,686 @@
1
+ import { defineModuleManifest, defineModuleRecentActivity, } from '@endora-commerce/contracts';
2
+ /**
3
+ * The demo data this module owns (feature 113, T224 — contract §1.3).
4
+ *
5
+ * A typed `const` rather than an inline object literal: declared inline the
6
+ * parameter infers from the schema and is `never`, so the author loses
7
+ * `context.ctx: ModuleContext`.
8
+ *
9
+ * Both bodies are reached by a **relative `await import()`** (§1.4), in
10
+ * `cliCommands.run`'s shape and for `cliCommands`' reason: a manifest is loaded
11
+ * by every process that composes the platform and by the check scripts that
12
+ * import the generated index, so a demo body imported at the top of this file
13
+ * would be a service graph pulled into all of them. It needs no `exports`
14
+ * subpath and no `files` entry (§1.5).
15
+ *
16
+ * **The catalogue is generated, not shipped.** 200 products, their descriptions
17
+ * and their images are built in process, so this module ships no non-`.ts` demo
18
+ * asset at all — which is what the Phase 3 budget assumes.
19
+ *
20
+ * **What is not here.** The attributes (a `custom_fields` definition paired to
21
+ * one of this module's extension rows), the placeholder images and the sample
22
+ * attachments (each mints an `assets_library` asset), and every join table a
23
+ * product hangs off. All of them write two modules' rows in one statement, so
24
+ * all of them are composition steps (§5.1).
25
+ */
26
+ const demo = {
27
+ summary: 'A three-level category tree, 200 generated products and three composites.',
28
+ seed: async (context) => (await import('./backend/demo/seed.js')).seedDemo(context),
29
+ reset: async (context) => (await import('./backend/demo/reset.js')).resetDemo(context),
30
+ };
31
+ /**
32
+ * Catalog module — feature 002 (and predecessors).
33
+ *
34
+ * Owns products, product variants, categories, attributes, attribute
35
+ * sets, gallery items, attachments, product links, grouped products,
36
+ * and bundle slots. The module pre-dates the lifecycle system; this
37
+ * manifest is a backfill landed alongside feature 020 so the module can
38
+ * declare command-palette actions.
39
+ *
40
+ * NOTE: hard-uninstall via `module:uninstall --hard` is intentionally
41
+ * unsupported for legacy modules — the migrations under
42
+ * `migrations/` are foundational to the entire B2B schema and reverting
43
+ * them in production would devastate the database. The lifecycle
44
+ * orchestrator's revert path is gated by an explicit operator-supplied
45
+ * `--hard` flag; reviewers are responsible for not invoking it on this
46
+ * module until a future feature adds proper teardown semantics.
47
+ */
48
+ export const manifest = defineModuleManifest({
49
+ id: 'catalog',
50
+ name: 'Catalog',
51
+ description: 'Products, variants, categories, attributes, attribute sets, gallery, attachments, links, and bundles.',
52
+ version: '1.6.0',
53
+ /**
54
+ * What this module needs from the environment (`specs/117-instance-bring-up/`
55
+ * FR-002). Only what it **owns**: its reads of platform-owned names are
56
+ * satisfied by `packages/platform/src/env/index.ts`.
57
+ *
58
+ * Why each of these is not a Setting is its entry in
59
+ * `backend/scripts/ledgers/module-environment-inputs/catalog.ts`.
60
+ */
61
+ env: [
62
+ {
63
+ name: 'CATALOG_SEARCH_BACKEND',
64
+ describes: {
65
+ en: 'Which engine answers product search; `meilisearch` routes queries to the search module instead of the database.',
66
+ pl: 'Który silnik obsługuje wyszukiwanie produktów; wartość `meilisearch` kieruje zapytania do modułu wyszukiwania zamiast do bazy danych.',
67
+ },
68
+ requirement: {
69
+ kind: 'optional',
70
+ without: {
71
+ en: 'Product search is answered from the database, which matches text but cannot rank results by relevance.',
72
+ pl: 'Wyszukiwanie produktów odpowiada z bazy danych, która dopasuje tekst, ale nie uszereguje wyników według trafności.',
73
+ },
74
+ },
75
+ secret: false,
76
+ generable: false,
77
+ owner: { kind: 'module', moduleId: 'catalog' },
78
+ consumers: ['backend'],
79
+ addressOf: null,
80
+ },
81
+ {
82
+ name: 'CATALOG_MAX_RESOLVE_IDS',
83
+ describes: {
84
+ en: 'The largest number of products one admin select-all may resolve at once.',
85
+ pl: 'Największa liczba produktów, jaką jedno zaznaczenie wszystkiego w panelu może rozwinąć naraz.',
86
+ },
87
+ requirement: {
88
+ kind: 'optional',
89
+ without: {
90
+ en: 'A select-all over a large catalogue is bounded by the platform rather than by a figure chosen for this shop.',
91
+ pl: 'Zaznaczenie wszystkiego w dużym katalogu jest ograniczone przez platformę, a nie przez wartość dobraną do tego sklepu.',
92
+ },
93
+ },
94
+ secret: false,
95
+ generable: false,
96
+ owner: { kind: 'module', moduleId: 'catalog' },
97
+ consumers: ['backend'],
98
+ addressOf: null,
99
+ },
100
+ ],
101
+ // Feature 061 (FR-020) — product attributes are catalog extensions of
102
+ // product-host Custom Field definitions; the lifecycle must install
103
+ // custom_fields first and must not hard-uninstall it under a live catalog.
104
+ // Feature 072 (T142) — `email` was reached through an option a root passed
105
+ // down, so it did not appear here: a finished bulk operation mails. The bell
106
+ // arrived in the same task and has moved to `nonBindingDependencies` below
107
+ // (D-179.3), which is what this module's own recorder has said since D-60.
108
+ //
109
+ // `price_lists` is deliberately absent and recorded in
110
+ // `acknowledgedDependencies` below instead. The external catalog namespace
111
+ // prices through the pricing engine, but `price_lists` declares *this* module
112
+ // — a price list is a list of prices for products — so the edge is mutual and
113
+ // declaring it back closes a cycle. Catalog installs first.
114
+ // `audit_logs` owns `auditReferenceRegistry`, the registry this module pushes
115
+ // its own "what is this audit row called, and where does the admin app show
116
+ // it?" resolver into (feature 075, D-87). The registry is ungated and its
117
+ // owner is non-deactivatable, so the declaration buys install and migration
118
+ // order rather than a flip-time refusal.
119
+ dependencies: [
120
+ 'audit_logs',
121
+ 'admin_users',
122
+ 'assets_library',
123
+ 'custom_fields',
124
+ 'email',
125
+ 'sales_channels',
126
+ ],
127
+ // Feature 075 — `organizations` is resolved, not imported, since the cut
128
+ // replaced `em.findOne(Organization, …)` in the external namespace's price
129
+ // decorator with `organizationDetailsPort`. It is acknowledged rather than
130
+ // declared for the reason `price_lists` is, one line down: `organizations`
131
+ // declares this module (the org-scoped catalogue restriction is a list of
132
+ // products), so declaring it back closes a cycle and `module-graph.test.ts`
133
+ // fails the build on one. The module is non-deactivatable, so the acknowledgement
134
+ // binds nothing an operator can flip.
135
+ // Feature 073, Amendment A1 — with its operator clause deleted rather than
136
+ // updated (issue #216). That clause distinguished this pair from the
137
+ // `organizations` one by naming a `price_lists` activation control and
138
+ // reasoning that the pricing engine could therefore be switched off
139
+ // underneath a live resolver. Feature 074 withdrew that control: it was one
140
+ // of the nineteen that never accepted a deactivation, and the pricing module
141
+ // is locked on both axes today. So the clause contradicted the manifests, in
142
+ // the file a reviewer opens to understand the edge, and the distinction it
143
+ // drew no longer exists. Per D-100 a reason states the ground a human had to
144
+ // decide, not a fact `lib/switchable-modules.ts` re-derives on every run —
145
+ // the ground here is the cycle, and the entry below says so.
146
+ acknowledgedDependencies: [
147
+ {
148
+ moduleId: 'organizations',
149
+ port: 'organizationDetailsPort',
150
+ reason: 'Feature 075. The external catalog namespace decorates a bound caller’s prices with ' +
151
+ 'their organisation’s effective tiers, and read the `Organization` entity directly to ' +
152
+ 'do it. Over the port now — but `organizations` declares this module, so declaring it ' +
153
+ 'back closes a cycle. Acknowledged rather than declared, and the module is ' +
154
+ 'non-deactivatable, so nothing an operator can flip depends on the difference.',
155
+ },
156
+ {
157
+ moduleId: 'price_lists',
158
+ port: 'pricingService',
159
+ reason: 'Mutual by nature, and the mirror of `organizations:addressService`. ' +
160
+ '`price_lists` declares this module — a price list is a list of prices for ' +
161
+ 'products, and it must install after them — while the external catalog ' +
162
+ 'namespace prices its responses through the pricing engine. Declaring the ' +
163
+ 'second direction closes the cycle, and `module-graph.test.ts` fails the ' +
164
+ 'build on it, which is how this was found.',
165
+ },
166
+ ],
167
+ // D-44 — five edges that are real to the container and bind no operator.
168
+ nonBindingDependencies: [
169
+ {
170
+ moduleId: 'admin_notifications',
171
+ name: 'adminNotificationRecordPort',
172
+ kind: 'degrades-without',
173
+ whenAbsent: 'bulk edits and search reindexes still run and still report on the Bulk actions page; ' +
174
+ 'only the bell entry is missing — the completion e-mail to the admin still goes out',
175
+ reason: 'D-179.3. This module reaches the bell once, from the bulk-operation completion ' +
176
+ 'notice, and it has decided the owner’s absence in front of the gate since D-60: ' +
177
+ '`presenceAwareBulkRecorder` probes the effective state and hands the bulk-operation ' +
178
+ 'service `not-present` in the return type, so nothing here fails closed. The ' +
179
+ '`dependencies` entry therefore contradicted this module’s own implementation. It ' +
180
+ 'bought no schema order either — neither `admin_notification` table is referenced ' +
181
+ 'from anything this module owns — only the flip-time refusal, which is what made ' +
182
+ '`admin_notifications.enabled` a control an operator could move with nothing ' +
183
+ 'happening. Feature 072 (T142) declared it when the recorder arrived through a root ' +
184
+ 'option; the recorder is the whole answer.',
185
+ },
186
+ {
187
+ moduleId: 'inventory',
188
+ // `inventoryAvailabilityPort`, which this module resolves itself since
189
+ // `specs/117-instance-bring-up/` Phase 6. The entry named
190
+ // `catalogExternalAvailability` while a composition root registered the
191
+ // closure on `inventory`'s behalf; that closure was
192
+ // `effectiveState.isPresent('inventory')` plus this port, which is the
193
+ // shape a module writes for itself, and nothing defaulted the name — so
194
+ // every composition that was neither root resolved it to nothing.
195
+ name: 'inventoryAvailabilityPort',
196
+ kind: 'degrades-without',
197
+ whenAbsent: 'product listings and the external catalog namespace stop carrying an availability band',
198
+ reason: 'D-61. Availability is an indication on a catalog read, never a reason to fail ' +
199
+ 'one: the decorator has always had an absent-contribution path answering the ' +
200
+ 'empty map, so `inventory` being off has a defined behaviour and 503-ing the ' +
201
+ 'product list would be the wrong one. What was missing is that the contribution ' +
202
+ 'said so — the behaviour was written in a `catch` at the call site, which also ' +
203
+ 'swallowed genuine inventory failures. Declared here, probed in front of the ' +
204
+ 'resolution, and the `catch` is gone.',
205
+ },
206
+ {
207
+ moduleId: 'inventory',
208
+ name: 'inventoryProductThresholdWritePort',
209
+ kind: 'degrades-without',
210
+ whenAbsent: 'a duplicated product does not inherit the source’s per-warehouse low-stock thresholds',
211
+ reason: 'Issue #185. Product duplication copied the source’s alerting profile with an ' +
212
+ '`insert … select` into `product_warehouse_low_stock_thresholds` — `inventory`’s table, ' +
213
+ 'reached with no import specifier, no gate, no declared edge and no audit row on the ' +
214
+ 'owner’s side. A second entry rather than a widening of `catalogExternalAvailability` ' +
215
+ 'above: that sentence describes a *read* degrade and must not be stretched over a write. ' +
216
+ 'Not `dependencies` (`inventory` declares this module) and not acknowledged either — an ' +
217
+ 'acknowledged edge sits in the refusal graph and would make `inventory` undeactivatable ' +
218
+ 'while a catalogue is present. The degrade is real: the duplicate falls back to the ' +
219
+ 'product- and warehouse-level chain, as on a deployment without the module.',
220
+ },
221
+ {
222
+ moduleId: 'search',
223
+ // The full reindex an attribute's `searchable` flip runs, resolved by
224
+ // this module since `specs/117-instance-bring-up/` Phase 6 — it was
225
+ // `catalogSearchReindex`, a root's closure over this same port, and
226
+ // nothing defaulted it. The degrade is the reason it is probed rather
227
+ // than gated: with `search` off there is no index to rebuild, so
228
+ // "nothing was indexed" is the honest answer and 503-ing an unrelated
229
+ // attribute edit because an optional module is off is not.
230
+ name: 'searchReindexPort',
231
+ kind: 'degrades-without',
232
+ whenAbsent: 'an attribute’s `searchable` flip rebuilds no search index',
233
+ reason: 'The same ground as `searchQueryPort` below and the same owner: PostgreSQL is the ' +
234
+ 'default backend for every catalogue read, so a switched-off `search` costs the ' +
235
+ 'index and nothing else. Declared rather than acknowledged, because an ' +
236
+ 'acknowledged edge keeps the bind and would make `search` undeactivatable for as ' +
237
+ 'long as the platform has a catalogue.',
238
+ },
239
+ {
240
+ moduleId: 'search',
241
+ name: 'searchQueryPort',
242
+ kind: 'degrades-without',
243
+ whenAbsent: 'the storefront product listing is served from PostgreSQL instead of the search index',
244
+ reason: 'Issue #153. This module used to build its own `SearchQueryService` out of `search`\'s ' +
245
+ 'class, so a composition held two Meilisearch clients and the public product list ' +
246
+ 'reached the index through no gate at all: a switched-off `search` went on serving that ' +
247
+ 'listing out of an index whose maintenance subscribers had stopped with it. It resolves ' +
248
+ 'the port now, and the degrade stays what it was — PostgreSQL is this route\'s default ' +
249
+ 'backend, and 503-ing a public catalogue because an optional search module is off would ' +
250
+ 'take the storefront down for a capability it never required. Declared rather than ' +
251
+ 'caught: presence is decided in front of the query, and an unreachable index is an arm ' +
252
+ 'of the port\'s return type.',
253
+ },
254
+ {
255
+ moduleId: 'prompt_actions',
256
+ name: 'promptActionToolRegistry',
257
+ kind: 'contributes-to',
258
+ reason: 'A push, from this module’s boot hook, of the six assistant tools built over its ' +
259
+ 'own admin services. It reads nothing back: the registry is a plain registration ' +
260
+ 'that drops every tool whose owner is not effectively present, so an absent ' +
261
+ 'contributor costs the host nothing and an absent host holds a table nobody walks. ' +
262
+ 'Declaring the edge would make an optional assistant undeactivatable for as long as ' +
263
+ 'the catalogue is present, which is a claim this contribution does not support.',
264
+ },
265
+ {
266
+ moduleId: 'prompt_actions',
267
+ name: 'promptActionBulkProgressRegistry',
268
+ kind: 'contributes-to',
269
+ reason: 'The twin of the tool push above, and the last member of the D-44 family to leave a ' +
270
+ 'composition root (D-72 point 4). It folds live `catalog_bulk_operations` progress ' +
271
+ 'into a delegated request and finalizes it when the run ends, so it is built from ' +
272
+ 'this module’s own bulk services and belongs here — it stayed in the roots only ' +
273
+ 'because the host defaulted a single name for it and a module may not write a name ' +
274
+ 'another module owns. Reads nothing back: the registry is a plain registration that ' +
275
+ 'skips every resolver whose owner is not effectively present, and the absent ' +
276
+ 'behaviour was already the documented one — the request reports no progress, keeps ' +
277
+ 'its row and its audit trail, and expires on the assistant’s own TTL.',
278
+ },
279
+ {
280
+ moduleId: 'api_keys',
281
+ name: 'requireApiKey',
282
+ kind: 'degrades-without',
283
+ whenAbsent: 'the external catalog namespace stops accepting machine-to-machine callers',
284
+ reason: 'The two gates guard `/api/v1/external/catalog/*` and the by-SKU upsert. Declaring ' +
285
+ '`api_keys` closes a cycle through `customer_accounts` → `price_lists` → `catalog`, ' +
286
+ 'and acknowledging it would bind the operator instead. The namespace has a defined ' +
287
+ 'behaviour without the module: the gate answers 401 rather than resolving a port ' +
288
+ 'whose owner is gone, so the catalogue keeps serving its own surfaces and only the ' +
289
+ 'machine-to-machine door closes.',
290
+ },
291
+ {
292
+ moduleId: 'api_keys',
293
+ name: 'requireBoundApiKey',
294
+ kind: 'degrades-without',
295
+ whenAbsent: 'the external catalog namespace stops accepting machine-to-machine callers',
296
+ reason: 'The organization-bound half of the gate above — same namespace, same cycle, same ' +
297
+ '401, and it drains with it.',
298
+ },
299
+ ],
300
+ // Feature 074 (Constitution XVII), test C2 — functional base. This module had
301
+ // no activation declaration at all, which resolved as "always activated" and
302
+ // read as an omission; the lock says the same thing on purpose and with a
303
+ // reason. Products, variants and categories are what a commerce platform is
304
+ // for: their absence does not reduce it, it makes it something else.
305
+ demo,
306
+ activation: {
307
+ nonDeactivatable: true,
308
+ reason: 'Products, variants and categories. A commerce platform without a catalogue is a ' +
309
+ 'different product, not a reduced one.',
310
+ },
311
+ /**
312
+ * The error codes this module owns — forty-seven from feature 090 Phase 3
313
+ * (`specs/090-module-owned-error-codes/contracts/error-code-declaration.md`
314
+ * §1.1) and six more from D-129's remaining sweep, MR 4, described at the end
315
+ * of this block. This is where the sentence for each is looked up from:
316
+ * `errors.<CODE>` in this module's own `i18n/{en,pl}.json`. Every code with
317
+ * no sentence there is an entry in `check-error-translations.ts`'s
318
+ * `UNTRANSLATED_ERROR_CODES` ledger and stays one — declaring a code writes no
319
+ * sentence (runbook §7 case 1).
320
+ *
321
+ * The Phase 3 forty-seven are answer-preserving, not a judgement (§6.2 and
322
+ * §6.5), and that list was not written by hand: it is the output of the
323
+ * runbook's step-1 derivation over the frozen capture at
324
+ * `backend/test/fixtures/error-code-routing/chain-answers.ts`, which records
325
+ * what the prefix chain in `@endora-commerce/mod-i18n` answered at
326
+ * `49f3c6817`. Re-routing a code to a better owner was
327
+ * `specs/082-error-code-ownership/rulings.md` §9's remaining work, deliberately
328
+ * not done in Phase 3; it is what the six additions below are.
329
+ *
330
+ * **Four codes are here because an earlier rule in that ordered chain shadows
331
+ * a later one that names them.** Read from the chain's source they look like
332
+ * somebody else's; read from its answer — which is the only reading that
333
+ * matches what a client receives today — they are this module's:
334
+ *
335
+ * - `PRODUCT_UNMANAGED_STOCK` and `PRODUCT_IN_STOCK` are members of the
336
+ * chain's own `INVENTORY_MISC_ERROR_CODES` set, and the `PRODUCT_` prefix
337
+ * above it claims both first. `inventory` raises the second one.
338
+ * - `ASSET_KIND_NOT_SUPPORTED` would match `assets_library`'s `ASSET_` prefix,
339
+ * and `CATALOG_MISC_ERROR_CODES` names it thirty lines earlier.
340
+ * - `UNKNOWN_OPTION` would match `sales_channels`' `UNKNOWN_` prefix, and the
341
+ * same misc set claims it first. `catalog`'s own `bundle.service.ts` raises
342
+ * it.
343
+ *
344
+ * **Ten more are counter-intuitive without any shadow** — the prefix rule is
345
+ * simply wider than the module that raises the code, which §6.5 leaves
346
+ * standing: the five `PRODUCT_FEED_*` codes (raised by `product_feeds`),
347
+ * `PRODUCT_NOT_IN_COMPARISON` (raised by `comparisons`),
348
+ * `SKU_NOT_IN_ASSORTMENT` (raised by `orders`), and
349
+ * `PRICE_ORDERING_UNAVAILABLE` / `PRICE_RANGE_INVALID`, which the chain names
350
+ * one by one rather than by a `PRICE_` prefix precisely so that the
351
+ * `PRICE_LIST_*` family stays with `price_lists`. `SKU_NOT_IN_ASSORTMENT` is
352
+ * the one of those ten the sweep does **not** revisit: D-121 T1 puts it here
353
+ * on the same reading the chain reached by accident, so there is nothing to
354
+ * re-home.
355
+ *
356
+ * No `tokens`: no code here carries a refusal discriminator. Derived from the
357
+ * raise sites rather than from this module's bundles, per the runbook's §5 —
358
+ * the nine codes in the tree that reach the envelope's `refusalToken` are
359
+ * `core`'s seven, `invoices`' two and `carts`' one, and none of them is here.
360
+ *
361
+ * **Six more arrived from `_i18n` in D-129's remaining sweep, MR 4**
362
+ * (`specs/090-module-owned-error-codes/d129-sweep.md` §5.2, Appendix A) —
363
+ * and unlike the forty-seven above these are a judgement rather than a
364
+ * transcription. The three `PACKAGING_UNIT_*` codes and
365
+ * `SYSTEM_ATTRIBUTE_SET_IMMUTABLE` are D-121 T1: a packaging unit is a row on
366
+ * a Product and an Attribute Set is this module's entity, so the noun decides
367
+ * and the raise site does not — `PACKAGING_UNIT_NOT_FOUND` is raised by
368
+ * `carts` as well as by this module, resolving a unit before adding a line,
369
+ * which makes `carts` the caller. `BULK_TOO_LARGE` and `SELECTION_TOO_LARGE`
370
+ * are T2: "bulk" and "selection" name no entity anybody owns, so T1 does not
371
+ * answer, and each names a mechanism this module implements and alone raises
372
+ * — the 200-product ceiling on `POST /products/bulk-update` and the
373
+ * 10 000-match ceiling on `POST /products/resolve-ids`.
374
+ *
375
+ * `SYSTEM_ATTRIBUTE_SET_IMMUTABLE` is the only one of the six that arrives
376
+ * with a sentence, and it is a new one. It carried a placeholder in `_i18n`'s
377
+ * bundle — `"System Attribute Set Immutable."` — which D-186 §2 deletes
378
+ * rather than moves; §5.4 keeps writing the prose available, and here the
379
+ * meaning is plain at both raise sites (the system set's `code` is immutable,
380
+ * and the set itself cannot be deleted) and the reader is an operator on the
381
+ * Attribute Sets screen. So it is written, and the code does not join
382
+ * `UNTRANSLATED_ERROR_CODES`. The other five had no sentence in either
383
+ * language before the move and have none after; they were ledgered under
384
+ * `_i18n` and are ledgered under `catalog`.
385
+ *
386
+ * None of the six carries a token either, measured the same way: every raise
387
+ * site's own arguments were extracted by balancing parentheses, and the two
388
+ * that pass a `details` object pass `{ maxBatchSize, recommendedSplitInto }`
389
+ * and `{ total, maxSelectionSize }` — neither holds a `code`, which is the
390
+ * only key `refusalToken` reads.
391
+ */
392
+ errorCodes: [
393
+ { code: 'ASSET_KIND_NOT_SUPPORTED' },
394
+ { code: 'ATTACHMENT_NOT_FOUND' },
395
+ { code: 'ATTACHMENT_TYPE_CODE_TAKEN' },
396
+ { code: 'ATTACHMENT_TYPE_IN_USE' },
397
+ { code: 'ATTACHMENT_TYPE_NOT_FOUND' },
398
+ { code: 'ATTRIBUTE_NOT_FOUND' },
399
+ { code: 'ATTRIBUTE_NOT_MASS_EDITABLE' },
400
+ { code: 'ATTRIBUTE_SET_CODE_TAKEN' },
401
+ { code: 'ATTRIBUTE_SET_IN_USE' },
402
+ { code: 'ATTRIBUTE_SET_NOT_FOUND' },
403
+ { code: 'ATTRIBUTE_VALUE_REJECTED' },
404
+ { code: 'BULK_TOO_LARGE' },
405
+ { code: 'BUNDLE_SLOT_NOT_FOUND' },
406
+ { code: 'BUNDLE_SLOT_OPTION_NOT_FOUND' },
407
+ { code: 'FIELD_IMMUTABLE' },
408
+ { code: 'FILTER_NOT_ALLOWED' },
409
+ { code: 'GALLERY_ITEM_NOT_FOUND' },
410
+ { code: 'GALLERY_LABEL_ALREADY_TAKEN' },
411
+ { code: 'GALLERY_LABEL_LIMIT_EXCEEDED' },
412
+ { code: 'GROUPED_ITEM_NOT_FOUND' },
413
+ { code: 'INVALID_QUANTITY_RANGE' },
414
+ { code: 'LINK_ALREADY_EXISTS' },
415
+ { code: 'MAX_EXCEEDED' },
416
+ { code: 'MIN_NOT_MET' },
417
+ { code: 'NESTED_COMPOSITE_NOT_ALLOWED' },
418
+ { code: 'OPTION_ALREADY_EXISTS' },
419
+ { code: 'PACKAGING_UNIT_NAME_CONFLICT' },
420
+ { code: 'PACKAGING_UNIT_NOT_FOUND' },
421
+ { code: 'PACKAGING_UNIT_NOT_SUPPORTED_FOR_TYPE' },
422
+ { code: 'PRICE_ORDERING_UNAVAILABLE' },
423
+ { code: 'PRICE_RANGE_INVALID' },
424
+ { code: 'PRODUCT_ARCHIVED' },
425
+ { code: 'PRODUCT_DELETE_BLOCKED' },
426
+ { code: 'PRODUCT_FEED_CONFIRMATION_REQUIRED' },
427
+ { code: 'PRODUCT_FEED_DISABLED' },
428
+ { code: 'PRODUCT_FEED_TAXONOMY_CONFLICT' },
429
+ { code: 'PRODUCT_FEED_TEMPLATE_CONFLICT' },
430
+ { code: 'PRODUCT_FEED_TEMPLATE_UNBOUND' },
431
+ { code: 'PRODUCT_IN_STOCK' },
432
+ { code: 'PRODUCT_LINK_NOT_FOUND' },
433
+ { code: 'PRODUCT_NOT_FOUND' },
434
+ { code: 'PRODUCT_NOT_IN_COMPARISON' },
435
+ { code: 'PRODUCT_TYPE_MISMATCH' },
436
+ { code: 'PRODUCT_UNMANAGED_STOCK' },
437
+ { code: 'SELECTION_TOO_LARGE' },
438
+ { code: 'SELF_LINK_NOT_ALLOWED' },
439
+ { code: 'SKU_ALREADY_EXISTS' },
440
+ { code: 'SKU_NOT_IN_ASSORTMENT' },
441
+ { code: 'SYSTEM_ATTRIBUTE_SET_IMMUTABLE' },
442
+ { code: 'TARGET_PRODUCT_NOT_FOUND' },
443
+ { code: 'UNKNOWN_OPTION' },
444
+ { code: 'VARIANT_AXIS_MISSING' },
445
+ { code: 'VARIANT_COMBINATION_EXISTS' },
446
+ ],
447
+ /**
448
+ * **One entry, and it declares a requirement rather than a code** (D-221).
449
+ *
450
+ * `catalog:read` and `catalog:write` are core rows — `PERMISSION_CATALOGUE`
451
+ * in `packages/contracts/src/admin.ts` declares both under
452
+ * `module: 'catalog'` — so this module already owns them and this array adds
453
+ * neither. What it adds is the field a core row cannot carry:
454
+ * `PermissionCatalogueService#merge` seeds every core row with an **empty**
455
+ * `requires` and never reads that field off a core entry, so a requirement
456
+ * written in the contracts package would be silently dropped. The manifest
457
+ * path is the designed one (D-175) and unions across declarers.
458
+ *
459
+ * The label is the core row's, repeated because the field is required and a
460
+ * second spelling would be a second answer waiting to disagree. The merge
461
+ * keeps the first label it was given, which is the core one, and adds
462
+ * `catalog` to an owner set it is already in — so `/admin-roles` renders
463
+ * exactly what it rendered before, plus the shortfall.
464
+ *
465
+ * **Why `catalog:write` requires `catalog:read`.** Since D-221 the product
466
+ * create form is a route of its own on `catalog:write`
467
+ * (`packages/modules/catalog/src/admin/index.ts`), and `ProductEditor`'s
468
+ * loader fetches `/catalog/categories` and `/catalog/attribute-sets`
469
+ * unconditionally — before any `isNew` branch — with the create path *using*
470
+ * the second to select the new product's default attribute set. Both are
471
+ * `requireAdmin('catalog:read')`. So a role holding the write code alone
472
+ * opens the form and watches both mount fetches refuse; one
473
+ * `requiredPermission` field cannot say two codes, and this is the field
474
+ * D-175 added for exactly that.
475
+ *
476
+ * It is **advisory**: no upsert is refused, nothing at runtime reads it, and
477
+ * it is not a lifecycle edge — it puts no module in `dependencies`. The role
478
+ * editor renders it as a one-click shortfall, which is what makes the
479
+ * incomplete role visible where it is created instead of at the gate.
480
+ * The requirement is attached to the **code** and not to this screen, so
481
+ * every holder of `catalog:write` is advised to add `catalog:read` —
482
+ * including the holders of the gates other modules enforce with it. How many
483
+ * of those there are is not written here, because a count copied into a
484
+ * comment goes stale in the merge request that changes it (D-100); a grep for
485
+ * `catalog:write` under the other modules' `src/backend` answers it. That
486
+ * breadth was weighed and accepted as correct rather than as collateral: a
487
+ * role that may edit the catalogue through any surface and cannot read it is
488
+ * incomplete wherever it was granted.
489
+ */
490
+ permissions: [
491
+ { code: 'catalog:write', label: 'Edit catalog', requires: ['catalog:read'] },
492
+ ],
493
+ i18n: { bundlesDir: 'i18n' },
494
+ docs: { dir: 'docs' },
495
+ actions: [
496
+ {
497
+ id: 'new-product',
498
+ labelKey: 'actions.newProduct.label',
499
+ descriptionKey: 'actions.newProduct.description',
500
+ icon: 'Plus',
501
+ targetRoute: '/catalog/products/new',
502
+ requiredPermission: 'catalog:write',
503
+ keywords: ['product', 'new', 'add', 'create', 'produkt', 'nowy', 'dodaj'],
504
+ weight: 100,
505
+ },
506
+ // The three below arrive with feature 091's Phase 4 batch 15, by the route
507
+ // batch 10 established: `AppShell.tsx` carried a hand-written
508
+ // `PALETTE_ITEMS` row for each of these destinations, and a hand-written
509
+ // palette row is a copy the server was never asked about — it went on
510
+ // advertising the screen after an operator withdrew the module. Each is a
511
+ // manifest action now, which is the surface the effective enabled-set
512
+ // filters. The destinations, codes and keywords are the rows'; the labels
513
+ // and descriptions are the six strings they rendered, moved out of
514
+ // `_i18n`'s bundle into this module's own.
515
+ {
516
+ id: 'open-products',
517
+ labelKey: 'actions.openProducts.label',
518
+ descriptionKey: 'actions.openProducts.description',
519
+ icon: 'Package',
520
+ targetRoute: '/catalog/products',
521
+ requiredPermission: 'catalog:read',
522
+ keywords: ['products', 'catalog', 'items', 'produkty', 'katalog'],
523
+ weight: 200,
524
+ },
525
+ {
526
+ id: 'open-categories',
527
+ labelKey: 'actions.openCategories.label',
528
+ descriptionKey: 'actions.openCategories.description',
529
+ icon: 'Boxes',
530
+ targetRoute: '/catalog/categories',
531
+ requiredPermission: 'catalog:read',
532
+ keywords: ['category', 'categories', 'tree', 'kategorie'],
533
+ weight: 300,
534
+ },
535
+ {
536
+ id: 'open-attributes',
537
+ labelKey: 'actions.openAttributes.label',
538
+ descriptionKey: 'actions.openAttributes.description',
539
+ icon: 'Tag',
540
+ targetRoute: '/catalog/attributes',
541
+ requiredPermission: 'catalog:read',
542
+ keywords: ['attribute', 'attributes', 'atrybuty'],
543
+ weight: 400,
544
+ },
545
+ ],
546
+ /**
547
+ * The eight Page Builder blocks this module owns — five in the CMS palette
548
+ * and three in the e-mail one (feature 096, §7.1 and §7.2) — and the two
549
+ * palette sections they sit in.
550
+ *
551
+ * `catalog` (CMS) is this module's own section: `cms` hand-writes it today
552
+ * and owns no block in it. `content` (e-mail) is a **joining** declaration —
553
+ * `transactional_emails` names that section and its nine blocks populate it,
554
+ * these three have sat in it since they shipped, and they stay there. It
555
+ * carries **no `weight` and no `visible`** on purpose: under
556
+ * `contracts/block-definition.md` §1.1's total order a declaration that
557
+ * states neither cannot take a presentation its author did not intend, so
558
+ * `transactional_emails` keeps naming the section while this module is only
559
+ * asking to be in it. `titleKey` stays required, and is this module's own
560
+ * key, because the fold runs over the **present** modules: whichever
561
+ * declaration survives has to be able to title the section on its own.
562
+ *
563
+ * The e-mail blocks declare `contexts: ['email']` and not
564
+ * `['email', 'newsletter']`, which is what `emailComponent` writes into the
565
+ * Puck config. They keep appearing in the newsletter palette regardless:
566
+ * `filterConfigByContext` admits an `email` block into the `newsletter`
567
+ * context by construction, and there is no newsletter section for a category
568
+ * declaration to name.
569
+ */
570
+ blocks: [
571
+ {
572
+ name: 'catalog.ProductCard',
573
+ labelKey: 'blocks.productCard.label',
574
+ descriptionKey: 'blocks.productCard.description',
575
+ category: 'catalog',
576
+ contexts: ['cms'],
577
+ fields: { productSlug: { type: 'text', label: 'Product slug' } },
578
+ responsiveFields: ['maxWidthPx', 'imageHeightPx', 'margin', 'padding', 'border'],
579
+ weight: 10,
580
+ },
581
+ {
582
+ name: 'catalog.ProductGrid',
583
+ labelKey: 'blocks.productGrid.label',
584
+ descriptionKey: 'blocks.productGrid.description',
585
+ category: 'catalog',
586
+ contexts: ['cms'],
587
+ fields: {},
588
+ responsiveFields: ['columns', 'gap', 'view', 'margin', 'padding', 'border'],
589
+ weight: 20,
590
+ },
591
+ {
592
+ name: 'catalog.ProductSlider',
593
+ labelKey: 'blocks.productSlider.label',
594
+ descriptionKey: 'blocks.productSlider.description',
595
+ category: 'catalog',
596
+ contexts: ['cms'],
597
+ fields: {},
598
+ responsiveFields: ['slidesPerView', 'gap', 'margin', 'padding', 'border'],
599
+ weight: 30,
600
+ },
601
+ {
602
+ name: 'catalog.CategoryList',
603
+ labelKey: 'blocks.categoryList.label',
604
+ descriptionKey: 'blocks.categoryList.description',
605
+ category: 'catalog',
606
+ contexts: ['cms'],
607
+ fields: {},
608
+ responsiveFields: ['margin', 'padding', 'border'],
609
+ weight: 40,
610
+ },
611
+ {
612
+ name: 'catalog.CategoryGrid',
613
+ labelKey: 'blocks.categoryGrid.label',
614
+ descriptionKey: 'blocks.categoryGrid.description',
615
+ category: 'catalog',
616
+ contexts: ['cms'],
617
+ fields: {},
618
+ responsiveFields: ['columns', 'gap', 'margin', 'padding', 'border'],
619
+ weight: 50,
620
+ },
621
+ {
622
+ name: 'catalog.EmailProductCard',
623
+ labelKey: 'blocks.emailProductCard.label',
624
+ descriptionKey: 'blocks.emailProductCard.description',
625
+ category: 'content',
626
+ contexts: ['email'],
627
+ fields: {},
628
+ weight: 70,
629
+ },
630
+ {
631
+ name: 'catalog.EmailProductGrid',
632
+ labelKey: 'blocks.emailProductGrid.label',
633
+ descriptionKey: 'blocks.emailProductGrid.description',
634
+ category: 'content',
635
+ contexts: ['email'],
636
+ fields: {},
637
+ weight: 80,
638
+ },
639
+ {
640
+ name: 'catalog.EmailCategoryGrid',
641
+ labelKey: 'blocks.emailCategoryGrid.label',
642
+ descriptionKey: 'blocks.emailCategoryGrid.description',
643
+ category: 'content',
644
+ contexts: ['email'],
645
+ fields: {},
646
+ weight: 90,
647
+ },
648
+ ],
649
+ blockCategories: [
650
+ { key: 'catalog', titleKey: 'blocks.category.catalog', contexts: ['cms'], weight: 40 },
651
+ { key: 'content', titleKey: 'blocks.category.content', contexts: ['email'] },
652
+ ],
653
+ });
654
+ /**
655
+ * What this module offers the admin home dashboard's Recent Activity card —
656
+ * feature 080, T042j / D-163.1.
657
+ *
658
+ * The **declaration** axis: eligibility, never a decision. Whether these rows
659
+ * actually appear is the operator's, held in `catalog.recent_activity_visible`
660
+ * and defaulting to visible, flipped on `/platform/modules` beside this
661
+ * module's activation control.
662
+ *
663
+ * These six tokens were four entries in four hand-maintained host tables —
664
+ * `RECENT_ACTIVITY_ACTIONS`, the `product.` prefix row of `PREFIX_TO_MODULE`,
665
+ * the route's `module` enum and the admin's `ACTIVITY_RENDERING`. All four are
666
+ * derived from this now, which is what lets a packaged module reach the card at
667
+ * all (D-163: `RecentActivityModule` was a closed union of four core ids).
668
+ *
669
+ * `product.delete` is deliberately not here and was not in `ACTIVITY_RENDERING`
670
+ * either: the allow-list carried it, the renderer did not, so it drew the
671
+ * unknown-verb fallback. One declaration cannot hold that disagreement.
672
+ */
673
+ export const recentActivity = defineModuleRecentActivity({
674
+ entries: [
675
+ { action: 'product.create', icon: 'Plus', labelKey: 'activity.verb.product.create' },
676
+ { action: 'product.update', icon: 'Edit', labelKey: 'activity.verb.product.update' },
677
+ { action: 'product.archive', icon: 'Archive', labelKey: 'activity.verb.product.archive' },
678
+ { action: 'product.unarchive', icon: 'Box', labelKey: 'activity.verb.product.unarchive' },
679
+ {
680
+ action: 'product.bulk_update',
681
+ icon: 'Edit',
682
+ labelKey: 'activity.verb.product.bulk_update',
683
+ },
684
+ ],
685
+ });
686
+ //# sourceMappingURL=manifest.js.map