@jhits/plugin-blog 0.0.7 → 0.0.9

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 (440) hide show
  1. package/dist/api/categories.d.ts +8 -0
  2. package/dist/api/categories.d.ts.map +1 -0
  3. package/dist/api/categories.js +30 -0
  4. package/dist/api/check-title.d.ts +8 -0
  5. package/dist/api/check-title.d.ts.map +1 -0
  6. package/dist/api/check-title.js +47 -0
  7. package/dist/api/config-handler.d.ts +21 -0
  8. package/dist/api/config-handler.d.ts.map +1 -0
  9. package/dist/api/config-handler.js +46 -0
  10. package/dist/api/handler.d.ts +42 -0
  11. package/dist/api/handler.d.ts.map +1 -0
  12. package/dist/api/handler.js +331 -0
  13. package/dist/api/index.d.ts +12 -0
  14. package/dist/api/index.d.ts.map +1 -0
  15. package/dist/api/index.js +12 -0
  16. package/dist/api/route.d.ts +50 -0
  17. package/dist/api/route.d.ts.map +1 -0
  18. package/dist/api/route.js +69 -0
  19. package/dist/api/router.d.ts +27 -0
  20. package/dist/api/router.d.ts.map +1 -0
  21. package/dist/api/router.js +98 -0
  22. package/dist/api-server.d.ts +9 -0
  23. package/dist/api-server.d.ts.map +1 -0
  24. package/dist/api-server.js +9 -0
  25. package/dist/config.d.ts +14 -0
  26. package/dist/config.d.ts.map +1 -0
  27. package/dist/config.js +156 -0
  28. package/dist/hooks/index.d.ts +8 -0
  29. package/dist/hooks/index.d.ts.map +1 -0
  30. package/dist/hooks/index.js +7 -0
  31. package/dist/hooks/useBlog.d.ts +31 -0
  32. package/dist/hooks/useBlog.d.ts.map +1 -0
  33. package/dist/hooks/useBlog.js +57 -0
  34. package/dist/hooks/useBlogs.d.ts +39 -0
  35. package/dist/hooks/useBlogs.d.ts.map +1 -0
  36. package/dist/hooks/useBlogs.js +82 -0
  37. package/dist/hooks/useCategories.d.ts +9 -0
  38. package/dist/hooks/useCategories.d.ts.map +1 -0
  39. package/dist/hooks/useCategories.js +70 -0
  40. package/dist/index.d.ts +55 -0
  41. package/dist/index.d.ts.map +1 -0
  42. package/dist/index.js +228 -0
  43. package/dist/index.server.d.ts +12 -0
  44. package/dist/index.server.d.ts.map +1 -0
  45. package/dist/index.server.js +10 -0
  46. package/dist/init.d.ts +40 -0
  47. package/dist/init.d.ts.map +1 -0
  48. package/dist/init.js +41 -0
  49. package/dist/lib/blocks/BlockRenderer.d.ts +54 -0
  50. package/dist/lib/blocks/BlockRenderer.d.ts.map +1 -0
  51. package/dist/lib/blocks/BlockRenderer.js +54 -0
  52. package/dist/lib/blocks/index.d.ts +5 -0
  53. package/dist/lib/blocks/index.d.ts.map +1 -0
  54. package/dist/lib/blocks/index.js +4 -0
  55. package/dist/lib/config-storage.d.ts +30 -0
  56. package/dist/lib/config-storage.d.ts.map +1 -0
  57. package/dist/lib/config-storage.js +31 -0
  58. package/dist/lib/index.d.ts +8 -0
  59. package/dist/lib/index.d.ts.map +1 -0
  60. package/dist/lib/index.js +7 -0
  61. package/dist/lib/layouts/blocks/ColumnsBlock.d.ts +25 -0
  62. package/dist/lib/layouts/blocks/ColumnsBlock.d.ts.map +1 -0
  63. package/dist/lib/layouts/blocks/ColumnsBlock.js +186 -0
  64. package/dist/lib/layouts/blocks/SectionBlock.d.ts +25 -0
  65. package/dist/lib/layouts/blocks/SectionBlock.d.ts.map +1 -0
  66. package/dist/lib/layouts/blocks/SectionBlock.js +44 -0
  67. package/dist/lib/layouts/blocks/index.d.ts +7 -0
  68. package/dist/lib/layouts/blocks/index.d.ts.map +1 -0
  69. package/dist/lib/layouts/blocks/index.js +6 -0
  70. package/dist/lib/layouts/index.d.ts +23 -0
  71. package/dist/lib/layouts/index.d.ts.map +1 -0
  72. package/dist/lib/layouts/index.js +45 -0
  73. package/dist/lib/layouts/registerLayoutBlocks.d.ts +9 -0
  74. package/dist/lib/layouts/registerLayoutBlocks.d.ts.map +1 -0
  75. package/dist/lib/layouts/registerLayoutBlocks.js +60 -0
  76. package/dist/lib/mappers/apiMapper.d.ts +66 -0
  77. package/dist/lib/mappers/apiMapper.d.ts.map +1 -0
  78. package/dist/lib/mappers/apiMapper.js +188 -0
  79. package/dist/lib/migration/index.d.ts +5 -0
  80. package/dist/lib/migration/index.d.ts.map +1 -0
  81. package/dist/lib/migration/index.js +4 -0
  82. package/dist/lib/migration/mapper.d.ts +37 -0
  83. package/dist/lib/migration/mapper.d.ts.map +1 -0
  84. package/dist/lib/migration/mapper.js +98 -0
  85. package/dist/lib/rich-text/RichTextEditor.d.ts +45 -0
  86. package/dist/lib/rich-text/RichTextEditor.d.ts.map +1 -0
  87. package/dist/lib/rich-text/RichTextEditor.js +556 -0
  88. package/dist/lib/rich-text/RichTextPreview.d.ts +16 -0
  89. package/dist/lib/rich-text/RichTextPreview.d.ts.map +1 -0
  90. package/dist/lib/rich-text/RichTextPreview.js +144 -0
  91. package/dist/lib/rich-text/index.d.ts +9 -0
  92. package/dist/lib/rich-text/index.d.ts.map +1 -0
  93. package/dist/lib/rich-text/index.js +6 -0
  94. package/dist/lib/utils/blockHelpers.d.ts +23 -0
  95. package/dist/lib/utils/blockHelpers.d.ts.map +1 -0
  96. package/dist/lib/utils/blockHelpers.js +65 -0
  97. package/dist/lib/utils/configValidation.d.ts +23 -0
  98. package/dist/lib/utils/configValidation.d.ts.map +1 -0
  99. package/dist/lib/utils/configValidation.js +111 -0
  100. package/dist/lib/utils/index.d.ts +7 -0
  101. package/dist/lib/utils/index.d.ts.map +1 -0
  102. package/dist/lib/utils/index.js +6 -0
  103. package/dist/lib/utils/slugify.d.ts +25 -0
  104. package/dist/lib/utils/slugify.d.ts.map +1 -0
  105. package/dist/lib/utils/slugify.js +65 -0
  106. package/dist/registry/BlockRegistry.d.ts +62 -0
  107. package/dist/registry/BlockRegistry.d.ts.map +1 -0
  108. package/dist/registry/BlockRegistry.js +112 -0
  109. package/dist/registry/index.d.ts +6 -0
  110. package/dist/registry/index.d.ts.map +1 -0
  111. package/dist/registry/index.js +4 -0
  112. package/dist/state/EditorContext.d.ts +45 -0
  113. package/dist/state/EditorContext.d.ts.map +1 -0
  114. package/dist/state/EditorContext.js +215 -0
  115. package/dist/state/index.d.ts +7 -0
  116. package/dist/state/index.d.ts.map +1 -0
  117. package/dist/state/index.js +6 -0
  118. package/dist/state/reducer.d.ts +11 -0
  119. package/dist/state/reducer.d.ts.map +1 -0
  120. package/dist/state/reducer.js +599 -0
  121. package/dist/state/types.d.ts +162 -0
  122. package/dist/state/types.d.ts.map +1 -0
  123. package/dist/state/types.js +27 -0
  124. package/dist/types/block.d.ts +221 -0
  125. package/dist/types/block.d.ts.map +1 -0
  126. package/dist/types/block.js +6 -0
  127. package/dist/types/index.d.ts +8 -0
  128. package/dist/types/index.d.ts.map +1 -0
  129. package/dist/types/index.js +5 -0
  130. package/dist/types/post.d.ts +136 -0
  131. package/dist/types/post.d.ts.map +1 -0
  132. package/dist/types/post.js +5 -0
  133. package/dist/utils/client.d.ts +48 -0
  134. package/dist/utils/client.d.ts.map +1 -0
  135. package/dist/utils/client.js +77 -0
  136. package/dist/utils/index.d.ts +6 -0
  137. package/dist/utils/index.d.ts.map +1 -0
  138. package/dist/utils/index.js +5 -0
  139. package/dist/views/CanvasEditor/BlockWrapper.d.ts +16 -0
  140. package/dist/views/CanvasEditor/BlockWrapper.d.ts.map +1 -0
  141. package/dist/views/CanvasEditor/BlockWrapper.js +285 -0
  142. package/dist/views/CanvasEditor/CanvasEditorView.d.ts +14 -0
  143. package/dist/views/CanvasEditor/CanvasEditorView.d.ts.map +1 -0
  144. package/dist/views/CanvasEditor/CanvasEditorView.js +215 -0
  145. package/dist/views/CanvasEditor/EditorBody.d.ts +22 -0
  146. package/dist/views/CanvasEditor/EditorBody.d.ts.map +1 -0
  147. package/dist/views/CanvasEditor/EditorBody.js +505 -0
  148. package/dist/views/CanvasEditor/EditorHeader.d.ts +18 -0
  149. package/dist/views/CanvasEditor/EditorHeader.d.ts.map +1 -0
  150. package/dist/views/CanvasEditor/EditorHeader.js +101 -0
  151. package/dist/views/CanvasEditor/LayoutContainer.d.ts +17 -0
  152. package/dist/views/CanvasEditor/LayoutContainer.d.ts.map +1 -0
  153. package/dist/views/CanvasEditor/LayoutContainer.js +222 -0
  154. package/dist/views/CanvasEditor/SaveConfirmationModal.d.ts +13 -0
  155. package/dist/views/CanvasEditor/SaveConfirmationModal.d.ts.map +1 -0
  156. package/dist/views/CanvasEditor/SaveConfirmationModal.js +78 -0
  157. package/dist/views/CanvasEditor/components/CustomBlockItem.d.ts +14 -0
  158. package/dist/views/CanvasEditor/components/CustomBlockItem.d.ts.map +1 -0
  159. package/dist/views/CanvasEditor/components/CustomBlockItem.js +44 -0
  160. package/dist/views/CanvasEditor/components/EditorCanvas.d.ts +29 -0
  161. package/dist/views/CanvasEditor/components/EditorCanvas.d.ts.map +1 -0
  162. package/dist/views/CanvasEditor/components/EditorCanvas.js +32 -0
  163. package/dist/views/CanvasEditor/components/EditorLibrary.d.ts +7 -0
  164. package/dist/views/CanvasEditor/components/EditorLibrary.d.ts.map +1 -0
  165. package/dist/views/CanvasEditor/components/EditorLibrary.js +25 -0
  166. package/dist/views/CanvasEditor/components/EditorSidebar.d.ts +13 -0
  167. package/dist/views/CanvasEditor/components/EditorSidebar.d.ts.map +1 -0
  168. package/dist/views/CanvasEditor/components/EditorSidebar.js +19 -0
  169. package/dist/views/CanvasEditor/components/ErrorBanner.d.ts +6 -0
  170. package/dist/views/CanvasEditor/components/ErrorBanner.d.ts.map +1 -0
  171. package/dist/views/CanvasEditor/components/ErrorBanner.js +8 -0
  172. package/dist/views/CanvasEditor/components/FeaturedMediaSection.d.ts +25 -0
  173. package/dist/views/CanvasEditor/components/FeaturedMediaSection.d.ts.map +1 -0
  174. package/dist/views/CanvasEditor/components/FeaturedMediaSection.js +199 -0
  175. package/dist/views/CanvasEditor/components/LibraryItem.d.ts +14 -0
  176. package/dist/views/CanvasEditor/components/LibraryItem.d.ts.map +1 -0
  177. package/dist/views/CanvasEditor/components/LibraryItem.js +43 -0
  178. package/dist/views/CanvasEditor/components/PrivacySettingsSection.d.ts +15 -0
  179. package/dist/views/CanvasEditor/components/PrivacySettingsSection.d.ts.map +1 -0
  180. package/dist/views/CanvasEditor/components/PrivacySettingsSection.js +70 -0
  181. package/dist/views/CanvasEditor/components/index.d.ts +21 -0
  182. package/dist/views/CanvasEditor/components/index.d.ts.map +1 -0
  183. package/dist/views/CanvasEditor/components/index.js +12 -0
  184. package/dist/views/CanvasEditor/hooks/index.d.ts +10 -0
  185. package/dist/views/CanvasEditor/hooks/index.d.ts.map +1 -0
  186. package/dist/views/CanvasEditor/hooks/index.js +9 -0
  187. package/dist/views/CanvasEditor/hooks/useHeroBlock.d.ts +8 -0
  188. package/dist/views/CanvasEditor/hooks/useHeroBlock.d.ts.map +1 -0
  189. package/dist/views/CanvasEditor/hooks/useHeroBlock.js +90 -0
  190. package/dist/views/CanvasEditor/hooks/useKeyboardShortcuts.d.ts +3 -0
  191. package/dist/views/CanvasEditor/hooks/useKeyboardShortcuts.d.ts.map +1 -0
  192. package/dist/views/CanvasEditor/hooks/useKeyboardShortcuts.js +119 -0
  193. package/dist/views/CanvasEditor/hooks/usePostLoader.d.ts +5 -0
  194. package/dist/views/CanvasEditor/hooks/usePostLoader.d.ts.map +1 -0
  195. package/dist/views/CanvasEditor/hooks/usePostLoader.js +32 -0
  196. package/dist/views/CanvasEditor/hooks/useRegisteredBlocks.d.ts +2 -0
  197. package/dist/views/CanvasEditor/hooks/useRegisteredBlocks.d.ts.map +1 -0
  198. package/dist/views/CanvasEditor/hooks/useRegisteredBlocks.js +47 -0
  199. package/dist/views/CanvasEditor/hooks/useUnsavedChanges.d.ts +25 -0
  200. package/dist/views/CanvasEditor/hooks/useUnsavedChanges.d.ts.map +1 -0
  201. package/dist/views/CanvasEditor/hooks/useUnsavedChanges.js +285 -0
  202. package/dist/views/CanvasEditor/index.d.ts +16 -0
  203. package/dist/views/CanvasEditor/index.d.ts.map +1 -0
  204. package/dist/views/CanvasEditor/index.js +9 -0
  205. package/dist/views/PostManager/EmptyState.d.ts +10 -0
  206. package/dist/views/PostManager/EmptyState.d.ts.map +1 -0
  207. package/dist/views/PostManager/EmptyState.js +12 -0
  208. package/dist/views/PostManager/PostActionsMenu.d.ts +12 -0
  209. package/dist/views/PostManager/PostActionsMenu.d.ts.map +1 -0
  210. package/dist/views/PostManager/PostActionsMenu.js +58 -0
  211. package/dist/views/PostManager/PostCards.d.ts +15 -0
  212. package/dist/views/PostManager/PostCards.d.ts.map +1 -0
  213. package/dist/views/PostManager/PostCards.js +77 -0
  214. package/dist/views/PostManager/PostFilters.d.ts +16 -0
  215. package/dist/views/PostManager/PostFilters.d.ts.map +1 -0
  216. package/dist/views/PostManager/PostFilters.js +10 -0
  217. package/dist/views/PostManager/PostManagerView.d.ts +11 -0
  218. package/dist/views/PostManager/PostManagerView.d.ts.map +1 -0
  219. package/dist/views/PostManager/PostManagerView.js +179 -0
  220. package/dist/views/PostManager/PostStats.d.ts +11 -0
  221. package/dist/views/PostManager/PostStats.d.ts.map +1 -0
  222. package/dist/views/PostManager/PostStats.js +46 -0
  223. package/dist/views/PostManager/PostTable.d.ts +15 -0
  224. package/dist/views/PostManager/PostTable.d.ts.map +1 -0
  225. package/dist/views/PostManager/PostTable.js +77 -0
  226. package/dist/views/PostManager/index.d.ts +12 -0
  227. package/dist/views/PostManager/index.d.ts.map +1 -0
  228. package/dist/views/PostManager/index.js +11 -0
  229. package/dist/views/Preview/PreviewBridgeView.d.ts +12 -0
  230. package/dist/views/Preview/PreviewBridgeView.d.ts.map +1 -0
  231. package/dist/views/Preview/PreviewBridgeView.js +11 -0
  232. package/dist/views/Preview/index.d.ts +6 -0
  233. package/dist/views/Preview/index.d.ts.map +1 -0
  234. package/dist/views/Preview/index.js +4 -0
  235. package/dist/views/Settings/SettingsView.d.ts +10 -0
  236. package/dist/views/Settings/SettingsView.d.ts.map +1 -0
  237. package/dist/views/Settings/SettingsView.js +113 -0
  238. package/dist/views/Settings/index.d.ts +6 -0
  239. package/dist/views/Settings/index.d.ts.map +1 -0
  240. package/dist/views/Settings/index.js +4 -0
  241. package/dist/views/SlugSEO/SlugSEOManagerView.d.ts +12 -0
  242. package/dist/views/SlugSEO/SlugSEOManagerView.d.ts.map +1 -0
  243. package/dist/views/SlugSEO/SlugSEOManagerView.js +11 -0
  244. package/dist/views/SlugSEO/index.d.ts +6 -0
  245. package/dist/views/SlugSEO/index.d.ts.map +1 -0
  246. package/dist/views/SlugSEO/index.js +4 -0
  247. package/package.json +59 -55
  248. package/src/hooks/index.d.ts +8 -0
  249. package/src/hooks/index.d.ts.map +1 -0
  250. package/src/hooks/index.js +7 -0
  251. package/src/hooks/useBlog.d.ts +31 -0
  252. package/src/hooks/useBlog.d.ts.map +1 -0
  253. package/src/hooks/useBlog.js +57 -0
  254. package/src/hooks/useBlogs.d.ts +39 -0
  255. package/src/hooks/useBlogs.d.ts.map +1 -0
  256. package/src/hooks/useBlogs.js +82 -0
  257. package/src/hooks/useCategories.d.ts +9 -0
  258. package/src/hooks/useCategories.d.ts.map +1 -0
  259. package/src/hooks/useCategories.js +70 -0
  260. package/src/index.d.ts +55 -0
  261. package/src/index.d.ts.map +1 -0
  262. package/src/index.js +228 -0
  263. package/src/init.d.ts +40 -0
  264. package/src/init.d.ts.map +1 -0
  265. package/src/init.js +41 -0
  266. package/src/lib/blocks/BlockRenderer.d.ts +54 -0
  267. package/src/lib/blocks/BlockRenderer.d.ts.map +1 -0
  268. package/src/lib/blocks/BlockRenderer.js +54 -0
  269. package/src/lib/config-storage.d.ts +30 -0
  270. package/src/lib/config-storage.d.ts.map +1 -0
  271. package/src/lib/config-storage.js +31 -0
  272. package/src/lib/layouts/blocks/ColumnsBlock.d.ts +25 -0
  273. package/src/lib/layouts/blocks/ColumnsBlock.d.ts.map +1 -0
  274. package/src/lib/layouts/blocks/ColumnsBlock.js +182 -0
  275. package/src/lib/layouts/blocks/SectionBlock.d.ts +25 -0
  276. package/src/lib/layouts/blocks/SectionBlock.d.ts.map +1 -0
  277. package/src/lib/layouts/blocks/SectionBlock.js +44 -0
  278. package/src/lib/layouts/index.d.ts +23 -0
  279. package/src/lib/layouts/index.d.ts.map +1 -0
  280. package/src/lib/layouts/index.js +45 -0
  281. package/src/lib/layouts/registerLayoutBlocks.d.ts +9 -0
  282. package/src/lib/layouts/registerLayoutBlocks.d.ts.map +1 -0
  283. package/src/lib/layouts/registerLayoutBlocks.js +60 -0
  284. package/src/lib/mappers/apiMapper.d.ts +66 -0
  285. package/src/lib/mappers/apiMapper.d.ts.map +1 -0
  286. package/src/lib/mappers/apiMapper.js +191 -0
  287. package/src/lib/rich-text/RichTextEditor.d.ts +45 -0
  288. package/src/lib/rich-text/RichTextEditor.d.ts.map +1 -0
  289. package/src/lib/rich-text/RichTextEditor.js +564 -0
  290. package/src/lib/rich-text/RichTextPreview.d.ts +16 -0
  291. package/src/lib/rich-text/RichTextPreview.d.ts.map +1 -0
  292. package/src/lib/rich-text/RichTextPreview.js +144 -0
  293. package/src/lib/rich-text/index.d.ts +9 -0
  294. package/src/lib/rich-text/index.d.ts.map +1 -0
  295. package/src/lib/rich-text/index.js +6 -0
  296. package/src/lib/utils/blockHelpers.d.ts +23 -0
  297. package/src/lib/utils/blockHelpers.d.ts.map +1 -0
  298. package/src/lib/utils/blockHelpers.js +65 -0
  299. package/src/lib/utils/configValidation.d.ts +23 -0
  300. package/src/lib/utils/configValidation.d.ts.map +1 -0
  301. package/src/lib/utils/configValidation.js +113 -0
  302. package/src/registry/BlockRegistry.d.ts +62 -0
  303. package/src/registry/BlockRegistry.d.ts.map +1 -0
  304. package/src/registry/BlockRegistry.js +112 -0
  305. package/src/registry/index.d.ts +6 -0
  306. package/src/registry/index.d.ts.map +1 -0
  307. package/src/registry/index.js +4 -0
  308. package/src/state/EditorContext.d.ts +45 -0
  309. package/src/state/EditorContext.d.ts.map +1 -0
  310. package/src/state/EditorContext.js +215 -0
  311. package/src/state/index.d.ts +7 -0
  312. package/src/state/index.d.ts.map +1 -0
  313. package/src/state/index.js +6 -0
  314. package/src/state/reducer.d.ts +11 -0
  315. package/src/state/reducer.d.ts.map +1 -0
  316. package/src/state/reducer.js +443 -0
  317. package/src/state/types.d.ts +162 -0
  318. package/src/state/types.d.ts.map +1 -0
  319. package/src/state/types.js +27 -0
  320. package/src/types/block.d.ts +221 -0
  321. package/src/types/block.d.ts.map +1 -0
  322. package/src/types/block.js +6 -0
  323. package/src/types/index.d.ts +8 -0
  324. package/src/types/index.d.ts.map +1 -0
  325. package/src/types/index.js +5 -0
  326. package/src/types/post.d.ts +136 -0
  327. package/src/types/post.d.ts.map +1 -0
  328. package/src/types/post.js +5 -0
  329. package/src/utils/client.d.ts +48 -0
  330. package/src/utils/client.d.ts.map +1 -0
  331. package/src/utils/client.js +77 -0
  332. package/src/utils/index.ts +0 -2
  333. package/src/views/CanvasEditor/BlockWrapper.d.ts +16 -0
  334. package/src/views/CanvasEditor/BlockWrapper.d.ts.map +1 -0
  335. package/src/views/CanvasEditor/BlockWrapper.js +276 -0
  336. package/src/views/CanvasEditor/CanvasEditorView.d.ts +14 -0
  337. package/src/views/CanvasEditor/CanvasEditorView.d.ts.map +1 -0
  338. package/src/views/CanvasEditor/CanvasEditorView.js +209 -0
  339. package/src/views/CanvasEditor/EditorBody.d.ts +22 -0
  340. package/src/views/CanvasEditor/EditorBody.d.ts.map +1 -0
  341. package/src/views/CanvasEditor/EditorBody.js +505 -0
  342. package/src/views/CanvasEditor/EditorHeader.d.ts +18 -0
  343. package/src/views/CanvasEditor/EditorHeader.d.ts.map +1 -0
  344. package/src/views/CanvasEditor/EditorHeader.js +101 -0
  345. package/src/views/CanvasEditor/LayoutContainer.d.ts +17 -0
  346. package/src/views/CanvasEditor/LayoutContainer.d.ts.map +1 -0
  347. package/src/views/CanvasEditor/LayoutContainer.js +222 -0
  348. package/src/views/CanvasEditor/SaveConfirmationModal.d.ts +13 -0
  349. package/src/views/CanvasEditor/SaveConfirmationModal.d.ts.map +1 -0
  350. package/src/views/CanvasEditor/SaveConfirmationModal.js +78 -0
  351. package/src/views/CanvasEditor/components/CustomBlockItem.d.ts +14 -0
  352. package/src/views/CanvasEditor/components/CustomBlockItem.d.ts.map +1 -0
  353. package/src/views/CanvasEditor/components/CustomBlockItem.js +44 -0
  354. package/src/views/CanvasEditor/components/EditorCanvas.d.ts +29 -0
  355. package/src/views/CanvasEditor/components/EditorCanvas.d.ts.map +1 -0
  356. package/src/views/CanvasEditor/components/EditorCanvas.js +32 -0
  357. package/src/views/CanvasEditor/components/EditorLibrary.d.ts +7 -0
  358. package/src/views/CanvasEditor/components/EditorLibrary.d.ts.map +1 -0
  359. package/src/views/CanvasEditor/components/EditorLibrary.js +25 -0
  360. package/src/views/CanvasEditor/components/EditorSidebar.d.ts +13 -0
  361. package/src/views/CanvasEditor/components/EditorSidebar.d.ts.map +1 -0
  362. package/src/views/CanvasEditor/components/EditorSidebar.js +20 -0
  363. package/src/views/CanvasEditor/components/ErrorBanner.d.ts +6 -0
  364. package/src/views/CanvasEditor/components/ErrorBanner.d.ts.map +1 -0
  365. package/src/views/CanvasEditor/components/ErrorBanner.js +8 -0
  366. package/src/views/CanvasEditor/components/FeaturedMediaSection.d.ts +25 -0
  367. package/src/views/CanvasEditor/components/FeaturedMediaSection.d.ts.map +1 -0
  368. package/src/views/CanvasEditor/components/FeaturedMediaSection.js +182 -0
  369. package/src/views/CanvasEditor/components/LibraryItem.d.ts +14 -0
  370. package/src/views/CanvasEditor/components/LibraryItem.d.ts.map +1 -0
  371. package/src/views/CanvasEditor/components/LibraryItem.js +43 -0
  372. package/src/views/CanvasEditor/components/PrivacySettingsSection.d.ts +15 -0
  373. package/src/views/CanvasEditor/components/PrivacySettingsSection.d.ts.map +1 -0
  374. package/src/views/CanvasEditor/components/PrivacySettingsSection.js +63 -0
  375. package/src/views/CanvasEditor/components/index.d.ts +21 -0
  376. package/src/views/CanvasEditor/components/index.d.ts.map +1 -0
  377. package/src/views/CanvasEditor/components/index.js +12 -0
  378. package/src/views/CanvasEditor/hooks/index.d.ts +10 -0
  379. package/src/views/CanvasEditor/hooks/index.d.ts.map +1 -0
  380. package/src/views/CanvasEditor/hooks/index.js +9 -0
  381. package/src/views/CanvasEditor/hooks/useHeroBlock.d.ts +8 -0
  382. package/src/views/CanvasEditor/hooks/useHeroBlock.d.ts.map +1 -0
  383. package/src/views/CanvasEditor/hooks/useHeroBlock.js +79 -0
  384. package/src/views/CanvasEditor/hooks/useKeyboardShortcuts.d.ts +3 -0
  385. package/src/views/CanvasEditor/hooks/useKeyboardShortcuts.d.ts.map +1 -0
  386. package/src/views/CanvasEditor/hooks/useKeyboardShortcuts.js +114 -0
  387. package/src/views/CanvasEditor/hooks/usePostLoader.d.ts +5 -0
  388. package/src/views/CanvasEditor/hooks/usePostLoader.d.ts.map +1 -0
  389. package/src/views/CanvasEditor/hooks/usePostLoader.js +32 -0
  390. package/src/views/CanvasEditor/hooks/useRegisteredBlocks.d.ts +2 -0
  391. package/src/views/CanvasEditor/hooks/useRegisteredBlocks.d.ts.map +1 -0
  392. package/src/views/CanvasEditor/hooks/useRegisteredBlocks.js +47 -0
  393. package/src/views/CanvasEditor/hooks/useUnsavedChanges.d.ts +25 -0
  394. package/src/views/CanvasEditor/hooks/useUnsavedChanges.d.ts.map +1 -0
  395. package/src/views/CanvasEditor/hooks/useUnsavedChanges.js +285 -0
  396. package/src/views/CanvasEditor/index.d.ts +16 -0
  397. package/src/views/CanvasEditor/index.d.ts.map +1 -0
  398. package/src/views/CanvasEditor/index.js +9 -0
  399. package/src/views/PostManager/EmptyState.d.ts +10 -0
  400. package/src/views/PostManager/EmptyState.d.ts.map +1 -0
  401. package/src/views/PostManager/EmptyState.js +12 -0
  402. package/src/views/PostManager/PostActionsMenu.d.ts +12 -0
  403. package/src/views/PostManager/PostActionsMenu.d.ts.map +1 -0
  404. package/src/views/PostManager/PostActionsMenu.js +58 -0
  405. package/src/views/PostManager/PostCards.d.ts +15 -0
  406. package/src/views/PostManager/PostCards.d.ts.map +1 -0
  407. package/src/views/PostManager/PostCards.js +79 -0
  408. package/src/views/PostManager/PostFilters.d.ts +16 -0
  409. package/src/views/PostManager/PostFilters.d.ts.map +1 -0
  410. package/src/views/PostManager/PostFilters.js +10 -0
  411. package/src/views/PostManager/PostManagerView.d.ts +11 -0
  412. package/src/views/PostManager/PostManagerView.d.ts.map +1 -0
  413. package/src/views/PostManager/PostManagerView.js +174 -0
  414. package/src/views/PostManager/PostStats.d.ts +11 -0
  415. package/src/views/PostManager/PostStats.d.ts.map +1 -0
  416. package/src/views/PostManager/PostStats.js +46 -0
  417. package/src/views/PostManager/PostTable.d.ts +15 -0
  418. package/src/views/PostManager/PostTable.d.ts.map +1 -0
  419. package/src/views/PostManager/PostTable.js +79 -0
  420. package/src/views/PostManager/index.d.ts +12 -0
  421. package/src/views/PostManager/index.d.ts.map +1 -0
  422. package/src/views/PostManager/index.js +11 -0
  423. package/src/views/Preview/PreviewBridgeView.d.ts +12 -0
  424. package/src/views/Preview/PreviewBridgeView.d.ts.map +1 -0
  425. package/src/views/Preview/PreviewBridgeView.js +11 -0
  426. package/src/views/Preview/index.d.ts +6 -0
  427. package/src/views/Preview/index.d.ts.map +1 -0
  428. package/src/views/Preview/index.js +4 -0
  429. package/src/views/Settings/SettingsView.d.ts +10 -0
  430. package/src/views/Settings/SettingsView.d.ts.map +1 -0
  431. package/src/views/Settings/SettingsView.js +111 -0
  432. package/src/views/Settings/index.d.ts +6 -0
  433. package/src/views/Settings/index.d.ts.map +1 -0
  434. package/src/views/Settings/index.js +4 -0
  435. package/src/views/SlugSEO/SlugSEOManagerView.d.ts +12 -0
  436. package/src/views/SlugSEO/SlugSEOManagerView.d.ts.map +1 -0
  437. package/src/views/SlugSEO/SlugSEOManagerView.js +11 -0
  438. package/src/views/SlugSEO/index.d.ts +6 -0
  439. package/src/views/SlugSEO/index.d.ts.map +1 -0
  440. package/src/views/SlugSEO/index.js +4 -0
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Blog Categories API Handler
3
+ * GET /api/plugin-blog/categories - Get all unique categories
4
+ */
5
+ import { NextRequest, NextResponse } from 'next/server';
6
+ import { BlogApiConfig } from './handler';
7
+ export declare function GET(req: NextRequest, config: BlogApiConfig): Promise<NextResponse>;
8
+ //# sourceMappingURL=categories.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"categories.d.ts","sourceRoot":"","sources":["../../src/api/categories.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AACxD,OAAO,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAE1C,wBAAsB,GAAG,CAAC,GAAG,EAAE,WAAW,EAAE,MAAM,EAAE,aAAa,GAAG,OAAO,CAAC,YAAY,CAAC,CAiCxF"}
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Blog Categories API Handler
3
+ * GET /api/plugin-blog/categories - Get all unique categories
4
+ */
5
+ import { NextResponse } from 'next/server';
6
+ export async function GET(req, config) {
7
+ try {
8
+ const dbConnection = await config.getDb();
9
+ const db = dbConnection.db();
10
+ const blogs = db.collection(config.collectionName || 'blogs');
11
+ // Get all unique categories from blog posts
12
+ const categories = await blogs.distinct('categoryTags.category');
13
+ // Also get categories from Hero blocks in contentBlocks
14
+ const heroBlocks = await blogs.aggregate([
15
+ { $unwind: '$contentBlocks' },
16
+ { $match: { 'contentBlocks.type': 'hero' } },
17
+ { $project: { category: '$contentBlocks.data.category' } },
18
+ { $match: { category: { $exists: true, $ne: null, $nin: [''] } } },
19
+ { $group: { _id: '$category' } },
20
+ ]).toArray();
21
+ const heroCategories = heroBlocks.map((block) => block._id);
22
+ // Combine and deduplicate
23
+ const allCategories = Array.from(new Set([...categories.filter(Boolean), ...heroCategories.filter(Boolean)])).sort();
24
+ return NextResponse.json({ categories: allCategories });
25
+ }
26
+ catch (err) {
27
+ console.error('[BlogAPI] Categories error:', err);
28
+ return NextResponse.json({ error: 'Failed to fetch categories', detail: err.message }, { status: 500 });
29
+ }
30
+ }
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Blog Check Title API Handler
3
+ * GET /api/plugin-blog/check-title - Check if a blog title already exists
4
+ */
5
+ import { NextRequest, NextResponse } from 'next/server';
6
+ import { BlogApiConfig } from './handler';
7
+ export declare function GET(req: NextRequest, config: BlogApiConfig): Promise<NextResponse>;
8
+ //# sourceMappingURL=check-title.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"check-title.d.ts","sourceRoot":"","sources":["../../src/api/check-title.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AACxD,OAAO,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAE1C,wBAAsB,GAAG,CAAC,GAAG,EAAE,WAAW,EAAE,MAAM,EAAE,aAAa,GAAG,OAAO,CAAC,YAAY,CAAC,CAkDxF"}
@@ -0,0 +1,47 @@
1
+ /**
2
+ * Blog Check Title API Handler
3
+ * GET /api/plugin-blog/check-title - Check if a blog title already exists
4
+ */
5
+ import { NextResponse } from 'next/server';
6
+ export async function GET(req, config) {
7
+ try {
8
+ const url = new URL(req.url);
9
+ const title = url.searchParams.get('title');
10
+ const excludeSlug = url.searchParams.get('excludeSlug');
11
+ // If title is empty or too short, don't bother the database
12
+ if (!title || title.trim().length < 3) {
13
+ return NextResponse.json({ duplicate: false });
14
+ }
15
+ const dbConnection = await config.getDb();
16
+ const db = dbConnection.db();
17
+ const blogs = db.collection(config.collectionName || 'blogs');
18
+ /**
19
+ * We search for a title match using:
20
+ * 1. A case-insensitive regex (^ and $ ensure it's the exact full string)
21
+ * 2. An exclusion of the current slug (so editing an article doesn't flag itself)
22
+ */
23
+ const query = {
24
+ title: {
25
+ $regex: new RegExp(`^${title.trim().replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}$`, 'i')
26
+ }
27
+ };
28
+ if (excludeSlug) {
29
+ query.slug = { $ne: excludeSlug };
30
+ }
31
+ const duplicate = await blogs.findOne(query);
32
+ if (duplicate) {
33
+ return NextResponse.json({
34
+ duplicate: true,
35
+ blog: {
36
+ title: duplicate.title,
37
+ slug: duplicate.slug
38
+ }
39
+ });
40
+ }
41
+ return NextResponse.json({ duplicate: false });
42
+ }
43
+ catch (err) {
44
+ console.error('[BlogAPI] Check title error:', err);
45
+ return NextResponse.json({ error: 'Internal server error', detail: err.message }, { status: 500 });
46
+ }
47
+ }
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Blog Config API Handler
3
+ * Handles saving/loading plugin configuration
4
+ */
5
+ import { NextRequest, NextResponse } from 'next/server';
6
+ export interface ConfigApiConfig {
7
+ getDb: () => Promise<{
8
+ db: any;
9
+ }>;
10
+ getUserId: (req: NextRequest) => Promise<string | null>;
11
+ siteId?: string;
12
+ }
13
+ /**
14
+ * GET /api/plugin-blog/config - Get plugin config
15
+ */
16
+ export declare function GET(req: NextRequest, config: ConfigApiConfig): Promise<NextResponse>;
17
+ /**
18
+ * POST /api/plugin-blog/config - Save plugin config
19
+ */
20
+ export declare function POST(req: NextRequest, config: ConfigApiConfig): Promise<NextResponse>;
21
+ //# sourceMappingURL=config-handler.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config-handler.d.ts","sourceRoot":"","sources":["../../src/api/config-handler.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAIxD,MAAM,WAAW,eAAe;IAC5B,KAAK,EAAE,MAAM,OAAO,CAAC;QAAE,EAAE,EAAE,GAAG,CAAA;KAAE,CAAC,CAAC;IAClC,SAAS,EAAE,CAAC,GAAG,EAAE,WAAW,KAAK,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IACxD,MAAM,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;GAEG;AACH,wBAAsB,GAAG,CAAC,GAAG,EAAE,WAAW,EAAE,MAAM,EAAE,eAAe,GAAG,OAAO,CAAC,YAAY,CAAC,CAsB1F;AAED;;GAEG;AACH,wBAAsB,IAAI,CAAC,GAAG,EAAE,WAAW,EAAE,MAAM,EAAE,eAAe,GAAG,OAAO,CAAC,YAAY,CAAC,CA8B3F"}
@@ -0,0 +1,46 @@
1
+ /**
2
+ * Blog Config API Handler
3
+ * Handles saving/loading plugin configuration
4
+ */
5
+ import { NextResponse } from 'next/server';
6
+ import { getPluginConfig, savePluginConfig } from '../lib/config-storage';
7
+ /**
8
+ * GET /api/plugin-blog/config - Get plugin config
9
+ */
10
+ export async function GET(req, config) {
11
+ try {
12
+ const siteId = config.siteId || 'default';
13
+ const pluginConfig = await getPluginConfig(config.getDb, 'plugin-blog', siteId);
14
+ if (!pluginConfig) {
15
+ return NextResponse.json({ config: null });
16
+ }
17
+ return NextResponse.json({ config: pluginConfig.config });
18
+ }
19
+ catch (err) {
20
+ console.error('[BlogConfigAPI] GET error:', err);
21
+ return NextResponse.json({ error: 'Failed to get config', detail: err.message }, { status: 500 });
22
+ }
23
+ }
24
+ /**
25
+ * POST /api/plugin-blog/config - Save plugin config
26
+ */
27
+ export async function POST(req, config) {
28
+ try {
29
+ const userId = await config.getUserId(req);
30
+ if (!userId) {
31
+ return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });
32
+ }
33
+ const body = await req.json();
34
+ const siteId = body.siteId || config.siteId || 'default';
35
+ const pluginConfig = body.config;
36
+ if (!pluginConfig) {
37
+ return NextResponse.json({ error: 'Config is required' }, { status: 400 });
38
+ }
39
+ await savePluginConfig(config.getDb, 'plugin-blog', siteId, pluginConfig);
40
+ return NextResponse.json({ message: 'Config saved successfully' });
41
+ }
42
+ catch (err) {
43
+ console.error('[BlogConfigAPI] POST error:', err);
44
+ return NextResponse.json({ error: 'Failed to save config', detail: err.message }, { status: 500 });
45
+ }
46
+ }
@@ -0,0 +1,42 @@
1
+ /**
2
+ * Blog API Handler
3
+ * RESTful API handler for blog posts
4
+ * Compatible with Next.js API routes
5
+ *
6
+ * IMPORTANT: This file should ONLY be imported in server-side API routes.
7
+ * Do NOT import this in client-side code.
8
+ */
9
+ import { NextRequest, NextResponse } from 'next/server';
10
+ export interface BlogApiConfig {
11
+ /** MongoDB client promise (from clientPromise) - should return { db: () => Database } */
12
+ getDb: () => Promise<{
13
+ db: () => any;
14
+ }>;
15
+ /** Function to get authenticated user ID from request */
16
+ getUserId: (req: NextRequest) => Promise<string | null>;
17
+ /** Collection name (default: 'blogs') */
18
+ collectionName?: string;
19
+ }
20
+ /**
21
+ * GET /api/blogs - List all blog posts
22
+ * GET /api/blogs?admin=true - List all posts for admin (includes drafts)
23
+ * GET /api/blogs?status=published - Filter by status
24
+ */
25
+ export declare function GET(req: NextRequest, config: BlogApiConfig): Promise<NextResponse>;
26
+ /**
27
+ * POST /api/blogs - Create new blog post
28
+ */
29
+ export declare function POST(req: NextRequest, config: BlogApiConfig): Promise<NextResponse>;
30
+ /**
31
+ * GET /api/blogs/[slug] - Get single blog post by slug
32
+ */
33
+ export declare function GET_BY_SLUG(req: NextRequest, slug: string, config: BlogApiConfig): Promise<NextResponse>;
34
+ /**
35
+ * PUT /api/blogs/[slug] - Update blog post by slug
36
+ */
37
+ export declare function PUT_BY_SLUG(req: NextRequest, slug: string, config: BlogApiConfig): Promise<NextResponse>;
38
+ /**
39
+ * DELETE /api/blogs/[slug] - Delete blog post by slug
40
+ */
41
+ export declare function DELETE_BY_SLUG(req: NextRequest, slug: string, config: BlogApiConfig): Promise<NextResponse>;
42
+ //# sourceMappingURL=handler.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"handler.d.ts","sourceRoot":"","sources":["../../src/api/handler.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAGxD,MAAM,WAAW,aAAa;IAC1B,yFAAyF;IACzF,KAAK,EAAE,MAAM,OAAO,CAAC;QAAE,EAAE,EAAE,MAAM,GAAG,CAAA;KAAE,CAAC,CAAC;IACxC,yDAAyD;IACzD,SAAS,EAAE,CAAC,GAAG,EAAE,WAAW,KAAK,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IACxD,yCAAyC;IACzC,cAAc,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED;;;;GAIG;AACH,wBAAsB,GAAG,CAAC,GAAG,EAAE,WAAW,EAAE,MAAM,EAAE,aAAa,GAAG,OAAO,CAAC,YAAY,CAAC,CAgExF;AAED;;GAEG;AACH,wBAAsB,IAAI,CAAC,GAAG,EAAE,WAAW,EAAE,MAAM,EAAE,aAAa,GAAG,OAAO,CAAC,YAAY,CAAC,CA0GzF;AAED;;GAEG;AACH,wBAAsB,WAAW,CAC7B,GAAG,EAAE,WAAW,EAChB,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,aAAa,GACtB,OAAO,CAAC,YAAY,CAAC,CAgCvB;AAED;;GAEG;AACH,wBAAsB,WAAW,CAC7B,GAAG,EAAE,WAAW,EAChB,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,aAAa,GACtB,OAAO,CAAC,YAAY,CAAC,CA8HvB;AAED;;GAEG;AACH,wBAAsB,cAAc,CAChC,GAAG,EAAE,WAAW,EAChB,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,aAAa,GACtB,OAAO,CAAC,YAAY,CAAC,CA8BvB"}
@@ -0,0 +1,331 @@
1
+ /**
2
+ * Blog API Handler
3
+ * RESTful API handler for blog posts
4
+ * Compatible with Next.js API routes
5
+ *
6
+ * IMPORTANT: This file should ONLY be imported in server-side API routes.
7
+ * Do NOT import this in client-side code.
8
+ */
9
+ import { NextResponse } from 'next/server';
10
+ import { slugify } from '../lib/utils/slugify';
11
+ /**
12
+ * GET /api/blogs - List all blog posts
13
+ * GET /api/blogs?admin=true - List all posts for admin (includes drafts)
14
+ * GET /api/blogs?status=published - Filter by status
15
+ */
16
+ export async function GET(req, config) {
17
+ try {
18
+ const url = new URL(req.url);
19
+ const limit = Number(url.searchParams.get('limit') ?? 10);
20
+ const skip = Number(url.searchParams.get('skip') ?? 0);
21
+ const statusFilter = url.searchParams.get('status');
22
+ const isAdminView = url.searchParams.get('admin') === 'true';
23
+ const userId = await config.getUserId(req);
24
+ const dbConnection = await config.getDb();
25
+ const db = dbConnection.db();
26
+ const blogs = db.collection(config.collectionName || 'blogs');
27
+ // Build query
28
+ let query = {};
29
+ if (isAdminView && userId) {
30
+ // Admin view: show all posts owned by user
31
+ if (statusFilter) {
32
+ query = {
33
+ 'publicationData.status': statusFilter,
34
+ authorId: userId,
35
+ };
36
+ }
37
+ else {
38
+ query = { authorId: userId };
39
+ }
40
+ }
41
+ else {
42
+ // Public view: only published posts
43
+ query = {
44
+ 'publicationData.status': 'published',
45
+ 'publicationData.date': { $lte: new Date() },
46
+ };
47
+ if (statusFilter && statusFilter !== 'published') {
48
+ // Non-admin can't filter by non-published status
49
+ return NextResponse.json({ error: 'Invalid status filter' }, { status: 400 });
50
+ }
51
+ }
52
+ const [data, totalCount] = await Promise.all([
53
+ blogs
54
+ .find(query)
55
+ .sort({ 'publicationData.date': -1 })
56
+ .skip(skip)
57
+ .limit(isAdminView ? 0 : limit)
58
+ .toArray(),
59
+ blogs.countDocuments(query),
60
+ ]);
61
+ const formatted = data.map((doc) => ({
62
+ ...doc,
63
+ _id: doc._id.toString(),
64
+ }));
65
+ return NextResponse.json({
66
+ blogs: formatted,
67
+ total: totalCount,
68
+ });
69
+ }
70
+ catch (err) {
71
+ console.error('[BlogAPI] GET error:', err);
72
+ return NextResponse.json({ error: 'Failed to fetch blogs', detail: err.message }, { status: 500 });
73
+ }
74
+ }
75
+ /**
76
+ * POST /api/blogs - Create new blog post
77
+ */
78
+ export async function POST(req, config) {
79
+ try {
80
+ const userId = await config.getUserId(req);
81
+ if (!userId) {
82
+ return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });
83
+ }
84
+ const body = await req.json();
85
+ const { title, summary, content, contentBlocks, image, categoryTags, publicationData, seo, } = body;
86
+ const isPublishing = publicationData?.status === 'published';
87
+ const isConcept = publicationData?.status === 'concept' || publicationData?.status === 'draft';
88
+ // Validation
89
+ const errors = [];
90
+ if (!title?.trim()) {
91
+ errors.push('Title is required');
92
+ }
93
+ if (isPublishing) {
94
+ // Publishing requires all fields
95
+ if (!summary?.trim())
96
+ errors.push('Summary is required for publishing');
97
+ if (!image?.id?.trim())
98
+ errors.push('Featured image is required for publishing');
99
+ // Only require category if it's explicitly provided and empty
100
+ // If categoryTags is undefined or category is undefined, that's also missing
101
+ if (!categoryTags || !categoryTags.category || !categoryTags.category.trim()) {
102
+ errors.push('Category is required for publishing');
103
+ }
104
+ const hasContent = (contentBlocks && Array.isArray(contentBlocks) && contentBlocks.length > 0) ||
105
+ (content && Array.isArray(content) && content.length > 0);
106
+ if (!hasContent) {
107
+ errors.push('Content is required for publishing');
108
+ }
109
+ if (!publicationData?.date)
110
+ errors.push('Publication date is required');
111
+ }
112
+ if (errors.length > 0) {
113
+ return NextResponse.json({ message: errors[0], allErrors: errors }, { status: 400 });
114
+ }
115
+ // Create slug
116
+ let baseSlug = slugify(title);
117
+ const slug = isPublishing
118
+ ? baseSlug
119
+ : `${baseSlug}-draft-${Date.now().toString().slice(-4)}`;
120
+ const dbConnection = await config.getDb();
121
+ const db = dbConnection.db();
122
+ const blogs = db.collection(config.collectionName || 'blogs');
123
+ // Determine the final status: if publishing, set to 'published', otherwise convert draft to concept
124
+ let finalStatus = publicationData?.status;
125
+ if (isPublishing) {
126
+ finalStatus = 'published';
127
+ }
128
+ else if (publicationData?.status === 'draft') {
129
+ finalStatus = 'concept';
130
+ }
131
+ else {
132
+ finalStatus = publicationData?.status || 'concept';
133
+ }
134
+ const blogDocument = {
135
+ title: title.trim(),
136
+ summary: (summary || '').trim(),
137
+ contentBlocks: contentBlocks || [],
138
+ content: content || [],
139
+ image: image || { id: '', alt: '' }, // Only store id and alt - plugin-images handles transforms
140
+ categoryTags: {
141
+ category: categoryTags?.category?.trim() || '',
142
+ tags: categoryTags?.tags || [],
143
+ },
144
+ publicationData: {
145
+ ...publicationData,
146
+ status: finalStatus,
147
+ date: publicationData?.date ? new Date(publicationData.date) : new Date(),
148
+ },
149
+ seo: seo || { title: '', description: '' },
150
+ slug,
151
+ authorId: userId,
152
+ createdAt: new Date(),
153
+ updatedAt: new Date(),
154
+ };
155
+ const result = await blogs.insertOne(blogDocument);
156
+ return NextResponse.json({
157
+ message: isPublishing ? 'Blog published successfully' : 'Draft saved successfully',
158
+ blogId: result.insertedId,
159
+ slug,
160
+ });
161
+ }
162
+ catch (err) {
163
+ console.error('[BlogAPI] POST error:', err);
164
+ return NextResponse.json({ error: 'Failed to create blog', detail: err.message }, { status: 500 });
165
+ }
166
+ }
167
+ /**
168
+ * GET /api/blogs/[slug] - Get single blog post by slug
169
+ */
170
+ export async function GET_BY_SLUG(req, slug, config) {
171
+ try {
172
+ const userId = await config.getUserId(req);
173
+ const dbConnection = await config.getDb();
174
+ const db = dbConnection.db();
175
+ const blogs = db.collection(config.collectionName || 'blogs');
176
+ const blog = await blogs.findOne({ slug });
177
+ if (!blog) {
178
+ return NextResponse.json({ error: 'Blog not found' }, { status: 404 });
179
+ }
180
+ // Security check
181
+ const isPublished = blog.publicationData?.status === 'published';
182
+ const isAuthor = userId && blog.authorId === userId;
183
+ if (!isPublished && !isAuthor) {
184
+ return NextResponse.json({ error: 'Access denied' }, { status: 403 });
185
+ }
186
+ return NextResponse.json({
187
+ ...blog,
188
+ _id: blog._id.toString(),
189
+ });
190
+ }
191
+ catch (err) {
192
+ console.error('[BlogAPI] GET_BY_SLUG error:', err);
193
+ return NextResponse.json({ error: 'Failed to fetch blog', detail: err.message }, { status: 500 });
194
+ }
195
+ }
196
+ /**
197
+ * PUT /api/blogs/[slug] - Update blog post by slug
198
+ */
199
+ export async function PUT_BY_SLUG(req, slug, config) {
200
+ try {
201
+ const userId = await config.getUserId(req);
202
+ if (!userId) {
203
+ return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });
204
+ }
205
+ const body = await req.json();
206
+ const { title, summary, content, contentBlocks, image, categoryTags, publicationData, seo, } = body;
207
+ const dbConnection = await config.getDb();
208
+ const db = dbConnection.db();
209
+ const blogs = db.collection(config.collectionName || 'blogs');
210
+ // Check if blog exists and user is author
211
+ const existingBlog = await blogs.findOne({ slug });
212
+ if (!existingBlog) {
213
+ return NextResponse.json({ error: 'Blog not found' }, { status: 404 });
214
+ }
215
+ if (existingBlog.authorId !== userId) {
216
+ return NextResponse.json({ error: 'Forbidden: Not the author' }, { status: 403 });
217
+ }
218
+ // Validation
219
+ const isPublishing = publicationData?.status === 'published';
220
+ if (!title?.trim()) {
221
+ return NextResponse.json({ message: 'Title is required' }, { status: 400 });
222
+ }
223
+ if (isPublishing) {
224
+ const hasContent = (contentBlocks && Array.isArray(contentBlocks) && contentBlocks.length > 0) ||
225
+ (content && Array.isArray(content) && content.length > 0);
226
+ // Collect all missing fields for better error messages
227
+ const missingFields = [];
228
+ if (!summary?.trim())
229
+ missingFields.push('summary');
230
+ if (!image?.id?.trim())
231
+ missingFields.push('featured image');
232
+ // Only require category if it's explicitly provided and empty
233
+ // If categoryTags is undefined or category is undefined, that's also missing
234
+ if (!categoryTags || !categoryTags.category || !categoryTags.category.trim()) {
235
+ missingFields.push('category');
236
+ }
237
+ if (!hasContent)
238
+ missingFields.push('content');
239
+ if (missingFields.length > 0) {
240
+ console.log('[BlogAPI] PUT_BY_SLUG validation failed:', {
241
+ isPublishing,
242
+ missingFields,
243
+ summary: summary?.trim() || 'missing',
244
+ imageId: image?.id?.trim() || 'missing',
245
+ category: categoryTags?.category?.trim() || 'missing',
246
+ hasContent,
247
+ contentBlocksLength: contentBlocks?.length || 0,
248
+ contentLength: content?.length || 0,
249
+ });
250
+ return NextResponse.json({
251
+ message: `Missing required fields for publishing: ${missingFields.join(', ')}`,
252
+ missingFields
253
+ }, { status: 400 });
254
+ }
255
+ }
256
+ // Slug logic
257
+ let finalSlug = slug;
258
+ if (isPublishing) {
259
+ finalSlug = slugify(title);
260
+ }
261
+ else if (publicationData?.status === 'concept' && !slug.includes('-draft-')) {
262
+ finalSlug = `${slugify(title)}-draft-${Date.now().toString().slice(-4)}`;
263
+ }
264
+ // Update data
265
+ // Determine the final status: if publishing, set to 'published', otherwise preserve or convert draft to concept
266
+ let finalStatus = publicationData?.status;
267
+ if (isPublishing) {
268
+ finalStatus = 'published';
269
+ }
270
+ else if (publicationData?.status === 'draft') {
271
+ finalStatus = 'concept';
272
+ }
273
+ const updateData = {
274
+ title: title.trim(),
275
+ summary: (summary || '').trim(),
276
+ contentBlocks: contentBlocks || [],
277
+ content: content || [],
278
+ image: image || {},
279
+ categoryTags: {
280
+ category: categoryTags?.category?.trim() || '',
281
+ tags: categoryTags?.tags || [],
282
+ },
283
+ publicationData: {
284
+ ...publicationData,
285
+ status: finalStatus,
286
+ date: publicationData?.date ? new Date(publicationData.date) : new Date(),
287
+ },
288
+ seo: seo || {},
289
+ slug: finalSlug,
290
+ authorId: userId,
291
+ updatedAt: new Date(),
292
+ };
293
+ await blogs.updateOne({ slug }, { $set: updateData });
294
+ return NextResponse.json({
295
+ message: 'Blog updated successfully',
296
+ slug: finalSlug,
297
+ });
298
+ }
299
+ catch (err) {
300
+ console.error('[BlogAPI] PUT_BY_SLUG error:', err);
301
+ return NextResponse.json({ error: 'Failed to update blog', detail: err.message }, { status: 500 });
302
+ }
303
+ }
304
+ /**
305
+ * DELETE /api/blogs/[slug] - Delete blog post by slug
306
+ */
307
+ export async function DELETE_BY_SLUG(req, slug, config) {
308
+ try {
309
+ const userId = await config.getUserId(req);
310
+ if (!userId) {
311
+ return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });
312
+ }
313
+ const dbConnection = await config.getDb();
314
+ const db = dbConnection.db();
315
+ const blogs = db.collection(config.collectionName || 'blogs');
316
+ // Verify ownership
317
+ const blog = await blogs.findOne({ slug });
318
+ if (!blog) {
319
+ return NextResponse.json({ error: 'Blog not found' }, { status: 404 });
320
+ }
321
+ if (blog.authorId !== userId) {
322
+ return NextResponse.json({ error: 'Forbidden: Not the author' }, { status: 403 });
323
+ }
324
+ await blogs.deleteOne({ slug });
325
+ return NextResponse.json({ message: 'Blog deleted successfully' });
326
+ }
327
+ catch (err) {
328
+ console.error('[BlogAPI] DELETE_BY_SLUG error:', err);
329
+ return NextResponse.json({ error: 'Failed to delete blog', detail: err.message }, { status: 500 });
330
+ }
331
+ }
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Blog API Exports
3
+ * RESTful API handlers for blog posts
4
+ */
5
+ export { GET, POST, PUT, DELETE, createBlogApiConfig, } from './route';
6
+ export type { BlogApiConfig } from './handler';
7
+ export { GET as GET_HANDLER, POST as POST_HANDLER, GET_BY_SLUG, PUT_BY_SLUG, DELETE_BY_SLUG, } from './handler';
8
+ export { handleBlogApi } from './router';
9
+ export type { BlogApiRouterConfig } from './router';
10
+ export { GET as GET_CATEGORIES } from './categories';
11
+ export { GET as GET_CHECK_TITLE } from './check-title';
12
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/api/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EACH,GAAG,EACH,IAAI,EACJ,GAAG,EACH,MAAM,EACN,mBAAmB,GACtB,MAAM,SAAS,CAAC;AAEjB,YAAY,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAE/C,OAAO,EACH,GAAG,IAAI,WAAW,EAClB,IAAI,IAAI,YAAY,EACpB,WAAW,EACX,WAAW,EACX,cAAc,GACjB,MAAM,WAAW,CAAC;AAGnB,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,YAAY,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAC;AAGpD,OAAO,EAAE,GAAG,IAAI,cAAc,EAAE,MAAM,cAAc,CAAC;AAGrD,OAAO,EAAE,GAAG,IAAI,eAAe,EAAE,MAAM,eAAe,CAAC"}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Blog API Exports
3
+ * RESTful API handlers for blog posts
4
+ */
5
+ export { GET, POST, PUT, DELETE, createBlogApiConfig, } from './route';
6
+ export { GET as GET_HANDLER, POST as POST_HANDLER, GET_BY_SLUG, PUT_BY_SLUG, DELETE_BY_SLUG, } from './handler';
7
+ // Router exports
8
+ export { handleBlogApi } from './router';
9
+ // Categories handler
10
+ export { GET as GET_CATEGORIES } from './categories';
11
+ // Check title handler
12
+ export { GET as GET_CHECK_TITLE } from './check-title';
@@ -0,0 +1,50 @@
1
+ /**
2
+ * Blog API Route Handler
3
+ * Server-only wrapper for the blog API handlers
4
+ * This file should ONLY be used in Next.js API routes
5
+ *
6
+ * IMPORTANT: This file should ONLY be imported in server-side API routes.
7
+ * Do NOT import this in client-side code.
8
+ */
9
+ import { NextRequest, NextResponse } from 'next/server';
10
+ import { BlogApiConfig } from './handler';
11
+ /**
12
+ * Default configuration factory
13
+ * Client apps should provide their own config with MongoDB connection and auth
14
+ */
15
+ export declare function createBlogApiConfig(config: BlogApiConfig): BlogApiConfig;
16
+ /**
17
+ * GET handler - List all blogs or get by slug
18
+ * Usage:
19
+ * GET /api/blogs - List all
20
+ * GET /api/blogs/[slug] - Get by slug
21
+ */
22
+ export declare function GET(req: NextRequest, context?: {
23
+ params?: Promise<{
24
+ slug?: string;
25
+ }>;
26
+ }, config?: BlogApiConfig): Promise<NextResponse>;
27
+ /**
28
+ * POST handler - Create new blog
29
+ * Usage: POST /api/blogs
30
+ */
31
+ export declare function POST(req: NextRequest, context?: any, config?: BlogApiConfig): Promise<NextResponse>;
32
+ /**
33
+ * PUT handler - Update blog by slug
34
+ * Usage: PUT /api/blogs/[slug]
35
+ */
36
+ export declare function PUT(req: NextRequest, context: {
37
+ params: Promise<{
38
+ slug: string;
39
+ }>;
40
+ }, config?: BlogApiConfig): Promise<NextResponse>;
41
+ /**
42
+ * DELETE handler - Delete blog by slug
43
+ * Usage: DELETE /api/blogs/[slug]
44
+ */
45
+ export declare function DELETE(req: NextRequest, context: {
46
+ params: Promise<{
47
+ slug: string;
48
+ }>;
49
+ }, config?: BlogApiConfig): Promise<NextResponse>;
50
+ //# sourceMappingURL=route.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"route.d.ts","sourceRoot":"","sources":["../../src/api/route.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AACxD,OAAO,EAMH,aAAa,EAChB,MAAM,WAAW,CAAC;AAEnB;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,aAAa,GAAG,aAAa,CAExE;AAED;;;;;GAKG;AACH,wBAAsB,GAAG,CACrB,GAAG,EAAE,WAAW,EAChB,OAAO,CAAC,EAAE;IAAE,MAAM,CAAC,EAAE,OAAO,CAAC;QAAE,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;CAAE,EACjD,MAAM,CAAC,EAAE,aAAa,GACvB,OAAO,CAAC,YAAY,CAAC,CAkBvB;AAED;;;GAGG;AACH,wBAAsB,IAAI,CACtB,GAAG,EAAE,WAAW,EAChB,OAAO,CAAC,EAAE,GAAG,EACb,MAAM,CAAC,EAAE,aAAa,GACvB,OAAO,CAAC,YAAY,CAAC,CASvB;AAED;;;GAGG;AACH,wBAAsB,GAAG,CACrB,GAAG,EAAE,WAAW,EAChB,OAAO,EAAE;IAAE,MAAM,EAAE,OAAO,CAAC;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;CAAE,EAC9C,MAAM,CAAC,EAAE,aAAa,GACvB,OAAO,CAAC,YAAY,CAAC,CAUvB;AAED;;;GAGG;AACH,wBAAsB,MAAM,CACxB,GAAG,EAAE,WAAW,EAChB,OAAO,EAAE;IAAE,MAAM,EAAE,OAAO,CAAC;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;CAAE,EAC9C,MAAM,CAAC,EAAE,aAAa,GACvB,OAAO,CAAC,YAAY,CAAC,CAUvB"}