@btst/stack 2.4.0 → 2.5.1

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 (225) hide show
  1. package/dist/node_modules/.pnpm/{@tiptap_core@3.15.3_@tiptap_pm@3.15.3 → @tiptap_core@3.20.0_@tiptap_pm@3.15.3}/node_modules/@tiptap/core/dist/index.cjs +68 -8
  2. package/dist/node_modules/.pnpm/{@tiptap_core@3.15.3_@tiptap_pm@3.15.3 → @tiptap_core@3.20.0_@tiptap_pm@3.15.3}/node_modules/@tiptap/core/dist/index.mjs +68 -8
  3. package/dist/node_modules/.pnpm/{@tiptap_extension-blockquote@3.15.3_@tiptap_core@3.15.3_@tiptap_pm@3.15.3_ → @tiptap_extension-blockquote@3.15.3_@tiptap_core@3.20.0_@tiptap_pm@3.15.3_}/node_modules/@tiptap/extension-blockquote/dist/index.cjs +2 -2
  4. package/dist/node_modules/.pnpm/{@tiptap_extension-blockquote@3.15.3_@tiptap_core@3.15.3_@tiptap_pm@3.15.3_ → @tiptap_extension-blockquote@3.15.3_@tiptap_core@3.20.0_@tiptap_pm@3.15.3_}/node_modules/@tiptap/extension-blockquote/dist/index.mjs +2 -2
  5. package/dist/node_modules/.pnpm/{@tiptap_extension-bold@3.15.3_@tiptap_core@3.15.3_@tiptap_pm@3.15.3_ → @tiptap_extension-bold@3.15.3_@tiptap_core@3.20.0_@tiptap_pm@3.15.3_}/node_modules/@tiptap/extension-bold/dist/index.cjs +2 -2
  6. package/dist/node_modules/.pnpm/{@tiptap_extension-bold@3.15.3_@tiptap_core@3.15.3_@tiptap_pm@3.15.3_ → @tiptap_extension-bold@3.15.3_@tiptap_core@3.20.0_@tiptap_pm@3.15.3_}/node_modules/@tiptap/extension-bold/dist/index.mjs +2 -2
  7. package/dist/node_modules/.pnpm/{@tiptap_extension-bubble-menu@3.15.3_@tiptap_core@3.15.3_@tiptap_pm@3.15.3__@tiptap_pm@3.15.3 → @tiptap_extension-bubble-menu@3.15.3_@tiptap_core@3.20.0_@tiptap_pm@3.15.3__@tiptap_pm@3.15.3}/node_modules/@tiptap/extension-bubble-menu/dist/index.cjs +1 -1
  8. package/dist/node_modules/.pnpm/{@tiptap_extension-bubble-menu@3.15.3_@tiptap_core@3.15.3_@tiptap_pm@3.15.3__@tiptap_pm@3.15.3 → @tiptap_extension-bubble-menu@3.15.3_@tiptap_core@3.20.0_@tiptap_pm@3.15.3__@tiptap_pm@3.15.3}/node_modules/@tiptap/extension-bubble-menu/dist/index.mjs +1 -1
  9. package/dist/node_modules/.pnpm/{@tiptap_extension-code-block-lowlight@3.15.3_@tiptap_core@3.15.3_@tiptap_pm@3.15.3__@ti_2245ac34d84b5693aa60775b0f7781e3 → @tiptap_extension-code-block-lowlight@3.15.3_@tiptap_core@3.20.0_@tiptap_pm@3.15.3__@ti_360e739196c451ebf408f4af5a9f3f24}/node_modules/@tiptap/extension-code-block-lowlight/dist/index.cjs +2 -2
  10. package/dist/node_modules/.pnpm/{@tiptap_extension-code-block-lowlight@3.15.3_@tiptap_core@3.15.3_@tiptap_pm@3.15.3__@ti_2245ac34d84b5693aa60775b0f7781e3 → @tiptap_extension-code-block-lowlight@3.15.3_@tiptap_core@3.20.0_@tiptap_pm@3.15.3__@ti_360e739196c451ebf408f4af5a9f3f24}/node_modules/@tiptap/extension-code-block-lowlight/dist/index.mjs +2 -2
  11. package/dist/node_modules/.pnpm/@tiptap_extension-code-block@3.15.3_@tiptap_core@3.20.0_@tiptap_pm@3.15.3__@tiptap_pm@3.15.3/node_modules/@tiptap/extension-code-block/dist/index.cjs +319 -0
  12. package/dist/node_modules/.pnpm/@tiptap_extension-code-block@3.15.3_@tiptap_core@3.20.0_@tiptap_pm@3.15.3__@tiptap_pm@3.15.3/node_modules/@tiptap/extension-code-block/dist/index.mjs +315 -0
  13. package/dist/node_modules/.pnpm/{@tiptap_extension-code-block@3.15.3_@tiptap_core@3.15.3_@tiptap_pm@3.15.3__@tiptap_pm@3.15.3 → @tiptap_extension-code-block@3.20.0_@tiptap_core@3.20.0_@tiptap_pm@3.15.3__@tiptap_pm@3.15.3}/node_modules/@tiptap/extension-code-block/dist/index.cjs +1 -1
  14. package/dist/node_modules/.pnpm/{@tiptap_extension-code-block@3.15.3_@tiptap_core@3.15.3_@tiptap_pm@3.15.3__@tiptap_pm@3.15.3 → @tiptap_extension-code-block@3.20.0_@tiptap_core@3.20.0_@tiptap_pm@3.15.3__@tiptap_pm@3.15.3}/node_modules/@tiptap/extension-code-block/dist/index.mjs +1 -1
  15. package/dist/node_modules/.pnpm/{@tiptap_extension-code@3.15.3_@tiptap_core@3.15.3_@tiptap_pm@3.15.3_ → @tiptap_extension-code@3.15.3_@tiptap_core@3.20.0_@tiptap_pm@3.15.3_}/node_modules/@tiptap/extension-code/dist/index.cjs +1 -1
  16. package/dist/node_modules/.pnpm/{@tiptap_extension-code@3.15.3_@tiptap_core@3.15.3_@tiptap_pm@3.15.3_ → @tiptap_extension-code@3.15.3_@tiptap_core@3.20.0_@tiptap_pm@3.15.3_}/node_modules/@tiptap/extension-code/dist/index.mjs +1 -1
  17. package/dist/node_modules/.pnpm/{@tiptap_extension-document@3.15.3_@tiptap_core@3.15.3_@tiptap_pm@3.15.3_ → @tiptap_extension-document@3.15.3_@tiptap_core@3.20.0_@tiptap_pm@3.15.3_}/node_modules/@tiptap/extension-document/dist/index.cjs +1 -1
  18. package/dist/node_modules/.pnpm/{@tiptap_extension-document@3.15.3_@tiptap_core@3.15.3_@tiptap_pm@3.15.3_ → @tiptap_extension-document@3.15.3_@tiptap_core@3.20.0_@tiptap_pm@3.15.3_}/node_modules/@tiptap/extension-document/dist/index.mjs +1 -1
  19. package/dist/node_modules/.pnpm/{@tiptap_extension-floating-menu@3.15.3_@floating-ui_dom@1.7.4_@tiptap_core@3.15.3_@tiptap_pm@3.15.3__@tiptap_pm@3.15.3 → @tiptap_extension-floating-menu@3.15.3_@floating-ui_dom@1.7.4_@tiptap_core@3.20.0_@tiptap_pm@3.15.3__@tiptap_pm@3.15.3}/node_modules/@tiptap/extension-floating-menu/dist/index.cjs +1 -1
  20. package/dist/node_modules/.pnpm/{@tiptap_extension-floating-menu@3.15.3_@floating-ui_dom@1.7.4_@tiptap_core@3.15.3_@tiptap_pm@3.15.3__@tiptap_pm@3.15.3 → @tiptap_extension-floating-menu@3.15.3_@floating-ui_dom@1.7.4_@tiptap_core@3.20.0_@tiptap_pm@3.15.3__@tiptap_pm@3.15.3}/node_modules/@tiptap/extension-floating-menu/dist/index.mjs +1 -1
  21. package/dist/node_modules/.pnpm/{@tiptap_extension-hard-break@3.15.3_@tiptap_core@3.15.3_@tiptap_pm@3.15.3_ → @tiptap_extension-hard-break@3.15.3_@tiptap_core@3.20.0_@tiptap_pm@3.15.3_}/node_modules/@tiptap/extension-hard-break/dist/index.cjs +1 -1
  22. package/dist/node_modules/.pnpm/{@tiptap_extension-hard-break@3.15.3_@tiptap_core@3.15.3_@tiptap_pm@3.15.3_ → @tiptap_extension-hard-break@3.15.3_@tiptap_core@3.20.0_@tiptap_pm@3.15.3_}/node_modules/@tiptap/extension-hard-break/dist/index.mjs +1 -1
  23. package/dist/node_modules/.pnpm/{@tiptap_extension-heading@3.15.3_@tiptap_core@3.15.3_@tiptap_pm@3.15.3_ → @tiptap_extension-heading@3.15.3_@tiptap_core@3.20.0_@tiptap_pm@3.15.3_}/node_modules/@tiptap/extension-heading/dist/index.cjs +1 -1
  24. package/dist/node_modules/.pnpm/{@tiptap_extension-heading@3.15.3_@tiptap_core@3.15.3_@tiptap_pm@3.15.3_ → @tiptap_extension-heading@3.15.3_@tiptap_core@3.20.0_@tiptap_pm@3.15.3_}/node_modules/@tiptap/extension-heading/dist/index.mjs +1 -1
  25. package/dist/node_modules/.pnpm/{@tiptap_extension-horizontal-rule@3.15.3_@tiptap_core@3.15.3_@tiptap_pm@3.15.3__@tiptap_pm@3.15.3 → @tiptap_extension-horizontal-rule@3.15.3_@tiptap_core@3.20.0_@tiptap_pm@3.15.3__@tiptap_pm@3.15.3}/node_modules/@tiptap/extension-horizontal-rule/dist/index.cjs +1 -1
  26. package/dist/node_modules/.pnpm/{@tiptap_extension-horizontal-rule@3.15.3_@tiptap_core@3.15.3_@tiptap_pm@3.15.3__@tiptap_pm@3.15.3 → @tiptap_extension-horizontal-rule@3.15.3_@tiptap_core@3.20.0_@tiptap_pm@3.15.3__@tiptap_pm@3.15.3}/node_modules/@tiptap/extension-horizontal-rule/dist/index.mjs +1 -1
  27. package/dist/node_modules/.pnpm/{@tiptap_extension-image@3.15.3_@tiptap_core@3.15.3_@tiptap_pm@3.15.3_ → @tiptap_extension-image@3.15.3_@tiptap_core@3.20.0_@tiptap_pm@3.15.3_}/node_modules/@tiptap/extension-image/dist/index.cjs +1 -1
  28. package/dist/node_modules/.pnpm/{@tiptap_extension-image@3.15.3_@tiptap_core@3.15.3_@tiptap_pm@3.15.3_ → @tiptap_extension-image@3.15.3_@tiptap_core@3.20.0_@tiptap_pm@3.15.3_}/node_modules/@tiptap/extension-image/dist/index.mjs +1 -1
  29. package/dist/node_modules/.pnpm/{@tiptap_extension-italic@3.15.3_@tiptap_core@3.15.3_@tiptap_pm@3.15.3_ → @tiptap_extension-italic@3.15.3_@tiptap_core@3.20.0_@tiptap_pm@3.15.3_}/node_modules/@tiptap/extension-italic/dist/index.cjs +1 -1
  30. package/dist/node_modules/.pnpm/{@tiptap_extension-italic@3.15.3_@tiptap_core@3.15.3_@tiptap_pm@3.15.3_ → @tiptap_extension-italic@3.15.3_@tiptap_core@3.20.0_@tiptap_pm@3.15.3_}/node_modules/@tiptap/extension-italic/dist/index.mjs +1 -1
  31. package/dist/node_modules/.pnpm/{@tiptap_extension-link@3.15.3_@tiptap_core@3.15.3_@tiptap_pm@3.15.3__@tiptap_pm@3.15.3 → @tiptap_extension-link@3.20.0_@tiptap_core@3.20.0_@tiptap_pm@3.15.3__@tiptap_pm@3.15.3}/node_modules/@tiptap/extension-link/dist/index.cjs +28 -22
  32. package/dist/node_modules/.pnpm/{@tiptap_extension-link@3.15.3_@tiptap_core@3.15.3_@tiptap_pm@3.15.3__@tiptap_pm@3.15.3 → @tiptap_extension-link@3.20.0_@tiptap_core@3.20.0_@tiptap_pm@3.15.3__@tiptap_pm@3.15.3}/node_modules/@tiptap/extension-link/dist/index.mjs +28 -22
  33. package/dist/node_modules/.pnpm/{@tiptap_extension-list@3.15.3_@tiptap_core@3.15.3_@tiptap_pm@3.15.3__@tiptap_pm@3.15.3 → @tiptap_extension-list@3.15.3_@tiptap_core@3.20.0_@tiptap_pm@3.15.3__@tiptap_pm@3.15.3}/node_modules/@tiptap/extension-list/dist/index.cjs +1 -1
  34. package/dist/node_modules/.pnpm/{@tiptap_extension-list@3.15.3_@tiptap_core@3.15.3_@tiptap_pm@3.15.3__@tiptap_pm@3.15.3 → @tiptap_extension-list@3.15.3_@tiptap_core@3.20.0_@tiptap_pm@3.15.3__@tiptap_pm@3.15.3}/node_modules/@tiptap/extension-list/dist/index.mjs +1 -1
  35. package/dist/node_modules/.pnpm/{@tiptap_extension-paragraph@3.15.3_@tiptap_core@3.15.3_@tiptap_pm@3.15.3_ → @tiptap_extension-paragraph@3.15.3_@tiptap_core@3.20.0_@tiptap_pm@3.15.3_}/node_modules/@tiptap/extension-paragraph/dist/index.cjs +1 -1
  36. package/dist/node_modules/.pnpm/{@tiptap_extension-paragraph@3.15.3_@tiptap_core@3.15.3_@tiptap_pm@3.15.3_ → @tiptap_extension-paragraph@3.15.3_@tiptap_core@3.20.0_@tiptap_pm@3.15.3_}/node_modules/@tiptap/extension-paragraph/dist/index.mjs +1 -1
  37. package/dist/node_modules/.pnpm/{@tiptap_extension-strike@3.15.3_@tiptap_core@3.15.3_@tiptap_pm@3.15.3_ → @tiptap_extension-strike@3.15.3_@tiptap_core@3.20.0_@tiptap_pm@3.15.3_}/node_modules/@tiptap/extension-strike/dist/index.cjs +1 -1
  38. package/dist/node_modules/.pnpm/{@tiptap_extension-strike@3.15.3_@tiptap_core@3.15.3_@tiptap_pm@3.15.3_ → @tiptap_extension-strike@3.15.3_@tiptap_core@3.20.0_@tiptap_pm@3.15.3_}/node_modules/@tiptap/extension-strike/dist/index.mjs +1 -1
  39. package/dist/node_modules/.pnpm/{@tiptap_extension-table@3.15.3_@tiptap_core@3.15.3_@tiptap_pm@3.15.3__@tiptap_pm@3.15.3 → @tiptap_extension-table@3.15.3_@tiptap_core@3.20.0_@tiptap_pm@3.15.3__@tiptap_pm@3.15.3}/node_modules/@tiptap/extension-table/dist/index.cjs +1 -1
  40. package/dist/node_modules/.pnpm/{@tiptap_extension-table@3.15.3_@tiptap_core@3.15.3_@tiptap_pm@3.15.3__@tiptap_pm@3.15.3 → @tiptap_extension-table@3.15.3_@tiptap_core@3.20.0_@tiptap_pm@3.15.3__@tiptap_pm@3.15.3}/node_modules/@tiptap/extension-table/dist/index.mjs +1 -1
  41. package/dist/node_modules/.pnpm/{@tiptap_extension-text-style@3.15.3_@tiptap_core@3.15.3_@tiptap_pm@3.15.3_ → @tiptap_extension-text-style@3.15.3_@tiptap_core@3.20.0_@tiptap_pm@3.15.3_}/node_modules/@tiptap/extension-text-style/dist/index.cjs +1 -1
  42. package/dist/node_modules/.pnpm/{@tiptap_extension-text-style@3.15.3_@tiptap_core@3.15.3_@tiptap_pm@3.15.3_ → @tiptap_extension-text-style@3.15.3_@tiptap_core@3.20.0_@tiptap_pm@3.15.3_}/node_modules/@tiptap/extension-text-style/dist/index.mjs +1 -1
  43. package/dist/node_modules/.pnpm/{@tiptap_extension-text@3.15.3_@tiptap_core@3.15.3_@tiptap_pm@3.15.3_ → @tiptap_extension-text@3.15.3_@tiptap_core@3.20.0_@tiptap_pm@3.15.3_}/node_modules/@tiptap/extension-text/dist/index.cjs +1 -1
  44. package/dist/node_modules/.pnpm/{@tiptap_extension-text@3.15.3_@tiptap_core@3.15.3_@tiptap_pm@3.15.3_ → @tiptap_extension-text@3.15.3_@tiptap_core@3.20.0_@tiptap_pm@3.15.3_}/node_modules/@tiptap/extension-text/dist/index.mjs +1 -1
  45. package/dist/node_modules/.pnpm/{@tiptap_extension-typography@3.15.3_@tiptap_core@3.15.3_@tiptap_pm@3.15.3_ → @tiptap_extension-typography@3.15.3_@tiptap_core@3.20.0_@tiptap_pm@3.15.3_}/node_modules/@tiptap/extension-typography/dist/index.cjs +1 -1
  46. package/dist/node_modules/.pnpm/{@tiptap_extension-typography@3.15.3_@tiptap_core@3.15.3_@tiptap_pm@3.15.3_ → @tiptap_extension-typography@3.15.3_@tiptap_core@3.20.0_@tiptap_pm@3.15.3_}/node_modules/@tiptap/extension-typography/dist/index.mjs +1 -1
  47. package/dist/node_modules/.pnpm/{@tiptap_extension-underline@3.15.3_@tiptap_core@3.15.3_@tiptap_pm@3.15.3_ → @tiptap_extension-underline@3.15.3_@tiptap_core@3.20.0_@tiptap_pm@3.15.3_}/node_modules/@tiptap/extension-underline/dist/index.cjs +1 -1
  48. package/dist/node_modules/.pnpm/{@tiptap_extension-underline@3.15.3_@tiptap_core@3.15.3_@tiptap_pm@3.15.3_ → @tiptap_extension-underline@3.15.3_@tiptap_core@3.20.0_@tiptap_pm@3.15.3_}/node_modules/@tiptap/extension-underline/dist/index.mjs +1 -1
  49. package/dist/node_modules/.pnpm/{@tiptap_extensions@3.15.3_@tiptap_core@3.15.3_@tiptap_pm@3.15.3__@tiptap_pm@3.15.3 → @tiptap_extensions@3.15.3_@tiptap_core@3.20.0_@tiptap_pm@3.15.3__@tiptap_pm@3.15.3}/node_modules/@tiptap/extensions/dist/index.cjs +1 -1
  50. package/dist/node_modules/.pnpm/{@tiptap_extensions@3.15.3_@tiptap_core@3.15.3_@tiptap_pm@3.15.3__@tiptap_pm@3.15.3 → @tiptap_extensions@3.15.3_@tiptap_core@3.20.0_@tiptap_pm@3.15.3__@tiptap_pm@3.15.3}/node_modules/@tiptap/extensions/dist/index.mjs +1 -1
  51. package/dist/node_modules/.pnpm/{@tiptap_markdown@3.15.3_@tiptap_core@3.15.3_@tiptap_pm@3.15.3__@tiptap_pm@3.15.3 → @tiptap_markdown@3.15.3_@tiptap_core@3.20.0_@tiptap_pm@3.15.3__@tiptap_pm@3.15.3}/node_modules/@tiptap/markdown/dist/index.cjs +1 -1
  52. package/dist/node_modules/.pnpm/{@tiptap_markdown@3.15.3_@tiptap_core@3.15.3_@tiptap_pm@3.15.3__@tiptap_pm@3.15.3 → @tiptap_markdown@3.15.3_@tiptap_core@3.20.0_@tiptap_pm@3.15.3__@tiptap_pm@3.15.3}/node_modules/@tiptap/markdown/dist/index.mjs +1 -1
  53. package/dist/node_modules/.pnpm/{@tiptap_react@3.15.3_@floating-ui_dom@1.7.4_@tiptap_core@3.15.3_@tiptap_pm@3.15.3__@tip_d7a2a9a319317617a8908309649a6dda → @tiptap_react@3.15.3_@floating-ui_dom@1.7.4_@tiptap_core@3.20.0_@tiptap_pm@3.15.3__@tip_b42b5b2d59902d8a01cd4cc3e2d5dc64}/node_modules/@tiptap/react/dist/index.cjs +1 -1
  54. package/dist/node_modules/.pnpm/{@tiptap_react@3.15.3_@floating-ui_dom@1.7.4_@tiptap_core@3.15.3_@tiptap_pm@3.15.3__@tip_d7a2a9a319317617a8908309649a6dda → @tiptap_react@3.15.3_@floating-ui_dom@1.7.4_@tiptap_core@3.20.0_@tiptap_pm@3.15.3__@tip_b42b5b2d59902d8a01cd4cc3e2d5dc64}/node_modules/@tiptap/react/dist/index.mjs +2 -2
  55. package/dist/node_modules/.pnpm/{@tiptap_react@3.15.3_@floating-ui_dom@1.7.4_@tiptap_core@3.15.3_@tiptap_pm@3.15.3__@tip_d7a2a9a319317617a8908309649a6dda → @tiptap_react@3.15.3_@floating-ui_dom@1.7.4_@tiptap_core@3.20.0_@tiptap_pm@3.15.3__@tip_b42b5b2d59902d8a01cd4cc3e2d5dc64}/node_modules/@tiptap/react/dist/menus/index.cjs +2 -2
  56. package/dist/node_modules/.pnpm/{@tiptap_react@3.15.3_@floating-ui_dom@1.7.4_@tiptap_core@3.15.3_@tiptap_pm@3.15.3__@tip_d7a2a9a319317617a8908309649a6dda → @tiptap_react@3.15.3_@floating-ui_dom@1.7.4_@tiptap_core@3.20.0_@tiptap_pm@3.15.3__@tip_b42b5b2d59902d8a01cd4cc3e2d5dc64}/node_modules/@tiptap/react/dist/menus/index.mjs +2 -2
  57. package/dist/node_modules/.pnpm/@tiptap_starter-kit@3.15.3/node_modules/@tiptap/starter-kit/dist/index.cjs +17 -17
  58. package/dist/node_modules/.pnpm/@tiptap_starter-kit@3.15.3/node_modules/@tiptap/starter-kit/dist/index.mjs +17 -17
  59. package/dist/packages/stack/src/plugins/ai-chat/api/plugin.cjs +33 -47
  60. package/dist/packages/stack/src/plugins/ai-chat/api/plugin.mjs +33 -47
  61. package/dist/packages/stack/src/plugins/ai-chat/client/plugin.cjs +14 -21
  62. package/dist/packages/stack/src/plugins/ai-chat/client/plugin.mjs +15 -22
  63. package/dist/packages/stack/src/plugins/blog/api/plugin.cjs +28 -45
  64. package/dist/packages/stack/src/plugins/blog/api/plugin.mjs +22 -39
  65. package/dist/packages/stack/src/plugins/blog/client/plugin.cjs +23 -27
  66. package/dist/packages/stack/src/plugins/blog/client/plugin.mjs +24 -28
  67. package/dist/packages/stack/src/plugins/cms/api/plugin.cjs +14 -17
  68. package/dist/packages/stack/src/plugins/cms/api/plugin.mjs +14 -17
  69. package/dist/packages/stack/src/plugins/cms/client/plugin.cjs +11 -15
  70. package/dist/packages/stack/src/plugins/cms/client/plugin.mjs +12 -16
  71. package/dist/packages/stack/src/plugins/form-builder/api/plugin.cjs +58 -62
  72. package/dist/packages/stack/src/plugins/form-builder/api/plugin.mjs +58 -62
  73. package/dist/packages/stack/src/plugins/form-builder/client/plugin.cjs +12 -12
  74. package/dist/packages/stack/src/plugins/form-builder/client/plugin.mjs +13 -13
  75. package/dist/packages/stack/src/plugins/kanban/api/plugin.cjs +86 -117
  76. package/dist/packages/stack/src/plugins/kanban/api/plugin.mjs +83 -114
  77. package/dist/packages/stack/src/plugins/kanban/client/plugin.cjs +22 -29
  78. package/dist/packages/stack/src/plugins/kanban/client/plugin.mjs +23 -30
  79. package/dist/packages/stack/src/plugins/open-api/api/generator.cjs +2 -1
  80. package/dist/packages/stack/src/plugins/open-api/api/generator.mjs +2 -1
  81. package/dist/packages/stack/src/plugins/ui-builder/client/plugin.cjs +8 -8
  82. package/dist/packages/stack/src/plugins/ui-builder/client/plugin.mjs +9 -9
  83. package/dist/packages/stack/src/plugins/utils.cjs +42 -0
  84. package/dist/packages/stack/src/plugins/utils.mjs +41 -1
  85. package/dist/packages/ui/src/components/minimal-tiptap/components/bubble-menu/link-bubble-menu.cjs +1 -1
  86. package/dist/packages/ui/src/components/minimal-tiptap/components/bubble-menu/link-bubble-menu.mjs +1 -1
  87. package/dist/packages/ui/src/components/minimal-tiptap/extensions/code-block-lowlight/code-block-lowlight.cjs +1 -1
  88. package/dist/packages/ui/src/components/minimal-tiptap/extensions/code-block-lowlight/code-block-lowlight.mjs +1 -1
  89. package/dist/packages/ui/src/components/minimal-tiptap/extensions/color/color.cjs +1 -1
  90. package/dist/packages/ui/src/components/minimal-tiptap/extensions/color/color.mjs +1 -1
  91. package/dist/packages/ui/src/components/minimal-tiptap/extensions/file-handler/index.cjs +1 -1
  92. package/dist/packages/ui/src/components/minimal-tiptap/extensions/file-handler/index.mjs +1 -1
  93. package/dist/packages/ui/src/components/minimal-tiptap/extensions/horizontal-rule/horizontal-rule.cjs +1 -1
  94. package/dist/packages/ui/src/components/minimal-tiptap/extensions/horizontal-rule/horizontal-rule.mjs +1 -1
  95. package/dist/packages/ui/src/components/minimal-tiptap/extensions/image/components/image-view-block.cjs +1 -1
  96. package/dist/packages/ui/src/components/minimal-tiptap/extensions/image/components/image-view-block.mjs +1 -1
  97. package/dist/packages/ui/src/components/minimal-tiptap/extensions/image/image.cjs +2 -2
  98. package/dist/packages/ui/src/components/minimal-tiptap/extensions/image/image.mjs +2 -2
  99. package/dist/packages/ui/src/components/minimal-tiptap/extensions/markdown-paste/markdown-paste.cjs +1 -1
  100. package/dist/packages/ui/src/components/minimal-tiptap/extensions/markdown-paste/markdown-paste.mjs +1 -1
  101. package/dist/packages/ui/src/components/minimal-tiptap/extensions/reset-marks-on-enter/reset-marks-on-enter.cjs +1 -1
  102. package/dist/packages/ui/src/components/minimal-tiptap/extensions/reset-marks-on-enter/reset-marks-on-enter.mjs +1 -1
  103. package/dist/packages/ui/src/components/minimal-tiptap/extensions/unset-all-marks/unset-all-marks.cjs +1 -1
  104. package/dist/packages/ui/src/components/minimal-tiptap/extensions/unset-all-marks/unset-all-marks.mjs +1 -1
  105. package/dist/packages/ui/src/components/minimal-tiptap/hooks/use-minimal-tiptap.cjs +7 -7
  106. package/dist/packages/ui/src/components/minimal-tiptap/hooks/use-minimal-tiptap.mjs +7 -7
  107. package/dist/packages/ui/src/components/minimal-tiptap/hooks/use-tiptap-editor.cjs +1 -1
  108. package/dist/packages/ui/src/components/minimal-tiptap/hooks/use-tiptap-editor.mjs +1 -1
  109. package/dist/packages/ui/src/components/minimal-tiptap/minimal-tiptap.cjs +1 -1
  110. package/dist/packages/ui/src/components/minimal-tiptap/minimal-tiptap.mjs +1 -1
  111. package/dist/plugins/ai-chat/api/index.d.cts +1 -1
  112. package/dist/plugins/ai-chat/api/index.d.mts +1 -1
  113. package/dist/plugins/ai-chat/api/index.d.ts +1 -1
  114. package/dist/plugins/ai-chat/client/hooks/index.d.cts +1 -1
  115. package/dist/plugins/ai-chat/client/hooks/index.d.mts +1 -1
  116. package/dist/plugins/ai-chat/client/hooks/index.d.ts +1 -1
  117. package/dist/plugins/ai-chat/client/index.d.cts +8 -8
  118. package/dist/plugins/ai-chat/client/index.d.mts +8 -8
  119. package/dist/plugins/ai-chat/client/index.d.ts +8 -8
  120. package/dist/plugins/ai-chat/query-keys.d.cts +1 -1
  121. package/dist/plugins/ai-chat/query-keys.d.mts +1 -1
  122. package/dist/plugins/ai-chat/query-keys.d.ts +1 -1
  123. package/dist/plugins/blog/api/index.d.cts +1 -1
  124. package/dist/plugins/blog/api/index.d.mts +1 -1
  125. package/dist/plugins/blog/api/index.d.ts +1 -1
  126. package/dist/plugins/blog/client/index.d.cts +12 -12
  127. package/dist/plugins/blog/client/index.d.mts +12 -12
  128. package/dist/plugins/blog/client/index.d.ts +12 -12
  129. package/dist/plugins/blog/query-keys.d.cts +1 -1
  130. package/dist/plugins/blog/query-keys.d.mts +1 -1
  131. package/dist/plugins/blog/query-keys.d.ts +1 -1
  132. package/dist/plugins/client/index.cjs +1 -0
  133. package/dist/plugins/client/index.d.cts +8 -1
  134. package/dist/plugins/client/index.d.mts +8 -1
  135. package/dist/plugins/client/index.d.ts +8 -1
  136. package/dist/plugins/client/index.mjs +1 -1
  137. package/dist/plugins/cms/api/index.d.cts +2 -2
  138. package/dist/plugins/cms/api/index.d.mts +2 -2
  139. package/dist/plugins/cms/api/index.d.ts +2 -2
  140. package/dist/plugins/cms/client/hooks/index.d.cts +1 -1
  141. package/dist/plugins/cms/client/hooks/index.d.mts +1 -1
  142. package/dist/plugins/cms/client/hooks/index.d.ts +1 -1
  143. package/dist/plugins/cms/client/index.d.cts +6 -6
  144. package/dist/plugins/cms/client/index.d.mts +6 -6
  145. package/dist/plugins/cms/client/index.d.ts +6 -6
  146. package/dist/plugins/cms/query-keys.d.cts +2 -2
  147. package/dist/plugins/cms/query-keys.d.mts +2 -2
  148. package/dist/plugins/cms/query-keys.d.ts +2 -2
  149. package/dist/plugins/form-builder/api/index.d.cts +2 -2
  150. package/dist/plugins/form-builder/api/index.d.mts +2 -2
  151. package/dist/plugins/form-builder/api/index.d.ts +2 -2
  152. package/dist/plugins/form-builder/client/components/index.d.cts +1 -1
  153. package/dist/plugins/form-builder/client/components/index.d.mts +1 -1
  154. package/dist/plugins/form-builder/client/components/index.d.ts +1 -1
  155. package/dist/plugins/form-builder/client/hooks/index.d.cts +1 -1
  156. package/dist/plugins/form-builder/client/hooks/index.d.mts +1 -1
  157. package/dist/plugins/form-builder/client/hooks/index.d.ts +1 -1
  158. package/dist/plugins/form-builder/client/index.d.cts +6 -6
  159. package/dist/plugins/form-builder/client/index.d.mts +6 -6
  160. package/dist/plugins/form-builder/client/index.d.ts +6 -6
  161. package/dist/plugins/form-builder/query-keys.d.cts +2 -2
  162. package/dist/plugins/form-builder/query-keys.d.mts +2 -2
  163. package/dist/plugins/form-builder/query-keys.d.ts +2 -2
  164. package/dist/plugins/kanban/api/index.d.cts +1 -1
  165. package/dist/plugins/kanban/api/index.d.mts +1 -1
  166. package/dist/plugins/kanban/api/index.d.ts +1 -1
  167. package/dist/plugins/kanban/client/index.d.cts +12 -12
  168. package/dist/plugins/kanban/client/index.d.mts +12 -12
  169. package/dist/plugins/kanban/client/index.d.ts +12 -12
  170. package/dist/plugins/kanban/query-keys.d.cts +1 -1
  171. package/dist/plugins/kanban/query-keys.d.mts +1 -1
  172. package/dist/plugins/kanban/query-keys.d.ts +1 -1
  173. package/dist/plugins/ui-builder/client/hooks/index.d.cts +1 -1
  174. package/dist/plugins/ui-builder/client/hooks/index.d.mts +1 -1
  175. package/dist/plugins/ui-builder/client/hooks/index.d.ts +1 -1
  176. package/dist/plugins/ui-builder/client/index.d.cts +3 -3
  177. package/dist/plugins/ui-builder/client/index.d.mts +3 -3
  178. package/dist/plugins/ui-builder/client/index.d.ts +3 -3
  179. package/dist/plugins/ui-builder/index.d.cts +2 -2
  180. package/dist/plugins/ui-builder/index.d.mts +2 -2
  181. package/dist/plugins/ui-builder/index.d.ts +2 -2
  182. package/dist/shared/{stack.C-WUPMT6.d.cts → stack.B2xZTSiO.d.cts} +4 -4
  183. package/dist/shared/{stack.CczspVn2.d.mts → stack.B58oHdqm.d.mts} +1 -1
  184. package/dist/shared/{stack.BepFXT3w.d.mts → stack.B8D4r97Z.d.mts} +22 -22
  185. package/dist/shared/{stack.CVDTkMoO.d.mts → stack.B8QD11QU.d.cts} +7 -7
  186. package/dist/shared/{stack.CVDTkMoO.d.cts → stack.B8QD11QU.d.mts} +7 -7
  187. package/dist/shared/{stack.CVDTkMoO.d.ts → stack.B8QD11QU.d.ts} +7 -7
  188. package/dist/shared/{stack.kcdnD4gA.d.cts → stack.BgTmujxW.d.mts} +1 -1
  189. package/dist/shared/{stack.DdI5W6MB.d.mts → stack.BozPgbrZ.d.cts} +19 -19
  190. package/dist/shared/{stack.DdI5W6MB.d.ts → stack.BozPgbrZ.d.mts} +19 -19
  191. package/dist/shared/{stack.DdI5W6MB.d.cts → stack.BozPgbrZ.d.ts} +19 -19
  192. package/dist/shared/{stack.BUkC2EsZ.d.cts → stack.C9Mg2Q46.d.cts} +1 -1
  193. package/dist/shared/{stack.Kq2-QzOC.d.ts → stack.CLQuVdwK.d.ts} +1 -1
  194. package/dist/shared/{stack.B7ONvlD_.d.mts → stack.CSx98K5H.d.cts} +1 -1
  195. package/dist/shared/{stack.BEn34wW6.d.ts → stack.CTDVxbrA.d.ts} +12 -12
  196. package/dist/shared/{stack.C-Ptrz8s.d.ts → stack.Cj_zKww4.d.ts} +4 -4
  197. package/dist/shared/{stack.DWoCZff7.d.cts → stack.D-b5zbPm.d.cts} +12 -12
  198. package/dist/shared/{stack.CL8ts1Mu.d.ts → stack.DXnclTG7.d.ts} +8 -8
  199. package/dist/shared/{stack.heOA9gzA.d.cts → stack.DaZM10cp.d.cts} +8 -8
  200. package/dist/shared/{stack.CgWzG5jH.d.ts → stack.DgKOwl20.d.ts} +22 -22
  201. package/dist/shared/{stack.DTDxgFj8.d.mts → stack.FVWf2JhZ.d.mts} +12 -12
  202. package/dist/shared/{stack.Dk5r4W1F.d.mts → stack.cfCkioTe.d.mts} +8 -8
  203. package/dist/shared/{stack.6fUOjLs9.d.mts → stack.dH7u-TJH.d.mts} +4 -4
  204. package/dist/shared/{stack.DASmUVjX.d.ts → stack.sO33ZDhK.d.ts} +1 -1
  205. package/dist/shared/{stack.D3GB6wKv.d.cts → stack.uWSqCWAb.d.cts} +22 -22
  206. package/package.json +1 -1
  207. package/src/plugins/ai-chat/api/plugin.ts +48 -63
  208. package/src/plugins/ai-chat/client/plugin.tsx +23 -31
  209. package/src/plugins/blog/api/plugin.ts +31 -47
  210. package/src/plugins/blog/client/plugin.tsx +36 -39
  211. package/src/plugins/client/index.ts +5 -1
  212. package/src/plugins/cms/api/plugin.ts +14 -17
  213. package/src/plugins/cms/client/plugin.tsx +18 -21
  214. package/src/plugins/cms/types.ts +7 -7
  215. package/src/plugins/form-builder/api/plugin.ts +64 -64
  216. package/src/plugins/form-builder/client/plugin.tsx +19 -18
  217. package/src/plugins/form-builder/types.ts +19 -24
  218. package/src/plugins/kanban/api/plugin.ts +111 -136
  219. package/src/plugins/kanban/client/plugin.tsx +35 -41
  220. package/src/plugins/open-api/api/generator.ts +3 -1
  221. package/src/plugins/ui-builder/client/plugin.tsx +11 -10
  222. package/src/plugins/ui-builder/types.ts +4 -4
  223. package/src/plugins/utils.ts +92 -1
  224. /package/dist/node_modules/.pnpm/{@tiptap_core@3.15.3_@tiptap_pm@3.15.3 → @tiptap_core@3.20.0_@tiptap_pm@3.15.3}/node_modules/@tiptap/core/dist/jsx-runtime/jsx-runtime.cjs +0 -0
  225. /package/dist/node_modules/.pnpm/{@tiptap_core@3.15.3_@tiptap_pm@3.15.3 → @tiptap_core@3.20.0_@tiptap_pm@3.15.3}/node_modules/@tiptap/core/dist/jsx-runtime/jsx-runtime.mjs +0 -0
@@ -21,6 +21,7 @@ import {
21
21
  BUILT_IN_PAGE_TOOL_ROUTE_ALLOWLIST,
22
22
  BUILT_IN_PAGE_TOOL_SCHEMAS,
23
23
  } from "./page-tools";
24
+ import { runHookWithShim } from "../../utils";
24
25
 
25
26
  /**
26
27
  * Context passed to AI Chat API hooks
@@ -40,48 +41,46 @@ export interface ChatApiContext<TBody = any, TParams = any, TQuery = any> {
40
41
  */
41
42
  export interface AiChatBackendHooks {
42
43
  // ============== Authorization Hooks ==============
43
- // Return false to deny access
44
+ // Throw an error to deny access
44
45
 
45
46
  /**
46
- * Called before processing a chat message. Return false to deny access.
47
+ * Called before processing a chat message. Throw an error to deny access.
47
48
  * @param messages - Array of messages being sent
48
49
  * @param context - Request context with headers, etc.
49
50
  */
50
51
  onBeforeChat?: (
51
52
  messages: Array<{ role: string; content: string }>,
52
53
  context: ChatApiContext,
53
- ) => Promise<boolean> | boolean;
54
+ ) => Promise<void> | void;
54
55
 
55
56
  /**
56
- * Called before listing conversations. Return false to deny access.
57
+ * Called before listing conversations. Throw an error to deny access.
57
58
  * @param context - Request context with headers, etc.
58
59
  */
59
- onBeforeListConversations?: (
60
- context: ChatApiContext,
61
- ) => Promise<boolean> | boolean;
60
+ onBeforeListConversations?: (context: ChatApiContext) => Promise<void> | void;
62
61
 
63
62
  /**
64
- * Called before getting a single conversation. Return false to deny access.
63
+ * Called before getting a single conversation. Throw an error to deny access.
65
64
  * @param conversationId - ID of the conversation being accessed
66
65
  * @param context - Request context with headers, etc.
67
66
  */
68
67
  onBeforeGetConversation?: (
69
68
  conversationId: string,
70
69
  context: ChatApiContext,
71
- ) => Promise<boolean> | boolean;
70
+ ) => Promise<void> | void;
72
71
 
73
72
  /**
74
- * Called before creating a conversation. Return false to deny access.
73
+ * Called before creating a conversation. Throw an error to deny access.
75
74
  * @param data - Conversation data being created
76
75
  * @param context - Request context with headers, etc.
77
76
  */
78
77
  onBeforeCreateConversation?: (
79
78
  data: { id?: string; title?: string },
80
79
  context: ChatApiContext,
81
- ) => Promise<boolean> | boolean;
80
+ ) => Promise<void> | void;
82
81
 
83
82
  /**
84
- * Called before updating a conversation. Return false to deny access.
83
+ * Called before updating a conversation. Throw an error to deny access.
85
84
  * @param conversationId - ID of the conversation being updated
86
85
  * @param data - Updated conversation data
87
86
  * @param context - Request context with headers, etc.
@@ -90,17 +89,17 @@ export interface AiChatBackendHooks {
90
89
  conversationId: string,
91
90
  data: { title?: string },
92
91
  context: ChatApiContext,
93
- ) => Promise<boolean> | boolean;
92
+ ) => Promise<void> | void;
94
93
 
95
94
  /**
96
- * Called before deleting a conversation. Return false to deny access.
95
+ * Called before deleting a conversation. Throw an error to deny access.
97
96
  * @param conversationId - ID of the conversation being deleted
98
97
  * @param context - Request context with headers, etc.
99
98
  */
100
99
  onBeforeDeleteConversation?: (
101
100
  conversationId: string,
102
101
  context: ChatApiContext,
103
- ) => Promise<boolean> | boolean;
102
+ ) => Promise<void> | void;
104
103
 
105
104
  /**
106
105
  * Called after the structural routeName/allowlist validation, with the list
@@ -452,15 +451,11 @@ export const aiChatBackendPlugin = <
452
451
  role: msg.role,
453
452
  content: getMessageTextContent(msg),
454
453
  }));
455
- const canChat = await config.hooks.onBeforeChat(
456
- messagesForHook,
457
- context,
454
+ await runHookWithShim(
455
+ () => config.hooks!.onBeforeChat!(messagesForHook, context),
456
+ ctx.error,
457
+ "Unauthorized: Cannot start chat",
458
458
  );
459
- if (!canChat) {
460
- throw ctx.error(403, {
461
- message: "Unauthorized: Cannot start chat",
462
- });
463
- }
464
459
  }
465
460
 
466
461
  const firstMessage = uiMessages[0];
@@ -848,15 +843,15 @@ export const aiChatBackendPlugin = <
848
843
 
849
844
  // Authorization hook
850
845
  if (config.hooks?.onBeforeCreateConversation) {
851
- const canCreate = await config.hooks.onBeforeCreateConversation(
852
- { id, title },
853
- context,
846
+ await runHookWithShim(
847
+ () =>
848
+ config.hooks!.onBeforeCreateConversation!(
849
+ { id, title },
850
+ context,
851
+ ),
852
+ ctx.error,
853
+ "Unauthorized: Cannot create conversation",
854
854
  );
855
- if (!canCreate) {
856
- throw ctx.error(403, {
857
- message: "Unauthorized: Cannot create conversation",
858
- });
859
- }
860
855
  }
861
856
 
862
857
  const newConv = await adapter.create<Conversation>({
@@ -914,13 +909,11 @@ export const aiChatBackendPlugin = <
914
909
 
915
910
  // Authorization hook
916
911
  if (config.hooks?.onBeforeListConversations) {
917
- const canList =
918
- await config.hooks.onBeforeListConversations(context);
919
- if (!canList) {
920
- throw ctx.error(403, {
921
- message: "Unauthorized: Cannot list conversations",
922
- });
923
- }
912
+ await runHookWithShim(
913
+ () => config.hooks!.onBeforeListConversations!(context),
914
+ ctx.error,
915
+ "Unauthorized: Cannot list conversations",
916
+ );
924
917
  }
925
918
 
926
919
  // Build where conditions - filter by userId if set
@@ -991,15 +984,11 @@ export const aiChatBackendPlugin = <
991
984
 
992
985
  // Authorization hook
993
986
  if (config.hooks?.onBeforeGetConversation) {
994
- const canGet = await config.hooks.onBeforeGetConversation(
995
- id,
996
- context,
987
+ await runHookWithShim(
988
+ () => config.hooks!.onBeforeGetConversation!(id, context),
989
+ ctx.error,
990
+ "Unauthorized: Cannot get conversation",
997
991
  );
998
- if (!canGet) {
999
- throw ctx.error(403, {
1000
- message: "Unauthorized: Cannot get conversation",
1001
- });
1002
- }
1003
992
  }
1004
993
 
1005
994
  // Fetch conversation with messages in a single query using join
@@ -1116,16 +1105,16 @@ export const aiChatBackendPlugin = <
1116
1105
 
1117
1106
  // Authorization hook
1118
1107
  if (config.hooks?.onBeforeUpdateConversation) {
1119
- const canUpdate = await config.hooks.onBeforeUpdateConversation(
1120
- id,
1121
- { title },
1122
- context,
1108
+ await runHookWithShim(
1109
+ () =>
1110
+ config.hooks!.onBeforeUpdateConversation!(
1111
+ id,
1112
+ { title },
1113
+ context,
1114
+ ),
1115
+ ctx.error,
1116
+ "Unauthorized: Cannot update conversation",
1123
1117
  );
1124
- if (!canUpdate) {
1125
- throw ctx.error(403, {
1126
- message: "Unauthorized: Cannot update conversation",
1127
- });
1128
- }
1129
1118
  }
1130
1119
 
1131
1120
  const updated = await adapter.update<Conversation>({
@@ -1211,15 +1200,11 @@ export const aiChatBackendPlugin = <
1211
1200
 
1212
1201
  // Authorization hook
1213
1202
  if (config.hooks?.onBeforeDeleteConversation) {
1214
- const canDelete = await config.hooks.onBeforeDeleteConversation(
1215
- id,
1216
- context,
1203
+ await runHookWithShim(
1204
+ () => config.hooks!.onBeforeDeleteConversation!(id, context),
1205
+ ctx.error,
1206
+ "Unauthorized: Cannot delete conversation",
1217
1207
  );
1218
- if (!canDelete) {
1219
- throw ctx.error(403, {
1220
- message: "Unauthorized: Cannot delete conversation",
1221
- });
1222
- }
1223
1208
  }
1224
1209
 
1225
1210
  // Messages are automatically deleted via cascade (onDelete: "cascade")
@@ -1,6 +1,7 @@
1
1
  import {
2
2
  defineClientPlugin,
3
3
  createApiClient,
4
+ runClientHookWithShim,
4
5
  } from "@btst/stack/plugins/client";
5
6
  import { createRoute } from "@btst/yar";
6
7
  import type { QueryClient } from "@tanstack/react-query";
@@ -92,35 +93,33 @@ export interface AiChatClientConfig {
92
93
  */
93
94
  export interface AiChatClientHooks {
94
95
  /**
95
- * Called before loading conversations list. Return false to cancel loading.
96
+ * Called before loading conversations list. Throw an error to cancel loading.
96
97
  * @param context - Loader context with path, params, etc.
97
98
  */
98
- beforeLoadConversations?: (
99
- context: LoaderContext,
100
- ) => Promise<boolean> | boolean;
99
+ beforeLoadConversations?: (context: LoaderContext) => Promise<void> | void;
101
100
 
102
101
  /**
103
- * Called after conversations are loaded. Return false to cancel further processing.
102
+ * Called after conversations are loaded. Throw an error to cancel further processing.
104
103
  * @param conversations - Array of loaded conversations or null
105
104
  * @param context - Loader context
106
105
  */
107
106
  afterLoadConversations?: (
108
107
  conversations: SerializedConversation[] | null,
109
108
  context: LoaderContext,
110
- ) => Promise<boolean> | boolean;
109
+ ) => Promise<void> | void;
111
110
 
112
111
  /**
113
- * Called before loading a single conversation. Return false to cancel loading.
112
+ * Called before loading a single conversation. Throw an error to cancel loading.
114
113
  * @param id - Conversation ID being loaded
115
114
  * @param context - Loader context
116
115
  */
117
116
  beforeLoadConversation?: (
118
117
  id: string,
119
118
  context: LoaderContext,
120
- ) => Promise<boolean> | boolean;
119
+ ) => Promise<void> | void;
121
120
 
122
121
  /**
123
- * Called after a conversation is loaded. Return false to cancel further processing.
122
+ * Called after a conversation is loaded. Throw an error to cancel further processing.
124
123
  * @param conversation - Loaded conversation or null if not found
125
124
  * @param id - Conversation ID that was requested
126
125
  * @param context - Loader context
@@ -131,7 +130,7 @@ export interface AiChatClientHooks {
131
130
  | null,
132
131
  id: string,
133
132
  context: LoaderContext,
134
- ) => Promise<boolean> | boolean;
133
+ ) => Promise<void> | void;
135
134
 
136
135
  /**
137
136
  * Called when a loading error occurs
@@ -163,10 +162,10 @@ function createConversationsLoader(config: AiChatClientConfig) {
163
162
  try {
164
163
  // Before hook
165
164
  if (hooks?.beforeLoadConversations) {
166
- const canLoad = await hooks.beforeLoadConversations(context);
167
- if (!canLoad) {
168
- throw new Error("Load prevented by beforeLoadConversations hook");
169
- }
165
+ await runClientHookWithShim(
166
+ () => hooks.beforeLoadConversations!(context),
167
+ "Load prevented by beforeLoadConversations hook",
168
+ );
170
169
  }
171
170
 
172
171
  const client = createApiClient<AiChatApiRouter>({
@@ -185,13 +184,10 @@ function createConversationsLoader(config: AiChatClientConfig) {
185
184
  queryClient.getQueryData<SerializedConversation[]>(
186
185
  listQuery.queryKey,
187
186
  ) || null;
188
- const canContinue = await hooks.afterLoadConversations(
189
- conversations,
190
- context,
187
+ await runClientHookWithShim(
188
+ () => hooks.afterLoadConversations!(conversations, context),
189
+ "Load prevented by afterLoadConversations hook",
191
190
  );
192
- if (canContinue === false) {
193
- throw new Error("Load prevented by afterLoadConversations hook");
194
- }
195
191
  }
196
192
 
197
193
  // Check for errors
@@ -230,10 +226,10 @@ function createConversationLoader(id: string, config: AiChatClientConfig) {
230
226
  try {
231
227
  // Before hook
232
228
  if (hooks?.beforeLoadConversation) {
233
- const canLoad = await hooks.beforeLoadConversation(id, context);
234
- if (!canLoad) {
235
- throw new Error("Load prevented by beforeLoadConversation hook");
236
- }
229
+ await runClientHookWithShim(
230
+ () => hooks.beforeLoadConversation!(id, context),
231
+ "Load prevented by beforeLoadConversation hook",
232
+ );
237
233
  }
238
234
 
239
235
  const client = createApiClient<AiChatApiRouter>({
@@ -258,14 +254,10 @@ function createConversationLoader(id: string, config: AiChatClientConfig) {
258
254
  queryClient.getQueryData<
259
255
  SerializedConversation & { messages: SerializedMessage[] }
260
256
  >(conversationQuery.queryKey) || null;
261
- const canContinue = await hooks.afterLoadConversation(
262
- conversation,
263
- id,
264
- context,
257
+ await runClientHookWithShim(
258
+ () => hooks.afterLoadConversation!(conversation, id, context),
259
+ "Load prevented by afterLoadConversation hook",
265
260
  );
266
- if (canContinue === false) {
267
- throw new Error("Load prevented by afterLoadConversation hook");
268
- }
269
261
  }
270
262
 
271
263
  // Check for errors
@@ -10,6 +10,7 @@ import { getAllPosts, getPostBySlug, getAllTags } from "./getters";
10
10
  import { BLOG_QUERY_KEYS } from "./query-key-defs";
11
11
  import { serializePost, serializeTag } from "./serializers";
12
12
  import type { QueryClient } from "@tanstack/react-query";
13
+ import { runHookWithShim } from "../../utils";
13
14
 
14
15
  /**
15
16
  * Route keys for the blog plugin — matches the keys returned by
@@ -131,25 +132,25 @@ export interface BlogApiContext<TBody = any, TParams = any, TQuery = any> {
131
132
  */
132
133
  export interface BlogBackendHooks {
133
134
  /**
134
- * Called before listing posts. Return false to deny access.
135
+ * Called before listing posts. Throw an error to deny access.
135
136
  * @param filter - Query parameters for filtering posts
136
137
  * @param context - Request context with headers, etc.
137
138
  */
138
139
  onBeforeListPosts?: (
139
140
  filter: z.infer<typeof PostListQuerySchema>,
140
141
  context: BlogApiContext,
141
- ) => Promise<boolean> | boolean;
142
+ ) => Promise<void> | void;
142
143
  /**
143
- * Called before creating a post. Return false to deny access.
144
+ * Called before creating a post. Throw an error to deny access.
144
145
  * @param data - Post data being created
145
146
  * @param context - Request context with headers, etc.
146
147
  */
147
148
  onBeforeCreatePost?: (
148
149
  data: z.infer<typeof createPostSchema>,
149
150
  context: BlogApiContext,
150
- ) => Promise<boolean> | boolean;
151
+ ) => Promise<void> | void;
151
152
  /**
152
- * Called before updating a post. Return false to deny access.
153
+ * Called before updating a post. Throw an error to deny access.
153
154
  * @param postId - ID of the post being updated
154
155
  * @param data - Updated post data
155
156
  * @param context - Request context with headers, etc.
@@ -158,16 +159,16 @@ export interface BlogBackendHooks {
158
159
  postId: string,
159
160
  data: z.infer<typeof updatePostSchema>,
160
161
  context: BlogApiContext,
161
- ) => Promise<boolean> | boolean;
162
+ ) => Promise<void> | void;
162
163
  /**
163
- * Called before deleting a post. Return false to deny access.
164
+ * Called before deleting a post. Throw an error to deny access.
164
165
  * @param postId - ID of the post being deleted
165
166
  * @param context - Request context with headers, etc.
166
167
  */
167
168
  onBeforeDeletePost?: (
168
169
  postId: string,
169
170
  context: BlogApiContext,
170
- ) => Promise<boolean> | boolean;
171
+ ) => Promise<void> | void;
171
172
 
172
173
  /**
173
174
  * Called after posts are read successfully
@@ -350,12 +351,11 @@ export const blogBackendPlugin = (hooks?: BlogBackendHooks) =>
350
351
 
351
352
  try {
352
353
  if (hooks?.onBeforeListPosts) {
353
- const canList = await hooks.onBeforeListPosts(query, context);
354
- if (!canList) {
355
- throw ctx.error(403, {
356
- message: "Unauthorized: Cannot list posts",
357
- });
358
- }
354
+ await runHookWithShim(
355
+ () => hooks.onBeforeListPosts!(query, context),
356
+ ctx.error,
357
+ "Unauthorized: Cannot list posts",
358
+ );
359
359
  }
360
360
 
361
361
  const result = await getAllPosts(adapter, query);
@@ -387,15 +387,11 @@ export const blogBackendPlugin = (hooks?: BlogBackendHooks) =>
387
387
 
388
388
  try {
389
389
  if (hooks?.onBeforeCreatePost) {
390
- const canCreate = await hooks.onBeforeCreatePost(
391
- ctx.body,
392
- context,
390
+ await runHookWithShim(
391
+ () => hooks.onBeforeCreatePost!(ctx.body, context),
392
+ ctx.error,
393
+ "Unauthorized: Cannot create post",
393
394
  );
394
- if (!canCreate) {
395
- throw ctx.error(403, {
396
- message: "Unauthorized: Cannot create post",
397
- });
398
- }
399
395
  }
400
396
 
401
397
  const { tags, ...postData } = ctx.body;
@@ -471,16 +467,12 @@ export const blogBackendPlugin = (hooks?: BlogBackendHooks) =>
471
467
 
472
468
  try {
473
469
  if (hooks?.onBeforeUpdatePost) {
474
- const canUpdate = await hooks.onBeforeUpdatePost(
475
- ctx.params.id,
476
- ctx.body,
477
- context,
470
+ await runHookWithShim(
471
+ () =>
472
+ hooks.onBeforeUpdatePost!(ctx.params.id, ctx.body, context),
473
+ ctx.error,
474
+ "Unauthorized: Cannot update post",
478
475
  );
479
- if (!canUpdate) {
480
- throw ctx.error(403, {
481
- message: "Unauthorized: Cannot update post",
482
- });
483
- }
484
476
  }
485
477
 
486
478
  const { tags, slug: rawSlug, ...restPostData } = ctx.body;
@@ -598,15 +590,11 @@ export const blogBackendPlugin = (hooks?: BlogBackendHooks) =>
598
590
  try {
599
591
  // Authorization hook
600
592
  if (hooks?.onBeforeDeletePost) {
601
- const canDelete = await hooks.onBeforeDeletePost(
602
- ctx.params.id,
603
- context,
593
+ await runHookWithShim(
594
+ () => hooks.onBeforeDeletePost!(ctx.params.id, context),
595
+ ctx.error,
596
+ "Unauthorized: Cannot delete post",
604
597
  );
605
- if (!canDelete) {
606
- throw ctx.error(403, {
607
- message: "Unauthorized: Cannot delete post",
608
- });
609
- }
610
598
  }
611
599
 
612
600
  await adapter.delete<Post>({
@@ -642,15 +630,11 @@ export const blogBackendPlugin = (hooks?: BlogBackendHooks) =>
642
630
 
643
631
  try {
644
632
  if (hooks?.onBeforeListPosts) {
645
- const canList = await hooks.onBeforeListPosts(
646
- { published: true },
647
- context,
633
+ await runHookWithShim(
634
+ () => hooks.onBeforeListPosts!({ published: true }, context),
635
+ ctx.error,
636
+ "Unauthorized: Cannot list posts",
648
637
  );
649
- if (!canList) {
650
- throw ctx.error(403, {
651
- message: "Unauthorized: Cannot list posts",
652
- });
653
- }
654
638
  }
655
639
 
656
640
  const date = query.date;
@@ -2,6 +2,7 @@ import {
2
2
  defineClientPlugin,
3
3
  createApiClient,
4
4
  isConnectionError,
5
+ runClientHookWithShim,
5
6
  } from "@btst/stack/plugins/client";
6
7
  import { createRoute } from "@btst/yar";
7
8
  import type { QueryClient } from "@tanstack/react-query";
@@ -91,16 +92,16 @@ export interface BlogClientConfig {
91
92
  */
92
93
  export interface BlogClientHooks {
93
94
  /**
94
- * Called before loading posts list. Return false to cancel loading.
95
+ * Called before loading posts list. Throw an error to cancel loading.
95
96
  * @param filter - Filter parameters including published status
96
97
  * @param context - Loader context with path, params, etc.
97
98
  */
98
99
  beforeLoadPosts?: (
99
100
  filter: { published: boolean },
100
101
  context: LoaderContext,
101
- ) => Promise<boolean> | boolean;
102
+ ) => Promise<void> | void;
102
103
  /**
103
- * Called after posts are loaded. Return false to cancel further processing.
104
+ * Called after posts are loaded. Throw an error to cancel further processing.
104
105
  * @param posts - Array of loaded posts or null
105
106
  * @param filter - Filter parameters used
106
107
  * @param context - Loader context
@@ -109,18 +110,18 @@ export interface BlogClientHooks {
109
110
  posts: Post[] | null,
110
111
  filter: { published: boolean },
111
112
  context: LoaderContext,
112
- ) => Promise<boolean> | boolean;
113
+ ) => Promise<void> | void;
113
114
  /**
114
- * Called before loading a single post. Return false to cancel loading.
115
+ * Called before loading a single post. Throw an error to cancel loading.
115
116
  * @param slug - Post slug being loaded
116
117
  * @param context - Loader context
117
118
  */
118
119
  beforeLoadPost?: (
119
120
  slug: string,
120
121
  context: LoaderContext,
121
- ) => Promise<boolean> | boolean;
122
+ ) => Promise<void> | void;
122
123
  /**
123
- * Called after a post is loaded. Return false to cancel further processing.
124
+ * Called after a post is loaded. Throw an error to cancel further processing.
124
125
  * @param post - Loaded post or null if not found
125
126
  * @param slug - Post slug that was requested
126
127
  * @param context - Loader context
@@ -129,17 +130,17 @@ export interface BlogClientHooks {
129
130
  post: Post | null,
130
131
  slug: string,
131
132
  context: LoaderContext,
132
- ) => Promise<boolean> | boolean;
133
+ ) => Promise<void> | void;
133
134
  /**
134
- * Called before loading the new post page. Return false to cancel.
135
+ * Called before loading the new post page. Throw an error to cancel.
135
136
  * @param context - Loader context
136
137
  */
137
- beforeLoadNewPost?: (context: LoaderContext) => Promise<boolean> | boolean;
138
+ beforeLoadNewPost?: (context: LoaderContext) => Promise<void> | void;
138
139
  /**
139
- * Called after the new post page is loaded. Return false to cancel.
140
+ * Called after the new post page is loaded. Throw an error to cancel.
140
141
  * @param context - Loader context
141
142
  */
142
- afterLoadNewPost?: (context: LoaderContext) => Promise<boolean> | boolean;
143
+ afterLoadNewPost?: (context: LoaderContext) => Promise<void> | void;
143
144
  /**
144
145
  * Called when a loading error occurs
145
146
  * @param error - The error that occurred
@@ -165,10 +166,10 @@ function createPostsLoader(published: boolean, config: BlogClientConfig) {
165
166
  try {
166
167
  // Before hook
167
168
  if (hooks?.beforeLoadPosts) {
168
- const canLoad = await hooks.beforeLoadPosts({ published }, context);
169
- if (!canLoad) {
170
- throw new Error("Load prevented by beforeLoadPosts hook");
171
- }
169
+ await runClientHookWithShim(
170
+ () => hooks.beforeLoadPosts!({ published }, context),
171
+ "Load prevented by beforeLoadPosts hook",
172
+ );
172
173
  }
173
174
 
174
175
  const limit = 10;
@@ -202,14 +203,10 @@ function createPostsLoader(published: boolean, config: BlogClientConfig) {
202
203
  if (hooks?.afterLoadPosts) {
203
204
  const posts =
204
205
  queryClient.getQueryData<Post[]>(listQuery.queryKey) || null;
205
- const canContinue = await hooks.afterLoadPosts(
206
- posts,
207
- { published },
208
- context,
206
+ await runClientHookWithShim(
207
+ () => hooks.afterLoadPosts!(posts, { published }, context),
208
+ "Load prevented by afterLoadPosts hook",
209
209
  );
210
- if (canContinue === false) {
211
- throw new Error("Load prevented by afterLoadPosts hook");
212
- }
213
210
  }
214
211
 
215
212
  // Check if there was an error after afterLoadPosts hook
@@ -263,10 +260,10 @@ function createPostLoader(
263
260
  try {
264
261
  // Before hook
265
262
  if (hooks?.beforeLoadPost) {
266
- const canLoad = await hooks.beforeLoadPost(slug, context);
267
- if (!canLoad) {
268
- throw new Error("Load prevented by beforeLoadPost hook");
269
- }
263
+ await runClientHookWithShim(
264
+ () => hooks.beforeLoadPost!(slug, context),
265
+ "Load prevented by beforeLoadPost hook",
266
+ );
270
267
  }
271
268
 
272
269
  const client = createApiClient<BlogApiRouter>({
@@ -285,10 +282,10 @@ function createPostLoader(
285
282
  if (hooks?.afterLoadPost) {
286
283
  const post =
287
284
  queryClient.getQueryData<Post>(postQuery.queryKey) || null;
288
- const canContinue = await hooks.afterLoadPost(post, slug, context);
289
- if (canContinue === false) {
290
- throw new Error("Load prevented by afterLoadPost hook");
291
- }
285
+ await runClientHookWithShim(
286
+ () => hooks.afterLoadPost!(post, slug, context),
287
+ "Load prevented by afterLoadPost hook",
288
+ );
292
289
  }
293
290
 
294
291
  // Check if there was an error after afterLoadPost hook
@@ -337,18 +334,18 @@ function createNewPostLoader(config: BlogClientConfig) {
337
334
  try {
338
335
  // Before hook
339
336
  if (hooks?.beforeLoadNewPost) {
340
- const canLoad = await hooks.beforeLoadNewPost(context);
341
- if (!canLoad) {
342
- throw new Error("Load prevented by beforeLoadNewPost hook");
343
- }
337
+ await runClientHookWithShim(
338
+ () => hooks.beforeLoadNewPost!(context),
339
+ "Load prevented by beforeLoadNewPost hook",
340
+ );
344
341
  }
345
342
 
346
343
  // After hook
347
344
  if (hooks?.afterLoadNewPost) {
348
- const canContinue = await hooks.afterLoadNewPost(context);
349
- if (canContinue === false) {
350
- throw new Error("Load prevented by afterLoadNewPost hook");
351
- }
345
+ await runClientHookWithShim(
346
+ () => hooks.afterLoadNewPost!(context),
347
+ "Load prevented by afterLoadNewPost hook",
348
+ );
352
349
  }
353
350
  } catch (error) {
354
351
  // Error hook - log the error but don't throw during SSR
@@ -18,7 +18,11 @@ export type {
18
18
  PluginOverrides,
19
19
  } from "../../types";
20
20
 
21
- export { createApiClient, isConnectionError } from "../utils";
21
+ export {
22
+ createApiClient,
23
+ isConnectionError,
24
+ runClientHookWithShim,
25
+ } from "../utils";
22
26
 
23
27
  // Re-export Yar types needed for plugins
24
28
  export type { Route } from "@btst/yar";