@endora-commerce/mod-cms 0.0.0-stage → 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 (264) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +65 -2
  3. package/dist/admin/api/cms-client.d.ts +77 -0
  4. package/dist/admin/api/cms-client.d.ts.map +1 -0
  5. package/dist/admin/api/cms-client.js +162 -0
  6. package/dist/admin/api/cms-client.js.map +1 -0
  7. package/dist/admin/components/AdminCatalogPreviewProvider.d.ts +6 -0
  8. package/dist/admin/components/AdminCatalogPreviewProvider.d.ts.map +1 -0
  9. package/dist/admin/components/AdminCatalogPreviewProvider.js +74 -0
  10. package/dist/admin/components/AdminCatalogPreviewProvider.js.map +1 -0
  11. package/dist/admin/components/AdminCmsAssetProvider.d.ts +9 -0
  12. package/dist/admin/components/AdminCmsAssetProvider.d.ts.map +1 -0
  13. package/dist/admin/components/AdminCmsAssetProvider.js +50 -0
  14. package/dist/admin/components/AdminCmsAssetProvider.js.map +1 -0
  15. package/dist/admin/components/BackgroundFields.d.ts +4 -0
  16. package/dist/admin/components/BackgroundFields.d.ts.map +1 -0
  17. package/dist/admin/components/BackgroundFields.js +40 -0
  18. package/dist/admin/components/BackgroundFields.js.map +1 -0
  19. package/dist/admin/components/ButtonLinkFields.d.ts +6 -0
  20. package/dist/admin/components/ButtonLinkFields.d.ts.map +1 -0
  21. package/dist/admin/components/ButtonLinkFields.js +127 -0
  22. package/dist/admin/components/ButtonLinkFields.js.map +1 -0
  23. package/dist/admin/components/CarouselPreviewNav.d.ts +12 -0
  24. package/dist/admin/components/CarouselPreviewNav.d.ts.map +1 -0
  25. package/dist/admin/components/CarouselPreviewNav.js +31 -0
  26. package/dist/admin/components/CarouselPreviewNav.js.map +1 -0
  27. package/dist/admin/components/CmsContentEditorLayout.d.ts +12 -0
  28. package/dist/admin/components/CmsContentEditorLayout.d.ts.map +1 -0
  29. package/dist/admin/components/CmsContentEditorLayout.js +9 -0
  30. package/dist/admin/components/CmsContentEditorLayout.js.map +1 -0
  31. package/dist/admin/components/ComponentDragHandle.d.ts +6 -0
  32. package/dist/admin/components/ComponentDragHandle.d.ts.map +1 -0
  33. package/dist/admin/components/ComponentDragHandle.js +119 -0
  34. package/dist/admin/components/ComponentDragHandle.js.map +1 -0
  35. package/dist/admin/components/ContentSliderActionBarExtras.d.ts +6 -0
  36. package/dist/admin/components/ContentSliderActionBarExtras.d.ts.map +1 -0
  37. package/dist/admin/components/ContentSliderActionBarExtras.js +109 -0
  38. package/dist/admin/components/ContentSliderActionBarExtras.js.map +1 -0
  39. package/dist/admin/components/HookBlockAttachmentsPanel.d.ts +9 -0
  40. package/dist/admin/components/HookBlockAttachmentsPanel.d.ts.map +1 -0
  41. package/dist/admin/components/HookBlockAttachmentsPanel.js +137 -0
  42. package/dist/admin/components/HookBlockAttachmentsPanel.js.map +1 -0
  43. package/dist/admin/components/PageBuilderActionBar.d.ts +10 -0
  44. package/dist/admin/components/PageBuilderActionBar.d.ts.map +1 -0
  45. package/dist/admin/components/PageBuilderActionBar.js +118 -0
  46. package/dist/admin/components/PageBuilderActionBar.js.map +1 -0
  47. package/dist/admin/components/PageBuilderDrawer.d.ts +16 -0
  48. package/dist/admin/components/PageBuilderDrawer.d.ts.map +1 -0
  49. package/dist/admin/components/PageBuilderDrawer.js +53 -0
  50. package/dist/admin/components/PageBuilderDrawer.js.map +1 -0
  51. package/dist/admin/components/PageBuilderEditor.d.ts +45 -0
  52. package/dist/admin/components/PageBuilderEditor.d.ts.map +1 -0
  53. package/dist/admin/components/PageBuilderEditor.js +632 -0
  54. package/dist/admin/components/PageBuilderEditor.js.map +1 -0
  55. package/dist/admin/components/PuckActionGuard.d.ts +12 -0
  56. package/dist/admin/components/PuckActionGuard.d.ts.map +1 -0
  57. package/dist/admin/components/PuckActionGuard.js +30 -0
  58. package/dist/admin/components/PuckActionGuard.js.map +1 -0
  59. package/dist/admin/components/RowLayoutPicker.d.ts +8 -0
  60. package/dist/admin/components/RowLayoutPicker.d.ts.map +1 -0
  61. package/dist/admin/components/RowLayoutPicker.js +17 -0
  62. package/dist/admin/components/RowLayoutPicker.js.map +1 -0
  63. package/dist/admin/components/SliderPreviewActionBarExtras.d.ts +6 -0
  64. package/dist/admin/components/SliderPreviewActionBarExtras.d.ts.map +1 -0
  65. package/dist/admin/components/SliderPreviewActionBarExtras.js +32 -0
  66. package/dist/admin/components/SliderPreviewActionBarExtras.js.map +1 -0
  67. package/dist/admin/components/admin-catalog-preview-map.d.ts +17 -0
  68. package/dist/admin/components/admin-catalog-preview-map.d.ts.map +1 -0
  69. package/dist/admin/components/admin-catalog-preview-map.js +18 -0
  70. package/dist/admin/components/admin-catalog-preview-map.js.map +1 -0
  71. package/dist/admin/components/build-viewports.d.ts +23 -0
  72. package/dist/admin/components/build-viewports.d.ts.map +1 -0
  73. package/dist/admin/components/build-viewports.js +23 -0
  74. package/dist/admin/components/build-viewports.js.map +1 -0
  75. package/dist/admin/components/cms-template-layout.d.ts +16 -0
  76. package/dist/admin/components/cms-template-layout.d.ts.map +1 -0
  77. package/dist/admin/components/cms-template-layout.js +53 -0
  78. package/dist/admin/components/cms-template-layout.js.map +1 -0
  79. package/dist/admin/components/page-builder-i18n.d.ts +27 -0
  80. package/dist/admin/components/page-builder-i18n.d.ts.map +1 -0
  81. package/dist/admin/components/page-builder-i18n.js +34 -0
  82. package/dist/admin/components/page-builder-i18n.js.map +1 -0
  83. package/dist/admin/components/puck-safe.d.ts +10 -0
  84. package/dist/admin/components/puck-safe.d.ts.map +1 -0
  85. package/dist/admin/components/puck-safe.js +22 -0
  86. package/dist/admin/components/puck-safe.js.map +1 -0
  87. package/dist/admin/components/scope-utils.d.ts +4 -0
  88. package/dist/admin/components/scope-utils.d.ts.map +1 -0
  89. package/dist/admin/components/scope-utils.js +7 -0
  90. package/dist/admin/components/scope-utils.js.map +1 -0
  91. package/dist/admin/editors/BlockEditor.d.ts +9 -0
  92. package/dist/admin/editors/BlockEditor.d.ts.map +1 -0
  93. package/dist/admin/editors/BlockEditor.js +217 -0
  94. package/dist/admin/editors/BlockEditor.js.map +1 -0
  95. package/dist/admin/editors/PageEditor.d.ts +9 -0
  96. package/dist/admin/editors/PageEditor.d.ts.map +1 -0
  97. package/dist/admin/editors/PageEditor.js +316 -0
  98. package/dist/admin/editors/PageEditor.js.map +1 -0
  99. package/dist/admin/editors/TemplateEditor.d.ts +9 -0
  100. package/dist/admin/editors/TemplateEditor.d.ts.map +1 -0
  101. package/dist/admin/editors/TemplateEditor.js +180 -0
  102. package/dist/admin/editors/TemplateEditor.js.map +1 -0
  103. package/dist/admin/index.d.ts +38 -0
  104. package/dist/admin/index.d.ts.map +1 -0
  105. package/dist/admin/index.js +144 -0
  106. package/dist/admin/index.js.map +1 -0
  107. package/dist/admin/pages/BlocksListPage.d.ts +9 -0
  108. package/dist/admin/pages/BlocksListPage.d.ts.map +1 -0
  109. package/dist/admin/pages/BlocksListPage.js +47 -0
  110. package/dist/admin/pages/BlocksListPage.js.map +1 -0
  111. package/dist/admin/pages/HooksPage.d.ts +9 -0
  112. package/dist/admin/pages/HooksPage.d.ts.map +1 -0
  113. package/dist/admin/pages/HooksPage.js +41 -0
  114. package/dist/admin/pages/HooksPage.js.map +1 -0
  115. package/dist/admin/pages/PagesListPage.d.ts +9 -0
  116. package/dist/admin/pages/PagesListPage.d.ts.map +1 -0
  117. package/dist/admin/pages/PagesListPage.js +51 -0
  118. package/dist/admin/pages/PagesListPage.js.map +1 -0
  119. package/dist/admin/pages/TemplatesListPage.d.ts +9 -0
  120. package/dist/admin/pages/TemplatesListPage.d.ts.map +1 -0
  121. package/dist/admin/pages/TemplatesListPage.js +47 -0
  122. package/dist/admin/pages/TemplatesListPage.js.map +1 -0
  123. package/dist/admin-ui/index.d.ts +90 -0
  124. package/dist/admin-ui/index.d.ts.map +1 -0
  125. package/dist/admin-ui/index.js +89 -0
  126. package/dist/admin-ui/index.js.map +1 -0
  127. package/dist/backend/cli/block-names.d.ts +92 -0
  128. package/dist/backend/cli/block-names.d.ts.map +1 -0
  129. package/dist/backend/cli/block-names.js +132 -0
  130. package/dist/backend/cli/block-names.js.map +1 -0
  131. package/dist/backend/entities/cms-block.entity.d.ts +20 -0
  132. package/dist/backend/entities/cms-block.entity.d.ts.map +1 -0
  133. package/dist/backend/entities/cms-block.entity.js +77 -0
  134. package/dist/backend/entities/cms-block.entity.js.map +1 -0
  135. package/dist/backend/entities/cms-hook-block-attachment.entity.d.ts +15 -0
  136. package/dist/backend/entities/cms-hook-block-attachment.entity.d.ts.map +1 -0
  137. package/dist/backend/entities/cms-hook-block-attachment.entity.js +46 -0
  138. package/dist/backend/entities/cms-hook-block-attachment.entity.js.map +1 -0
  139. package/dist/backend/entities/cms-hook.entity.d.ts +20 -0
  140. package/dist/backend/entities/cms-hook.entity.d.ts.map +1 -0
  141. package/dist/backend/entities/cms-hook.entity.js +73 -0
  142. package/dist/backend/entities/cms-hook.entity.js.map +1 -0
  143. package/dist/backend/entities/cms-page.entity.d.ts +43 -0
  144. package/dist/backend/entities/cms-page.entity.d.ts.map +1 -0
  145. package/dist/backend/entities/cms-page.entity.js +140 -0
  146. package/dist/backend/entities/cms-page.entity.js.map +1 -0
  147. package/dist/backend/entities/cms-template.entity.d.ts +20 -0
  148. package/dist/backend/entities/cms-template.entity.d.ts.map +1 -0
  149. package/dist/backend/entities/cms-template.entity.js +73 -0
  150. package/dist/backend/entities/cms-template.entity.js.map +1 -0
  151. package/dist/backend/index.d.ts +157 -0
  152. package/dist/backend/index.d.ts.map +1 -0
  153. package/dist/backend/index.js +317 -0
  154. package/dist/backend/index.js.map +1 -0
  155. package/dist/backend/plugin.d.ts +81 -0
  156. package/dist/backend/plugin.d.ts.map +1 -0
  157. package/dist/backend/plugin.js +81 -0
  158. package/dist/backend/plugin.js.map +1 -0
  159. package/dist/backend/routes.admin.d.ts +19 -0
  160. package/dist/backend/routes.admin.d.ts.map +1 -0
  161. package/dist/backend/routes.admin.js +164 -0
  162. package/dist/backend/routes.admin.js.map +1 -0
  163. package/dist/backend/routes.storefront.d.ts +6 -0
  164. package/dist/backend/routes.storefront.d.ts.map +1 -0
  165. package/dist/backend/routes.storefront.js +89 -0
  166. package/dist/backend/routes.storefront.js.map +1 -0
  167. package/dist/backend/services/asset-embed-resolver.d.ts +17 -0
  168. package/dist/backend/services/asset-embed-resolver.d.ts.map +1 -0
  169. package/dist/backend/services/asset-embed-resolver.js +40 -0
  170. package/dist/backend/services/asset-embed-resolver.js.map +1 -0
  171. package/dist/backend/services/asset-references.d.ts +4 -0
  172. package/dist/backend/services/asset-references.d.ts.map +1 -0
  173. package/dist/backend/services/asset-references.js +55 -0
  174. package/dist/backend/services/asset-references.js.map +1 -0
  175. package/dist/backend/services/cms-block-read-port.d.ts +27 -0
  176. package/dist/backend/services/cms-block-read-port.d.ts.map +1 -0
  177. package/dist/backend/services/cms-block-read-port.js +50 -0
  178. package/dist/backend/services/cms-block-read-port.js.map +1 -0
  179. package/dist/backend/services/cms-block-seed-port.d.ts +31 -0
  180. package/dist/backend/services/cms-block-seed-port.d.ts.map +1 -0
  181. package/dist/backend/services/cms-block-seed-port.js +68 -0
  182. package/dist/backend/services/cms-block-seed-port.js.map +1 -0
  183. package/dist/backend/services/cms-block-service.d.ts +38 -0
  184. package/dist/backend/services/cms-block-service.d.ts.map +1 -0
  185. package/dist/backend/services/cms-block-service.js +218 -0
  186. package/dist/backend/services/cms-block-service.js.map +1 -0
  187. package/dist/backend/services/cms-cache.d.ts +54 -0
  188. package/dist/backend/services/cms-cache.d.ts.map +1 -0
  189. package/dist/backend/services/cms-cache.js +113 -0
  190. package/dist/backend/services/cms-cache.js.map +1 -0
  191. package/dist/backend/services/cms-hook-service.d.ts +35 -0
  192. package/dist/backend/services/cms-hook-service.d.ts.map +1 -0
  193. package/dist/backend/services/cms-hook-service.js +216 -0
  194. package/dist/backend/services/cms-hook-service.js.map +1 -0
  195. package/dist/backend/services/cms-language-reference.d.ts +11 -0
  196. package/dist/backend/services/cms-language-reference.d.ts.map +1 -0
  197. package/dist/backend/services/cms-language-reference.js +26 -0
  198. package/dist/backend/services/cms-language-reference.js.map +1 -0
  199. package/dist/backend/services/cms-page-read-port.d.ts +23 -0
  200. package/dist/backend/services/cms-page-read-port.d.ts.map +1 -0
  201. package/dist/backend/services/cms-page-read-port.js +54 -0
  202. package/dist/backend/services/cms-page-read-port.js.map +1 -0
  203. package/dist/backend/services/cms-page-service.d.ts +104 -0
  204. package/dist/backend/services/cms-page-service.d.ts.map +1 -0
  205. package/dist/backend/services/cms-page-service.js +468 -0
  206. package/dist/backend/services/cms-page-service.js.map +1 -0
  207. package/dist/backend/services/cms-reference-registry.d.ts +30 -0
  208. package/dist/backend/services/cms-reference-registry.d.ts.map +1 -0
  209. package/dist/backend/services/cms-reference-registry.js +98 -0
  210. package/dist/backend/services/cms-reference-registry.js.map +1 -0
  211. package/dist/backend/services/cms-template-service.d.ts +37 -0
  212. package/dist/backend/services/cms-template-service.d.ts.map +1 -0
  213. package/dist/backend/services/cms-template-service.js +205 -0
  214. package/dist/backend/services/cms-template-service.js.map +1 -0
  215. package/dist/backend/services/content-tree-walker.d.ts +7 -0
  216. package/dist/backend/services/content-tree-walker.d.ts.map +1 -0
  217. package/dist/backend/services/content-tree-walker.js +89 -0
  218. package/dist/backend/services/content-tree-walker.js.map +1 -0
  219. package/dist/backend/services/page-builder-registry.d.ts +120 -0
  220. package/dist/backend/services/page-builder-registry.d.ts.map +1 -0
  221. package/dist/backend/services/page-builder-registry.js +220 -0
  222. package/dist/backend/services/page-builder-registry.js.map +1 -0
  223. package/dist/backend/services/seed-hooks.d.ts +22 -0
  224. package/dist/backend/services/seed-hooks.d.ts.map +1 -0
  225. package/dist/backend/services/seed-hooks.js +94 -0
  226. package/dist/backend/services/seed-hooks.js.map +1 -0
  227. package/dist/backend/services/storefront-resolver.d.ts +71 -0
  228. package/dist/backend/services/storefront-resolver.d.ts.map +1 -0
  229. package/dist/backend/services/storefront-resolver.js +329 -0
  230. package/dist/backend/services/storefront-resolver.js.map +1 -0
  231. package/dist/manifest.d.ts +225 -0
  232. package/dist/manifest.d.ts.map +1 -0
  233. package/dist/manifest.js +695 -0
  234. package/dist/manifest.js.map +1 -0
  235. package/dist/migrations/20260425T162418_cms_pages_init.d.ts +10 -0
  236. package/dist/migrations/20260425T162418_cms_pages_init.d.ts.map +1 -0
  237. package/dist/migrations/20260425T162418_cms_pages_init.js +30 -0
  238. package/dist/migrations/20260425T162418_cms_pages_init.js.map +1 -0
  239. package/dist/migrations/20260505T130214_cms_init.d.ts +28 -0
  240. package/dist/migrations/20260505T130214_cms_init.d.ts.map +1 -0
  241. package/dist/migrations/20260505T130214_cms_init.js +332 -0
  242. package/dist/migrations/20260505T130214_cms_init.js.map +1 -0
  243. package/dist/migrations/20260903T101741_cms_namespace_block_names.d.ts +6 -0
  244. package/dist/migrations/20260903T101741_cms_namespace_block_names.d.ts.map +1 -0
  245. package/dist/migrations/20260903T101741_cms_namespace_block_names.js +60 -0
  246. package/dist/migrations/20260903T101741_cms_namespace_block_names.js.map +1 -0
  247. package/dist/migrations/20260912T094733_cms_sales_channel_cms_pages.d.ts +27 -0
  248. package/dist/migrations/20260912T094733_cms_sales_channel_cms_pages.d.ts.map +1 -0
  249. package/dist/migrations/20260912T094733_cms_sales_channel_cms_pages.js +44 -0
  250. package/dist/migrations/20260912T094733_cms_sales_channel_cms_pages.js.map +1 -0
  251. package/dist/migrations/20260912T125709_cms_page_body_asset_ref_index.d.ts +32 -0
  252. package/dist/migrations/20260912T125709_cms_page_body_asset_ref_index.d.ts.map +1 -0
  253. package/dist/migrations/20260912T125709_cms_page_body_asset_ref_index.js +36 -0
  254. package/dist/migrations/20260912T125709_cms_page_body_asset_ref_index.js.map +1 -0
  255. package/dist/migrations/index.d.ts +31 -0
  256. package/dist/migrations/index.d.ts.map +1 -0
  257. package/dist/migrations/index.js +37 -0
  258. package/dist/migrations/index.js.map +1 -0
  259. package/docs/cms/extending-page-builder.md +256 -0
  260. package/docs/cms/index.md +233 -0
  261. package/i18n/en.json +231 -0
  262. package/i18n/pl.json +231 -0
  263. package/package.json +125 -3
  264. package/tailwind.css +16 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cms-block-seed-port.js","sourceRoot":"","sources":["../../../src/backend/services/cms-block-seed-port.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAGzC,OAAO,EAAE,YAAY,EAAE,MAAM,kCAAkC,CAAC;AAEhE;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,MAAM,OAAO,mBAAmB;IACD;IAA7B,YAA6B,SAA8B;QAA9B,cAAS,GAAT,SAAS,CAAqB;IAAG,CAAC;IAE/D,KAAK,CAAC,iBAAiB,CAAC,KAAqB;QAC3C,MAAM,EAAE,GAAG,IAAI,CAAC,SAAS,EAAE,CAAC;QAE5B,MAAM,EAAE,CAAC,OAAO,CACd;;kEAE4D,EAC5D;YACE,UAAU,EAAE;YACZ,KAAK,CAAC,IAAI;YACV,KAAK,CAAC,IAAI;YACV,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,OAAO,CAAC;YAC7B,IAAI,CAAC,SAAS,CAAC,CAAC,GAAG,KAAK,CAAC,SAAS,CAAC,CAAC;YACpC,KAAK,CAAC,IAAI;SACX,CACF,CAAC;QAEF,MAAM,IAAI,GAAG,CAAC,MAAM,EAAE,CAAC,OAAO,CAAC,kDAAkD,EAAE;YACjF,KAAK,CAAC,IAAI;SACX,CAAC,CAA0B,CAAC;QAC7B,MAAM,OAAO,GAAG,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;QAC5B,IAAI,OAAO,KAAK,SAAS;YAAE,OAAO;QAElC;;;;;;;WAOG;QACH,MAAM,UAAU,GAAG,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,YAAY,EAAE,EAAE,EAAE,EAAE,MAAM,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QAC1F,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO;QACpC,MAAM,aAAa,GAAG,UAAU,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAEnE,MAAM,EAAE,CAAC,OAAO,CACd;yCACmC,aAAa;;;SAG7C,EACH,CAAC,OAAO,EAAE,KAAK,CAAC,IAAI,EAAE,GAAG,UAAU,EAAE,KAAK,CAAC,IAAI,CAAC,CACjD,CAAC;IACJ,CAAC;CACF"}
@@ -0,0 +1,38 @@
1
+ import type { EntityManager } from '@mikro-orm/postgresql';
2
+ import { type CmsBlockDetail, type CmsBlockSummary, type CreateCmsBlockRequest, type PatchCmsBlockRequest } from '@endora-commerce/contracts';
3
+ import type { CmsReferenceRegistry } from './cms-reference-registry.js';
4
+ import type { CmsCache } from './cms-cache.js';
5
+ export declare class CmsBlockService {
6
+ private readonly emFactory;
7
+ private readonly knownComponentNames;
8
+ private readonly references;
9
+ private readonly cache?;
10
+ constructor(emFactory: () => EntityManager, knownComponentNames: () => Iterable<string>, references: CmsReferenceRegistry, cache?: CmsCache | undefined);
11
+ /**
12
+ * Invalidates the block's own cache entries plus the page-level
13
+ * namespace, since we don't track which pages embed which block. The
14
+ * page invalidation is coarse but safe: at platform scale (low
15
+ * hundreds of pages) the next request rebuilds the cache trivially.
16
+ */
17
+ private invalidateForBlockCode;
18
+ list(filters?: {
19
+ salesChannelId?: string;
20
+ }): Promise<{
21
+ data: CmsBlockSummary[];
22
+ nextCursor: null;
23
+ }>;
24
+ create(input: CreateCmsBlockRequest): Promise<CmsBlockDetail>;
25
+ get(id: string): Promise<CmsBlockDetail>;
26
+ patch(id: string, input: PatchCmsBlockRequest): Promise<CmsBlockDetail>;
27
+ setContent(id: string, language: string, data: unknown, version: number): Promise<CmsBlockDetail>;
28
+ delete(id: string): Promise<void>;
29
+ private findRow;
30
+ private assertCodeAvailable;
31
+ private replaceChannelScope;
32
+ private channelIdsFor;
33
+ private assertVersion;
34
+ private toSummary;
35
+ private toDetail;
36
+ private iso;
37
+ }
38
+ //# sourceMappingURL=cms-block-service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cms-block-service.d.ts","sourceRoot":"","sources":["../../../src/backend/services/cms-block-service.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,EAEL,KAAK,cAAc,EACnB,KAAK,eAAe,EACpB,KAAK,qBAAqB,EAC1B,KAAK,oBAAoB,EAC1B,MAAM,4BAA4B,CAAC;AAGpC,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;AACxE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAiB/C,qBAAa,eAAe;IAExB,OAAO,CAAC,QAAQ,CAAC,SAAS;IAC1B,OAAO,CAAC,QAAQ,CAAC,mBAAmB;IACpC,OAAO,CAAC,QAAQ,CAAC,UAAU;IAC3B,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC;gBAHN,SAAS,EAAE,MAAM,aAAa,EAC9B,mBAAmB,EAAE,MAAM,QAAQ,CAAC,MAAM,CAAC,EAC3C,UAAU,EAAE,oBAAoB,EAChC,KAAK,CAAC,EAAE,QAAQ,YAAA;IAGnC;;;;;OAKG;YACW,sBAAsB;IAM9B,IAAI,CAAC,OAAO,GAAE;QAAE,cAAc,CAAC,EAAE,MAAM,CAAA;KAAO,GAAG,OAAO,CAAC;QAC7D,IAAI,EAAE,eAAe,EAAE,CAAC;QACxB,UAAU,EAAE,IAAI,CAAC;KAClB,CAAC;IAwBI,MAAM,CAAC,KAAK,EAAE,qBAAqB,GAAG,OAAO,CAAC,cAAc,CAAC;IA4B7D,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC;IAMxC,KAAK,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,oBAAoB,GAAG,OAAO,CAAC,cAAc,CAAC;IA6CvE,UAAU,CAAC,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC;IA8BjG,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;YAWzB,OAAO;YAOP,mBAAmB;YAoBnB,mBAAmB;YAkBnB,aAAa;IAQ3B,OAAO,CAAC,aAAa;YAMP,SAAS;YAeT,QAAQ;IAStB,OAAO,CAAC,GAAG;CAGZ"}
@@ -0,0 +1,218 @@
1
+ import { randomUUID } from 'crypto';
2
+ import { ERROR_CODES, } from '@endora-commerce/contracts';
3
+ import { HttpError } from '@endora-commerce/platform/http';
4
+ import { walkUnknownComponents } from './content-tree-walker.js';
5
+ const emptyContent = { languages: {} };
6
+ export class CmsBlockService {
7
+ emFactory;
8
+ knownComponentNames;
9
+ references;
10
+ cache;
11
+ constructor(emFactory, knownComponentNames, references, cache) {
12
+ this.emFactory = emFactory;
13
+ this.knownComponentNames = knownComponentNames;
14
+ this.references = references;
15
+ this.cache = cache;
16
+ }
17
+ /**
18
+ * Invalidates the block's own cache entries plus the page-level
19
+ * namespace, since we don't track which pages embed which block. The
20
+ * page invalidation is coarse but safe: at platform scale (low
21
+ * hundreds of pages) the next request rebuilds the cache trivially.
22
+ */
23
+ async invalidateForBlockCode(code) {
24
+ if (!this.cache)
25
+ return;
26
+ await this.cache.invalidateBlocksByCode([code]);
27
+ await this.cache.invalidateAllPages();
28
+ }
29
+ async list(filters = {}) {
30
+ const params = [];
31
+ const where = [];
32
+ if (filters.salesChannelId) {
33
+ params.push(filters.salesChannelId);
34
+ where.push(`exists (
35
+ select 1 from cms_block_sales_channels cbsc
36
+ where cbsc.block_id = b.id and cbsc.sales_channel_id = ?
37
+ )`);
38
+ }
39
+ const rows = (await this.emFactory().execute(`select b.* from cms_blocks b
40
+ ${where.length > 0 ? `where ${where.join(' and ')}` : ''}
41
+ order by b.updated_at desc
42
+ limit 50`, params));
43
+ return { data: await Promise.all(rows.map((row) => this.toSummary(row))), nextCursor: null };
44
+ }
45
+ async create(input) {
46
+ const em = this.emFactory();
47
+ const id = randomUUID();
48
+ const now = new Date();
49
+ await em.transactional(async (tx) => {
50
+ await this.assertCodeAvailable(tx, input.code, input.salesChannelIds);
51
+ await tx.execute(`insert into cms_blocks
52
+ (id, name, code, active, description, content, languages, version, created_at, updated_at)
53
+ values (?, ?, ?, ?, ?, ?::jsonb, ?::jsonb, 1, ?, ?)`, [
54
+ id,
55
+ input.name,
56
+ input.code,
57
+ input.active ?? true,
58
+ input.description ?? null,
59
+ JSON.stringify(emptyContent),
60
+ JSON.stringify(input.languages),
61
+ now,
62
+ now,
63
+ ]);
64
+ await this.replaceChannelScope(tx, id, input.salesChannelIds, input.code);
65
+ });
66
+ await this.invalidateForBlockCode(input.code);
67
+ return this.get(id);
68
+ }
69
+ async get(id) {
70
+ const row = await this.findRow(id);
71
+ if (!row)
72
+ throw new HttpError(404, ERROR_CODES.CMS_BLOCK_NOT_FOUND, 'CMS Block not found.');
73
+ return this.toDetail(row);
74
+ }
75
+ async patch(id, input) {
76
+ const em = this.emFactory();
77
+ const codesToInvalidate = new Set();
78
+ await em.transactional(async (tx) => {
79
+ const row = await this.findRow(id, tx);
80
+ if (!row)
81
+ throw new HttpError(404, ERROR_CODES.CMS_BLOCK_NOT_FOUND, 'CMS Block not found.');
82
+ this.assertVersion(row, input.version);
83
+ codesToInvalidate.add(row.code);
84
+ const nextCode = input.code ?? row.code;
85
+ const nextChannels = input.salesChannelIds ?? (await this.channelIdsFor(id, tx));
86
+ if (input.code || input.salesChannelIds) {
87
+ await this.assertCodeAvailable(tx, nextCode, nextChannels, id);
88
+ }
89
+ const sets = [];
90
+ const params = [];
91
+ const set = (sql, value) => {
92
+ sets.push(sql);
93
+ params.push(value);
94
+ };
95
+ if (input.name !== undefined)
96
+ set('name = ?', input.name);
97
+ if (input.code !== undefined)
98
+ set('code = ?', input.code);
99
+ if (input.active !== undefined)
100
+ set('active = ?', input.active);
101
+ if (input.description !== undefined)
102
+ set('description = ?', input.description);
103
+ if (input.languages !== undefined)
104
+ set('languages = ?::jsonb', JSON.stringify(input.languages));
105
+ if (sets.length > 0) {
106
+ params.push(id);
107
+ await tx.execute(`update cms_blocks
108
+ set ${sets.join(', ')}, version = version + 1, updated_at = now()
109
+ where id = ?`, params);
110
+ }
111
+ if (input.salesChannelIds || input.code) {
112
+ await this.replaceChannelScope(tx, id, nextChannels, nextCode);
113
+ }
114
+ codesToInvalidate.add(nextCode);
115
+ });
116
+ for (const code of codesToInvalidate)
117
+ await this.invalidateForBlockCode(code);
118
+ return this.get(id);
119
+ }
120
+ async setContent(id, language, data, version) {
121
+ const em = this.emFactory();
122
+ let invalidatedCode = null;
123
+ await em.transactional(async (tx) => {
124
+ const row = await this.findRow(id, tx);
125
+ if (!row)
126
+ throw new HttpError(404, ERROR_CODES.CMS_BLOCK_NOT_FOUND, 'CMS Block not found.');
127
+ this.assertVersion(row, version);
128
+ invalidatedCode = row.code;
129
+ const unknown = walkUnknownComponents(data, new Set(this.knownComponentNames()));
130
+ if (unknown.size > 0) {
131
+ console.warn(`CMS block ${id} saved with unknown components: ${Array.from(unknown).join(', ')}`);
132
+ }
133
+ const content = {
134
+ languages: { ...(row.content.languages ?? {}), [language]: data },
135
+ };
136
+ const languages = row.languages.includes(language) ? row.languages : [...row.languages, language];
137
+ await tx.execute(`update cms_blocks
138
+ set content = ?::jsonb, languages = ?::jsonb, version = version + 1, updated_at = now()
139
+ where id = ?`, [JSON.stringify(content), JSON.stringify(languages), id]);
140
+ });
141
+ if (invalidatedCode)
142
+ await this.invalidateForBlockCode(invalidatedCode);
143
+ return this.get(id);
144
+ }
145
+ async delete(id) {
146
+ const row = await this.findRow(id);
147
+ if (!row)
148
+ throw new HttpError(404, ERROR_CODES.CMS_BLOCK_NOT_FOUND, 'CMS Block not found.');
149
+ const refs = await this.references.findBlockReferences(row.id, row.code);
150
+ if (refs.length > 0) {
151
+ throw new HttpError(409, ERROR_CODES.CMS_REFERENCED, 'CMS Block is referenced.');
152
+ }
153
+ await this.emFactory().execute('delete from cms_blocks where id = ?', [id]);
154
+ await this.invalidateForBlockCode(row.code);
155
+ }
156
+ async findRow(id, em = this.emFactory()) {
157
+ const rows = (await em.execute('select * from cms_blocks where id = ?', [
158
+ id,
159
+ ]));
160
+ return rows[0] ?? null;
161
+ }
162
+ async assertCodeAvailable(em, code, salesChannelIds, exceptBlockId) {
163
+ if (salesChannelIds.length === 0)
164
+ return;
165
+ const placeholders = salesChannelIds.map(() => '?').join(', ');
166
+ const rows = (await em.execute(`select block_id from cms_block_sales_channels
167
+ where code = ? and sales_channel_id in (${placeholders})
168
+ ${exceptBlockId ? 'and block_id <> ?' : ''}
169
+ limit 1`, exceptBlockId ? [code, ...salesChannelIds, exceptBlockId] : [code, ...salesChannelIds]));
170
+ if (rows.length > 0) {
171
+ throw new HttpError(409, ERROR_CODES.CMS_CODE_CONFLICT, 'CMS Block code already exists.');
172
+ }
173
+ }
174
+ async replaceChannelScope(em, blockId, salesChannelIds, code) {
175
+ await em.execute('delete from cms_block_sales_channels where block_id = ?', [
176
+ blockId,
177
+ ]);
178
+ for (const salesChannelId of salesChannelIds) {
179
+ await em.execute(`insert into cms_block_sales_channels (block_id, sales_channel_id, code)
180
+ values (?, ?, ?)`, [blockId, salesChannelId, code]);
181
+ }
182
+ }
183
+ async channelIdsFor(blockId, em = this.emFactory()) {
184
+ const rows = (await em.execute('select sales_channel_id::text as id from cms_block_sales_channels where block_id = ?', [blockId]));
185
+ return rows.map((row) => row.id);
186
+ }
187
+ assertVersion(row, version) {
188
+ if (version !== undefined && version !== row.version) {
189
+ throw new HttpError(409, ERROR_CODES.VERSION_CONFLICT, 'CMS Block was updated concurrently.');
190
+ }
191
+ }
192
+ async toSummary(row) {
193
+ return {
194
+ id: row.id,
195
+ name: row.name,
196
+ code: row.code,
197
+ active: row.active,
198
+ description: row.description,
199
+ salesChannelIds: await this.channelIdsFor(row.id),
200
+ languages: row.languages,
201
+ version: row.version,
202
+ createdAt: this.iso(row.created_at),
203
+ updatedAt: this.iso(row.updated_at),
204
+ };
205
+ }
206
+ async toDetail(row) {
207
+ return {
208
+ ...(await this.toSummary(row)),
209
+ content: {
210
+ languages: row.content.languages ?? {},
211
+ },
212
+ };
213
+ }
214
+ iso(value) {
215
+ return value instanceof Date ? value.toISOString() : new Date(value).toISOString();
216
+ }
217
+ }
218
+ //# sourceMappingURL=cms-block-service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cms-block-service.js","sourceRoot":"","sources":["../../../src/backend/services/cms-block-service.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,54 @@
1
+ import type { Redis } from 'ioredis';
2
+ import type { CmsResolvedBlock, CmsResolvedHook, CmsResolvedPage } from '@endora-commerce/contracts';
3
+ /**
4
+ * Storefront read-through cache for the CMS module — feature 014 / T094 (R10).
5
+ *
6
+ * Caches the resolved payloads from `StorefrontResolver` under three key
7
+ * families:
8
+ *
9
+ * - `cms:v1:page:<slug>:<channel>:<language>` → CmsResolvedPage
10
+ * - `cms:v1:block:<code>:<channel>:<language>` → CmsResolvedBlock
11
+ * - `cms:v1:hook:<code>:<channel>:<language>` → CmsResolvedHook
12
+ *
13
+ * TTL is fixed at 5 minutes; invalidation runs on every Page / Block /
14
+ * Template / Hook write and on hook-attachment changes. Tests can pass a
15
+ * custom `ttlSeconds` (or `0` to disable).
16
+ */
17
+ export declare const CMS_CACHE_KEY_PREFIX = "cms:v1:";
18
+ export declare const CMS_CACHE_DEFAULT_TTL_SECONDS: number;
19
+ export interface CmsCacheOptions {
20
+ ttlSeconds?: number;
21
+ /** When false, get/set are short-circuit no-ops (useful for tests). */
22
+ enabled?: boolean;
23
+ }
24
+ export declare class CmsCache {
25
+ private readonly redis;
26
+ private readonly ttlSeconds;
27
+ private readonly enabled;
28
+ constructor(redis: Redis, options?: CmsCacheOptions);
29
+ static pageKey(slug: string, channel: string, language: string): string;
30
+ static blockKey(code: string, channel: string, language: string): string;
31
+ static hookKey(code: string, channel: string, language: string): string;
32
+ getPage(slug: string, channel: string, language: string): Promise<CmsResolvedPage | null>;
33
+ setPage(slug: string, channel: string, language: string, value: CmsResolvedPage): Promise<void>;
34
+ getBlock(code: string, channel: string, language: string): Promise<CmsResolvedBlock | null>;
35
+ setBlock(code: string, channel: string, language: string, value: CmsResolvedBlock): Promise<void>;
36
+ getHook(code: string, channel: string, language: string): Promise<CmsResolvedHook | null>;
37
+ setHook(code: string, channel: string, language: string, value: CmsResolvedHook): Promise<void>;
38
+ /** Drop every page-keyed entry for a given slug across every channel/language. */
39
+ invalidatePagesBySlug(slugs: Iterable<string>): Promise<void>;
40
+ invalidateBlocksByCode(codes: Iterable<string>): Promise<void>;
41
+ invalidateHooksByCode(codes: Iterable<string>): Promise<void>;
42
+ /**
43
+ * Drop every cached page in the namespace. Used when a Block / Template
44
+ * change ripples through pages that embed it; we don't track inverse
45
+ * indices yet, so a coarse drop is acceptable at platform scale.
46
+ */
47
+ invalidateAllPages(): Promise<void>;
48
+ /** Used in tests + as a sweep on full cache reset. */
49
+ invalidateAll(): Promise<void>;
50
+ private read;
51
+ private write;
52
+ private scanDelete;
53
+ }
54
+ //# sourceMappingURL=cms-cache.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cms-cache.d.ts","sourceRoot":"","sources":["../../../src/backend/services/cms-cache.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,KAAK,EACV,gBAAgB,EAChB,eAAe,EACf,eAAe,EAChB,MAAM,4BAA4B,CAAC;AAEpC;;;;;;;;;;;;;GAaG;AAEH,eAAO,MAAM,oBAAoB,YAAY,CAAC;AAC9C,eAAO,MAAM,6BAA6B,QAAS,CAAC;AAEpD,MAAM,WAAW,eAAe;IAC9B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,uEAAuE;IACvE,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,qBAAa,QAAQ;IAIP,OAAO,CAAC,QAAQ,CAAC,KAAK;IAHlC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IACpC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAU;gBAEL,KAAK,EAAE,KAAK,EAAE,OAAO,GAAE,eAAoB;IAKxE,MAAM,CAAC,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM;IAIvE,MAAM,CAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM;IAIxE,MAAM,CAAC,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM;IAIjE,OAAO,CACX,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC;IAI5B,OAAO,CACX,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,eAAe,GACrB,OAAO,CAAC,IAAI,CAAC;IAIV,QAAQ,CACZ,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC;IAI7B,QAAQ,CACZ,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,gBAAgB,GACtB,OAAO,CAAC,IAAI,CAAC;IAIV,OAAO,CACX,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC;IAI5B,OAAO,CACX,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,eAAe,GACrB,OAAO,CAAC,IAAI,CAAC;IAIhB,kFAAkF;IAC5E,qBAAqB,CAAC,KAAK,EAAE,QAAQ,CAAC,MAAM,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAO7D,sBAAsB,CAAC,KAAK,EAAE,QAAQ,CAAC,MAAM,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAO9D,qBAAqB,CAAC,KAAK,EAAE,QAAQ,CAAC,MAAM,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAOnE;;;;OAIG;IACG,kBAAkB,IAAI,OAAO,CAAC,IAAI,CAAC;IAIzC,sDAAsD;IAChD,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC;YAItB,IAAI;YAaJ,KAAK;YAKL,UAAU;CAmBzB"}
@@ -0,0 +1,113 @@
1
+ /**
2
+ * Storefront read-through cache for the CMS module — feature 014 / T094 (R10).
3
+ *
4
+ * Caches the resolved payloads from `StorefrontResolver` under three key
5
+ * families:
6
+ *
7
+ * - `cms:v1:page:<slug>:<channel>:<language>` → CmsResolvedPage
8
+ * - `cms:v1:block:<code>:<channel>:<language>` → CmsResolvedBlock
9
+ * - `cms:v1:hook:<code>:<channel>:<language>` → CmsResolvedHook
10
+ *
11
+ * TTL is fixed at 5 minutes; invalidation runs on every Page / Block /
12
+ * Template / Hook write and on hook-attachment changes. Tests can pass a
13
+ * custom `ttlSeconds` (or `0` to disable).
14
+ */
15
+ export const CMS_CACHE_KEY_PREFIX = 'cms:v1:';
16
+ export const CMS_CACHE_DEFAULT_TTL_SECONDS = 5 * 60;
17
+ export class CmsCache {
18
+ redis;
19
+ ttlSeconds;
20
+ enabled;
21
+ constructor(redis, options = {}) {
22
+ this.redis = redis;
23
+ this.ttlSeconds = options.ttlSeconds ?? CMS_CACHE_DEFAULT_TTL_SECONDS;
24
+ this.enabled = (options.enabled ?? true) && this.ttlSeconds > 0;
25
+ }
26
+ static pageKey(slug, channel, language) {
27
+ return `${CMS_CACHE_KEY_PREFIX}page:${encodeURIComponent(slug)}:${channel}:${language}`;
28
+ }
29
+ static blockKey(code, channel, language) {
30
+ return `${CMS_CACHE_KEY_PREFIX}block:${encodeURIComponent(code)}:${channel}:${language}`;
31
+ }
32
+ static hookKey(code, channel, language) {
33
+ return `${CMS_CACHE_KEY_PREFIX}hook:${encodeURIComponent(code)}:${channel}:${language}`;
34
+ }
35
+ async getPage(slug, channel, language) {
36
+ return this.read(CmsCache.pageKey(slug, channel, language));
37
+ }
38
+ async setPage(slug, channel, language, value) {
39
+ await this.write(CmsCache.pageKey(slug, channel, language), value);
40
+ }
41
+ async getBlock(code, channel, language) {
42
+ return this.read(CmsCache.blockKey(code, channel, language));
43
+ }
44
+ async setBlock(code, channel, language, value) {
45
+ await this.write(CmsCache.blockKey(code, channel, language), value);
46
+ }
47
+ async getHook(code, channel, language) {
48
+ return this.read(CmsCache.hookKey(code, channel, language));
49
+ }
50
+ async setHook(code, channel, language, value) {
51
+ await this.write(CmsCache.hookKey(code, channel, language), value);
52
+ }
53
+ /** Drop every page-keyed entry for a given slug across every channel/language. */
54
+ async invalidatePagesBySlug(slugs) {
55
+ const patterns = Array.from(slugs).map((slug) => `${CMS_CACHE_KEY_PREFIX}page:${encodeURIComponent(slug)}:*`);
56
+ await this.scanDelete(patterns);
57
+ }
58
+ async invalidateBlocksByCode(codes) {
59
+ const patterns = Array.from(codes).map((code) => `${CMS_CACHE_KEY_PREFIX}block:${encodeURIComponent(code)}:*`);
60
+ await this.scanDelete(patterns);
61
+ }
62
+ async invalidateHooksByCode(codes) {
63
+ const patterns = Array.from(codes).map((code) => `${CMS_CACHE_KEY_PREFIX}hook:${encodeURIComponent(code)}:*`);
64
+ await this.scanDelete(patterns);
65
+ }
66
+ /**
67
+ * Drop every cached page in the namespace. Used when a Block / Template
68
+ * change ripples through pages that embed it; we don't track inverse
69
+ * indices yet, so a coarse drop is acceptable at platform scale.
70
+ */
71
+ async invalidateAllPages() {
72
+ await this.scanDelete([`${CMS_CACHE_KEY_PREFIX}page:*`]);
73
+ }
74
+ /** Used in tests + as a sweep on full cache reset. */
75
+ async invalidateAll() {
76
+ await this.scanDelete([`${CMS_CACHE_KEY_PREFIX}*`]);
77
+ }
78
+ async read(key) {
79
+ if (!this.enabled)
80
+ return null;
81
+ const raw = await this.redis.get(key);
82
+ if (raw === null)
83
+ return null;
84
+ try {
85
+ return JSON.parse(raw);
86
+ }
87
+ catch {
88
+ // A stray non-JSON value never came from us — drop it and miss.
89
+ await this.redis.del(key);
90
+ return null;
91
+ }
92
+ }
93
+ async write(key, value) {
94
+ if (!this.enabled)
95
+ return;
96
+ await this.redis.set(key, JSON.stringify(value), 'EX', this.ttlSeconds);
97
+ }
98
+ async scanDelete(patterns) {
99
+ if (!this.enabled || patterns.length === 0)
100
+ return;
101
+ for (const pattern of patterns) {
102
+ let cursor = '0';
103
+ do {
104
+ const [next, keys] = await this.redis.scan(cursor, 'MATCH', pattern, 'COUNT', 200);
105
+ cursor = next;
106
+ if (keys.length > 0) {
107
+ await this.redis.del(...keys);
108
+ }
109
+ } while (cursor !== '0');
110
+ }
111
+ }
112
+ }
113
+ //# sourceMappingURL=cms-cache.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cms-cache.js","sourceRoot":"","sources":["../../../src/backend/services/cms-cache.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,35 @@
1
+ import type { EntityManager } from '@mikro-orm/postgresql';
2
+ import { type CmsHookDetail, type CmsHookSummary, type CreateCmsHookRequest, type PatchCmsHookRequest } from '@endora-commerce/contracts';
3
+ import type { CmsCache } from './cms-cache.js';
4
+ export declare class CmsHookService {
5
+ private readonly emFactory;
6
+ private readonly cache?;
7
+ constructor(emFactory: () => EntityManager, cache?: CmsCache | undefined);
8
+ private invalidateForHookId;
9
+ list(filters?: {
10
+ salesChannelId?: string;
11
+ }): Promise<{
12
+ data: CmsHookSummary[];
13
+ nextCursor: null;
14
+ }>;
15
+ create(input: CreateCmsHookRequest): Promise<CmsHookDetail>;
16
+ get(id: string): Promise<CmsHookDetail>;
17
+ patch(id: string, input: PatchCmsHookRequest): Promise<CmsHookDetail>;
18
+ delete(id: string): Promise<void>;
19
+ listAttachments(hookId: string): Promise<CmsHookDetail['attachments']>;
20
+ addAttachment(hookId: string, blockId: string, position: number): Promise<CmsHookDetail['attachments']>;
21
+ reorderAttachment(hookId: string, blockId: string, position: number): Promise<CmsHookDetail['attachments']>;
22
+ removeAttachment(hookId: string, blockId: string): Promise<void>;
23
+ private findRow;
24
+ private assertExists;
25
+ private assertBlockExists;
26
+ private assertCodeAvailable;
27
+ private replaceChannelScope;
28
+ private channelIdsFor;
29
+ private attachmentsFor;
30
+ private assertVersion;
31
+ private toSummary;
32
+ private toDetail;
33
+ private iso;
34
+ }
35
+ //# sourceMappingURL=cms-hook-service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cms-hook-service.d.ts","sourceRoot":"","sources":["../../../src/backend/services/cms-hook-service.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,EAEL,KAAK,aAAa,EAClB,KAAK,cAAc,EACnB,KAAK,oBAAoB,EACzB,KAAK,mBAAmB,EACzB,MAAM,4BAA4B,CAAC;AAEpC,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAqB/C,qBAAa,cAAc;IAEvB,OAAO,CAAC,QAAQ,CAAC,SAAS;IAC1B,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC;gBADN,SAAS,EAAE,MAAM,aAAa,EAC9B,KAAK,CAAC,EAAE,QAAQ,YAAA;YAGrB,mBAAmB;IAU3B,IAAI,CAAC,OAAO,GAAE;QAAE,cAAc,CAAC,EAAE,MAAM,CAAA;KAAO,GAAG,OAAO,CAAC;QAC7D,IAAI,EAAE,cAAc,EAAE,CAAC;QACvB,UAAU,EAAE,IAAI,CAAC;KAClB,CAAC;IAyBI,MAAM,CAAC,KAAK,EAAE,oBAAoB,GAAG,OAAO,CAAC,aAAa,CAAC;IAkB3D,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC;IAMvC,KAAK,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,mBAAmB,GAAG,OAAO,CAAC,aAAa,CAAC;IAsCrE,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAcjC,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC,aAAa,CAAC,CAAC;IAKtE,aAAa,CACjB,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,aAAa,CAAC,aAAa,CAAC,CAAC;IAelC,iBAAiB,CACrB,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,aAAa,CAAC,aAAa,CAAC,CAAC;IAkBlC,gBAAgB,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;YASxD,OAAO;YAYP,YAAY;YAKZ,iBAAiB;YAUjB,mBAAmB;YAUnB,mBAAmB;YAiBnB,aAAa;YAQb,cAAc;IAgB5B,OAAO,CAAC,aAAa;YAMP,SAAS;YAgBT,QAAQ;IAOtB,OAAO,CAAC,GAAG;CAGZ"}