@jhits/plugin-blog 0.0.18 → 0.0.20

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 (291) hide show
  1. package/dist/api/categories.d.ts.map +1 -1
  2. package/dist/api/categories.js +42 -38
  3. package/dist/api/handler.d.ts +1 -26
  4. package/dist/api/handler.d.ts.map +1 -1
  5. package/dist/api/handler.js +81 -500
  6. package/dist/api/router.d.ts +0 -5
  7. package/dist/api/router.d.ts.map +1 -1
  8. package/dist/api/router.js +8 -35
  9. package/dist/api/service.d.ts +80 -0
  10. package/dist/api/service.d.ts.map +1 -0
  11. package/dist/api/service.js +219 -0
  12. package/dist/hooks/useAutoSave.d.ts +10 -0
  13. package/dist/hooks/useAutoSave.d.ts.map +1 -0
  14. package/dist/hooks/useAutoSave.js +57 -0
  15. package/dist/hooks/useCategories.d.ts +1 -1
  16. package/dist/hooks/useCategories.d.ts.map +1 -1
  17. package/dist/hooks/useCategories.js +15 -46
  18. package/dist/index.d.ts +24 -31
  19. package/dist/index.d.ts.map +1 -1
  20. package/dist/index.js +44 -201
  21. package/dist/init.d.ts +20 -7
  22. package/dist/init.d.ts.map +1 -1
  23. package/dist/init.js +8 -7
  24. package/dist/lib/blocks/BlockRenderer.d.ts.map +1 -1
  25. package/dist/lib/layouts/blocks/ColumnsBlock.d.ts.map +1 -1
  26. package/dist/lib/layouts/blocks/ColumnsBlock.js +30 -113
  27. package/dist/lib/layouts/blocks/SectionBlock.d.ts.map +1 -1
  28. package/dist/lib/layouts/blocks/SectionBlock.js +9 -21
  29. package/dist/lib/layouts/index.d.ts +3 -3
  30. package/dist/lib/layouts/index.js +4 -4
  31. package/dist/lib/mappers/apiMapper.d.ts +10 -0
  32. package/dist/lib/mappers/apiMapper.d.ts.map +1 -1
  33. package/dist/lib/mappers/apiMapper.js +47 -32
  34. package/dist/lib/rich-text/RichTextEditor.d.ts +4 -2
  35. package/dist/lib/rich-text/RichTextEditor.d.ts.map +1 -1
  36. package/dist/lib/rich-text/RichTextEditor.js +12 -9
  37. package/dist/lib/utils/config-resolver.d.ts +28 -0
  38. package/dist/lib/utils/config-resolver.d.ts.map +1 -0
  39. package/dist/lib/utils/config-resolver.js +46 -0
  40. package/dist/lib/utils/tree.d.ts +29 -0
  41. package/dist/lib/utils/tree.d.ts.map +1 -0
  42. package/dist/lib/utils/tree.js +129 -0
  43. package/dist/state/EditorContext.d.ts +3 -25
  44. package/dist/state/EditorContext.d.ts.map +1 -1
  45. package/dist/state/EditorContext.js +124 -174
  46. package/dist/state/reducer.d.ts +1 -5
  47. package/dist/state/reducer.d.ts.map +1 -1
  48. package/dist/state/reducer.js +128 -521
  49. package/dist/state/types.d.ts +12 -1
  50. package/dist/state/types.d.ts.map +1 -1
  51. package/dist/types/block.d.ts +9 -0
  52. package/dist/types/block.d.ts.map +1 -1
  53. package/dist/types/post.d.ts +17 -1
  54. package/dist/types/post.d.ts.map +1 -1
  55. package/dist/views/CanvasEditor/BlockWrapper.d.ts +5 -6
  56. package/dist/views/CanvasEditor/BlockWrapper.d.ts.map +1 -1
  57. package/dist/views/CanvasEditor/BlockWrapper.js +56 -264
  58. package/dist/views/CanvasEditor/CanvasEditorView.d.ts +5 -3
  59. package/dist/views/CanvasEditor/CanvasEditorView.d.ts.map +1 -1
  60. package/dist/views/CanvasEditor/CanvasEditorView.js +55 -315
  61. package/dist/views/CanvasEditor/EditorBody.d.ts +6 -8
  62. package/dist/views/CanvasEditor/EditorBody.d.ts.map +1 -1
  63. package/dist/views/CanvasEditor/EditorBody.js +34 -482
  64. package/dist/views/CanvasEditor/EditorHeader.d.ts.map +1 -1
  65. package/dist/views/CanvasEditor/EditorHeader.js +27 -63
  66. package/dist/views/CanvasEditor/LayoutContainer.d.ts.map +1 -1
  67. package/dist/views/CanvasEditor/LayoutContainer.js +49 -70
  68. package/dist/views/CanvasEditor/components/CustomBlockItem.js +1 -1
  69. package/dist/views/CanvasEditor/components/EditorCanvas.d.ts +15 -3
  70. package/dist/views/CanvasEditor/components/EditorCanvas.d.ts.map +1 -1
  71. package/dist/views/CanvasEditor/components/EditorCanvas.js +40 -18
  72. package/dist/views/CanvasEditor/components/EditorLibrary.d.ts +5 -1
  73. package/dist/views/CanvasEditor/components/EditorLibrary.d.ts.map +1 -1
  74. package/dist/views/CanvasEditor/components/EditorLibrary.js +11 -7
  75. package/dist/views/CanvasEditor/components/EditorSidebar.d.ts.map +1 -1
  76. package/dist/views/CanvasEditor/components/EditorSidebar.js +32 -14
  77. package/dist/views/CanvasEditor/components/FeaturedMediaSection.d.ts +0 -6
  78. package/dist/views/CanvasEditor/components/FeaturedMediaSection.d.ts.map +1 -1
  79. package/dist/views/CanvasEditor/components/FeaturedMediaSection.js +17 -128
  80. package/dist/views/CanvasEditor/components/JSONInspector.d.ts +9 -0
  81. package/dist/views/CanvasEditor/components/JSONInspector.d.ts.map +1 -0
  82. package/dist/views/CanvasEditor/components/JSONInspector.js +56 -0
  83. package/dist/views/CanvasEditor/components/LibraryItem.js +2 -2
  84. package/dist/views/CanvasEditor/components/PrivacySettingsSection.d.ts +0 -4
  85. package/dist/views/CanvasEditor/components/PrivacySettingsSection.d.ts.map +1 -1
  86. package/dist/views/CanvasEditor/components/PrivacySettingsSection.js +6 -28
  87. package/dist/views/CanvasEditor/components/index.d.ts +2 -0
  88. package/dist/views/CanvasEditor/components/index.d.ts.map +1 -1
  89. package/dist/views/CanvasEditor/components/index.js +1 -0
  90. package/dist/views/CanvasEditor/hooks/useHeroBlock.d.ts.map +1 -1
  91. package/dist/views/CanvasEditor/hooks/useHeroBlock.js +15 -18
  92. package/dist/views/CanvasEditor/hooks/usePostLoader.d.ts +3 -0
  93. package/dist/views/CanvasEditor/hooks/usePostLoader.d.ts.map +1 -1
  94. package/dist/views/CanvasEditor/hooks/usePostLoader.js +12 -13
  95. package/dist/views/CanvasEditor/hooks/useUnsavedChanges.js +0 -4
  96. package/dist/views/PostManager/EmptyState.d.ts +1 -1
  97. package/dist/views/PostManager/EmptyState.js +4 -4
  98. package/dist/views/PostManager/FilterDropdown.d.ts +21 -0
  99. package/dist/views/PostManager/FilterDropdown.d.ts.map +1 -0
  100. package/dist/views/PostManager/FilterDropdown.js +28 -0
  101. package/dist/views/PostManager/LanguageFlags.d.ts.map +1 -1
  102. package/dist/views/PostManager/LanguageFlags.js +4 -1
  103. package/dist/views/PostManager/PostCards.d.ts.map +1 -1
  104. package/dist/views/PostManager/PostCards.js +23 -40
  105. package/dist/views/PostManager/PostFilters.d.ts.map +1 -1
  106. package/dist/views/PostManager/PostFilters.js +34 -3
  107. package/dist/views/PostManager/PostManagerView.d.ts +1 -2
  108. package/dist/views/PostManager/PostManagerView.d.ts.map +1 -1
  109. package/dist/views/PostManager/PostManagerView.js +30 -96
  110. package/dist/views/PostManager/PostStats.d.ts.map +1 -1
  111. package/dist/views/PostManager/PostStats.js +10 -10
  112. package/dist/views/PostManager/PostTable.d.ts.map +1 -1
  113. package/dist/views/PostManager/PostTable.js +23 -40
  114. package/dist/views/Settings/SettingsView.d.ts +1 -1
  115. package/dist/views/Settings/SettingsView.d.ts.map +1 -1
  116. package/dist/views/Settings/SettingsView.js +12 -39
  117. package/dist/views/SlugSEO/SlugSEOManagerView.d.ts.map +1 -1
  118. package/dist/views/SlugSEO/SlugSEOManagerView.js +2 -2
  119. package/package.json +42 -6
  120. package/src/api/categories.ts +48 -52
  121. package/src/api/handler.ts +87 -604
  122. package/src/api/router.ts +15 -65
  123. package/src/api/service.ts +241 -0
  124. package/src/hooks/useAutoSave.ts +64 -0
  125. package/src/hooks/useCategories.ts +19 -47
  126. package/src/index.tsx +79 -293
  127. package/src/init.tsx +24 -11
  128. package/src/lib/blocks/BlockRenderer.tsx +1 -0
  129. package/src/lib/layouts/blocks/ColumnsBlock.tsx +60 -173
  130. package/src/lib/layouts/blocks/SectionBlock.tsx +22 -26
  131. package/src/lib/layouts/index.ts +4 -4
  132. package/src/lib/mappers/apiMapper.ts +63 -32
  133. package/src/lib/rich-text/RichTextEditor.tsx +16 -9
  134. package/src/lib/utils/config-resolver.ts +64 -0
  135. package/src/lib/utils/tree.ts +150 -0
  136. package/src/state/EditorContext.tsx +153 -232
  137. package/src/state/reducer.ts +141 -606
  138. package/src/state/types.ts +14 -1
  139. package/src/types/block.ts +10 -0
  140. package/src/types/post.ts +19 -1
  141. package/src/views/CanvasEditor/BlockWrapper.tsx +130 -460
  142. package/src/views/CanvasEditor/CanvasEditorView.tsx +145 -420
  143. package/src/views/CanvasEditor/EditorBody.tsx +98 -610
  144. package/src/views/CanvasEditor/EditorHeader.tsx +176 -196
  145. package/src/views/CanvasEditor/LayoutContainer.tsx +74 -89
  146. package/src/views/CanvasEditor/components/CustomBlockItem.tsx +7 -8
  147. package/src/views/CanvasEditor/components/EditorCanvas.tsx +139 -84
  148. package/src/views/CanvasEditor/components/EditorLibrary.tsx +25 -10
  149. package/src/views/CanvasEditor/components/EditorSidebar.tsx +196 -127
  150. package/src/views/CanvasEditor/components/FeaturedMediaSection.tsx +78 -210
  151. package/src/views/CanvasEditor/components/JSONInspector.tsx +125 -0
  152. package/src/views/CanvasEditor/components/LibraryItem.tsx +5 -6
  153. package/src/views/CanvasEditor/components/PrivacySettingsSection.tsx +73 -124
  154. package/src/views/CanvasEditor/components/index.ts +2 -1
  155. package/src/views/CanvasEditor/hooks/useHeroBlock.ts +15 -18
  156. package/src/views/CanvasEditor/hooks/usePostLoader.ts +21 -13
  157. package/src/views/CanvasEditor/hooks/useUnsavedChanges.ts +4 -4
  158. package/src/views/PostManager/EmptyState.tsx +9 -10
  159. package/src/views/PostManager/FilterDropdown.tsx +95 -0
  160. package/src/views/PostManager/LanguageFlags.tsx +6 -2
  161. package/src/views/PostManager/PostCards.tsx +127 -133
  162. package/src/views/PostManager/PostFilters.tsx +73 -68
  163. package/src/views/PostManager/PostManagerView.tsx +132 -179
  164. package/src/views/PostManager/PostStats.tsx +21 -20
  165. package/src/views/PostManager/PostTable.tsx +137 -165
  166. package/src/views/Settings/SettingsView.tsx +64 -180
  167. package/src/views/SlugSEO/SlugSEOManagerView.tsx +59 -44
  168. package/src/hooks/index.d.ts +0 -8
  169. package/src/hooks/index.d.ts.map +0 -1
  170. package/src/hooks/useBlog.d.ts +0 -31
  171. package/src/hooks/useBlog.d.ts.map +0 -1
  172. package/src/hooks/useBlogs.d.ts +0 -39
  173. package/src/hooks/useBlogs.d.ts.map +0 -1
  174. package/src/hooks/useCategories.d.ts +0 -9
  175. package/src/hooks/useCategories.d.ts.map +0 -1
  176. package/src/lib/blocks/BlockRenderer.d.ts +0 -54
  177. package/src/lib/blocks/BlockRenderer.d.ts.map +0 -1
  178. package/src/lib/config-storage.d.ts +0 -30
  179. package/src/lib/config-storage.d.ts.map +0 -1
  180. package/src/lib/layouts/blocks/ColumnsBlock.d.ts +0 -25
  181. package/src/lib/layouts/blocks/ColumnsBlock.d.ts.map +0 -1
  182. package/src/lib/layouts/blocks/SectionBlock.d.ts +0 -25
  183. package/src/lib/layouts/blocks/SectionBlock.d.ts.map +0 -1
  184. package/src/lib/layouts/index.d.ts +0 -23
  185. package/src/lib/layouts/index.d.ts.map +0 -1
  186. package/src/lib/layouts/registerLayoutBlocks.d.ts +0 -9
  187. package/src/lib/layouts/registerLayoutBlocks.d.ts.map +0 -1
  188. package/src/lib/mappers/apiMapper.d.ts +0 -66
  189. package/src/lib/mappers/apiMapper.d.ts.map +0 -1
  190. package/src/lib/rich-text/RichTextEditor.d.ts +0 -45
  191. package/src/lib/rich-text/RichTextEditor.d.ts.map +0 -1
  192. package/src/lib/rich-text/RichTextPreview.d.ts +0 -16
  193. package/src/lib/rich-text/RichTextPreview.d.ts.map +0 -1
  194. package/src/lib/rich-text/index.d.ts +0 -9
  195. package/src/lib/rich-text/index.d.ts.map +0 -1
  196. package/src/lib/utils/blockHelpers.d.ts +0 -23
  197. package/src/lib/utils/blockHelpers.d.ts.map +0 -1
  198. package/src/lib/utils/configValidation.d.ts +0 -23
  199. package/src/lib/utils/configValidation.d.ts.map +0 -1
  200. package/src/registry/BlockRegistry.d.ts +0 -62
  201. package/src/registry/BlockRegistry.d.ts.map +0 -1
  202. package/src/registry/index.d.ts +0 -6
  203. package/src/registry/index.d.ts.map +0 -1
  204. package/src/state/EditorContext.d.ts +0 -45
  205. package/src/state/EditorContext.d.ts.map +0 -1
  206. package/src/state/index.d.ts +0 -7
  207. package/src/state/index.d.ts.map +0 -1
  208. package/src/state/reducer.d.ts +0 -11
  209. package/src/state/reducer.d.ts.map +0 -1
  210. package/src/state/types.d.ts +0 -162
  211. package/src/state/types.d.ts.map +0 -1
  212. package/src/types/block.d.ts +0 -221
  213. package/src/types/block.d.ts.map +0 -1
  214. package/src/types/index.d.ts +0 -8
  215. package/src/types/index.d.ts.map +0 -1
  216. package/src/types/post.d.ts +0 -136
  217. package/src/types/post.d.ts.map +0 -1
  218. package/src/utils/client.d.ts +0 -48
  219. package/src/utils/client.d.ts.map +0 -1
  220. package/src/views/CanvasEditor/BlockWrapper.d.ts +0 -16
  221. package/src/views/CanvasEditor/BlockWrapper.d.ts.map +0 -1
  222. package/src/views/CanvasEditor/CanvasEditorView.d.ts +0 -14
  223. package/src/views/CanvasEditor/CanvasEditorView.d.ts.map +0 -1
  224. package/src/views/CanvasEditor/EditorBody.d.ts +0 -22
  225. package/src/views/CanvasEditor/EditorBody.d.ts.map +0 -1
  226. package/src/views/CanvasEditor/EditorHeader.d.ts +0 -18
  227. package/src/views/CanvasEditor/EditorHeader.d.ts.map +0 -1
  228. package/src/views/CanvasEditor/LayoutContainer.d.ts +0 -17
  229. package/src/views/CanvasEditor/LayoutContainer.d.ts.map +0 -1
  230. package/src/views/CanvasEditor/SaveConfirmationModal.d.ts +0 -13
  231. package/src/views/CanvasEditor/SaveConfirmationModal.d.ts.map +0 -1
  232. package/src/views/CanvasEditor/components/CustomBlockItem.d.ts +0 -14
  233. package/src/views/CanvasEditor/components/CustomBlockItem.d.ts.map +0 -1
  234. package/src/views/CanvasEditor/components/EditorCanvas.d.ts +0 -29
  235. package/src/views/CanvasEditor/components/EditorCanvas.d.ts.map +0 -1
  236. package/src/views/CanvasEditor/components/EditorLibrary.d.ts +0 -7
  237. package/src/views/CanvasEditor/components/EditorLibrary.d.ts.map +0 -1
  238. package/src/views/CanvasEditor/components/EditorSidebar.d.ts +0 -13
  239. package/src/views/CanvasEditor/components/EditorSidebar.d.ts.map +0 -1
  240. package/src/views/CanvasEditor/components/ErrorBanner.d.ts +0 -6
  241. package/src/views/CanvasEditor/components/ErrorBanner.d.ts.map +0 -1
  242. package/src/views/CanvasEditor/components/FeaturedMediaSection.d.ts +0 -25
  243. package/src/views/CanvasEditor/components/FeaturedMediaSection.d.ts.map +0 -1
  244. package/src/views/CanvasEditor/components/LibraryItem.d.ts +0 -14
  245. package/src/views/CanvasEditor/components/LibraryItem.d.ts.map +0 -1
  246. package/src/views/CanvasEditor/components/PrivacySettingsSection.d.ts +0 -15
  247. package/src/views/CanvasEditor/components/PrivacySettingsSection.d.ts.map +0 -1
  248. package/src/views/CanvasEditor/components/index.d.ts +0 -21
  249. package/src/views/CanvasEditor/components/index.d.ts.map +0 -1
  250. package/src/views/CanvasEditor/hooks/index.d.ts +0 -10
  251. package/src/views/CanvasEditor/hooks/index.d.ts.map +0 -1
  252. package/src/views/CanvasEditor/hooks/useHeroBlock.d.ts +0 -8
  253. package/src/views/CanvasEditor/hooks/useHeroBlock.d.ts.map +0 -1
  254. package/src/views/CanvasEditor/hooks/useKeyboardShortcuts.d.ts +0 -3
  255. package/src/views/CanvasEditor/hooks/useKeyboardShortcuts.d.ts.map +0 -1
  256. package/src/views/CanvasEditor/hooks/usePostLoader.d.ts +0 -5
  257. package/src/views/CanvasEditor/hooks/usePostLoader.d.ts.map +0 -1
  258. package/src/views/CanvasEditor/hooks/useRegisteredBlocks.d.ts +0 -2
  259. package/src/views/CanvasEditor/hooks/useRegisteredBlocks.d.ts.map +0 -1
  260. package/src/views/CanvasEditor/hooks/useUnsavedChanges.d.ts +0 -25
  261. package/src/views/CanvasEditor/hooks/useUnsavedChanges.d.ts.map +0 -1
  262. package/src/views/CanvasEditor/index.d.ts +0 -16
  263. package/src/views/CanvasEditor/index.d.ts.map +0 -1
  264. package/src/views/PostManager/EmptyState.d.ts +0 -10
  265. package/src/views/PostManager/EmptyState.d.ts.map +0 -1
  266. package/src/views/PostManager/PostActionsMenu.d.ts +0 -12
  267. package/src/views/PostManager/PostActionsMenu.d.ts.map +0 -1
  268. package/src/views/PostManager/PostCards.d.ts +0 -15
  269. package/src/views/PostManager/PostCards.d.ts.map +0 -1
  270. package/src/views/PostManager/PostFilters.d.ts +0 -16
  271. package/src/views/PostManager/PostFilters.d.ts.map +0 -1
  272. package/src/views/PostManager/PostManagerView.d.ts +0 -11
  273. package/src/views/PostManager/PostManagerView.d.ts.map +0 -1
  274. package/src/views/PostManager/PostStats.d.ts +0 -11
  275. package/src/views/PostManager/PostStats.d.ts.map +0 -1
  276. package/src/views/PostManager/PostTable.d.ts +0 -15
  277. package/src/views/PostManager/PostTable.d.ts.map +0 -1
  278. package/src/views/PostManager/index.d.ts +0 -12
  279. package/src/views/PostManager/index.d.ts.map +0 -1
  280. package/src/views/Preview/PreviewBridgeView.d.ts +0 -12
  281. package/src/views/Preview/PreviewBridgeView.d.ts.map +0 -1
  282. package/src/views/Preview/index.d.ts +0 -6
  283. package/src/views/Preview/index.d.ts.map +0 -1
  284. package/src/views/Settings/SettingsView.d.ts +0 -10
  285. package/src/views/Settings/SettingsView.d.ts.map +0 -1
  286. package/src/views/Settings/index.d.ts +0 -6
  287. package/src/views/Settings/index.d.ts.map +0 -1
  288. package/src/views/SlugSEO/SlugSEOManagerView.d.ts +0 -12
  289. package/src/views/SlugSEO/SlugSEOManagerView.d.ts.map +0 -1
  290. package/src/views/SlugSEO/index.d.ts +0 -6
  291. package/src/views/SlugSEO/index.d.ts.map +0 -1
@@ -2,9 +2,6 @@
2
2
  /**
3
3
  * Plugin Blog API Router
4
4
  * Centralized API handler for all blog plugin routes
5
- *
6
- * This router handles requests to /api/plugin-blog/*
7
- * and routes them to the appropriate handler
8
5
  */
9
6
  import { NextResponse } from 'next/server';
10
7
  import { GET as BlogListHandler, POST as BlogCreateHandler } from './handler';
@@ -12,83 +9,59 @@ import { GET as BlogGetHandler, PUT as BlogUpdateHandler, DELETE as BlogDeleteHa
12
9
  import { GET as ConfigGetHandler, POST as ConfigPostHandler } from './config-handler';
13
10
  /**
14
11
  * Handle blog API requests
15
- * Routes requests to appropriate handlers based on path
16
- * Similar to plugin-dep, accepts config directly instead of requiring initialization
17
12
  */
18
13
  export async function handleBlogApi(req, path, config) {
19
- // Create the blog API config from the router config
20
14
  const blogApiConfig = createBlogApiConfig({
21
15
  getDb: config.getDb,
22
16
  getUserId: config.getUserId,
23
17
  collectionName: config.collectionName || 'blogs',
24
18
  });
25
19
  const method = req.method;
26
- // Handle empty path array - means we're at /api/plugin-blog
27
- // Ensure path is always an array
28
20
  const safePath = Array.isArray(path) ? path : [];
29
21
  const route = safePath.length > 0 ? safePath[0] : '';
30
22
  try {
31
- // Route: /api/plugin-blog (list/create) - empty path or 'list'
32
- // This handles both /api/plugin-blog and /api/plugin-blog?limit=3
33
23
  if (!route || route === 'list') {
34
- if (method === 'GET') {
24
+ if (method === 'GET')
35
25
  return await BlogListHandler(req, blogApiConfig);
36
- }
37
- if (method === 'POST') {
26
+ if (method === 'POST')
38
27
  return await BlogCreateHandler(req, blogApiConfig);
39
- }
40
- // Method not allowed for root route
41
- return NextResponse.json({ error: `Method ${method} not allowed for route: /` }, { status: 405 });
42
28
  }
43
- // Route: /api/plugin-blog/new (create new)
44
29
  else if (route === 'new') {
45
- if (method === 'POST') {
30
+ if (method === 'POST')
46
31
  return await BlogCreateHandler(req, blogApiConfig);
47
- }
48
32
  }
49
- // Route: /api/plugin-blog/categories (get categories)
50
33
  else if (route === 'categories') {
51
34
  if (method === 'GET') {
52
- // Import categories handler
53
35
  const categoriesModule = await import('./categories');
54
36
  return await categoriesModule.GET(req, blogApiConfig);
55
37
  }
56
38
  }
57
- // Route: /api/plugin-blog/check-title (check title duplicate)
58
39
  else if (route === 'check-title') {
59
40
  if (method === 'GET') {
60
41
  const checkTitleModule = await import('./check-title');
61
42
  return await checkTitleModule.GET(req, blogApiConfig);
62
43
  }
63
44
  }
64
- // Route: /api/plugin-blog/config (get/save plugin config)
65
45
  else if (route === 'config') {
66
46
  const configApiConfig = {
67
47
  getDb: config.getDb,
68
48
  getUserId: config.getUserId,
69
49
  siteId: config.siteId || 'default',
70
50
  };
71
- if (method === 'GET') {
51
+ if (method === 'GET')
72
52
  return await ConfigGetHandler(req, configApiConfig);
73
- }
74
- if (method === 'POST') {
53
+ if (method === 'POST')
75
54
  return await ConfigPostHandler(req, configApiConfig);
76
- }
77
55
  }
78
- // Route: /api/plugin-blog/[slug] (get/update/delete by slug)
79
56
  else {
80
57
  const slug = route;
81
- if (method === 'GET') {
58
+ if (method === 'GET')
82
59
  return await BlogGetHandler(req, { params: Promise.resolve({ slug }) }, blogApiConfig);
83
- }
84
- if (method === 'PUT') {
60
+ if (method === 'PUT')
85
61
  return await BlogUpdateHandler(req, { params: Promise.resolve({ slug }) }, blogApiConfig);
86
- }
87
- if (method === 'DELETE') {
62
+ if (method === 'DELETE')
88
63
  return await BlogDeleteHandler(req, { params: Promise.resolve({ slug }) }, blogApiConfig);
89
- }
90
64
  }
91
- // Method not allowed
92
65
  return NextResponse.json({ error: `Method ${method} not allowed for route: ${route || '/'}` }, { status: 405 });
93
66
  }
94
67
  catch (error) {
@@ -0,0 +1,80 @@
1
+ /**
2
+ * Blog API Service
3
+ * Shared server-side logic for MongoDB operations and language fallbacks
4
+ */
5
+ import { BlogApiConfig } from './handler';
6
+ export declare class BlogService {
7
+ private config;
8
+ constructor(config: BlogApiConfig);
9
+ /**
10
+ * Common aggregation pipeline for including author data
11
+ */
12
+ private getAuthorLookupPipeline;
13
+ /**
14
+ * List blogs with filters and language fallbacks
15
+ */
16
+ listBlogs(options: {
17
+ limit: number;
18
+ skip: number;
19
+ status?: string;
20
+ isAdmin: boolean;
21
+ userId?: string | null;
22
+ requestedLanguage: string;
23
+ }): Promise<{
24
+ blogs: any;
25
+ total: any;
26
+ }>;
27
+ /**
28
+ * Get single blog by slug
29
+ */
30
+ getBlogBySlug(slug: string, requestedLanguage: string, isAdmin?: boolean): Promise<{
31
+ id: any;
32
+ slug: any;
33
+ title: any;
34
+ summary: any;
35
+ contentBlocks: any;
36
+ image: any;
37
+ categoryTags: {
38
+ category: any;
39
+ tags: any;
40
+ };
41
+ lang: string;
42
+ isMissingTranslation: boolean;
43
+ requestedLanguage: string;
44
+ availableLanguages: string[];
45
+ updatedAt: any;
46
+ languages: any;
47
+ status: any;
48
+ publication: {
49
+ status: any;
50
+ date: any;
51
+ };
52
+ author: {
53
+ name: any;
54
+ image: any;
55
+ displayRole: any;
56
+ } | undefined;
57
+ } | null>;
58
+ /**
59
+ * Create or update the language-specific document structure
60
+ */
61
+ prepareUpdateData(body: any, existingBlog: any | null, language: string): {
62
+ title: any;
63
+ slug: any;
64
+ summary: any;
65
+ contentBlocks: any;
66
+ image: any;
67
+ categoryTags: {
68
+ category: any;
69
+ tags: any;
70
+ };
71
+ publicationData: any;
72
+ languages: any;
73
+ updatedAt: Date;
74
+ };
75
+ /**
76
+ * Format a document for a specific language
77
+ */
78
+ private formatWithLanguage;
79
+ }
80
+ //# sourceMappingURL=service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../../src/api/service.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAG1C,qBAAa,WAAW;IACR,OAAO,CAAC,MAAM;gBAAN,MAAM,EAAE,aAAa;IAEzC;;OAEG;IACH,OAAO,CAAC,uBAAuB;IAiB/B;;OAEG;IACG,SAAS,CAAC,OAAO,EAAE;QACrB,KAAK,EAAE,MAAM,CAAC;QACd,IAAI,EAAE,MAAM,CAAC;QACb,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,OAAO,EAAE,OAAO,CAAC;QACjB,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QACvB,iBAAiB,EAAE,MAAM,CAAC;KAC7B;;;;IAiCD;;OAEG;IACG,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,iBAAiB,EAAE,MAAM,EAAE,OAAO,GAAE,OAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAarF;;OAEG;IACH,iBAAiB,CAAC,IAAI,EAAE,GAAG,EAAE,YAAY,EAAE,GAAG,GAAG,IAAI,EAAE,QAAQ,EAAE,MAAM;;;;;;;;;;;;;;IAqEvE;;OAEG;IACH,OAAO,CAAC,kBAAkB;CA2E7B"}
@@ -0,0 +1,219 @@
1
+ /**
2
+ * Blog API Service
3
+ * Shared server-side logic for MongoDB operations and language fallbacks
4
+ */
5
+ import { slugify } from '../lib/utils/slugify';
6
+ export class BlogService {
7
+ constructor(config) {
8
+ this.config = config;
9
+ }
10
+ /**
11
+ * Common aggregation pipeline for including author data
12
+ */
13
+ getAuthorLookupPipeline() {
14
+ return [
15
+ {
16
+ $lookup: {
17
+ from: 'users',
18
+ let: { authorId: '$authorId' },
19
+ pipeline: [
20
+ { $match: { $expr: { $or: [{ $eq: ['$_id', '$$authorId'] }, { $eq: [{ $toString: '$_id' }, '$$authorId'] }] } } },
21
+ { $project: { password: 0 } }
22
+ ],
23
+ as: 'author'
24
+ }
25
+ },
26
+ { $addFields: { author: { $arrayElemAt: ['$author', 0] } } }
27
+ ];
28
+ }
29
+ /**
30
+ * List blogs with filters and language fallbacks
31
+ */
32
+ async listBlogs(options) {
33
+ const dbConn = await this.config.getDb();
34
+ const db = dbConn.db();
35
+ const collection = db.collection(this.config.collectionName || 'blogs');
36
+ let query = {};
37
+ if (options.isAdmin && options.userId) {
38
+ if (options.status)
39
+ query = { 'publicationData.status': options.status, authorId: options.userId };
40
+ else
41
+ query = { authorId: options.userId };
42
+ }
43
+ else {
44
+ query = {
45
+ [`languages.${options.requestedLanguage}.status`]: 'published',
46
+ 'publicationData.date': { $lte: new Date() },
47
+ };
48
+ }
49
+ const pipeline = [
50
+ { $match: query },
51
+ { $sort: { 'publicationData.date': -1 } },
52
+ { $skip: options.skip },
53
+ { $limit: options.isAdmin ? 1000 : options.limit },
54
+ ...this.getAuthorLookupPipeline()
55
+ ];
56
+ const [data, totalCount] = await Promise.all([
57
+ collection.aggregate(pipeline).toArray(),
58
+ collection.countDocuments(query),
59
+ ]);
60
+ const formatted = data.map((doc) => this.formatWithLanguage(doc, options.requestedLanguage, options.isAdmin)).filter(Boolean);
61
+ return { blogs: formatted, total: totalCount };
62
+ }
63
+ /**
64
+ * Get single blog by slug
65
+ */
66
+ async getBlogBySlug(slug, requestedLanguage, isAdmin = false) {
67
+ const dbConn = await this.config.getDb();
68
+ const db = dbConn.db();
69
+ const collection = db.collection(this.config.collectionName || 'blogs');
70
+ const pipeline = [{ $match: { slug } }, ...this.getAuthorLookupPipeline()];
71
+ const results = await collection.aggregate(pipeline).toArray();
72
+ const blog = results[0];
73
+ if (!blog)
74
+ return null;
75
+ return this.formatWithLanguage(blog, requestedLanguage, isAdmin);
76
+ }
77
+ /**
78
+ * Create or update the language-specific document structure
79
+ */
80
+ prepareUpdateData(body, existingBlog, language) {
81
+ const { title, summary, contentBlocks, image, categoryTags, publicationData, seo } = body;
82
+ const now = new Date();
83
+ const finalStatus = publicationData?.status || 'concept';
84
+ // Generate a localized slug for this specific language edition
85
+ // If it's not published, we add a draft suffix
86
+ const isPublishing = finalStatus === 'published';
87
+ let localizedSlug = slugify(title);
88
+ // Only append draft suffix if NOT publishing
89
+ if (!isPublishing) {
90
+ localizedSlug = `${localizedSlug}-draft-${Date.now().toString().slice(-4)}`;
91
+ }
92
+ const langData = {
93
+ blocks: contentBlocks || [],
94
+ metadata: {
95
+ title: title.trim(),
96
+ slug: localizedSlug, // Store the slug inside the language object
97
+ excerpt: (summary || '').trim(),
98
+ featuredImage: image,
99
+ categories: categoryTags?.category ? [categoryTags.category] : [],
100
+ tags: categoryTags?.tags || [],
101
+ seo: seo || {},
102
+ },
103
+ updatedAt: now.toISOString(),
104
+ status: finalStatus,
105
+ };
106
+ const updatedLanguages = {
107
+ ...(existingBlog?.languages || {}),
108
+ [language]: langData,
109
+ };
110
+ // Determine global status based on ALL languages
111
+ // If at least ONE language is published, the global status is 'published'
112
+ // This ensures a new draft edition doesn't hide existing published editions
113
+ const anyPublished = Object.values(updatedLanguages).some((l) => l.status === 'published');
114
+ const globalStatus = anyPublished ? 'published' : 'draft';
115
+ // Update root slug if this is the primary language
116
+ const isPrimaryLanguage = !existingBlog || language === (existingBlog.metadata?.lang || 'nl');
117
+ const rootSlug = isPrimaryLanguage ? localizedSlug : (existingBlog?.slug || localizedSlug);
118
+ return {
119
+ // Keep the primary title/summary but allow them to be updated
120
+ title: title.trim(),
121
+ slug: rootSlug, // Include root slug in update
122
+ summary: (summary || '').trim(),
123
+ contentBlocks: contentBlocks || [],
124
+ image: image || {},
125
+ categoryTags: {
126
+ category: categoryTags?.category?.trim() || '',
127
+ tags: categoryTags?.tags || [],
128
+ },
129
+ publicationData: {
130
+ ...(existingBlog?.publicationData || {}),
131
+ ...publicationData,
132
+ status: globalStatus,
133
+ date: publicationData?.date ? new Date(publicationData.date) : (existingBlog?.publicationData?.date || now),
134
+ },
135
+ languages: updatedLanguages,
136
+ updatedAt: now,
137
+ };
138
+ }
139
+ /**
140
+ * Format a document for a specific language
141
+ */
142
+ formatWithLanguage(doc, requestedLanguage, isAdmin) {
143
+ const languages = doc.languages || {};
144
+ let bestLanguage = requestedLanguage;
145
+ let isMissingTranslation = !languages[requestedLanguage];
146
+ if (isMissingTranslation && !isAdmin) {
147
+ const fallbacks = [doc.metadata?.lang || 'nl', 'nl', 'en'];
148
+ for (const lang of fallbacks) {
149
+ if (languages[lang]) {
150
+ bestLanguage = lang;
151
+ isMissingTranslation = false;
152
+ break;
153
+ }
154
+ }
155
+ if (isMissingTranslation)
156
+ return null; // Public view requires translation or fallback
157
+ }
158
+ const content = languages[bestLanguage] || {};
159
+ const meta = content.metadata || {};
160
+ const status = isMissingTranslation ? 'draft' : (content.status || 'draft');
161
+ // --- ROBUST SLUG RESOLUTION ---
162
+ let resolvedSlug = doc.slug;
163
+ if (!isMissingTranslation) {
164
+ if (meta.slug) {
165
+ resolvedSlug = meta.slug;
166
+ }
167
+ else if (meta.title) {
168
+ resolvedSlug = slugify(meta.title);
169
+ if (status !== 'published')
170
+ resolvedSlug += `-draft-${Date.now().toString().slice(-4)}`;
171
+ }
172
+ }
173
+ return {
174
+ id: doc.id || doc._id?.toString(),
175
+ // Prefer localized slug if available, fallback to root slug or generated one
176
+ slug: resolvedSlug,
177
+ // If missing translation, provide root content as template but keep status 'not-translated'
178
+ title: isMissingTranslation ? (doc.title || '') : (meta.title || doc.title || ''),
179
+ summary: isMissingTranslation ? (doc.summary || '') : (meta.excerpt || doc.summary || ''),
180
+ contentBlocks: isMissingTranslation ? (doc.contentBlocks || []) : (content.blocks || doc.contentBlocks || []),
181
+ image: isMissingTranslation ? doc.image : (meta.featuredImage || doc.image),
182
+ categoryTags: isMissingTranslation ? { category: '', tags: [] } : {
183
+ category: meta.categories?.[0] || '',
184
+ tags: meta.tags || []
185
+ },
186
+ lang: bestLanguage,
187
+ isMissingTranslation,
188
+ requestedLanguage,
189
+ availableLanguages: Object.keys(languages),
190
+ updatedAt: doc.updatedAt || doc.publicationData?.date || new Date().toISOString(),
191
+ // Include a lightweight summary of all languages for admin view (tooltips)
192
+ languages: isAdmin ? (() => {
193
+ const summary = {};
194
+ // Use Object.keys(languages) to ensure we iterate over all existing translations
195
+ Object.keys(languages).forEach(lang => {
196
+ const lData = languages[lang] || {};
197
+ // Normalize status: handle 'concept' -> 'draft'
198
+ let langStatus = lData.status || 'draft';
199
+ if (langStatus === 'concept')
200
+ langStatus = 'draft';
201
+ summary[lang] = {
202
+ status: langStatus,
203
+ metadata: {
204
+ title: lData.metadata?.title || doc.title || 'Untitled'
205
+ }
206
+ };
207
+ });
208
+ return summary;
209
+ })() : undefined,
210
+ status: status,
211
+ publication: {
212
+ status: status,
213
+ // FORCE undefined date for new editions so they don't look published or inherit old dates
214
+ date: isMissingTranslation ? undefined : (doc.publicationData?.date || doc.updatedAt)
215
+ },
216
+ author: doc.author ? { name: doc.author.name, image: doc.author.image, displayRole: doc.author.displayRole } : undefined
217
+ };
218
+ }
219
+ }
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Hook for automatic saving of editor state
3
+ */
4
+ export declare function useAutoSave(postId: string | undefined, state: any, onSave: (state: any) => Promise<void>, delay?: number): {
5
+ autoSaveEnabled: boolean;
6
+ setAutoSaveEnabled: import("react").Dispatch<import("react").SetStateAction<boolean>>;
7
+ saveStatus: "error" | "idle" | "saving" | "saved";
8
+ countdown: number | null;
9
+ };
10
+ //# sourceMappingURL=useAutoSave.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useAutoSave.d.ts","sourceRoot":"","sources":["../../src/hooks/useAutoSave.ts"],"names":[],"mappings":"AAIA;;GAEG;AACH,wBAAgB,WAAW,CACvB,MAAM,EAAE,MAAM,GAAG,SAAS,EAC1B,KAAK,EAAE,GAAG,EACV,MAAM,EAAE,CAAC,KAAK,EAAE,GAAG,KAAK,OAAO,CAAC,IAAI,CAAC,EACrC,KAAK,SAAQ;;;;;EAoDhB"}
@@ -0,0 +1,57 @@
1
+ 'use client';
2
+ import { useState, useEffect, useRef } from 'react';
3
+ /**
4
+ * Hook for automatic saving of editor state
5
+ */
6
+ export function useAutoSave(postId, state, onSave, delay = 10000) {
7
+ const [autoSaveEnabled, setAutoSaveEnabled] = useState(true);
8
+ const [saveStatus, setSaveStatus] = useState('idle');
9
+ const [countdown, setCountdown] = useState(null);
10
+ const timerRef = useRef(null);
11
+ const countdownIntervalRef = useRef(null);
12
+ useEffect(() => {
13
+ if (!autoSaveEnabled || !state.isDirty || !postId) {
14
+ setCountdown(null);
15
+ if (timerRef.current)
16
+ clearTimeout(timerRef.current);
17
+ if (countdownIntervalRef.current)
18
+ clearInterval(countdownIntervalRef.current);
19
+ return;
20
+ }
21
+ // Reset timer on state change
22
+ if (timerRef.current)
23
+ clearTimeout(timerRef.current);
24
+ if (countdownIntervalRef.current)
25
+ clearInterval(countdownIntervalRef.current);
26
+ const startTime = Date.now();
27
+ setCountdown(Math.ceil(delay / 1000));
28
+ countdownIntervalRef.current = setInterval(() => {
29
+ const remaining = Math.max(0, delay - (Date.now() - startTime));
30
+ setCountdown(Math.ceil(remaining / 1000));
31
+ }, 1000);
32
+ timerRef.current = setTimeout(async () => {
33
+ setSaveStatus('saving');
34
+ try {
35
+ await onSave(state);
36
+ setSaveStatus('saved');
37
+ setTimeout(() => setSaveStatus('idle'), 2000);
38
+ }
39
+ catch (error) {
40
+ setSaveStatus('error');
41
+ setTimeout(() => setSaveStatus('idle'), 3000);
42
+ }
43
+ }, delay);
44
+ return () => {
45
+ if (timerRef.current)
46
+ clearTimeout(timerRef.current);
47
+ if (countdownIntervalRef.current)
48
+ clearInterval(countdownIntervalRef.current);
49
+ };
50
+ }, [state, autoSaveEnabled, postId, delay, onSave]);
51
+ return {
52
+ autoSaveEnabled,
53
+ setAutoSaveEnabled,
54
+ saveStatus,
55
+ countdown
56
+ };
57
+ }
@@ -2,7 +2,7 @@
2
2
  * Hook to fetch categories from existing blog posts
3
3
  * Extracts categories from Hero blocks in all posts
4
4
  */
5
- export declare function useCategories(): {
5
+ export declare function useCategories(language?: string): {
6
6
  categories: string[];
7
7
  loading: boolean;
8
8
  };
@@ -1 +1 @@
1
- {"version":3,"file":"useCategories.d.ts","sourceRoot":"","sources":["../../src/hooks/useCategories.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAMH,wBAAgB,aAAa;;;EAkE5B"}
1
+ {"version":3,"file":"useCategories.d.ts","sourceRoot":"","sources":["../../src/hooks/useCategories.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAMH,wBAAgB,aAAa,CAAC,QAAQ,CAAC,EAAE,MAAM;;;EAsC9C"}
@@ -4,60 +4,29 @@
4
4
  */
5
5
  'use client';
6
6
  import { useState, useEffect } from 'react';
7
- export function useCategories() {
7
+ export function useCategories(language) {
8
8
  const [categories, setCategories] = useState([]);
9
9
  const [loading, setLoading] = useState(true);
10
10
  useEffect(() => {
11
11
  const fetchCategories = async () => {
12
12
  try {
13
- const categorySet = new Set();
14
- // 1. Fetch from categories endpoint (legacy categoryTags.category)
15
- try {
16
- const categoriesResponse = await fetch('/api/plugin-blog/categories');
17
- if (categoriesResponse.ok) {
18
- const categoriesData = await categoriesResponse.json();
19
- if (Array.isArray(categoriesData.categories)) {
20
- categoriesData.categories.forEach((cat) => {
21
- if (cat && cat.trim()) {
22
- categorySet.add(cat.trim());
23
- }
24
- });
25
- }
26
- }
13
+ // We rely on the specialized categories endpoint which is strictly filtered by the Orchestrator
14
+ const url = language
15
+ ? `/api/plugin-blog/categories?language=${language}`
16
+ : '/api/plugin-blog/categories';
17
+ const response = await fetch(url);
18
+ if (response.ok) {
19
+ const data = await response.json();
20
+ const list = Array.isArray(data.categories) ? data.categories : [];
21
+ setCategories(list);
27
22
  }
28
- catch (e) {
29
- // Categories endpoint not available, continue
23
+ else {
24
+ console.error(`[useCategories] API_ERROR: ${response.status}`);
25
+ setCategories([]);
30
26
  }
31
- // 2. Fetch all blog posts and extract categories from Hero blocks
32
- try {
33
- const response = await fetch('/api/plugin-blog?admin=true&limit=1000');
34
- if (response.ok) {
35
- const data = await response.json();
36
- const posts = Array.isArray(data.blogs) ? data.blogs : (Array.isArray(data) ? data : []);
37
- posts.forEach((post) => {
38
- if (post.blocks && Array.isArray(post.blocks)) {
39
- // Find Hero block
40
- const heroBlock = post.blocks.find((block) => block.type === 'hero');
41
- if (heroBlock && heroBlock.data && heroBlock.data.category) {
42
- const category = heroBlock.data.category.trim();
43
- if (category) {
44
- categorySet.add(category);
45
- }
46
- }
47
- }
48
- });
49
- }
50
- }
51
- catch (e) {
52
- console.error('Failed to fetch posts for categories:', e);
53
- }
54
- // Convert to sorted array
55
- const sortedCategories = Array.from(categorySet).sort();
56
- setCategories(sortedCategories);
57
27
  }
58
28
  catch (error) {
59
- console.error('Failed to fetch categories:', error);
60
- // Fallback to empty array
29
+ console.error('[useCategories] CRITICAL_SYNC_FAILURE:', error);
61
30
  setCategories([]);
62
31
  }
63
32
  finally {
@@ -65,6 +34,6 @@ export function useCategories() {
65
34
  }
66
35
  };
67
36
  fetchCategories();
68
- }, []);
37
+ }, [language]);
69
38
  return { categories, loading };
70
39
  }
package/dist/index.d.ts CHANGED
@@ -1,55 +1,48 @@
1
1
  /**
2
2
  * Plugin Blog - Main Entry Point
3
- * Block-Based Blog Management System
4
- * Multi-Tenant Architecture: Accepts custom blocks from client applications
3
+ * Simplified with Configuration Resolver
5
4
  */
5
+ import React from 'react';
6
6
  import { ClientBlockDefinition } from './types/block';
7
- /**
8
- * Plugin Props Interface
9
- * Matches the PluginProps from @jhits/jhits-dashboard
10
- */
11
7
  export interface PluginProps {
12
8
  subPath: string[];
13
9
  siteId: string;
14
10
  locale: string;
15
- /** Custom blocks from client application (optional, can also come from window.__JHITS_PLUGIN_PROPS__) */
16
11
  customBlocks?: ClientBlockDefinition[];
17
- /** Enable dark mode for content area and wrappers (default: true) */
18
12
  darkMode?: boolean;
19
- /** Background colors for the editor */
20
13
  backgroundColors?: {
21
- /** Background color for light mode (REQUIRED) */
22
14
  light: string;
23
- /** Background color for dark mode (optional) */
24
15
  dark?: string;
25
16
  };
17
+ LayoutWrapper?: React.ComponentType<any>;
18
+ translations?: Record<string, any>;
26
19
  }
27
20
  /**
28
- * Main Router Component
29
- * Handles routing within the blog plugin
30
- *
31
- * Client Handshake:
32
- * - Client apps can pass customBlocks via props
33
- * - Or via window.__JHITS_PLUGIN_PROPS__['plugin-blog'].customBlocks
34
- * - The EditorProvider will automatically register these blocks
21
+ * Client-facing configuration type
22
+ * Allows partial overrides of plugin behavior
35
23
  */
24
+ export type BlogPluginConfig = Partial<Omit<PluginProps, 'subPath' | 'siteId' | 'locale'>> & {
25
+ customBlocks?: ClientBlockDefinition[];
26
+ darkMode?: boolean;
27
+ backgroundColors?: {
28
+ light: string;
29
+ dark?: string;
30
+ };
31
+ LayoutWrapper?: React.ComponentType<any>;
32
+ translations?: Record<string, any>;
33
+ };
36
34
  export default function BlogPlugin(props: PluginProps): import("react/jsx-runtime").JSX.Element;
37
35
  export { BlogPlugin as Index };
38
- export type { Block, BlockTypeDefinition, ClientBlockDefinition, RichTextFormattingConfig, BlockEditProps, BlockPreviewProps, IBlockComponent, } from './types';
39
- export type { SEOMetadata, PublicationData, PostStatus, PostMetadata, BlogPost, PostListItem, PostFilterOptions, BlogPostLanguageContent, BlogPostLanguages, } from './types/post';
36
+ export type { Block, ClientBlockDefinition, BlockEditProps, BlockPreviewProps, BlockTypeDefinition, IBlockComponent } from './types';
37
+ export type { SEOMetadata, PublicationData, BlogPost, PostListItem, PostStatus } from './types';
40
38
  export { initBlogPlugin } from './init';
41
- export type { BlogPluginConfig } from './init';
42
39
  export { RichTextEditor, RichTextPreview } from './lib/rich-text';
43
- export type { RichTextEditorProps, RichTextPreviewProps } from './lib/rich-text';
44
- export { useBlogs, useBlog } from './hooks';
45
- export type { UseBlogsOptions, UseBlogsResult, UseBlogOptions, UseBlogResult } from './hooks';
46
- export { fetchBlogs, fetchBlog } from './utils/client';
47
- export type { FetchBlogsOptions, FetchBlogsResult, FetchBlogOptions } from './utils/client';
48
- export { BlockRenderer, BlocksRenderer } from './lib/blocks/BlockRenderer';
40
+ export { useBlogs, useBlog, useCategories } from './hooks';
49
41
  export { blockRegistry } from './registry';
50
- export { registerLayoutBlocks } from './lib/layouts/registerLayoutBlocks';
51
- export { getPluginConfig, savePluginConfig } from './lib/config-storage';
52
42
  export { EditorProvider, useEditor } from './state/EditorContext';
53
- export type { EditorProviderProps, EditorState, EditorContextValue } from './state';
54
- export { useCategories } from './hooks/useCategories';
43
+ export type { EditorProviderProps } from './state/EditorContext';
44
+ export type { EditorState, EditorContextValue } from './state/types';
45
+ export { BlockRenderer, BlocksRenderer } from './lib/blocks/BlockRenderer';
46
+ export { ColumnsPreview } from './lib/layouts/blocks/ColumnsBlock';
47
+ export { registerLayoutBlocks } from './lib/layouts/registerLayoutBlocks';
55
48
  //# sourceMappingURL=index.d.ts.map